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