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 <commoncontrols.h>
27 #include <shlwapi_undoc.h>
32 ****Add tooltip notify handler
33 **Properly implement GetBandInfo
35 Implement QueryService
40 CAddressBand::CAddressBand()
45 fGoButtonShown
= false;
48 CAddressBand::~CAddressBand()
52 void CAddressBand::FocusChange(BOOL bFocus
)
56 //Inform the input object site that the focus has changed.
60 fSite
->OnFocusChangeIS((IDockingWindow
*)this, bFocus
);
65 HRESULT STDMETHODCALLTYPE
CAddressBand::GetBandInfo(DWORD dwBandID
, DWORD dwViewMode
, DESKBANDINFO
*pdbi
)
67 if (!m_hWnd
|| !pdbi
) return E_FAIL
; /* Verify window exists */
68 if (pdbi
->dwMask
& DBIM_MINSIZE
)
71 pdbi
->ptMinSize
.x
= 100;
73 pdbi
->ptMinSize
.x
= 150;
74 pdbi
->ptMinSize
.y
= 22;
76 if (pdbi
->dwMask
& DBIM_MAXSIZE
)
78 pdbi
->ptMaxSize
.x
= 0;
79 pdbi
->ptMaxSize
.y
= 0;
81 if (pdbi
->dwMask
& DBIM_INTEGRAL
)
83 pdbi
->ptIntegral
.x
= 0;
84 pdbi
->ptIntegral
.y
= 0;
86 if (pdbi
->dwMask
& DBIM_ACTUAL
)
89 pdbi
->ptActual
.x
= 100;
91 pdbi
->ptActual
.x
= 150;
92 pdbi
->ptActual
.y
= 22;
94 if (pdbi
->dwMask
& DBIM_TITLE
)
96 if (!LoadStringW(_AtlBaseModule
.GetResourceInstance(), IDS_ADDRESSBANDLABEL
, pdbi
->wszTitle
, _countof(pdbi
->wszTitle
)))
97 return HRESULT_FROM_WIN32(GetLastError());
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
;
115 if (pUnkSite
== NULL
)
123 hResult
= pUnkSite
->QueryInterface(IID_PPV_ARG(IDockingWindowSite
, &fSite
));
124 if (FAILED_UNEXPECTEDLY(hResult
))
127 // get window handle of parent
129 hResult
= IUnknown_GetWindow(fSite
, &parentWindow
);
131 if (!::IsWindow(parentWindow
))
134 // create combo box ex
135 combobox
= CreateWindowEx(WS_EX_TOOLWINDOW
, WC_COMBOBOXEXW
, NULL
, WS_CHILD
| WS_VISIBLE
|
136 WS_CLIPCHILDREN
| WS_TABSTOP
| CCS_NODIVIDER
| CCS_NOMOVEY
| CBS_OWNERDRAWFIXED
,
137 0, 0, 500, 250, parentWindow
, (HMENU
)IDM_TOOLBARS_ADDRESSBAR
, _AtlBaseModule
.GetModuleInstance(), 0);
138 if (combobox
== NULL
)
140 SubclassWindow(combobox
);
142 HRESULT hr
= SHGetImageList(SHIL_SMALL
, IID_PPV_ARG(IImageList
, &piml
));
143 if (FAILED_UNEXPECTEDLY(hr
))
145 SendMessageW(combobox
, CBEM_SETIMAGELIST
, 0, 0);
149 SendMessageW(combobox
, CBEM_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(piml
));
152 SendMessage(CBEM_SETEXTENDEDSTYLE
,
153 CBES_EX_CASESENSITIVE
| CBES_EX_NOSIZELIMIT
, CBES_EX_CASESENSITIVE
| CBES_EX_NOSIZELIMIT
);
155 fEditControl
= reinterpret_cast<HWND
>(SendMessage(CBEM_GETEDITCONTROL
, 0, 0));
156 fComboBox
= reinterpret_cast<HWND
>(SendMessage(CBEM_GETCOMBOCONTROL
, 0, 0));
157 hResult
= CAddressEditBox_CreateInstance(IID_PPV_ARG(IAddressEditBox
, &fAddressEditBox
));
158 if (FAILED_UNEXPECTEDLY(hResult
))
161 hResult
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IShellService
, &shellService
));
162 if (FAILED_UNEXPECTEDLY(hResult
))
164 hResult
= fAddressEditBox
->Init(combobox
, fEditControl
, 8, fSite
/*(IAddressBand *)this*/);
165 if (FAILED_UNEXPECTEDLY(hResult
))
167 hResult
= shellService
->SetOwner(fSite
);
168 if (FAILED_UNEXPECTEDLY(hResult
))
171 fGoButtonShown
= SHRegGetBoolUSValueW(L
"Software\\Microsoft\\Internet Explorer\\Main", L
"ShowGoButton", FALSE
, TRUE
);
178 HRESULT STDMETHODCALLTYPE
CAddressBand::GetSite(REFIID riid
, void **ppvSite
)
182 return fSite
->QueryInterface(riid
, ppvSite
);
185 HRESULT STDMETHODCALLTYPE
CAddressBand::GetWindow(HWND
*lphwnd
)
193 HRESULT STDMETHODCALLTYPE
CAddressBand::ContextSensitiveHelp(BOOL fEnterMode
)
198 HRESULT STDMETHODCALLTYPE
CAddressBand::CloseDW(DWORD dwReserved
)
207 CComPtr
<IShellService
> pservice
;
208 HRESULT hres
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IShellService
, &pservice
));
209 if (SUCCEEDED(hres
))
210 pservice
->SetOwner(NULL
);
212 if (fAddressEditBox
) fAddressEditBox
.Release();
213 if (fSite
) fSite
.Release();
216 ImageList_Destroy(m_himlNormal
);
219 ImageList_Destroy(m_himlHot
);
224 HRESULT STDMETHODCALLTYPE
CAddressBand::ResizeBorderDW(
225 const RECT
*prcBorder
, IUnknown
*punkToolbarSite
, BOOL fReserved
)
230 HRESULT STDMETHODCALLTYPE
CAddressBand::ShowDW(BOOL fShow
)
242 HRESULT STDMETHODCALLTYPE
CAddressBand::QueryStatus(
243 const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
245 return IUnknown_QueryStatus(fAddressEditBox
, *pguidCmdGroup
, cCmds
, prgCmds
, pCmdText
);
248 HRESULT STDMETHODCALLTYPE
CAddressBand::Exec(const GUID
*pguidCmdGroup
,
249 DWORD nCmdID
, DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
255 HRESULT STDMETHODCALLTYPE
CAddressBand::HasFocusIO()
257 if (GetFocus() == fEditControl
|| SendMessage(CB_GETDROPPEDSTATE
, 0, 0))
262 HRESULT STDMETHODCALLTYPE
CAddressBand::TranslateAcceleratorIO(LPMSG lpMsg
)
264 if (lpMsg
->hwnd
== fEditControl
)
266 switch (lpMsg
->message
)
276 TranslateMessage(lpMsg
);
277 DispatchMessage(lpMsg
);
283 HRESULT STDMETHODCALLTYPE
CAddressBand::UIActivateIO(BOOL fActivate
, LPMSG lpMsg
)
287 IUnknown_OnFocusChangeIS(fSite
, static_cast<IDeskBand
*>(this), fActivate
);
293 HRESULT STDMETHODCALLTYPE
CAddressBand::OnWinEvent(
294 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
296 CComPtr
<IWinEventHandler
> winEventHandler
;
305 case WM_WININICHANGE
:
308 if (wParam
== IDM_TOOLBARS_GOBUTTON
)
310 fGoButtonShown
= !SHRegGetBoolUSValueW(L
"Software\\Microsoft\\Internet Explorer\\Main", L
"ShowGoButton", FALSE
, TRUE
);
311 SHRegSetUSValueW(L
"Software\\Microsoft\\Internet Explorer\\Main", L
"ShowGoButton", REG_SZ
, fGoButtonShown
? (LPVOID
)L
"yes" : (LPVOID
)L
"no", fGoButtonShown
? 8 : 6, SHREGSET_FORCE_HKCU
);
314 ::ShowWindow(fGoButton
,fGoButtonShown
? SW_HIDE
: SW_SHOW
);
315 GetWindowRect(&rect
);
316 SendMessage(m_hWnd
,WM_SIZE
,0,MAKELPARAM(rect
.right
-rect
.left
,rect
.bottom
-rect
.top
));
317 // broadcast change notification to all explorer windows
321 hResult
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &winEventHandler
));
322 if (FAILED_UNEXPECTEDLY(hResult
))
324 return winEventHandler
->OnWinEvent(hWnd
, uMsg
, wParam
, lParam
, theResult
);
327 HRESULT STDMETHODCALLTYPE
CAddressBand::IsWindowOwner(HWND hWnd
)
329 CComPtr
<IWinEventHandler
> winEventHandler
;
334 hResult
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IWinEventHandler
, &winEventHandler
));
335 if (FAILED_UNEXPECTEDLY(hResult
))
337 return winEventHandler
->IsWindowOwner(hWnd
);
342 HRESULT STDMETHODCALLTYPE
CAddressBand::FileSysChange(long param8
, long paramC
)
344 CComPtr
<IAddressBand
> addressBand
;
347 hResult
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IAddressBand
, &addressBand
));
348 if (FAILED_UNEXPECTEDLY(hResult
))
350 return addressBand
->FileSysChange(param8
, paramC
);
353 HRESULT STDMETHODCALLTYPE
CAddressBand::Refresh(long param8
)
355 CComPtr
<IAddressBand
> addressBand
;
358 hResult
= fAddressEditBox
->QueryInterface(IID_PPV_ARG(IAddressBand
, &addressBand
));
359 if (FAILED_UNEXPECTEDLY(hResult
))
361 return addressBand
->Refresh(param8
);
364 HRESULT STDMETHODCALLTYPE
CAddressBand::QueryService(REFGUID guidService
, REFIID riid
, void **ppvObject
)
369 HRESULT STDMETHODCALLTYPE
CAddressBand::OnFocusChangeIS(IUnknown
*punkObj
, BOOL fSetFocus
)
374 HRESULT STDMETHODCALLTYPE
CAddressBand::GetClassID(CLSID
*pClassID
)
376 if (pClassID
== NULL
)
378 *pClassID
= CLSID_SH_AddressBand
;
382 HRESULT STDMETHODCALLTYPE
CAddressBand::IsDirty()
387 HRESULT STDMETHODCALLTYPE
CAddressBand::Load(IStream
*pStm
)
393 HRESULT STDMETHODCALLTYPE
CAddressBand::Save(IStream
*pStm
, BOOL fClearDirty
)
399 HRESULT STDMETHODCALLTYPE
CAddressBand::GetSizeMax(ULARGE_INTEGER
*pcbSize
)
405 LRESULT
CAddressBand::OnNotifyClick(WPARAM wParam
, NMHDR
*notifyHeader
, BOOL
&bHandled
)
407 if (notifyHeader
->hwndFrom
== fGoButton
)
409 fAddressEditBox
->Execute(0);
414 LRESULT
CAddressBand::OnTipText(UINT idControl
, NMHDR
*notifyHeader
, BOOL
&bHandled
)
416 if (notifyHeader
->hwndFrom
== fGoButton
)
418 WCHAR szText
[MAX_PATH
];
419 WCHAR szFormat
[MAX_PATH
];
420 LPNMTBGETINFOTIP pGIT
= (LPNMTBGETINFOTIP
)notifyHeader
;
422 if (::GetWindowTextW(fEditControl
, szText
, _countof(szText
)))
424 LoadStringW(_AtlBaseModule
.GetResourceInstance(), IDS_GOBUTTONTIPTEMPLATE
, szFormat
, _countof(szFormat
));
425 wnsprintf(pGIT
->pszText
, pGIT
->cchTextMax
, szFormat
, szText
);
433 LRESULT
CAddressBand::OnEraseBackground(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
440 if (fGoButtonShown
== false)
447 parentWindow
= GetParent();
448 ::MapWindowPoints(m_hWnd
, parentWindow
, &pt
, 1);
449 OffsetWindowOrgEx(reinterpret_cast<HDC
>(wParam
), pt
.x
, pt
.y
, &ptOrig
);
450 result
= SendMessage(parentWindow
, WM_ERASEBKGND
, wParam
, 0);
451 SetWindowOrgEx(reinterpret_cast<HDC
>(wParam
), ptOrig
.x
, ptOrig
.y
, NULL
);
460 LRESULT
CAddressBand::OnSize(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
470 if (fGoButtonShown
== false)
476 newHeight
= HIWORD(lParam
);
477 newWidth
= LOWORD(lParam
);
482 SendMessage(fGoButton
, TB_GETITEMRECT
, 0, reinterpret_cast<LPARAM
>(&buttonBounds
));
483 buttonWidth
= buttonBounds
.right
- buttonBounds
.left
;
484 buttonHeight
= buttonBounds
.bottom
- buttonBounds
.top
;
486 DefWindowProc(WM_SIZE
, wParam
, MAKELONG(newWidth
- buttonWidth
- 2, newHeight
));
487 ::GetWindowRect(fComboBox
, &comboBoxBounds
);
488 ::SetWindowPos(fGoButton
, NULL
, newWidth
- buttonWidth
, (comboBoxBounds
.bottom
- comboBoxBounds
.top
- buttonHeight
) / 2,
489 buttonWidth
, buttonHeight
, SWP_NOOWNERZORDER
| SWP_SHOWWINDOW
| SWP_NOACTIVATE
| SWP_NOZORDER
);
491 goButtonBounds
.left
= newWidth
- buttonWidth
;
492 goButtonBounds
.top
= 0;
493 goButtonBounds
.right
= newWidth
- buttonWidth
;
494 goButtonBounds
.bottom
= newHeight
;
495 InvalidateRect(&goButtonBounds
, TRUE
);
497 SendMessage(fComboBox
, CB_SETDROPPEDWIDTH
, 200, 0);
501 LRESULT
CAddressBand::OnWindowPosChanging(UINT uMsg
, WPARAM wParam
, LPARAM lParam
, BOOL
&bHandled
)
508 WINDOWPOS positionInfoCopy
;
521 positionInfoCopy
= *reinterpret_cast<WINDOWPOS
*>(lParam
);
522 newHeight
= positionInfoCopy
.cy
;
523 newWidth
= positionInfoCopy
.cx
;
525 SendMessage(fGoButton
, TB_GETITEMRECT
, 0, reinterpret_cast<LPARAM
>(&buttonBounds
));
527 buttonWidth
= buttonBounds
.right
- buttonBounds
.left
;
528 buttonHeight
= buttonBounds
.bottom
- buttonBounds
.top
;
529 positionInfoCopy
.cx
= newWidth
- 2 - buttonWidth
;
530 DefWindowProc(WM_WINDOWPOSCHANGING
, wParam
, reinterpret_cast<LPARAM
>(&positionInfoCopy
));
531 ::GetWindowRect(fComboBox
, &comboBoxBounds
);
532 ::SetWindowPos(fGoButton
, NULL
, newWidth
- buttonWidth
, (comboBoxBounds
.bottom
- comboBoxBounds
.top
- buttonHeight
) / 2,
533 buttonWidth
, buttonHeight
, SWP_NOOWNERZORDER
| SWP_SHOWWINDOW
| SWP_NOACTIVATE
| SWP_NOZORDER
);
535 goButtonBounds
.left
= newWidth
- buttonWidth
;
536 goButtonBounds
.top
= 0;
537 goButtonBounds
.right
= newWidth
- buttonWidth
;
538 goButtonBounds
.bottom
= newHeight
;
539 InvalidateRect(&goButtonBounds
, TRUE
);
541 SendMessage(fComboBox
, CB_SETDROPPEDWIDTH
, 200, 0);
545 void CAddressBand::CreateGoButton()
547 const TBBUTTON buttonInfo
[] = { { 0, 1, TBSTATE_ENABLED
, 0 } };
548 HINSTANCE shellInstance
;
550 shellInstance
= _AtlBaseModule
.GetResourceInstance();
551 m_himlNormal
= ImageList_LoadImageW(shellInstance
, MAKEINTRESOURCEW(IDB_GOBUTTON_NORMAL
),
552 20, 0, RGB(255, 0, 255), IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
553 m_himlHot
= ImageList_LoadImageW(shellInstance
, MAKEINTRESOURCEW(IDB_GOBUTTON_HOT
),
554 20, 0, RGB(255, 0, 255), IMAGE_BITMAP
, LR_CREATEDIBSECTION
);
556 fGoButton
= CreateWindowEx(WS_EX_TOOLWINDOW
, TOOLBARCLASSNAMEW
, 0, WS_CHILD
| WS_CLIPSIBLINGS
|
557 WS_CLIPCHILDREN
| TBSTYLE_LIST
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
| CCS_NODIVIDER
|
558 CCS_NOPARENTALIGN
| CCS_NORESIZE
,
559 0, 0, 0, 0, m_hWnd
, NULL
, _AtlBaseModule
.GetModuleInstance(), NULL
);
560 SendMessage(fGoButton
, TB_BUTTONSTRUCTSIZE
, sizeof(TBBUTTON
), 0);
561 SendMessage(fGoButton
, TB_SETMAXTEXTROWS
, 1, 0);
563 SendMessage(fGoButton
, TB_SETIMAGELIST
, 0, reinterpret_cast<LPARAM
>(m_himlNormal
));
565 SendMessage(fGoButton
, TB_SETHOTIMAGELIST
, 0, reinterpret_cast<LPARAM
>(m_himlHot
));
566 SendMessage(fGoButton
, TB_ADDSTRINGW
,
567 reinterpret_cast<WPARAM
>(_AtlBaseModule
.GetResourceInstance()), IDS_GOBUTTONLABEL
);
568 SendMessage(fGoButton
, TB_ADDBUTTONSW
, 1, (LPARAM
) &buttonInfo
);