1 /* 2 * ReactOS Explorer 3 * 4 * Copyright 2009 Andrew Hill <ash77 at domain reactos.org> 5 * Copyright 2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 22 /* 23 This class handles the combo box of the address band. 24 */ 25 26 #include "precomp.h" 27 28 /* 29 TODO: 30 Add drag and drop of icon in edit box 31 Handle change notifies to update appropriately 32 */ 33 34 CAddressEditBox::CAddressEditBox() : 35 fCombobox(WC_COMBOBOXEXW, this), 36 fEditWindow(WC_EDITW, this), 37 fSite(NULL), 38 pidlLastParsed(NULL) 39 { 40 } 41 42 CAddressEditBox::~CAddressEditBox() 43 { 44 if (pidlLastParsed) 45 ILFree(pidlLastParsed); 46 } 47 48 HRESULT STDMETHODCALLTYPE CAddressEditBox::SetOwner(IUnknown *pOwner) 49 { 50 if (!pOwner) 51 { 52 CComPtr<IBrowserService> browserService; 53 HRESULT hResult = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 54 if (SUCCEEDED(hResult)) 55 AtlUnadvise(browserService, DIID_DWebBrowserEvents, fAdviseCookie); 56 fSite = NULL; 57 } 58 // connect to browser connection point 59 return 0; 60 } 61 62 HRESULT STDMETHODCALLTYPE CAddressEditBox::FileSysChange(long param8, long paramC) 63 { 64 return E_NOTIMPL; 65 } 66 67 HRESULT STDMETHODCALLTYPE CAddressEditBox::Refresh(long param8) 68 { 69 return E_NOTIMPL; 70 } 71 72 HRESULT STDMETHODCALLTYPE CAddressEditBox::Init(HWND comboboxEx, HWND editControl, long param14, IUnknown *param18) 73 { 74 CComPtr<IBrowserService> browserService; 75 76 fCombobox.SubclassWindow(comboboxEx); 77 fEditWindow.SubclassWindow(editControl); 78 fSite = param18; 79 hComboBoxEx = comboboxEx; 80 81 SHAutoComplete(fEditWindow.m_hWnd, SHACF_FILESYSTEM | SHACF_URLALL | SHACF_USETAB); 82 83 // take advice to watch events 84 HRESULT hResult = IUnknown_QueryService(param18, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &browserService)); 85 if (SUCCEEDED(hResult)) 86 { 87 hResult = AtlAdvise(browserService, static_cast<IDispatch *>(this), DIID_DWebBrowserEvents, &fAdviseCookie); 88 } 89 90 return hResult; 91 } 92 93 HRESULT STDMETHODCALLTYPE CAddressEditBox::SetCurrentDir(long paramC) 94 { 95 return E_NOTIMPL; 96 } 97 98 BOOL CAddressEditBox::GetComboBoxText(CComHeapPtr<WCHAR>& pszText) 99 { 100 pszText.Free(); 101 INT cchMax = fCombobox.GetWindowTextLength() + sizeof(UNICODE_NULL); 102 if (!pszText.Allocate(cchMax)) 103 return FALSE; 104 return fCombobox.GetWindowText(pszText, cchMax); 105 } 106 107 HRESULT CAddressEditBox::RefreshAddress() 108 { 109 /* Get the current pidl of the browser */ 110 CComHeapPtr<ITEMIDLIST> absolutePIDL; 111 HRESULT hr = GetAbsolutePidl(&absolutePIDL); 112 if (FAILED_UNEXPECTEDLY(hr)) 113 return hr; 114 115 /* Fill the combobox */ 116 ATLASSERT(absolutePIDL != NULL); 117 PopulateComboBox(absolutePIDL); 118 119 /* Get pShellFolder and pidlChild */ 120 CComPtr<IShellFolder> pShellFolder; 121 PCITEMID_CHILD pidlChild; 122 hr = SHBindToParent(absolutePIDL, IID_PPV_ARG(IShellFolder, &pShellFolder), &pidlChild); 123 if (FAILED_UNEXPECTEDLY(hr)) 124 return hr; 125 126 /* Get ready to set the displayed item */ 127 COMBOBOXEXITEMW item = { CBEIF_IMAGE | CBEIF_SELECTEDIMAGE | CBEIF_TEXT | CBEIF_LPARAM }; 128 item.iItem = -1; /* -1 to specify the displayed item */ 129 item.iImage = SHMapPIDLToSystemImageListIndex(pShellFolder, pidlChild, &item.iSelectedImage); 130 131 /* Set the path if filesystem; otherwise use the name */ 132 WCHAR szPathOrName[MAX_PATH]; 133 SHGDNF flags = SHGDN_FORADDRESSBAR; 134 if (gCabinetState.fFullPathAddress) 135 flags |= SHGDN_FORPARSING; 136 137 if (SUCCEEDED(IEGetNameAndFlags(absolutePIDL, flags, szPathOrName, _countof(szPathOrName), NULL))) 138 item.pszText = szPathOrName; 139 140 /* Ownership of absolutePIDL will be moved to fCombobox. See CBEN_DELETEITEM */ 141 item.lParam = reinterpret_cast<LPARAM>(absolutePIDL.Detach()); 142 143 fCombobox.SendMessage(CBEM_SETITEM, 0, reinterpret_cast<LPARAM>(&item)); /* Set it! */ 144 return S_OK; 145 } 146 147 HRESULT CAddressEditBox::GetAbsolutePidl(PIDLIST_ABSOLUTE *pAbsolutePIDL) 148 { 149 CComPtr<IBrowserService> isb; 150 HRESULT hr = IUnknown_QueryService(fSite, SID_STopLevelBrowser, IID_PPV_ARG(IBrowserService, &isb)); 151 if (FAILED_UNEXPECTEDLY(hr)) 152 return hr; 153 154 hr = isb->GetPidl(pAbsolutePIDL); 155 if (FAILED_UNEXPECTEDLY(hr)) 156 return hr; 157 158 return S_OK; 159 } 160 161 /* Execute command line from address bar */ 162 BOOL CAddressEditBox::ExecuteCommandLine() 163 { 164 /* Get command line */ 165 CComHeapPtr<WCHAR> pszCmdLine; 166 if (!GetComboBoxText(pszCmdLine)) 167 return FALSE; 168 169 /* Split 1st parameter from trailing arguments */ 170 PWCHAR args = PathGetArgsW(pszCmdLine); 171 PathRemoveArgsW(pszCmdLine); 172 173 PathUnquoteSpacesW(pszCmdLine); /* Unquote the 1st parameter */ 174 175 /* Get ready for execution */ 176 SHELLEXECUTEINFOW info = { sizeof(info), SEE_MASK_FLAG_NO_UI, m_hWnd }; 177 info.lpFile = pszCmdLine; 178 info.lpParameters = args; 179 info.nShow = SW_SHOWNORMAL; 180 181 /* Set current directory */ 182 WCHAR dir[MAX_PATH] = L""; 183 CComHeapPtr<ITEMIDLIST> pidl; 184 if (SUCCEEDED(GetAbsolutePidl(&pidl))) 185 { 186 if (SHGetPathFromIDListW(pidl, dir) && PathIsDirectoryW(dir)) 187 info.lpDirectory = dir; 188 } 189 190 if (!::ShellExecuteExW(&info)) /* Execute! */ 191 return FALSE; 192 193 RefreshAddress(); 194 return TRUE; 195 } 196 197 HRESULT STDMETHODCALLTYPE CAddressEditBox::ParseNow(long paramC) 198 { 199 ULONG eaten; 200 ULONG attributes; 201 HRESULT hr; 202 HWND topLevelWindow; 203 PIDLIST_ABSOLUTE pidlCurrent= NULL; 204 PIDLIST_RELATIVE pidlRelative = NULL; 205 CComPtr<IShellFolder> psfCurrent; 206 207 CComPtr<IBrowserService> pbs; 208 hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IBrowserService, &pbs)); 209 if (FAILED_UNEXPECTEDLY(hr)) 210 return hr; 211 212 hr = IUnknown_GetWindow(pbs, &topLevelWindow); 213 if (FAILED_UNEXPECTEDLY(hr)) 214 return hr; 215 216 /* Get the path to browse and expand it if needed */ 217 CComHeapPtr<WCHAR> input, address; 218 if (!GetComboBoxText(input)) 219 return E_FAIL; 220 221 INT addressLength = (wcschr(input, L'%') ? ::SHExpandEnvironmentStringsW(input, NULL, 0) : 0); 222 if (addressLength <= 0 || 223 !address.Allocate(addressLength + 1) || 224 !::SHExpandEnvironmentStringsW(input, address, addressLength)) 225 { 226 address.Free(); 227 address.Attach(input.Detach()); 228 } 229 230 /* Try to parse a relative path and if it fails, try to browse an absolute path */ 231 CComPtr<IShellFolder> psfDesktop; 232 hr = SHGetDesktopFolder(&psfDesktop); 233 if (FAILED_UNEXPECTEDLY(hr)) 234 goto cleanup; 235 236 hr = pbs->GetPidl(&pidlCurrent); 237 if (FAILED_UNEXPECTEDLY(hr)) 238 goto parseabsolute; 239 240 hr = psfDesktop->BindToObject(pidlCurrent, NULL, IID_PPV_ARG(IShellFolder, &psfCurrent)); 241 if (FAILED_UNEXPECTEDLY(hr)) 242 goto parseabsolute; 243 244 hr = psfCurrent->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlRelative, &attributes); 245 if (SUCCEEDED(hr)) 246 { 247 pidlLastParsed = ILCombine(pidlCurrent, pidlRelative); 248 ILFree(pidlRelative); 249 goto cleanup; 250 } 251 252 parseabsolute: 253 /* We couldn't parse a relative path, attempt to parse an absolute path */ 254 hr = psfDesktop->ParseDisplayName(topLevelWindow, NULL, address, &eaten, &pidlLastParsed, &attributes); 255 256 cleanup: 257 if (pidlCurrent) 258 ILFree(pidlCurrent); 259 return hr; 260 } 261 262 HRESULT STDMETHODCALLTYPE CAddressEditBox::ShowFileNotFoundError(HRESULT hRet) 263 { 264 CComHeapPtr<WCHAR> input; 265 if (!GetComboBoxText(input)) 266 return E_FAIL; 267 268 ShellMessageBoxW(_AtlBaseModule.GetResourceInstance(), fCombobox.m_hWnd, MAKEINTRESOURCEW(IDS_PARSE_ADDR_ERR_TEXT), MAKEINTRESOURCEW(IDS_PARSE_ADDR_ERR_TITLE), MB_OK | MB_ICONERROR, input.m_pData); 269 270 return hRet; 271 } 272 273 HRESULT STDMETHODCALLTYPE CAddressEditBox::Execute(long paramC) 274 { 275 HRESULT hr; 276 277 /* 278 * Parse the path if it wasn't parsed 279 */ 280 if (!pidlLastParsed) 281 { 282 hr = ParseNow(0); 283 284 /* If the destination path doesn't exist then display an error message */ 285 if (hr == HRESULT_FROM_WIN32(ERROR_INVALID_DRIVE) || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)) 286 { 287 if (ExecuteCommandLine()) 288 return S_OK; 289 290 return ShowFileNotFoundError(hr); 291 } 292 293 if (!pidlLastParsed) 294 return E_FAIL; 295 } 296 297 /* 298 * Get the IShellBrowser and IBrowserService interfaces of the shell browser 299 */ 300 CComPtr<IShellBrowser> pisb; 301 hr = IUnknown_QueryService(fSite, SID_SShellBrowser, IID_PPV_ARG(IShellBrowser, &pisb)); 302 if (FAILED(hr)) 303 return hr; 304 305 /* 306 * Get the current pidl of the shellbrowser and check if it is the same with the parsed one 307 */ 308 PIDLIST_ABSOLUTE pidl; 309 hr = GetAbsolutePidl(&pidl); 310 if (FAILED(hr)) 311 return hr; 312 313 CComPtr<IShellFolder> psf; 314 hr = SHGetDesktopFolder(&psf); 315 if (FAILED(hr)) 316 return hr; 317 318 hr = psf->CompareIDs(0, pidl, pidlLastParsed); 319 320 SHFree(pidl); 321 if (hr == 0) 322 return S_OK; 323 324 /* 325 * Attempt to browse to the parsed pidl 326 */ 327 hr = pisb->BrowseObject(pidlLastParsed, 0); 328 if (SUCCEEDED(hr)) 329 return hr; 330 331 /* 332 * Browsing to the pidl failed so it's not a folder. So invoke its defaule command. 333 */ 334 HWND topLevelWindow; 335 hr = IUnknown_GetWindow(pisb, &topLevelWindow); 336 if (FAILED(hr)) 337 return hr; 338 339 LPCITEMIDLIST pidlChild; 340 CComPtr<IShellFolder> sf; 341 hr = SHBindToParent(pidlLastParsed, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); 342 if (FAILED(hr)) 343 return hr; 344 345 hr = SHInvokeDefaultCommand(topLevelWindow, sf, pidlChild); 346 if (FAILED(hr)) 347 return hr; 348 349 return hr; 350 } 351 352 HRESULT STDMETHODCALLTYPE CAddressEditBox::Save(long paramC) 353 { 354 return E_NOTIMPL; 355 } 356 357 HRESULT STDMETHODCALLTYPE CAddressEditBox::OnWinEvent( 358 HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *theResult) 359 { 360 LPNMHDR hdr; 361 362 if (theResult) 363 *theResult = 0; 364 365 switch (uMsg) 366 { 367 case WM_COMMAND: 368 { 369 if (HIWORD(wParam) == CBN_SELCHANGE) 370 { 371 UINT selectedIndex = SendMessageW((HWND)lParam, CB_GETCURSEL, 0, 0); 372 pidlLastParsed = ILClone((LPITEMIDLIST)SendMessageW((HWND)lParam, CB_GETITEMDATA, selectedIndex, 0)); 373 Execute(0); 374 } 375 break; 376 } 377 case WM_NOTIFY: 378 { 379 hdr = (LPNMHDR) lParam; 380 if (hdr->code == CBEN_ENDEDIT) 381 { 382 NMCBEENDEDITW *endEdit = (NMCBEENDEDITW*) lParam; 383 if (endEdit->iWhy == CBENF_RETURN) 384 { 385 Execute(0); 386 } 387 else if (endEdit->iWhy == CBENF_ESCAPE) 388 { 389 /* Reset the contents of the combo box */ 390 RefreshAddress(); 391 } 392 } 393 else if (hdr->code == CBEN_DELETEITEM) 394 { 395 PNMCOMBOBOXEX pCBEx = (PNMCOMBOBOXEX) lParam; 396 LPITEMIDLIST itemPidl = (LPITEMIDLIST)pCBEx->ceItem.lParam; 397 if (itemPidl) 398 { 399 ILFree(itemPidl); 400 } 401 } 402 break; 403 } 404 } 405 return S_OK; 406 } 407 408 HRESULT STDMETHODCALLTYPE CAddressEditBox::IsWindowOwner(HWND hWnd) 409 { 410 if (fCombobox.m_hWnd == hWnd) 411 return S_OK; 412 if (fEditWindow.m_hWnd == hWnd) 413 return S_OK; 414 return S_FALSE; 415 } 416 417 HRESULT STDMETHODCALLTYPE CAddressEditBox::QueryStatus( 418 const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[ ], OLECMDTEXT *pCmdText) 419 { 420 return E_NOTIMPL; 421 } 422 423 HRESULT STDMETHODCALLTYPE CAddressEditBox::Exec(const GUID *pguidCmdGroup, DWORD nCmdID, 424 DWORD nCmdexecopt, VARIANT *pvaIn, VARIANT *pvaOut) 425 { 426 return E_NOTIMPL; 427 } 428 429 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetTypeInfoCount(UINT *pctinfo) 430 { 431 return E_NOTIMPL; 432 } 433 434 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo **ppTInfo) 435 { 436 return E_NOTIMPL; 437 } 438 439 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetIDsOfNames( 440 REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) 441 { 442 return E_NOTIMPL; 443 } 444 445 HRESULT STDMETHODCALLTYPE CAddressEditBox::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, 446 WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) 447 { 448 if (pDispParams == NULL) 449 return E_INVALIDARG; 450 451 switch (dispIdMember) 452 { 453 case DISPID_NAVIGATECOMPLETE2: 454 case DISPID_DOCUMENTCOMPLETE: 455 if (pidlLastParsed) 456 { 457 ILFree(pidlLastParsed); 458 pidlLastParsed = NULL; 459 } 460 461 RefreshAddress(); 462 break; 463 } 464 return S_OK; 465 } 466 467 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetClassID(CLSID *pClassID) 468 { 469 if (pClassID == NULL) 470 return E_POINTER; 471 *pClassID = CLSID_AddressEditBox; 472 return S_OK; 473 } 474 475 HRESULT STDMETHODCALLTYPE CAddressEditBox::IsDirty() 476 { 477 return E_NOTIMPL; 478 } 479 480 HRESULT STDMETHODCALLTYPE CAddressEditBox::Load(IStream *pStm) 481 { 482 return E_NOTIMPL; 483 } 484 485 HRESULT STDMETHODCALLTYPE CAddressEditBox::Save(IStream *pStm, BOOL fClearDirty) 486 { 487 return E_NOTIMPL; 488 } 489 490 HRESULT STDMETHODCALLTYPE CAddressEditBox::GetSizeMax(ULARGE_INTEGER *pcbSize) 491 { 492 return E_NOTIMPL; 493 } 494 495 void CAddressEditBox::PopulateComboBox(LPITEMIDLIST pidlCurrent) 496 { 497 HRESULT hr; 498 LPITEMIDLIST pidl; 499 int indent = 0; 500 int index; 501 502 index = SendMessageW(hComboBoxEx, CB_GETCOUNT, 0, 0); 503 for (int i = 0; i < index; i++) 504 SendMessageW(hComboBoxEx, CBEM_DELETEITEM, i, 0); 505 SendMessageW(hComboBoxEx, CB_RESETCONTENT, 0, 0); 506 507 /* Calculate the indent level. No need to clone the pidl */ 508 pidl = pidlCurrent; 509 do 510 { 511 if(!pidl->mkid.cb) 512 break; 513 pidl = ILGetNext(pidl); 514 indent++; 515 } while (pidl); 516 index = indent; 517 518 /* Add every id from the pidl in the combo box */ 519 pidl = ILClone(pidlCurrent); 520 do 521 { 522 AddComboBoxItem(pidl, 0, index); 523 ILRemoveLastID(pidl); 524 index--; 525 } while (index >= 0); 526 ILFree(pidl); 527 528 /* Add the items of the desktop */ 529 FillOneLevel(0, 1, indent); 530 531 /* Add the items of My Computer */ 532 hr = SHGetSpecialFolderLocation(0, CSIDL_DRIVES, &pidl); 533 if (FAILED_UNEXPECTEDLY(hr)) 534 return; 535 536 for(LPITEMIDLIST i = GetItemData(0); i; i = GetItemData(index)) 537 { 538 if (ILIsEqual(i, pidl)) 539 { 540 FillOneLevel(index, 2, indent); 541 break; 542 } 543 index++; 544 } 545 ILFree(pidl); 546 } 547 548 void CAddressEditBox::AddComboBoxItem(LPITEMIDLIST pidl, int index, int indent) 549 { 550 HRESULT hr; 551 WCHAR buf[4096]; 552 553 LPCITEMIDLIST pidlChild; 554 CComPtr<IShellFolder> sf; 555 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &sf), &pidlChild); 556 if (FAILED_UNEXPECTEDLY(hr)) 557 return; 558 559 STRRET strret; 560 hr = sf->GetDisplayNameOf(pidlChild, SHGDN_FORADDRESSBAR, &strret); 561 if (FAILED_UNEXPECTEDLY(hr)) 562 return; 563 564 hr = StrRetToBufW(&strret, pidlChild, buf, 4095); 565 if (FAILED_UNEXPECTEDLY(hr)) 566 return; 567 568 COMBOBOXEXITEMW item = {0}; 569 item.mask = CBEIF_LPARAM | CBEIF_INDENT | CBEIF_SELECTEDIMAGE | CBEIF_IMAGE | CBEIF_TEXT; 570 item.iImage = SHMapPIDLToSystemImageListIndex(sf, pidlChild, &item.iSelectedImage); 571 item.pszText = buf; 572 item.lParam = (LPARAM)(ILClone(pidl)); 573 item.iIndent = indent; 574 item.iItem = index; 575 SendMessageW(hComboBoxEx, CBEM_INSERTITEMW, 0, (LPARAM)&item); 576 } 577 578 void CAddressEditBox::FillOneLevel(int index, int levelIndent, int indent) 579 { 580 HRESULT hr; 581 ULONG numObj; 582 int count; 583 LPITEMIDLIST pidl, pidl2, pidl3, pidl4; 584 585 count = index + 1; 586 pidl = GetItemData(index); 587 pidl2 = GetItemData(count); 588 if(pidl) 589 { 590 CComPtr<IShellFolder> psfDesktop; 591 CComPtr<IShellFolder> psfItem; 592 593 hr = SHGetDesktopFolder(&psfDesktop); 594 if (FAILED_UNEXPECTEDLY(hr)) 595 return; 596 597 if (!pidl->mkid.cb) 598 { 599 psfItem = psfDesktop; 600 } 601 else 602 { 603 hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfItem)); 604 if (FAILED_UNEXPECTEDLY(hr)) 605 return; 606 } 607 608 CComPtr<IEnumIDList> pEnumIDList; 609 hr = psfItem->EnumObjects(0, SHCONTF_FOLDERS | SHCONTF_INCLUDEHIDDEN, &pEnumIDList); 610 if (FAILED_UNEXPECTEDLY(hr)) 611 return; 612 613 do 614 { 615 hr = pEnumIDList->Next(1, &pidl3, &numObj); 616 if(hr != S_OK || !numObj) 617 break; 618 619 pidl4 = ILCombine(pidl, pidl3); 620 if (pidl2 && ILIsEqual(pidl4, pidl2)) 621 count += (indent - levelIndent); 622 else 623 AddComboBoxItem(pidl4, count, levelIndent); 624 count++; 625 ILFree(pidl3); 626 ILFree(pidl4); 627 } while (true); 628 } 629 } 630 631 LPITEMIDLIST CAddressEditBox::GetItemData(int index) 632 { 633 COMBOBOXEXITEMW item; 634 635 memset(&item, 0, sizeof(COMBOBOXEXITEMW)); 636 item.mask = CBEIF_LPARAM; 637 item.iItem = index; 638 SendMessageW(hComboBoxEx, CBEM_GETITEMW, 0, (LPARAM)&item); 639 return (LPITEMIDLIST)item.lParam; 640 } 641 642 LRESULT CAddressEditBox::OnSettingChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled) 643 { 644 RefreshAddress(); 645 return NO_ERROR; 646 } 647