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