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