4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 Implements the navigation band of the cabinet window
26 #include <shlobj_undoc.h>
28 #include <shlguid_undoc.h>
34 #include "addressband.h"
38 ****Add command handler for show/hide Go button to OnWinEvent
39 ****Add tooltip notify handler
40 **Properly implement GetBandInfo
41 **Add support for showing/hiding Go button
42 **Fix so Go button will be shown/hidden properly on load
43 **Add correct text to Go button
44 **Implement TranslateAcceleratorIO
46 Implement QueryService
51 CAddressBand::CAddressBand()
56 fGoButtonShown
= false;
59 CAddressBand::~CAddressBand()
63 void CAddressBand::FocusChange(BOOL bFocus
)
67 //Inform the input object site that the focus has changed.
71 fSite
->OnFocusChangeIS((IDockingWindow
*)this, bFocus
);
76 HRESULT STDMETHODCALLTYPE
CAddressBand::GetBandInfo(DWORD dwBandID
, DWORD dwViewMode
, DESKBANDINFO
*pdbi
)
78 if (pdbi
->dwMask
& DBIM_MINSIZE
)
80 pdbi
->ptMinSize
.x
= 400;
81 pdbi
->ptMinSize
.y
= 22;
83 if (pdbi
->dwMask
& DBIM_MAXSIZE
)
85 pdbi
->ptMaxSize
.x
= 0;
86 pdbi
->ptMaxSize
.y
= 0;
88 if (pdbi
->dwMask
& DBIM_INTEGRAL
)
90 pdbi
->ptIntegral
.x
= 0;
91 pdbi
->ptIntegral
.y
= 0;
93 if (pdbi
->dwMask
& DBIM_ACTUAL
)
95 pdbi
->ptActual
.x
= 400;
96 pdbi
->ptActual
.y
= 22;
98 if (pdbi
->dwMask
& DBIM_TITLE
)
99 wcscpy(pdbi
->wszTitle
, L
"Address");
100 if (pdbi
->dwMask
& DBIM_MODEFLAGS
)
101 pdbi
->dwModeFlags
= DBIMF_UNDELETEABLE
;
102 if (pdbi
->dwMask
& DBIM_BKCOLOR
)
107 HRESULT STDMETHODCALLTYPE
CAddressBand::SetSite(IUnknown
*pUnkSite
)
109 CComPtr
<IShellService
> shellService
;
110 CComPtr
<IUnknown
> offset34
;
112 IOleWindow
*oleWindow
;
114 static const TBBUTTON buttonInfo
[] = { {0, 1, TBSTATE_ENABLED
, 0} };
115 HIMAGELIST normalImagelist
;
116 HIMAGELIST hotImageList
;
117 HINSTANCE shellInstance
;
121 if (pUnkSite
== NULL
)
123 hResult
= pUnkSite
->QueryInterface(IID_IDockingWindowSite
, (void **)&fSite
);
127 hResult
= pUnkSite
->QueryInterface(IID_IOleWindow
, (void **)&oleWindow
);
128 if (SUCCEEDED(hResult
))
130 oleWindow
->GetWindow(&parentWindow
);
131 oleWindow
->Release();
133 if (!::IsWindow(parentWindow
))
136 toolbar
= CreateWindowEx(WS_EX_TOOLWINDOW
, WC_COMBOBOXEXW
, NULL
, WS_CHILD
| WS_VISIBLE
|
137 WS_CLIPCHILDREN
| WS_TABSTOP
| CCS_NODIVIDER
| CCS_NOMOVEY
,
138 0, 0, 500, 250, parentWindow
, (HMENU
)0xa205, _AtlBaseModule
.GetModuleInstance(), 0);
141 SubclassWindow(toolbar
);
142 SendMessage(CBEM_SETEXTENDEDSTYLE
, CBES_EX_CASESENSITIVE
| CBES_EX_NOSIZELIMIT
, CBES_EX_CASESENSITIVE
| CBES_EX_NOSIZELIMIT
);
143 fEditControl
= (HWND
)SendMessage(CBEM_GETEDITCONTROL
, 0, 0);
144 fComboBox
= (HWND
)SendMessage(CBEM_GETCOMBOCONTROL
, 0, 0);
146 hResult
= CoCreateInstance(CLSID_AddressEditBox
, NULL
, CLSCTX_INPROC_SERVER
, IID_IAddressEditBox
, (void **)&fAddressEditBox
);
150 // instantiate new version
152 hResult
= fAddressEditBox
->QueryInterface(IID_IShellService
, (void **)&shellService
);
155 hResult
= fAddressEditBox
->Init(toolbar
, fEditControl
, 8, pUnkSite
/*(IAddressBand *)this*/ );
158 hResult
= shellService
->SetOwner(pUnkSite
);
162 // TODO: properly initialize this from registry
163 fGoButtonShown
= true;
165 shellInstance
= GetModuleHandle(_T("shell32.dll"));
166 normalImagelist
= ImageList_LoadImageW(shellInstance
, MAKEINTRESOURCE(IDB_GOBUTTON_NORMAL
), 20, 0, RGB(255, 0, 255), IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
167 hotImageList
= ImageList_LoadImageW(shellInstance
, MAKEINTRESOURCE(IDB_GOBUTTON_HOT
), 20, 0, RGB(255, 0, 255), IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
169 fGoButton
= CreateWindowEx(WS_EX_TOOLWINDOW
, TOOLBARCLASSNAMEW
, 0, WS_CHILD
| WS_CLIPSIBLINGS
| WS_CLIPCHILDREN
| TBSTYLE_LIST
|
170 TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| CCS_NODIVIDER
| CCS_NOPARENTALIGN
| CCS_NORESIZE
,
171 0, 0, 0, 0, m_hWnd
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
172 SendMessage(fGoButton
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
173 SendMessage(fGoButton
, TB_SETMAXTEXTROWS
, 1, 0);
174 SendMessage(fGoButton
, TB_SETIMAGELIST
, 0, (LPARAM
)normalImagelist
);
175 SendMessage(fGoButton
, TB_SETHOTIMAGELIST
, 0, (LPARAM
)hotImageList
);
176 SendMessage(fGoButton
, TB_ADDSTRINGW
, (WPARAM
)_AtlBaseModule
.GetResourceInstance(), IDS_GOBUTTONLABEL
);
177 SendMessage(fGoButton
, TB_ADDBUTTONSW
, 1, (LPARAM
)&buttonInfo
);
182 HRESULT STDMETHODCALLTYPE
CAddressBand::GetSite(REFIID riid
, void **ppvSite
)
186 return fSite
->QueryInterface(riid
, ppvSite
);
189 HRESULT STDMETHODCALLTYPE
CAddressBand::GetWindow(HWND
*lphwnd
)
197 HRESULT STDMETHODCALLTYPE
CAddressBand::ContextSensitiveHelp(BOOL fEnterMode
)
202 HRESULT STDMETHODCALLTYPE
CAddressBand::CloseDW(DWORD dwReserved
)
214 HRESULT STDMETHODCALLTYPE
CAddressBand::ResizeBorderDW(const RECT
*prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
)
219 HRESULT STDMETHODCALLTYPE
CAddressBand::ShowDW(BOOL fShow
)
231 HRESULT STDMETHODCALLTYPE
CAddressBand::QueryStatus(const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
233 CComPtr
<IOleCommandTarget
> oleCommandTarget
;
236 hResult
= fAddressEditBox
->QueryInterface(IID_IOleCommandTarget
, (void **)&oleCommandTarget
);
239 return oleCommandTarget
->QueryStatus(pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
242 HRESULT STDMETHODCALLTYPE
CAddressBand::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
248 HRESULT STDMETHODCALLTYPE
CAddressBand::HasFocusIO()
250 if (GetFocus() == fEditControl
|| SendMessage(CB_GETDROPPEDSTATE
, 0, 0))
255 HRESULT STDMETHODCALLTYPE
CAddressBand::TranslateAcceleratorIO(LPMSG lpMsg
)
261 HRESULT STDMETHODCALLTYPE
CAddressBand::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
263 CComPtr
<IInputObjectSite
> inputObjectSite
;
268 hResult
= fSite
->QueryInterface(IID_IInputObjectSite
, (void **)&inputObjectSite
);
271 hResult
= inputObjectSite
->OnFocusChangeIS((IDeskBand
*)this, fActivate
);
277 HRESULT STDMETHODCALLTYPE
CAddressBand::OnWinEvent(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
279 CComPtr
<IWinEventHandler
> winEventHandler
;
284 case WM_WININICHANGE
:
287 if (wParam
== IDM_TOOLBARS_GOBUTTON
)
289 // toggle whether the Go button is displayed
290 // setting is Yes or No, stored in key "Software\Microsoft\Internet Explorer\Main" in value ShowGoButton
291 // broadcast change notification to all explorer windows
295 hResult
= fAddressEditBox
->QueryInterface(IID_IWinEventHandler
, (void **)&winEventHandler
);
298 return winEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
301 HRESULT STDMETHODCALLTYPE
CAddressBand::IsWindowOwner(HWND hWnd
)
303 CComPtr
<IWinEventHandler
> winEventHandler
;
306 hResult
= fAddressEditBox
->QueryInterface(IID_IWinEventHandler
, (void **)&winEventHandler
);
309 return winEventHandler
->IsWindowOwner(hWnd
);
312 HRESULT STDMETHODCALLTYPE
CAddressBand::FileSysChange(long param8
, long paramC
)
314 CComPtr
<IAddressBand
> addressBand
;
317 hResult
= fAddressEditBox
->QueryInterface(IID_IAddressBand
, (void **)&addressBand
);
320 return addressBand
->FileSysChange(param8
, paramC
);
323 HRESULT STDMETHODCALLTYPE
CAddressBand::Refresh(long param8
)
325 CComPtr
<IAddressBand
> addressBand
;
328 hResult
= fAddressEditBox
->QueryInterface(IID_IAddressBand
, (void **)&addressBand
);
331 return addressBand
->Refresh(param8
);
334 HRESULT STDMETHODCALLTYPE
CAddressBand::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
339 HRESULT STDMETHODCALLTYPE
CAddressBand::OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
)
344 HRESULT STDMETHODCALLTYPE
CAddressBand::GetClassID(CLSID
*pClassID
)
346 if (pClassID
== NULL
)
348 *pClassID
= CLSID_SH_AddressBand
;
352 HRESULT STDMETHODCALLTYPE
CAddressBand::IsDirty()
357 HRESULT STDMETHODCALLTYPE
CAddressBand::Load(IStream
*pStm
)
363 HRESULT STDMETHODCALLTYPE
CAddressBand::Save(IStream
*pStm
, BOOL fClearDirty
)
369 HRESULT STDMETHODCALLTYPE
CAddressBand::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
375 LRESULT
CAddressBand::OnNotifyClick(WPARAM wParam
, NMHDR
*notifyHeader
, BOOL
&bHandled
)
377 if (notifyHeader
->hwndFrom
== fGoButton
)
379 SendMessage(fEditControl
, WM_KEYDOWN
, 13, 0);
380 SendMessage(fEditControl
, WM_KEYUP
, 13, 0);
385 LRESULT
CAddressBand::OnTipText(UINT idControl
, NMHDR
*notifyHeader
, BOOL
&bHandled
)
387 if (notifyHeader
->hwndFrom
== fGoButton
)
390 // Go to "destination path"
395 LRESULT
CAddressBand::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
402 if (fGoButtonShown
== false)
409 parentWindow
= GetParent();
410 ::MapWindowPoints(m_hWnd
, parentWindow
, &pt
, 1);
411 OffsetWindowOrgEx((HDC
)wParam
, pt
.x
, pt
.y
, &ptOrig
);
412 result
= SendMessage(parentWindow
, WM_ERASEBKGND
, wParam
, 0);
413 SetWindowOrgEx((HDC
)wParam
, ptOrig
.x
, ptOrig
.y
, NULL
);
422 LRESULT
CAddressBand::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
432 if (fGoButtonShown
== false)
437 newHeight
= HIWORD(lParam
);
438 newWidth
= LOWORD(lParam
);
439 SendMessage(fGoButton
, TB_GETITEMRECT
, 0, (LPARAM
)&buttonBounds
);
440 buttonWidth
= buttonBounds
.right
- buttonBounds
.left
;
441 buttonHeight
= buttonBounds
.bottom
- buttonBounds
.top
;
442 DefWindowProc(WM_SIZE
, wParam
, MAKELONG(newWidth
- buttonWidth
- 2, newHeight
));
443 ::GetWindowRect(fComboBox
, &comboBoxBounds
);
444 ::SetWindowPos(fGoButton
, NULL
, newWidth
- buttonWidth
, (comboBoxBounds
.bottom
- comboBoxBounds
.top
- buttonHeight
) / 2,
445 buttonWidth
, buttonHeight
, SWP_NOOWNERZORDER
| SWP_SHOWWINDOW
| SWP_NOACTIVATE
| SWP_NOZORDER
);
446 goButtonBounds
.left
= newWidth
- buttonWidth
;
447 goButtonBounds
.top
= 0;
448 goButtonBounds
.right
= newWidth
- buttonWidth
;
449 goButtonBounds
.bottom
= newHeight
;
450 InvalidateRect(&goButtonBounds
, TRUE
);
451 SendMessage(fComboBox
, CB_SETDROPPEDWIDTH
, 200, 0);
455 LRESULT
CAddressBand::OnWindowPosChanging(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
462 WINDOWPOS positionInfoCopy
;
466 if (fGoButtonShown
== false)
471 positionInfoCopy
= *(WINDOWPOS
*)lParam
;
472 newHeight
= positionInfoCopy
.cy
;
473 newWidth
= positionInfoCopy
.cx
;
474 SendMessage(fGoButton
, TB_GETITEMRECT
, 0, (LPARAM
)&buttonBounds
);
475 buttonWidth
= buttonBounds
.right
- buttonBounds
.left
;
476 buttonHeight
= buttonBounds
.bottom
- buttonBounds
.top
;
477 positionInfoCopy
.cx
= newWidth
- 2 - buttonWidth
;
478 DefWindowProc(WM_WINDOWPOSCHANGING
, wParam
, (LPARAM
)&positionInfoCopy
);
479 ::GetWindowRect(fComboBox
, &comboBoxBounds
);
480 ::SetWindowPos(fGoButton
, NULL
, newWidth
- buttonWidth
, (comboBoxBounds
.bottom
- comboBoxBounds
.top
- buttonHeight
) / 2,
481 buttonWidth
, buttonHeight
, SWP_NOOWNERZORDER
| SWP_SHOWWINDOW
| SWP_NOACTIVATE
| SWP_NOZORDER
);
482 goButtonBounds
.left
= newWidth
- buttonWidth
;
483 goButtonBounds
.top
= 0;
484 goButtonBounds
.right
= newWidth
- buttonWidth
;
485 goButtonBounds
.bottom
= newHeight
;
486 InvalidateRect(&goButtonBounds
, TRUE
);
487 SendMessage(fComboBox
, CB_SETDROPPEDWIDTH
, 200, 0);
491 HRESULT
CreateAddressBand(REFIID riid
, void **ppv
)
493 CComObject
<CAddressBand
> *theMenuBar
;
499 ATLTRY (theMenuBar
= new CComObject
<CAddressBand
>);
500 if (theMenuBar
== NULL
)
501 return E_OUTOFMEMORY
;
502 hResult
= theMenuBar
->QueryInterface (riid
, (void **)ppv
);
503 if (FAILED (hResult
))