[SHELL32]
[reactos.git] / dll / win32 / browseui / addressband.cpp
1 /*
2 * ReactOS Explorer
3 *
4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org>
5 *
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.
10 *
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.
15 *
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
19 */
20
21 /*
22 Implements the navigation band of the cabinet window
23 */
24
25 #include "precomp.h"
26 #include <commoncontrols.h>
27 #include <shlwapi_undoc.h>
28 #include <shellapi.h>
29
30 HRESULT CreateAddressEditBox(REFIID riid, void **ppv);
31
32 extern "C"
33 HRESULT WINAPI SHGetImageList(
34 _In_ int iImageList,
35 _In_ REFIID riid,
36 _Out_ void **ppv
37 );
38
39 /*
40 TODO:
41 ****Add command handler for show/hide Go button to OnWinEvent
42 ****Add tooltip notify handler
43 **Properly implement GetBandInfo
44 **Add support for showing/hiding Go button
45 **Fix so Go button will be shown/hidden properly on load
46 **Add correct text to Go button
47 **Implement TranslateAcceleratorIO
48 Implement Exec
49 Implement QueryService
50 Implement Load
51 Implement Save
52 */
53
54 CAddressBand::CAddressBand()
55 {
56 fEditControl = NULL;
57 fGoButton = NULL;
58 fComboBox = NULL;
59 fGoButtonShown = false;
60 fAdviseCookie = 0;
61 }
62
63 CAddressBand::~CAddressBand()
64 {
65 }
66
67 void CAddressBand::FocusChange(BOOL bFocus)
68 {
69 // m_bFocus = bFocus;
70
71 //Inform the input object site that the focus has changed.
72 if (fSite)
73 {
74 #if 0
75 fSite->OnFocusChangeIS((IDockingWindow *)this, bFocus);
76 #endif
77 }
78 }
79
80 HRESULT STDMETHODCALLTYPE CAddressBand::GetBandInfo(DWORD dwBandID, DWORD dwViewMode, DESKBANDINFO *pdbi)
81 {
82 if (pdbi->dwMask & DBIM_MINSIZE)
83 {
84 pdbi->ptMinSize.x = 400;
85 pdbi->ptMinSize.y = 22;
86 }
87 if (pdbi->dwMask & DBIM_MAXSIZE)
88 {
89 pdbi->ptMaxSize.x = 0;
90 pdbi->ptMaxSize.y = 0;
91 }
92 if (pdbi->dwMask & DBIM_INTEGRAL)
93 {
94 pdbi->ptIntegral.x = 0;
95 pdbi->ptIntegral.y = 0;
96 }
97 if (pdbi->dwMask & DBIM_ACTUAL)
98 {
99 pdbi->ptActual.x = 400;
100 pdbi->ptActual.y = 22;
101 }
102 if (pdbi->dwMask & DBIM_TITLE)
103 wcscpy(pdbi->wszTitle, L"Address");
104 if (pdbi->dwMask & DBIM_MODEFLAGS)
105 pdbi->dwModeFlags = DBIMF_UNDELETEABLE;
106 if (pdbi->dwMask & DBIM_BKCOLOR)
107 pdbi->crBkgnd = 0;
108 return S_OK;
109 }
110
111 HRESULT STDMETHODCALLTYPE CAddressBand::SetSite(IUnknown *pUnkSite)
112 {
113 CComPtr<IBrowserService> browserService;
114 CComPtr<IOleWindow> oleWindow;
115 CComPtr<IShellService> shellService;
116 CComPtr<IUnknown> offset34;
117 HWND parentWindow;
118 HWND combobox;
119 static const TBBUTTON buttonInfo[] = { {0, 1, TBSTATE_ENABLED, 0} };
120 HIMAGELIST normalImagelist;
121 HIMAGELIST hotImageList;
122 HINSTANCE shellInstance;
123 HRESULT hResult;
124
125 if (pUnkSite == NULL)
126 {
127 hResult = AtlUnadvise(fSite, DIID_DWebBrowserEvents, fAdviseCookie);
128 fSite.Release();
129 return S_OK;
130 }
131
132 fSite.Release();
133
134 hResult = pUnkSite->QueryInterface(IID_PPV_ARG(IDockingWindowSite, &fSite));
135 if (FAILED(hResult))
136 return hResult;
137
138 // get window handle of parent
139 parentWindow = NULL;
140 hResult = IUnknown_GetWindow(pUnkSite, &parentWindow);
141
142 if (!::IsWindow(parentWindow))
143 return E_FAIL;
144
145 // create combo box ex
146 combobox = CreateWindowEx(WS_EX_TOOLWINDOW, WC_COMBOBOXEXW, NULL, WS_CHILD | WS_VISIBLE |
147 WS_CLIPCHILDREN | WS_TABSTOP | CCS_NODIVIDER | CCS_NOMOVEY | CBS_OWNERDRAWFIXED,
148 0, 0, 500, 250, parentWindow, (HMENU)0xa205, _AtlBaseModule.GetModuleInstance(), 0);
149 if (combobox == NULL)
150 return E_FAIL;
151 SubclassWindow(combobox);
152
153 SendMessage(CBEM_SETEXTENDEDSTYLE,
154 CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT, CBES_EX_CASESENSITIVE | CBES_EX_NOSIZELIMIT);
155
156 fEditControl = reinterpret_cast<HWND>(SendMessage(CBEM_GETEDITCONTROL, 0, 0));
157 fComboBox = reinterpret_cast<HWND>(SendMessage(CBEM_GETCOMBOCONTROL, 0, 0));
158 #if 1
159 hResult = CoCreateInstance(CLSID_AddressEditBox, NULL, CLSCTX_INPROC_SERVER,
160 IID_PPV_ARG(IAddressEditBox, &fAddressEditBox));
161 #else
162 hResult = E_FAIL;
163 #endif
164 if (FAILED(hResult))
165 {
166 // instantiate new version
167 hResult = CreateAddressEditBox(IID_PPV_ARG(IAddressEditBox, &fAddressEditBox));
168 if (FAILED(hResult))
169 return hResult;
170 }
171
172 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IShellService, &shellService));
173 if (FAILED(hResult))
174 return hResult;
175 hResult = fAddressEditBox->Init(combobox, fEditControl, 8, pUnkSite /*(IAddressBand *)this*/);
176 if (FAILED(hResult))
177 return hResult;
178 hResult = shellService->SetOwner(pUnkSite);
179 if (FAILED(hResult))
180 return hResult;
181
182 // TODO: properly initialize this from registry
183 fGoButtonShown = true;
184
185 shellInstance = GetModuleHandle(_T("shell32.dll"));
186 normalImagelist = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_NORMAL),
187 20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
188 hotImageList = ImageList_LoadImageW(shellInstance, MAKEINTRESOURCE(IDB_GOBUTTON_HOT),
189 20, 0, RGB(255, 0, 255), IMAGE_BITMAP, LR_CREATEDIBSECTION);
190
191 fGoButton = CreateWindowEx(WS_EX_TOOLWINDOW, TOOLBARCLASSNAMEW, 0, WS_CHILD | WS_CLIPSIBLINGS |
192 WS_CLIPCHILDREN | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS | CCS_NODIVIDER |
193 CCS_NOPARENTALIGN | CCS_NORESIZE,
194 0, 0, 0, 0, m_hWnd, NULL, _AtlBaseModule.GetModuleInstance(), NULL);
195 SendMessage(fGoButton, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
196 SendMessage(fGoButton, TB_SETMAXTEXTROWS, 1, 0);
197 if (normalImagelist)
198 SendMessage(fGoButton, TB_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(normalImagelist));
199 if (hotImageList)
200 SendMessage(fGoButton, TB_SETHOTIMAGELIST, 0, reinterpret_cast<LPARAM>(hotImageList));
201 SendMessage(fGoButton, TB_ADDSTRINGW,
202 reinterpret_cast<WPARAM>(_AtlBaseModule.GetResourceInstance()), IDS_GOBUTTONLABEL);
203 SendMessage(fGoButton, TB_ADDBUTTONSW, 1, (LPARAM)&buttonInfo);
204
205 IImageList * piml;
206 HRESULT hr = SHGetImageList(SHIL_SMALL, IID_PPV_ARG(IImageList, &piml));
207 if (FAILED_UNEXPECTEDLY(hr))
208 {
209 SendMessageW(combobox, CBEM_SETIMAGELIST, 0, 0);
210 }
211 else
212 {
213 SendMessageW(combobox, CBEM_SETIMAGELIST, 0, reinterpret_cast<LPARAM>(piml));
214 }
215
216 // take advice to watch events
217 hResult = IUnknown_QueryService(pUnkSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
218 if (SUCCEEDED(hResult))
219 {
220 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
221 }
222
223 return hResult;
224 }
225
226 HRESULT STDMETHODCALLTYPE CAddressBand::GetSite(REFIID riid, void **ppvSite)
227 {
228 if (fSite == NULL)
229 return E_FAIL;
230 return fSite->QueryInterface(riid, ppvSite);
231 }
232
233 HRESULT STDMETHODCALLTYPE CAddressBand::GetWindow(HWND *lphwnd)
234 {
235 if (lphwnd == NULL)
236 return E_POINTER;
237 *lphwnd = m_hWnd;
238 return S_OK;
239 }
240
241 HRESULT STDMETHODCALLTYPE CAddressBand::ContextSensitiveHelp(BOOL fEnterMode)
242 {
243 return E_NOTIMPL;
244 }
245
246 HRESULT STDMETHODCALLTYPE CAddressBand::CloseDW(DWORD dwReserved)
247 {
248 ShowDW(FALSE);
249
250 if (IsWindow())
251 DestroyWindow();
252
253 m_hWnd = NULL;
254
255 return S_OK;
256 }
257
258 HRESULT STDMETHODCALLTYPE CAddressBand::ResizeBorderDW(
259 const RECT *prcBorder, IUnknown *punkToolbarSite, BOOL fReserved)
260 {
261 return E_NOTIMPL;
262 }
263
264 HRESULT STDMETHODCALLTYPE CAddressBand::ShowDW(BOOL fShow)
265 {
266 if (m_hWnd)
267 {
268 if (fShow)
269 ShowWindow(SW_SHOW);
270 else
271 ShowWindow(SW_HIDE);
272 }
273 return S_OK;
274 }
275
276 HRESULT STDMETHODCALLTYPE CAddressBand::QueryStatus(
277 const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
278 {
279 CComPtr<IOleCommandTarget> oleCommandTarget;
280 HRESULT hResult;
281
282 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IOleCommandTarget, &oleCommandTarget));
283 if (FAILED(hResult))
284 return hResult;
285 return oleCommandTarget->QueryStatus(pguidCmdGroup, cCmds, prgCmds, pCmdText);
286 }
287
288 HRESULT STDMETHODCALLTYPE CAddressBand::Exec(const GUID *pguidCmdGroup,
289 DWORD nCmdID, DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
290 {
291 // incomplete
292 return E_NOTIMPL;
293 }
294
295 HRESULT STDMETHODCALLTYPE CAddressBand::HasFocusIO()
296 {
297 if (GetFocus() == fEditControl || SendMessage(CB_GETDROPPEDSTATE, 0, 0))
298 return S_OK;
299 return S_FALSE;
300 }
301
302 HRESULT STDMETHODCALLTYPE CAddressBand::TranslateAcceleratorIO(LPMSG lpMsg)
303 {
304 if (lpMsg->hwnd == fEditControl)
305 {
306 switch (lpMsg->message)
307 {
308 case WM_SYSKEYDOWN:
309 case WM_SYSKEYUP:
310 case WM_SYSCOMMAND:
311 case WM_SYSDEADCHAR:
312 case WM_SYSCHAR:
313 return S_FALSE;
314 }
315
316 TranslateMessage(lpMsg);
317 DispatchMessage(lpMsg);
318 return S_OK;
319 }
320 return S_FALSE;
321 }
322
323 HRESULT STDMETHODCALLTYPE CAddressBand::UIActivateIO(BOOL fActivate, LPMSG lpMsg)
324 {
325 CComPtr<IInputObjectSite> inputObjectSite;
326 HRESULT hResult;
327
328 if (fActivate)
329 {
330 hResult = fSite->QueryInterface(IID_PPV_ARG(IInputObjectSite, &inputObjectSite));
331 if (FAILED(hResult))
332 return hResult;
333 hResult = inputObjectSite->OnFocusChangeIS(static_cast<IDeskBand *>(this), fActivate);
334 SetFocus();
335 }
336 return S_OK;
337 }
338
339 HRESULT STDMETHODCALLTYPE CAddressBand::OnWinEvent(
340 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
341 {
342 CComPtr<IWinEventHandler> winEventHandler;
343 HRESULT hResult;
344
345 switch (uMsg)
346 {
347 case WM_WININICHANGE:
348 break;
349 case WM_COMMAND:
350 if (wParam == IDM_TOOLBARS_GOBUTTON)
351 {
352 // toggle whether the Go button is displayed
353 // setting is Yes or No, stored in key "Software\Microsoft\Internet Explorer\Main" in value ShowGoButton
354 // broadcast change notification to all explorer windows
355 }
356 break;
357 }
358 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
359 if (FAILED(hResult))
360 return hResult;
361 return winEventHandler->OnWinEvent(hWnd, uMsg, wParam, lParam, theResult);
362 }
363
364 HRESULT STDMETHODCALLTYPE CAddressBand::IsWindowOwner(HWND hWnd)
365 {
366 CComPtr<IWinEventHandler> winEventHandler;
367 HRESULT hResult;
368
369 if (fAddressEditBox)
370 {
371 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IWinEventHandler, &winEventHandler));
372 if (FAILED(hResult))
373 return hResult;
374 return winEventHandler->IsWindowOwner(hWnd);
375 }
376 return S_FALSE;
377 }
378
379 HRESULT STDMETHODCALLTYPE CAddressBand::FileSysChange(long param8, long paramC)
380 {
381 CComPtr<IAddressBand> addressBand;
382 HRESULT hResult;
383
384 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
385 if (FAILED(hResult))
386 return hResult;
387 return addressBand->FileSysChange(param8, paramC);
388 }
389
390 HRESULT STDMETHODCALLTYPE CAddressBand::Refresh(long param8)
391 {
392 CComPtr<IAddressBand> addressBand;
393 HRESULT hResult;
394
395 hResult = fAddressEditBox->QueryInterface(IID_PPV_ARG(IAddressBand, &addressBand));
396 if (FAILED(hResult))
397 return hResult;
398 return addressBand->Refresh(param8);
399 }
400
401 HRESULT STDMETHODCALLTYPE CAddressBand::QueryService(REFGUID guidService, REFIID riid, void **ppvObject)
402 {
403 return E_NOTIMPL;
404 }
405
406 HRESULT STDMETHODCALLTYPE CAddressBand::OnFocusChangeIS(IUnknown *punkObj, BOOL fSetFocus)
407 {
408 return E_NOTIMPL;
409 }
410
411 HRESULT STDMETHODCALLTYPE CAddressBand::GetClassID(CLSID *pClassID)
412 {
413 if (pClassID == NULL)
414 return E_POINTER;
415 *pClassID = CLSID_SH_AddressBand;
416 return S_OK;
417 }
418
419 HRESULT STDMETHODCALLTYPE CAddressBand::IsDirty()
420 {
421 return E_NOTIMPL;
422 }
423
424 HRESULT STDMETHODCALLTYPE CAddressBand::Load(IStream *pStm)
425 {
426 // incomplete
427 return E_NOTIMPL;
428 }
429
430 HRESULT STDMETHODCALLTYPE CAddressBand::Save(IStream *pStm, BOOL fClearDirty)
431 {
432 // incomplete
433 return E_NOTIMPL;
434 }
435
436 HRESULT STDMETHODCALLTYPE CAddressBand::GetSizeMax(ULARGE_INTEGER *pcbSize)
437 {
438 // incomplete
439 return E_NOTIMPL;
440 }
441
442 HRESULT STDMETHODCALLTYPE CAddressBand::GetTypeInfoCount(UINT *pctinfo)
443 {
444 return E_NOTIMPL;
445 }
446
447 HRESULT STDMETHODCALLTYPE CAddressBand::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
448 {
449 return E_NOTIMPL;
450 }
451
452 HRESULT STDMETHODCALLTYPE CAddressBand::GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames,
453 LCID lcid, DISPID *rgDispId)
454 {
455 return E_NOTIMPL;
456 }
457
458 HRESULT STDMETHODCALLTYPE CAddressBand::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags,
459 DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
460 {
461 CComPtr<IBrowserService> isb;
462 CComPtr<IShellFolder> sf;
463 HRESULT hr;
464 INT indexClosed, indexOpen, itemExists, oldIndex;
465 DWORD result;
466 COMBOBOXEXITEMW item;
467 PIDLIST_ABSOLUTE absolutePIDL;
468 LPCITEMIDLIST pidlChild;
469 LPITEMIDLIST pidlPrevious;
470 STRRET ret;
471 WCHAR buf[4096];
472
473 if (pDispParams == NULL)
474 return E_INVALIDARG;
475
476 switch (dispIdMember)
477 {
478 case DISPID_NAVIGATECOMPLETE2:
479 case DISPID_DOCUMENTCOMPLETE:
480
481 oldIndex = SendMessage(m_hWnd, CB_GETCURSEL, 0, 0);
482
483 item.mask = CBEIF_LPARAM;
484 item.iItem = 0;
485 itemExists = SendMessage(m_hWnd, CBEM_GETITEM, 0, reinterpret_cast<LPARAM>(&item));
486 if (itemExists)
487 {
488 pidlPrevious = reinterpret_cast<LPITEMIDLIST>(item.lParam);
489 }
490
491 hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb));
492 if (FAILED(hr))
493 return hr;
494 isb->GetPidl(&absolutePIDL);
495
496 SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
497
498 sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR | SHGDN_FORPARSING, &ret);
499
500 StrRetToBufW(&ret, pidlChild, buf, 4095);
501
502 indexClosed = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &indexOpen);
503
504 item.mask = CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM;
505 item.iItem = 0;
506 item.iImage = indexClosed;
507 item.iSelectedImage = indexOpen;
508 item.pszText = buf;
509 item.lParam = reinterpret_cast<LPARAM>(absolutePIDL);
510
511 if (itemExists)
512 {
513 result = SendMessage(m_hWnd, CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&item));
514
515 if (result)
516 {
517 ILFree(pidlPrevious);
518 }
519 }
520 else
521 {
522 oldIndex = SendMessage(m_hWnd, CBEM_INSERTITEM, 0, reinterpret_cast<LPARAM>(&item));
523
524 if (oldIndex < 0)
525 DbgPrint("ERROR %d\n", GetLastError());
526 }
527
528 SendMessage(m_hWnd, CB_SETCURSEL, -1, 0);
529 SendMessage(m_hWnd, CB_SETCURSEL, oldIndex, 0);
530
531 //fAddressEditBox->SetCurrentDir(index);
532
533 break;
534 }
535 return S_OK;
536 }
537
538 LRESULT CAddressBand::OnNotifyClick(WPARAM wParam, NMHDR *notifyHeader, BOOL &bHandled)
539 {
540 if (notifyHeader->hwndFrom == fGoButton)
541 {
542 fAddressEditBox->ParseNow(0);
543 fAddressEditBox->Execute(0);
544 }
545 return 0;
546 }
547
548 LRESULT CAddressBand::OnTipText(UINT idControl, NMHDR *notifyHeader, BOOL &bHandled)
549 {
550 if (notifyHeader->hwndFrom == fGoButton)
551 {
552 // TODO
553 // Go to "destination path"
554 }
555 return 0;
556 }
557
558 LRESULT CAddressBand::OnEraseBackground(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
559 {
560 POINT pt;
561 POINT ptOrig;
562 HWND parentWindow;
563 LRESULT result;
564
565 if (fGoButtonShown == false)
566 {
567 bHandled = FALSE;
568 return 0;
569 }
570 pt.x = 0;
571 pt.y = 0;
572 parentWindow = GetParent();
573 ::MapWindowPoints(m_hWnd, parentWindow, &pt, 1);
574 OffsetWindowOrgEx(reinterpret_cast<HDC>(wParam), pt.x, pt.y, &ptOrig);
575 result = SendMessage(parentWindow, WM_ERASEBKGND, wParam, 0);
576 SetWindowOrgEx(reinterpret_cast<HDC>(wParam), ptOrig.x, ptOrig.y, NULL);
577 if (result == 0)
578 {
579 bHandled = FALSE;
580 return 0;
581 }
582 return result;
583 }
584
585 LRESULT CAddressBand::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
586 {
587 RECT goButtonBounds;
588 RECT buttonBounds;
589 long buttonWidth;
590 long buttonHeight;
591 RECT comboBoxBounds;
592 long newHeight;
593 long newWidth;
594
595 if (fGoButtonShown == false)
596 {
597 bHandled = FALSE;
598 return 0;
599 }
600
601 newHeight = HIWORD(lParam);
602 newWidth = LOWORD(lParam);
603
604 SendMessage(fGoButton, TB_GETITEMRECT, 0, reinterpret_cast<LPARAM>(&buttonBounds));
605 buttonWidth = buttonBounds.right - buttonBounds.left;
606 buttonHeight = buttonBounds.bottom - buttonBounds.top;
607
608 DefWindowProc(WM_SIZE, wParam, MAKELONG(newWidth - buttonWidth - 2, newHeight));
609 ::GetWindowRect(fComboBox, &comboBoxBounds);
610 ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
611 buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
612
613 goButtonBounds.left = newWidth - buttonWidth;
614 goButtonBounds.top = 0;
615 goButtonBounds.right = newWidth - buttonWidth;
616 goButtonBounds.bottom = newHeight;
617 InvalidateRect(&goButtonBounds, TRUE);
618
619 SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
620 return 0;
621 }
622
623 LRESULT CAddressBand::OnWindowPosChanging(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
624 {
625 RECT goButtonBounds;
626 RECT buttonBounds;
627 long buttonWidth;
628 long buttonHeight;
629 RECT comboBoxBounds;
630 WINDOWPOS positionInfoCopy;
631 long newHeight;
632 long newWidth;
633
634 if (!fGoButtonShown)
635 {
636 bHandled = FALSE;
637 return 0;
638 }
639
640 positionInfoCopy = *reinterpret_cast<WINDOWPOS *>(lParam);
641 newHeight = positionInfoCopy.cy;
642 newWidth = positionInfoCopy.cx;
643 SendMessage(fGoButton, TB_GETITEMRECT, 0, reinterpret_cast<LPARAM>(&buttonBounds));
644
645 buttonWidth = buttonBounds.right - buttonBounds.left;
646 buttonHeight = buttonBounds.bottom - buttonBounds.top;
647 positionInfoCopy.cx = newWidth - 2 - buttonWidth;
648 DefWindowProc(WM_WINDOWPOSCHANGING, wParam, reinterpret_cast<LPARAM>(&positionInfoCopy));
649 ::GetWindowRect(fComboBox, &comboBoxBounds);
650 ::SetWindowPos(fGoButton, NULL, newWidth - buttonWidth, (comboBoxBounds.bottom - comboBoxBounds.top - buttonHeight) / 2,
651 buttonWidth, buttonHeight, SWP_NOOWNERZORDER | SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER);
652
653 goButtonBounds.left = newWidth - buttonWidth;
654 goButtonBounds.top = 0;
655 goButtonBounds.right = newWidth - buttonWidth;
656 goButtonBounds.bottom = newHeight;
657 InvalidateRect(&goButtonBounds, TRUE);
658
659 SendMessage(fComboBox, CB_SETDROPPEDWIDTH, 200, 0);
660 return 0;
661 }
662
663 HRESULT CreateAddressBand(REFIID riid, void **ppv)
664 {
665 CComObject<CAddressBand> *theMenuBar;
666 HRESULT hResult;
667
668 if (ppv == NULL)
669 return E_POINTER;
670 *ppv = NULL;
671 ATLTRY (theMenuBar = new CComObject<CAddressBand>);
672 if (theMenuBar == NULL)
673 return E_OUTOFMEMORY;
674 hResult = theMenuBar->QueryInterface(riid, reinterpret_cast<void **>(ppv));
675 if (FAILED(hResult))
676 {
677 delete theMenuBar;
678 return hResult;
679 }
680 return S_OK;
681 }