[SHELL32]
[reactos.git] / dll / win32 / browseui / addresseditbox.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 This class handles the combo box of the address band.
23 */
24
25 #include "precomp.h"
26
27 /*
28 TODO:
29 Add auto completion support
30 Subclass windows in Init method
31 Connect to browser connection point
32 Handle navigation complete messages to set edit box text
33 Handle listbox dropdown message and fill contents
34 Add drag and drop of icon in edit box
35 Handle enter in edit box to browse to typed path
36 Handle change notifies to update appropriately
37 Add handling of enter in edit box
38 Fix so selection in combo listbox navigates
39 Fix so editing text and typing enter navigates
40 */
41
42 CAddressEditBox::CAddressEditBox() :
43 fCombobox(NULL, this, 1),
44 fEditWindow(NULL, this, 1),
45 fSite(NULL)
46 {
47 }
48
49 CAddressEditBox::~CAddressEditBox()
50 {
51 }
52
53 HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *)
54 {
55 // connect to browser connection point
56 return 0;
57 }
58
59 HRESULT STDMETHODCALLTYPE CAddressEditBox::FileSysChange(long param8, long paramC)
60 {
61 return E_NOTIMPL;
62 }
63
64 HRESULT STDMETHODCALLTYPE CAddressEditBox::Refresh(long param8)
65 {
66 return E_NOTIMPL;
67 }
68
69 HRESULT STDMETHODCALLTYPE CAddressEditBox::Init(HWND comboboxEx, HWND editControl, long param14, IUnknown *param18)
70 {
71 CComPtr<IBrowserService> browserService;
72
73 fCombobox.SubclassWindow(comboboxEx);
74 fEditWindow.SubclassWindow(editControl);
75 fSite = param18;
76
77 // take advice to watch events
78 HRESULT hResult = IUnknown_QueryService(param18, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService));
79 if (SUCCEEDED(hResult))
80 {
81 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie);
82 }
83
84 return hResult;
85 }
86
87 HRESULT STDMETHODCALLTYPE CAddressEditBox::SetCurrentDir(long paramC)
88 {
89 return E_NOTIMPL;
90 }
91
92 HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC)
93 {
94 ULONG eaten;
95 ULONG attributes;
96 HRESULT hr;
97 HWND topLevelWindow;
98
99 CComPtr<IShellBrowser> pisb;
100 hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb));
101
102 IUnknown_GetWindow(pisb, &topLevelWindow);
103
104 LPWSTR input;
105 int inputLength = GetWindowTextLength(fCombobox.m_hWnd) + 2;
106
107 input = new WCHAR[inputLength];
108 GetWindowText(fCombobox.m_hWnd, input, inputLength);
109
110 LPWSTR address;
111 int addressLength = ExpandEnvironmentStrings(input, NULL, 0);
112
113 if (addressLength <= 0)
114 {
115 address = input;
116 }
117 else
118 {
119 addressLength += 2;
120 address = new WCHAR[addressLength];
121 ExpandEnvironmentStrings(input, address, 0);
122 }
123
124 CComPtr<IShellFolder> psfDesktop;
125 hr = SHGetDesktopFolder(&psfDesktop);
126 hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlLastParsed, &attributes);
127
128 if (address != input)
129 delete [] address;
130 delete [] input;
131
132 return hr;
133 }
134
135 HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC)
136 {
137 HRESULT hr;
138
139 if (!pidlLastParsed)
140 return E_FAIL;
141
142 CComPtr<IShellBrowser> pisb;
143 hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb));
144 if (SUCCEEDED(hr))
145 {
146 hr = pisb->BrowseObject(pidlLastParsed, 0);
147 if (FAILED(hr))
148 {
149 HWND topLevelWindow;
150 LPCITEMIDLIST pidlChild;
151 CComPtr<IShellFolder> sf;
152 CComPtr<IShellBrowser> pisb;
153
154 hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb));
155
156 IUnknown_GetWindow(pisb, &topLevelWindow);
157
158 hr = SHBindToParent(pidlLastParsed, IID_PPV_ARG(IShellFolder, &sf), &pidlChild);
159
160 SHInvokeDefaultCommand(topLevelWindow, sf, pidlChild);
161 }
162 }
163 return hr;
164 }
165
166 HRESULT STDMETHODCALLTYPE CAddressEditBox::Save(long paramC)
167 {
168 return E_NOTIMPL;
169 }
170
171 HRESULT STDMETHODCALLTYPE CAddressEditBox::OnWinEvent(
172 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult)
173 {
174 // handle fill of listbox here
175 return E_NOTIMPL;
176 }
177
178 HRESULT STDMETHODCALLTYPE CAddressEditBox::IsWindowOwner(HWND hWnd)
179 {
180 if (fCombobox.m_hWnd == hWnd)
181 return S_OK;
182 if (fEditWindow.m_hWnd == hWnd)
183 return S_OK;
184 return S_FALSE;
185 }
186
187 HRESULT STDMETHODCALLTYPE CAddressEditBox::QueryStatus(
188 const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText)
189 {
190 return E_NOTIMPL;
191 }
192
193 HRESULT STDMETHODCALLTYPE CAddressEditBox::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
194 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut)
195 {
196 return E_NOTIMPL;
197 }
198
199 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetTypeInfoCount(UINT *pctinfo)
200 {
201 return E_NOTIMPL;
202 }
203
204 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo)
205 {
206 return E_NOTIMPL;
207 }
208
209 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetIDsOfNames(
210 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
211 {
212 return E_NOTIMPL;
213 }
214
215 HRESULT STDMETHODCALLTYPE CAddressEditBox::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
216 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
217 {
218 if (pDispParams == NULL)
219 return E_INVALIDARG;
220
221 switch (dispIdMember)
222 {
223 case DISPID_NAVIGATECOMPLETE2:
224 case DISPID_DOCUMENTCOMPLETE:
225 pidlLastParsed = NULL;
226 }
227 return S_OK;
228 }
229
230 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetClassID(CLSID *pClassID)
231 {
232 if (pClassID == NULL)
233 return E_POINTER;
234 *pClassID = CLSID_AddressEditBox;
235 return S_OK;
236 }
237
238 HRESULT STDMETHODCALLTYPE CAddressEditBox::IsDirty()
239 {
240 return E_NOTIMPL;
241 }
242
243 HRESULT STDMETHODCALLTYPE CAddressEditBox::Load(IStream *pStm)
244 {
245 return E_NOTIMPL;
246 }
247
248 HRESULT STDMETHODCALLTYPE CAddressEditBox::Save(IStream *pStm, BOOL fClearDirty)
249 {
250 return E_NOTIMPL;
251 }
252
253 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetSizeMax(ULARGE_INTEGER *pcbSize)
254 {
255 return E_NOTIMPL;
256 }
257
258 HRESULT CreateAddressEditBox(REFIID riid, void **ppv)
259 {
260 CComObject<CAddressEditBox> *theMenuBar;
261 HRESULT hResult;
262
263 if (ppv == NULL)
264 return E_POINTER;
265 *ppv = NULL;
266 ATLTRY (theMenuBar = new CComObject<CAddressEditBox>);
267 if (theMenuBar == NULL)
268 return E_OUTOFMEMORY;
269 hResult = theMenuBar->QueryInterface(riid, reinterpret_cast<void **>(ppv));
270 if (FAILED(hResult))
271 {
272 delete theMenuBar;
273 return hResult;
274 }
275 return S_OK;
276 }