1 /* -*- Mode: C; tab-width: 4 -*-
3 * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "DebugServices.h"
27 #include "ExplorerBar.h"
35 static char THIS_FILE
[] = __FILE__
;
38 //===========================================================================================================================
40 //===========================================================================================================================
41 #define LENGTHOF(a) (sizeof(a) == sizeof(&*a)) ? 0 : (sizeof(a) / sizeof(*a))
45 //===========================================================================================================================
47 //===========================================================================================================================
49 ExplorerBar::ExplorerBar( void )
62 //===========================================================================================================================
64 //===========================================================================================================================
66 ExplorerBar::~ExplorerBar( void )
70 mWebBrowser
->Release();
84 #pragma mark == IUnknown implementation ==
87 //===========================================================================================================================
89 //===========================================================================================================================
91 STDMETHODIMP
ExplorerBar::QueryInterface( REFIID inID
, LPVOID
*outResult
)
95 if( IsEqualIID( inID
, IID_IUnknown
) ) // IUnknown
99 else if( IsEqualIID( inID
, IID_IOleWindow
) ) // IOleWindow
101 *outResult
= (IOleWindow
*) this;
103 else if( IsEqualIID( inID
, IID_IDockingWindow
) ) // IDockingWindow
105 *outResult
= (IDockingWindow
*) this;
107 else if( IsEqualIID( inID
, IID_IDeskBand
) ) // IDeskBand
109 *outResult
= (IDeskBand
*) this;
111 else if( IsEqualIID( inID
, IID_IInputObject
) ) // IInputObject
113 *outResult
= (IInputObject
*) this;
115 else if( IsEqualIID( inID
, IID_IObjectWithSite
) ) // IObjectWithSite
117 *outResult
= (IObjectWithSite
*) this;
119 else if( IsEqualIID( inID
, IID_IPersistStream
) ) // IPersistStream
121 *outResult
= (IPersistStream
*) this;
123 else if( IsEqualIID( inID
, IID_IContextMenu
) ) // IContextMenu
125 *outResult
= (IContextMenu
*) this;
134 ( *( (LPUNKNOWN
*) outResult
) )->AddRef();
141 //===========================================================================================================================
143 //===========================================================================================================================
145 STDMETHODIMP_( DWORD
) ExplorerBar::AddRef( void )
147 return( ++mRefCount
);
150 //===========================================================================================================================
152 //===========================================================================================================================
154 STDMETHODIMP_( DWORD
) ExplorerBar::Release( void )
168 #pragma mark == IOleWindow implementation ==
171 //===========================================================================================================================
173 //===========================================================================================================================
175 STDMETHODIMP
ExplorerBar::GetWindow( HWND
*outWindow
)
177 *outWindow
= mWindow
.GetSafeHwnd();
181 //===========================================================================================================================
182 // ContextSensitiveHelp
183 //===========================================================================================================================
185 STDMETHODIMP
ExplorerBar::ContextSensitiveHelp( BOOL inEnterMode
)
187 DEBUG_UNUSED( inEnterMode
);
194 #pragma mark == IDockingWindow implementation ==
197 //===========================================================================================================================
199 //===========================================================================================================================
201 STDMETHODIMP
ExplorerBar::ShowDW( BOOL inShow
)
203 if( mWindow
.GetSafeHwnd() )
205 mWindow
.ShowWindow( inShow
? SW_SHOW
: SW_HIDE
);
210 //===========================================================================================================================
212 //===========================================================================================================================
214 STDMETHODIMP
ExplorerBar::CloseDW( DWORD inReserved
)
216 DEBUG_UNUSED( inReserved
);
219 if( mWindow
.GetSafeHwnd() )
221 mWindow
.SendMessage( WM_CLOSE
);
226 //===========================================================================================================================
228 //===========================================================================================================================
230 STDMETHODIMP
ExplorerBar::ResizeBorderDW( LPCRECT inBorder
, IUnknown
*inPunkSite
, BOOL inReserved
)
232 DEBUG_UNUSED( inBorder
);
233 DEBUG_UNUSED( inPunkSite
);
234 DEBUG_UNUSED( inReserved
);
241 #pragma mark == IDeskBand implementation ==
244 //===========================================================================================================================
246 //===========================================================================================================================
248 STDMETHODIMP
ExplorerBar::GetBandInfo( DWORD inBandID
, DWORD inViewMode
, DESKBANDINFO
*outInfo
)
252 require_action( outInfo
, exit
, err
= E_INVALIDARG
);
255 mViewMode
= inViewMode
;
257 if( outInfo
->dwMask
& DBIM_MINSIZE
)
259 outInfo
->ptMinSize
.x
= 100;
260 outInfo
->ptMinSize
.y
= 100;
262 if( outInfo
->dwMask
& DBIM_MAXSIZE
)
264 // Unlimited max size.
266 outInfo
->ptMaxSize
.x
= -1;
267 outInfo
->ptMaxSize
.y
= -1;
269 if( outInfo
->dwMask
& DBIM_INTEGRAL
)
271 outInfo
->ptIntegral
.x
= 1;
272 outInfo
->ptIntegral
.y
= 1;
274 if( outInfo
->dwMask
& DBIM_ACTUAL
)
276 outInfo
->ptActual
.x
= 0;
277 outInfo
->ptActual
.y
= 0;
279 if( outInfo
->dwMask
& DBIM_TITLE
)
284 ok
= s
.LoadString( IDS_NAME
);
285 require_action( ok
, exit
, err
= kNoResourcesErr
);
288 lstrcpyn( outInfo
->wszTitle
, s
, sizeof_array( outInfo
->wszTitle
) );
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
);
297 if( outInfo
->dwMask
& DBIM_MODEFLAGS
)
299 outInfo
->dwModeFlags
= DBIMF_NORMAL
| DBIMF_VARIABLEHEIGHT
;
302 // Force the default background color.
304 outInfo
->dwMask
&= ~DBIM_BKCOLOR
;
313 #pragma mark == IInputObject implementation ==
316 //===========================================================================================================================
318 //===========================================================================================================================
320 STDMETHODIMP
ExplorerBar::UIActivateIO( BOOL inActivate
, LPMSG inMsg
)
322 DEBUG_UNUSED( inMsg
);
331 //===========================================================================================================================
333 //===========================================================================================================================
335 STDMETHODIMP
ExplorerBar::HasFocusIO( void )
337 if( mWindow
.GetFocus()->GetSafeHwnd() == mWindow
.GetSafeHwnd() )
344 //===========================================================================================================================
345 // TranslateAcceleratorIO
346 //===========================================================================================================================
348 STDMETHODIMP
ExplorerBar::TranslateAcceleratorIO( LPMSG inMsg
)
350 DEBUG_UNUSED( inMsg
);
357 #pragma mark == IObjectWithSite implementation ==
360 //===========================================================================================================================
362 //===========================================================================================================================
364 STDMETHODIMP
ExplorerBar::SetSite( IUnknown
*inPunkSite
)
366 AFX_MANAGE_STATE( AfxGetStaticModuleState() );
370 // Release the old interfaces.
374 mWebBrowser
->Release();
383 // A non-NULL site means we're setting the site. Otherwise, the site is being released (done above).
391 // Get the parent window.
393 IOleWindow
* oleWindow
;
395 mParentWindow
= NULL
;
396 err
= inPunkSite
->QueryInterface( IID_IOleWindow
, (LPVOID
*) &oleWindow
);
397 require( SUCCEEDED( err
), exit
);
399 err
= oleWindow
->GetWindow( &mParentWindow
);
400 oleWindow
->Release();
401 require_noerr( err
, exit
);
402 require_action( mParentWindow
, exit
, err
= E_FAIL
);
404 // Get the IInputObject interface.
406 err
= inPunkSite
->QueryInterface( IID_IInputObjectSite
, (LPVOID
*) &mSite
);
407 require( SUCCEEDED( err
), exit
);
410 // Get the IWebBrowser2 interface.
412 IOleCommandTarget
* oleCommandTarget
;
414 err
= inPunkSite
->QueryInterface( IID_IOleCommandTarget
, (LPVOID
*) &oleCommandTarget
);
415 require( SUCCEEDED( err
), exit
);
417 IServiceProvider
* serviceProvider
;
419 err
= oleCommandTarget
->QueryInterface( IID_IServiceProvider
, (LPVOID
*) &serviceProvider
);
420 oleCommandTarget
->Release();
421 require( SUCCEEDED( err
), exit
);
423 err
= serviceProvider
->QueryService( SID_SWebBrowserApp
, IID_IWebBrowser2
, (LPVOID
*) &mWebBrowser
);
424 serviceProvider
->Release();
425 require( SUCCEEDED( err
), exit
);
427 // Create the main window.
430 require_noerr( err
, exit
);
436 //===========================================================================================================================
438 //===========================================================================================================================
440 STDMETHODIMP
ExplorerBar::GetSite( REFIID inID
, LPVOID
*outResult
)
445 require_action( mSite
, exit
, err
= E_FAIL
);
447 err
= mSite
->QueryInterface( inID
, outResult
);
455 #pragma mark == IPersistStream implementation ==
459 // IPersistStream implementation
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.
465 //===========================================================================================================================
467 //===========================================================================================================================
469 STDMETHODIMP
ExplorerBar::GetClassID( LPCLSID outClassID
)
471 *outClassID
= CLSID_ExplorerBar
;
475 //===========================================================================================================================
477 //===========================================================================================================================
479 STDMETHODIMP
ExplorerBar::IsDirty( void )
484 //===========================================================================================================================
486 //===========================================================================================================================
488 STDMETHODIMP
ExplorerBar::Load( LPSTREAM inStream
)
490 DEBUG_UNUSED( inStream
);
495 //===========================================================================================================================
497 //===========================================================================================================================
499 STDMETHODIMP
ExplorerBar::Save( LPSTREAM inStream
, BOOL inClearDirty
)
501 DEBUG_UNUSED( inStream
);
502 DEBUG_UNUSED( inClearDirty
);
507 //===========================================================================================================================
509 //===========================================================================================================================
511 STDMETHODIMP
ExplorerBar::GetSizeMax( ULARGE_INTEGER
*outSizeMax
)
513 DEBUG_UNUSED( outSizeMax
);
519 //===========================================================================================================================
521 //===========================================================================================================================
523 STDMETHODIMP
ExplorerBar::QueryContextMenu(HMENU hShellContextMenu
, UINT iContextMenuFirstItem
, UINT idCmdFirst
, UINT idCmdLast
, UINT uFlags
)
525 DEBUG_UNUSED( idCmdLast
);
526 DEBUG_UNUSED( uFlags
);
530 menubar
.LoadMenu(IDR_CONTEXT_MENU
);
531 CMenu
* menu
= menubar
.GetSubMenu(0);
535 shellmenu
.Attach(hShellContextMenu
);
537 UINT iShellItem
= iContextMenuFirstItem
; //! remove plus one
538 UINT idShellCmd
= idCmdFirst
;
540 int n
= menu
->GetMenuItemCount();
542 for (int i
=0; i
<n
; ++i
)
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
);
554 menu
->GetMenuItemInfo(i
, &mii
, TRUE
);
556 mii
.wID
= idShellCmd
++;
558 shellmenu
.InsertMenuItem(iShellItem
++, &mii
, TRUE
);
567 //===========================================================================================================================
569 //===========================================================================================================================
571 // Not called for explorer bars
572 STDMETHODIMP
ExplorerBar::GetCommandString(UINT_PTR idCmd
, UINT uType
, UINT
* pwReserved
, LPSTR pszName
, UINT cchMax
)
574 DEBUG_UNUSED( idCmd
);
575 DEBUG_UNUSED( uType
);
576 DEBUG_UNUSED( pwReserved
);
577 DEBUG_UNUSED( pszName
);
578 DEBUG_UNUSED( cchMax
);
583 //===========================================================================================================================
585 //===========================================================================================================================
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
)
595 // IE doesn't send string commands
596 if (HIWORD(lpici
->lpVerb
) != 0) return 0;
607 #pragma mark == Other ==
610 //===========================================================================================================================
612 //===========================================================================================================================
614 OSStatus
ExplorerBar::SetupWindow( void )
622 window
= CWnd::FromHandle( mParentWindow
);
624 window
->GetClientRect( rect
);
626 ok
= s
.LoadString( IDS_NAME
);
627 require_action( ok
, exit
, err
= kNoResourcesErr
);
629 ok
= mWindow
.Create( NULL
, s
, WS_CHILD
| WS_VISIBLE
, rect
, window
, 100 ) != 0;
630 require_action( ok
, exit
, err
= kNoResourcesErr
);
632 mWindow
.SetOwner( this );
639 //===========================================================================================================================
641 //===========================================================================================================================
643 OSStatus
ExplorerBar::GoToURL( const CString
&inURL
)
649 s
= inURL
.AllocSysString();
650 require_action( s
, exit
, err
= kNoMemoryErr
);
652 VariantInit( &empty
);
653 err
= mWebBrowser
->Navigate( s
, &empty
, &empty
, &empty
, &empty
);
655 require_noerr( err
, exit
);