]> git.saurik.com Git - apple/mdnsresponder.git/blob - Clients/ExplorerPlugin/ExplorerBar.cpp
mDNSResponder-258.13.tar.gz
[apple/mdnsresponder.git] / Clients / ExplorerPlugin / ExplorerBar.cpp
1 /* -*- Mode: C; tab-width: 4 -*-
2 *
3 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "StdAfx.h"
19
20 #include "comutil.h"
21 #include "ShObjIdl.h"
22
23 #include "DebugServices.h"
24
25 #include "Resource.h"
26
27 #include "ExplorerBar.h"
28
29 #include "About.h"
30 // MFC Debugging
31
32 #ifdef _DEBUG
33 #define new DEBUG_NEW
34 #undef THIS_FILE
35 static char THIS_FILE[] = __FILE__;
36 #endif
37
38 //===========================================================================================================================
39 // Constants
40 //===========================================================================================================================
41 #define LENGTHOF(a) (sizeof(a) == sizeof(&*a)) ? 0 : (sizeof(a) / sizeof(*a))
42 #define MIN_SIZE_X 10
43 #define MIN_SIZE_Y 10
44
45 //===========================================================================================================================
46 // ExplorerBar
47 //===========================================================================================================================
48
49 ExplorerBar::ExplorerBar( void )
50 {
51 ++gDLLRefCount;
52
53 mRefCount = 1;
54 mSite = NULL;
55 mWebBrowser = NULL;
56 mParentWindow = NULL;
57 mFocus = FALSE;
58 mViewMode = 0;
59 mBandID = 0;
60 }
61
62 //===========================================================================================================================
63 // ~ExplorerBar
64 //===========================================================================================================================
65
66 ExplorerBar::~ExplorerBar( void )
67 {
68 if( mWebBrowser )
69 {
70 mWebBrowser->Release();
71 mWebBrowser = NULL;
72 }
73 if( mSite )
74 {
75 mSite->Release();
76 mSite = NULL;
77 }
78
79 --gDLLRefCount;
80 }
81
82 #if 0
83 #pragma mark -
84 #pragma mark == IUnknown implementation ==
85 #endif
86
87 //===========================================================================================================================
88 // QueryInterface
89 //===========================================================================================================================
90
91 STDMETHODIMP ExplorerBar::QueryInterface( REFIID inID, LPVOID *outResult )
92 {
93 HRESULT err;
94
95 if( IsEqualIID( inID, IID_IUnknown ) ) // IUnknown
96 {
97 *outResult = this;
98 }
99 else if( IsEqualIID( inID, IID_IOleWindow ) ) // IOleWindow
100 {
101 *outResult = (IOleWindow *) this;
102 }
103 else if( IsEqualIID( inID, IID_IDockingWindow ) ) // IDockingWindow
104 {
105 *outResult = (IDockingWindow *) this;
106 }
107 else if( IsEqualIID( inID, IID_IDeskBand ) ) // IDeskBand
108 {
109 *outResult = (IDeskBand *) this;
110 }
111 else if( IsEqualIID( inID, IID_IInputObject ) ) // IInputObject
112 {
113 *outResult = (IInputObject *) this;
114 }
115 else if( IsEqualIID( inID, IID_IObjectWithSite ) ) // IObjectWithSite
116 {
117 *outResult = (IObjectWithSite *) this;
118 }
119 else if( IsEqualIID( inID, IID_IPersistStream ) ) // IPersistStream
120 {
121 *outResult = (IPersistStream *) this;
122 }
123 else if( IsEqualIID( inID, IID_IContextMenu ) ) // IContextMenu
124 {
125 *outResult = (IContextMenu *) this;
126 }
127 else
128 {
129 *outResult = NULL;
130 err = E_NOINTERFACE;
131 goto exit;
132 }
133
134 ( *( (LPUNKNOWN *) outResult ) )->AddRef();
135 err = S_OK;
136
137 exit:
138 return( err );
139 }
140
141 //===========================================================================================================================
142 // AddRef
143 //===========================================================================================================================
144
145 STDMETHODIMP_( DWORD ) ExplorerBar::AddRef( void )
146 {
147 return( ++mRefCount );
148 }
149
150 //===========================================================================================================================
151 // Release
152 //===========================================================================================================================
153
154 STDMETHODIMP_( DWORD ) ExplorerBar::Release( void )
155 {
156 DWORD count;
157
158 count = --mRefCount;
159 if( count == 0 )
160 {
161 delete this;
162 }
163 return( count );
164 }
165
166 #if 0
167 #pragma mark -
168 #pragma mark == IOleWindow implementation ==
169 #endif
170
171 //===========================================================================================================================
172 // GetWindow
173 //===========================================================================================================================
174
175 STDMETHODIMP ExplorerBar::GetWindow( HWND *outWindow )
176 {
177 *outWindow = mWindow.GetSafeHwnd();
178 return( S_OK );
179 }
180
181 //===========================================================================================================================
182 // ContextSensitiveHelp
183 //===========================================================================================================================
184
185 STDMETHODIMP ExplorerBar::ContextSensitiveHelp( BOOL inEnterMode )
186 {
187 DEBUG_UNUSED( inEnterMode );
188
189 return( E_NOTIMPL );
190 }
191
192 #if 0
193 #pragma mark -
194 #pragma mark == IDockingWindow implementation ==
195 #endif
196
197 //===========================================================================================================================
198 // ShowDW
199 //===========================================================================================================================
200
201 STDMETHODIMP ExplorerBar::ShowDW( BOOL inShow )
202 {
203 if( mWindow.GetSafeHwnd() )
204 {
205 mWindow.ShowWindow( inShow ? SW_SHOW : SW_HIDE );
206 }
207 return( S_OK );
208 }
209
210 //===========================================================================================================================
211 // CloseDW
212 //===========================================================================================================================
213
214 STDMETHODIMP ExplorerBar::CloseDW( DWORD inReserved )
215 {
216 DEBUG_UNUSED( inReserved );
217
218 ShowDW( FALSE );
219 if( mWindow.GetSafeHwnd() )
220 {
221 mWindow.SendMessage( WM_CLOSE );
222 }
223 return( S_OK );
224 }
225
226 //===========================================================================================================================
227 // ResizeBorderDW
228 //===========================================================================================================================
229
230 STDMETHODIMP ExplorerBar::ResizeBorderDW( LPCRECT inBorder, IUnknown *inPunkSite, BOOL inReserved )
231 {
232 DEBUG_UNUSED( inBorder );
233 DEBUG_UNUSED( inPunkSite );
234 DEBUG_UNUSED( inReserved );
235
236 return( E_NOTIMPL );
237 }
238
239 #if 0
240 #pragma mark -
241 #pragma mark == IDeskBand implementation ==
242 #endif
243
244 //===========================================================================================================================
245 // GetBandInfo
246 //===========================================================================================================================
247
248 STDMETHODIMP ExplorerBar::GetBandInfo( DWORD inBandID, DWORD inViewMode, DESKBANDINFO *outInfo )
249 {
250 HRESULT err;
251
252 require_action( outInfo, exit, err = E_INVALIDARG );
253
254 mBandID = inBandID;
255 mViewMode = inViewMode;
256
257 if( outInfo->dwMask & DBIM_MINSIZE )
258 {
259 outInfo->ptMinSize.x = 100;
260 outInfo->ptMinSize.y = 100;
261 }
262 if( outInfo->dwMask & DBIM_MAXSIZE )
263 {
264 // Unlimited max size.
265
266 outInfo->ptMaxSize.x = -1;
267 outInfo->ptMaxSize.y = -1;
268 }
269 if( outInfo->dwMask & DBIM_INTEGRAL )
270 {
271 outInfo->ptIntegral.x = 1;
272 outInfo->ptIntegral.y = 1;
273 }
274 if( outInfo->dwMask & DBIM_ACTUAL )
275 {
276 outInfo->ptActual.x = 0;
277 outInfo->ptActual.y = 0;
278 }
279 if( outInfo->dwMask & DBIM_TITLE )
280 {
281 CString s;
282 BOOL ok;
283
284 ok = s.LoadString( IDS_NAME );
285 require_action( ok, exit, err = kNoResourcesErr );
286
287 #ifdef UNICODE
288 lstrcpyn( outInfo->wszTitle, s, sizeof_array( outInfo->wszTitle ) );
289 #else
290 DWORD nChars;
291
292 nChars = MultiByteToWideChar( CP_ACP, 0, s, -1, outInfo->wszTitle, sizeof_array( outInfo->wszTitle ) );
293 err = translate_errno( nChars > 0, (OSStatus) GetLastError(), kUnknownErr );
294 require_noerr( err, exit );
295 #endif
296 }
297 if( outInfo->dwMask & DBIM_MODEFLAGS )
298 {
299 outInfo->dwModeFlags = DBIMF_NORMAL | DBIMF_VARIABLEHEIGHT;
300 }
301
302 // Force the default background color.
303
304 outInfo->dwMask &= ~DBIM_BKCOLOR;
305 err = S_OK;
306
307 exit:
308 return( err );
309 }
310
311 #if 0
312 #pragma mark -
313 #pragma mark == IInputObject implementation ==
314 #endif
315
316 //===========================================================================================================================
317 // UIActivateIO
318 //===========================================================================================================================
319
320 STDMETHODIMP ExplorerBar::UIActivateIO( BOOL inActivate, LPMSG inMsg )
321 {
322 DEBUG_UNUSED( inMsg );
323
324 if( inActivate )
325 {
326 mWindow.SetFocus();
327 }
328 return( S_OK );
329 }
330
331 //===========================================================================================================================
332 // HasFocusIO
333 //===========================================================================================================================
334
335 STDMETHODIMP ExplorerBar::HasFocusIO( void )
336 {
337 if( mWindow.GetFocus()->GetSafeHwnd() == mWindow.GetSafeHwnd() )
338 {
339 return( S_OK );
340 }
341 return( S_FALSE );
342 }
343
344 //===========================================================================================================================
345 // TranslateAcceleratorIO
346 //===========================================================================================================================
347
348 STDMETHODIMP ExplorerBar::TranslateAcceleratorIO( LPMSG inMsg )
349 {
350 DEBUG_UNUSED( inMsg );
351
352 return( S_FALSE );
353 }
354
355 #if 0
356 #pragma mark -
357 #pragma mark == IObjectWithSite implementation ==
358 #endif
359
360 //===========================================================================================================================
361 // SetSite
362 //===========================================================================================================================
363
364 STDMETHODIMP ExplorerBar::SetSite( IUnknown *inPunkSite )
365 {
366 AFX_MANAGE_STATE( AfxGetStaticModuleState() );
367
368 HRESULT err;
369
370 // Release the old interfaces.
371
372 if( mWebBrowser )
373 {
374 mWebBrowser->Release();
375 mWebBrowser = NULL;
376 }
377 if( mSite )
378 {
379 mSite->Release();
380 mSite = NULL;
381 }
382
383 // A non-NULL site means we're setting the site. Otherwise, the site is being released (done above).
384
385 if( !inPunkSite )
386 {
387 err = S_OK;
388 goto exit;
389 }
390
391 // Get the parent window.
392
393 IOleWindow * oleWindow;
394
395 mParentWindow = NULL;
396 err = inPunkSite->QueryInterface( IID_IOleWindow, (LPVOID *) &oleWindow );
397 require( SUCCEEDED( err ), exit );
398
399 err = oleWindow->GetWindow( &mParentWindow );
400 oleWindow->Release();
401 require_noerr( err, exit );
402 require_action( mParentWindow, exit, err = E_FAIL );
403
404 // Get the IInputObject interface.
405
406 err = inPunkSite->QueryInterface( IID_IInputObjectSite, (LPVOID *) &mSite );
407 require( SUCCEEDED( err ), exit );
408 check( mSite );
409
410 // Get the IWebBrowser2 interface.
411
412 IOleCommandTarget * oleCommandTarget;
413
414 err = inPunkSite->QueryInterface( IID_IOleCommandTarget, (LPVOID *) &oleCommandTarget );
415 require( SUCCEEDED( err ), exit );
416
417 IServiceProvider * serviceProvider;
418
419 err = oleCommandTarget->QueryInterface( IID_IServiceProvider, (LPVOID *) &serviceProvider );
420 oleCommandTarget->Release();
421 require( SUCCEEDED( err ), exit );
422
423 err = serviceProvider->QueryService( SID_SWebBrowserApp, IID_IWebBrowser2, (LPVOID *) &mWebBrowser );
424 serviceProvider->Release();
425 require( SUCCEEDED( err ), exit );
426
427 // Create the main window.
428
429 err = SetupWindow();
430 require_noerr( err, exit );
431
432 exit:
433 return( err );
434 }
435
436 //===========================================================================================================================
437 // GetSite
438 //===========================================================================================================================
439
440 STDMETHODIMP ExplorerBar::GetSite( REFIID inID, LPVOID *outResult )
441 {
442 HRESULT err;
443
444 *outResult = NULL;
445 require_action( mSite, exit, err = E_FAIL );
446
447 err = mSite->QueryInterface( inID, outResult );
448
449 exit:
450 return( err );
451 }
452
453 #if 0
454 #pragma mark -
455 #pragma mark == IPersistStream implementation ==
456 #endif
457
458 //
459 // IPersistStream implementation
460 //
461 // This is only supported to allow the desk band to be dropped on the desktop and to prevent multiple instances of
462 // the desk band from showing up in the context menu. This desk band doesn't actually persist any data.
463 //
464
465 //===========================================================================================================================
466 // GetClassID
467 //===========================================================================================================================
468
469 STDMETHODIMP ExplorerBar::GetClassID( LPCLSID outClassID )
470 {
471 *outClassID = CLSID_ExplorerBar;
472 return( S_OK );
473 }
474
475 //===========================================================================================================================
476 // IsDirty
477 //===========================================================================================================================
478
479 STDMETHODIMP ExplorerBar::IsDirty( void )
480 {
481 return( S_FALSE );
482 }
483
484 //===========================================================================================================================
485 // Load
486 //===========================================================================================================================
487
488 STDMETHODIMP ExplorerBar::Load( LPSTREAM inStream )
489 {
490 DEBUG_UNUSED( inStream );
491
492 return( S_OK );
493 }
494
495 //===========================================================================================================================
496 // Save
497 //===========================================================================================================================
498
499 STDMETHODIMP ExplorerBar::Save( LPSTREAM inStream, BOOL inClearDirty )
500 {
501 DEBUG_UNUSED( inStream );
502 DEBUG_UNUSED( inClearDirty );
503
504 return( S_OK );
505 }
506
507 //===========================================================================================================================
508 // GetSizeMax
509 //===========================================================================================================================
510
511 STDMETHODIMP ExplorerBar::GetSizeMax( ULARGE_INTEGER *outSizeMax )
512 {
513 DEBUG_UNUSED( outSizeMax );
514
515 return( E_NOTIMPL );
516 }
517
518
519 //===========================================================================================================================
520 // QueryContextMenu
521 //===========================================================================================================================
522
523 STDMETHODIMP ExplorerBar::QueryContextMenu(HMENU hShellContextMenu, UINT iContextMenuFirstItem, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
524 {
525 DEBUG_UNUSED( idCmdLast );
526 DEBUG_UNUSED( uFlags );
527
528 CMenu menubar;
529
530 menubar.LoadMenu(IDR_CONTEXT_MENU);
531 CMenu * menu = menubar.GetSubMenu(0);
532
533 CMenu shellmenu;
534
535 shellmenu.Attach(hShellContextMenu);
536
537 UINT iShellItem = iContextMenuFirstItem; //! remove plus one
538 UINT idShellCmd = idCmdFirst;
539
540 int n = menu->GetMenuItemCount();
541
542 for (int i=0; i<n; ++i)
543 {
544 MENUITEMINFO mii;
545 TCHAR sz[128] = {0};
546
547 ZeroMemory(&mii, sizeof(mii));
548 mii.fMask = MIIM_TYPE | MIIM_ID;
549 mii.fType = MFT_STRING;
550 mii.cbSize = sizeof(mii);
551 mii.cch = LENGTHOF(sz);
552 mii.dwTypeData = sz;
553
554 menu->GetMenuItemInfo(i, &mii, TRUE);
555
556 mii.wID = idShellCmd++;
557
558 shellmenu.InsertMenuItem(iShellItem++, &mii, TRUE);
559 }
560
561 shellmenu.Detach();
562
563 return n;
564 }
565
566
567 //===========================================================================================================================
568 // GetCommandString
569 //===========================================================================================================================
570
571 // Not called for explorer bars
572 STDMETHODIMP ExplorerBar::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pwReserved, LPSTR pszName, UINT cchMax)
573 {
574 DEBUG_UNUSED( idCmd );
575 DEBUG_UNUSED( uType );
576 DEBUG_UNUSED( pwReserved );
577 DEBUG_UNUSED( pszName );
578 DEBUG_UNUSED( cchMax );
579
580 return E_NOTIMPL;
581 }
582
583 //===========================================================================================================================
584 // InvokeCommand
585 //===========================================================================================================================
586
587 // The shell sends either strings or indexes
588 // IE never sends strings
589 // The indexes are into an array of my commands
590 // So the verb for the first command I added to the menu is always 0x0000
591 // Here - because I don't have any submenus -
592 // I can treat the 'verb' as an menu item position
593 STDMETHODIMP ExplorerBar::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
594 {
595 // IE doesn't send string commands
596 if (HIWORD(lpici->lpVerb) != 0) return 0;
597
598 CAbout dlg;
599
600 dlg.DoModal();
601
602 return S_OK;
603 }
604
605 #if 0
606 #pragma mark -
607 #pragma mark == Other ==
608 #endif
609
610 //===========================================================================================================================
611 // SetupWindow
612 //===========================================================================================================================
613
614 OSStatus ExplorerBar::SetupWindow( void )
615 {
616 OSStatus err;
617 CWnd * window;
618 CRect rect;
619 CString s;
620 BOOL ok;
621
622 window = CWnd::FromHandle( mParentWindow );
623 check( window );
624 window->GetClientRect( rect );
625
626 ok = s.LoadString( IDS_NAME );
627 require_action( ok, exit, err = kNoResourcesErr );
628
629 ok = mWindow.Create( NULL, s, WS_CHILD | WS_VISIBLE, rect, window, 100 ) != 0;
630 require_action( ok, exit, err = kNoResourcesErr );
631
632 mWindow.SetOwner( this );
633 err = kNoErr;
634
635 exit:
636 return( err );
637 }
638
639 //===========================================================================================================================
640 // GoToURL
641 //===========================================================================================================================
642
643 OSStatus ExplorerBar::GoToURL( const CString &inURL )
644 {
645 OSStatus err;
646 BSTR s;
647 VARIANT empty;
648
649 s = inURL.AllocSysString();
650 require_action( s, exit, err = kNoMemoryErr );
651
652 VariantInit( &empty );
653 err = mWebBrowser->Navigate( s, &empty, &empty, &empty, &empty );
654 SysFreeString( s );
655 require_noerr( err, exit );
656
657 exit:
658 return( err );
659 }