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 This class handles the combo box of the address band.
29 Handle listbox dropdown message and fill contents
30 Add drag and drop of icon in edit box
31 Handle change notifies to update appropriately
32 Fix so selection in combo listbox navigates
35 CAddressEditBox::CAddressEditBox() :
36 fCombobox(NULL
, this, 1),
37 fEditWindow(NULL
, this, 1),
42 CAddressEditBox::~CAddressEditBox()
46 HRESULT STDMETHODCALLTYPE
CAddressEditBox::SetOwner(IUnknown
*)
48 // connect to browser connection point
52 HRESULT STDMETHODCALLTYPE
CAddressEditBox::FileSysChange(long param8
, long paramC
)
57 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Refresh(long param8
)
62 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Init(HWND comboboxEx
, HWND editControl
, long param14
, IUnknown
*param18
)
64 CComPtr
<IBrowserService
> browserService
;
66 fCombobox
.SubclassWindow(comboboxEx
);
67 fEditWindow
.SubclassWindow(editControl
);
70 SHAutoComplete(fEditWindow
.m_hWnd
, SHACF_FILESYSTEM
| SHACF_URLALL
| SHACF_USETAB
);
72 // take advice to watch events
73 HRESULT hResult
= IUnknown_QueryService(param18
, SID_SShellBrowser
, IID_PPV_ARG(IBrowserService
, &browserService
));
74 if (SUCCEEDED(hResult
))
76 hResult
= AtlAdvise(browserService
, static_cast<IDispatch
*>(this), DIID_DWebBrowserEvents
, &fAdviseCookie
);
82 HRESULT STDMETHODCALLTYPE
CAddressEditBox::SetCurrentDir(long paramC
)
87 HRESULT STDMETHODCALLTYPE
CAddressEditBox::ParseNow(long paramC
)
94 CComPtr
<IShellBrowser
> pisb
;
95 hr
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IShellBrowser
, &pisb
));
96 if (FAILED_UNEXPECTEDLY(hr
))
99 hr
= IUnknown_GetWindow(pisb
, &topLevelWindow
);
100 if (FAILED_UNEXPECTEDLY(hr
))
104 int inputLength
= fCombobox
.GetWindowTextLength() + 2;
106 input
= new WCHAR
[inputLength
];
107 fCombobox
.GetWindowText(input
, inputLength
);
110 int addressLength
= ExpandEnvironmentStrings(input
, NULL
, 0);
112 if (addressLength
<= 0)
119 address
= new WCHAR
[addressLength
];
120 if (!ExpandEnvironmentStrings(input
, address
, addressLength
))
127 CComPtr
<IShellFolder
> psfDesktop
;
128 hr
= SHGetDesktopFolder(&psfDesktop
);
131 hr
= psfDesktop
->ParseDisplayName(topLevelWindow
, NULL
, address
, &eaten
, &pidlLastParsed
, &attributes
);
134 if (address
!= input
)
141 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Execute(long paramC
)
146 * Parse the path is it wasn't parsed
155 * Get the IShellBrowser and IBrowserService interfaces of the shell browser
157 CComPtr
<IShellBrowser
> pisb
;
158 hr
= IUnknown_QueryService(fSite
, SID_SShellBrowser
, IID_PPV_ARG(IShellBrowser
, &pisb
));
162 CComPtr
<IBrowserService
> pbs
;
163 pisb
->QueryInterface(IID_PPV_ARG(IBrowserService
, &pbs
));
168 * Get the current pidl of the shellbrowser and check if it is the same with the parsed one
170 PIDLIST_ABSOLUTE pidl
;
171 hr
= pbs
->GetPidl(&pidl
);
175 CComPtr
<IShellFolder
> psf
;
176 hr
= SHGetDesktopFolder(&psf
);
180 hr
= psf
->CompareIDs(0, pidl
, pidlLastParsed
);
187 * Attempt to browse to the parsed pidl
189 hr
= pisb
->BrowseObject(pidlLastParsed
, 0);
194 * Browsing to the pidl failed so it's not a folder. So invoke its defaule command.
197 hr
= IUnknown_GetWindow(pisb
, &topLevelWindow
);
201 LPCITEMIDLIST pidlChild
;
202 CComPtr
<IShellFolder
> sf
;
203 hr
= SHBindToParent(pidlLastParsed
, IID_PPV_ARG(IShellFolder
, &sf
), &pidlChild
);
207 hr
= SHInvokeDefaultCommand(topLevelWindow
, sf
, pidlChild
);
214 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Save(long paramC
)
219 HRESULT STDMETHODCALLTYPE
CAddressEditBox::OnWinEvent(
220 HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
, LRESULT
*theResult
)
229 hdr
= (LPNMHDR
) lParam
;
230 if (hdr
->code
== CBEN_ENDEDIT
)
232 NMCBEENDEDITW
*endEdit
= (NMCBEENDEDITW
*) lParam
;
233 if (endEdit
->iWhy
== CBENF_RETURN
)
237 else if (endEdit
->iWhy
== CBENF_ESCAPE
)
239 /* Reset the contents of the combo box */
247 HRESULT STDMETHODCALLTYPE
CAddressEditBox::IsWindowOwner(HWND hWnd
)
249 if (fCombobox
.m_hWnd
== hWnd
)
251 if (fEditWindow
.m_hWnd
== hWnd
)
256 HRESULT STDMETHODCALLTYPE
CAddressEditBox::QueryStatus(
257 const GUID
*pguidCmdGroup
, ULONG cCmds
, OLECMD prgCmds
[ ], OLECMDTEXT
*pCmdText
)
262 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Exec(const GUID
*pguidCmdGroup
, DWORD nCmdID
,
263 DWORD nCmdexecopt
, VARIANT
*pvaIn
, VARIANT
*pvaOut
)
268 HRESULT STDMETHODCALLTYPE
CAddressEditBox::GetTypeInfoCount(UINT
*pctinfo
)
273 HRESULT STDMETHODCALLTYPE
CAddressEditBox::GetTypeInfo(UINT iTInfo
, LCID lcid
, ITypeInfo
**ppTInfo
)
278 HRESULT STDMETHODCALLTYPE
CAddressEditBox::GetIDsOfNames(
279 REFIID riid
, LPOLESTR
*rgszNames
, UINT cNames
, LCID lcid
, DISPID
*rgDispId
)
284 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Invoke(DISPID dispIdMember
, REFIID riid
, LCID lcid
,
285 WORD wFlags
, DISPPARAMS
*pDispParams
, VARIANT
*pVarResult
, EXCEPINFO
*pExcepInfo
, UINT
*puArgErr
)
287 CComPtr
<IBrowserService
> isb
;
288 CComPtr
<IShellFolder
> sf
;
290 INT indexClosed
, indexOpen
, itemExists
, oldIndex
;
292 COMBOBOXEXITEMW item
;
293 PIDLIST_ABSOLUTE absolutePIDL
;
294 LPCITEMIDLIST pidlChild
;
295 LPITEMIDLIST pidlPrevious
;
299 if (pDispParams
== NULL
)
302 switch (dispIdMember
)
304 case DISPID_NAVIGATECOMPLETE2
:
305 case DISPID_DOCUMENTCOMPLETE
:
306 pidlLastParsed
= NULL
;
308 oldIndex
= fCombobox
.SendMessage(CB_GETCURSEL
, 0, 0);
313 ZeroMemory(&item
, sizeof(item
));
314 item
.mask
= CBEIF_LPARAM
;
316 if (fCombobox
.SendMessage(CBEM_GETITEM
, 0, reinterpret_cast<LPARAM
>(&item
)))
318 pidlPrevious
= reinterpret_cast<LPITEMIDLIST
>(item
.lParam
);
323 hr
= IUnknown_QueryService(fSite
, SID_STopLevelBrowser
, IID_PPV_ARG(IBrowserService
, &isb
));
324 if (FAILED_UNEXPECTEDLY(hr
))
326 isb
->GetPidl(&absolutePIDL
);
328 SHBindToParent(absolutePIDL
, IID_PPV_ARG(IShellFolder
, &sf
), &pidlChild
);
330 sf
->GetDisplayNameOf(pidlChild
, SHGDN_FORADDRESSBAR
| SHGDN_FORPARSING
, &ret
);
332 StrRetToBufW(&ret
, pidlChild
, buf
, 4095);
334 indexClosed
= SHMapPIDLToSystemImageListIndex(sf
, pidlChild
, &indexOpen
);
336 item
.mask
= CBEIF_IMAGE
| CBEIF_SELECTEDIMAGE
| CBEIF_TEXT
| CBEIF_LPARAM
;
338 item
.iImage
= indexClosed
;
339 item
.iSelectedImage
= indexOpen
;
341 item
.lParam
= reinterpret_cast<LPARAM
>(absolutePIDL
);
345 result
= fCombobox
.SendMessage(CBEM_SETITEM
, 0, reinterpret_cast<LPARAM
>(&item
));
350 ILFree(pidlPrevious
);
355 oldIndex
= fCombobox
.SendMessage(CBEM_INSERTITEM
, 0, reinterpret_cast<LPARAM
>(&item
));
358 DbgPrint("ERROR %d\n", GetLastError());
361 fCombobox
.SendMessage(CB_SETCURSEL
, -1, 0);
362 fCombobox
.SendMessage(CB_SETCURSEL
, oldIndex
, 0);
364 //fAddressEditBox->SetCurrentDir(index);
369 HRESULT STDMETHODCALLTYPE
CAddressEditBox::GetClassID(CLSID
*pClassID
)
371 if (pClassID
== NULL
)
373 *pClassID
= CLSID_AddressEditBox
;
377 HRESULT STDMETHODCALLTYPE
CAddressEditBox::IsDirty()
382 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Load(IStream
*pStm
)
387 HRESULT STDMETHODCALLTYPE
CAddressEditBox::Save(IStream
*pStm
, BOOL fClearDirty
)
392 HRESULT STDMETHODCALLTYPE
CAddressEditBox::GetSizeMax(ULARGE_INTEGER
*pcbSize
)