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