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