From: Hermès Bélusca-Maïto Date: Sun, 30 Sep 2018 19:22:50 +0000 (+0200) Subject: [SHELL32] Fixes and improvements for PickIconDlg(). X-Git-Tag: 0.4.12-dev~691 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=ccde12483fdfc1e6909aec14fb865c2df35b3804 [SHELL32] Fixes and improvements for PickIconDlg(). - Deal with expanded paths only when loading icons. If the user specifies an unexpanded path to a module containing icons, this unexpanded path is returned to the caller! - Perform the dialog cleanup in WM_DESTROY message handler. - When pressing ENTER/OK in the dialog box, retrieve the selected icon and close the dialog *ONLY WHEN* the user actually has selected an icon. If the user modified manually the module path, pressing ENTER/OK instead reloads the icons list. --- diff --git a/dll/win32/shell32/dialogs/dialogs.cpp b/dll/win32/shell32/dialogs/dialogs.cpp index 2d939ee11bb..47b6f04d5a5 100644 --- a/dll/win32/shell32/dialogs/dialogs.cpp +++ b/dll/win32/shell32/dialogs/dialogs.cpp @@ -48,7 +48,6 @@ typedef struct HMODULE hLibrary; HWND hDlgCtrl; WCHAR szPath[MAX_PATH]; - WCHAR szExpandedPath[MAX_PATH]; INT Index; INT nIcons; HICON *phIcons; @@ -90,19 +89,21 @@ DestroyIconList(HWND hDlgCtrl, PPICK_ICON_CONTEXT pIconContext) } static BOOL -DoLoadIcons(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext, LPCWSTR pszFile) +DoLoadIcons(HWND hwndDlg, PPICK_ICON_CONTEXT pIconContext, LPCWSTR pszFile) { + WCHAR szExpandedPath[MAX_PATH]; + // Destroy previous icons DestroyIconList(pIconContext->hDlgCtrl, pIconContext); SendMessageW(pIconContext->hDlgCtrl, LB_RESETCONTENT, 0, 0); delete[] pIconContext->phIcons; - // Store the paths + // Store the path StringCchCopyW(pIconContext->szPath, _countof(pIconContext->szPath), pszFile); - ExpandEnvironmentStringsW(pszFile, pIconContext->szExpandedPath, _countof(pIconContext->szExpandedPath)); + ExpandEnvironmentStringsW(pszFile, szExpandedPath, _countof(szExpandedPath)); // Load the module if possible - HMODULE hLibrary = LoadLibraryExW(pIconContext->szExpandedPath, NULL, LOAD_LIBRARY_AS_DATAFILE); + HMODULE hLibrary = LoadLibraryExW(szExpandedPath, NULL, LOAD_LIBRARY_AS_DATAFILE); if (pIconContext->hLibrary) FreeLibrary(pIconContext->hLibrary); pIconContext->hLibrary = hLibrary; @@ -110,10 +111,10 @@ DoLoadIcons(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext, LPCWSTR pszFile) if (pIconContext->hLibrary) { // Load the icons from the module - pIconContext->nIcons = ExtractIconExW(pIconContext->szExpandedPath, -1, NULL, NULL, 0); + pIconContext->nIcons = ExtractIconExW(szExpandedPath, -1, NULL, NULL, 0); pIconContext->phIcons = new HICON[pIconContext->nIcons]; - if (ExtractIconExW(pIconContext->szExpandedPath, 0, pIconContext->phIcons, NULL, pIconContext->nIcons)) + if (ExtractIconExW(szExpandedPath, 0, pIconContext->phIcons, NULL, pIconContext->nIcons)) { EnumResourceNamesW(pIconContext->hLibrary, RT_GROUP_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext); } @@ -128,7 +129,7 @@ DoLoadIcons(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext, LPCWSTR pszFile) pIconContext->nIcons = 1; pIconContext->phIcons = new HICON[1]; - if (ExtractIconExW(pIconContext->szExpandedPath, 0, pIconContext->phIcons, NULL, pIconContext->nIcons)) + if (ExtractIconExW(szExpandedPath, 0, pIconContext->phIcons, NULL, pIconContext->nIcons)) { SendMessageW(pIconContext->hDlgCtrl, LB_ADDSTRING, 0, 0); } @@ -138,8 +139,9 @@ DoLoadIcons(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext, LPCWSTR pszFile) } } - // Set the text + // Set the text and reset the edit control's modification flag SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szPath); + SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_SETMODIFY, FALSE, 0); if (pIconContext->nIcons == 0) { @@ -147,12 +149,12 @@ DoLoadIcons(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext, LPCWSTR pszFile) pIconContext->phIcons = NULL; } - return pIconContext->nIcons > 0; + return (pIconContext->nIcons > 0); } static const LPCWSTR s_pszDefaultPath = L"%SystemRoot%\\system32\\shell32.dll"; -static void NoIconsInFile(HWND hwndDlg, PICK_ICON_CONTEXT *pIconContext) +static void NoIconsInFile(HWND hwndDlg, PPICK_ICON_CONTEXT pIconContext) { // Show an error message CStringW strText, strTitle(MAKEINTRESOURCEW(IDS_PICK_ICON_TITLE)); @@ -221,22 +223,45 @@ INT_PTR CALLBACK PickIconProc( return TRUE; } + case WM_DESTROY: + { + DestroyIconList(pIconContext->hDlgCtrl, pIconContext); + delete[] pIconContext->phIcons; + + if (pIconContext->hLibrary) + FreeLibrary(pIconContext->hLibrary); + break; + } + case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: - index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0); - pIconContext->Index = index; + { + /* Check whether the path edit control has been modified; if so load the icons instead of validating */ + if (SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_GETMODIFY, 0, 0)) + { + /* Reset the edit control's modification flag and retrieve the text */ + SendDlgItemMessage(hwndDlg, IDC_EDIT_PATH, EM_SETMODIFY, FALSE, 0); + GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText, _countof(szText)); + + // Load the icons + if (!DoLoadIcons(hwndDlg, pIconContext, szText)) + NoIconsInFile(hwndDlg, pIconContext); + + // Set the selection + SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); + break; + } + + /* The path edit control has not been modified, return the selection */ + pIconContext->Index = (INT)SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0); GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szPath, _countof(pIconContext->szPath)); - ExpandEnvironmentStringsW(pIconContext->szPath, pIconContext->szExpandedPath, _countof(pIconContext->szExpandedPath)); - DestroyIconList(pIconContext->hDlgCtrl, pIconContext); - delete[] pIconContext->phIcons; EndDialog(hwndDlg, 1); break; + } case IDCANCEL: - DestroyIconList(pIconContext->hDlgCtrl, pIconContext); - delete[] pIconContext->phIcons; EndDialog(hwndDlg, 0); break; @@ -293,9 +318,7 @@ INT_PTR CALLBACK PickIconProc( { lpdis = (LPDRAWITEMSTRUCT)lParam; if (lpdis->itemID == (UINT)-1) - { break; - } switch (lpdis->itemAction) { case ODA_SELECT: @@ -331,17 +354,18 @@ BOOL WINAPI PickIconDlg( INT* lpdwIconIndex) { int res; + WCHAR szExpandedPath[MAX_PATH]; // Initialize the dialog PICK_ICON_CONTEXT IconContext = { NULL }; IconContext.Index = *lpdwIconIndex; StringCchCopyW(IconContext.szPath, _countof(IconContext.szPath), lpstrFile); - ExpandEnvironmentStringsW(lpstrFile, IconContext.szExpandedPath, _countof(IconContext.szExpandedPath)); + ExpandEnvironmentStringsW(lpstrFile, szExpandedPath, _countof(szExpandedPath)); - if (!IconContext.szExpandedPath[0] || - GetFileAttributesW(IconContext.szExpandedPath) == INVALID_FILE_ATTRIBUTES) + if (!szExpandedPath[0] || + GetFileAttributesW(szExpandedPath) == INVALID_FILE_ATTRIBUTES) { - if (IconContext.szExpandedPath[0]) + if (szExpandedPath[0]) { // No such file CStringW strText, strTitle(MAKEINTRESOURCEW(IDS_PICK_ICON_TITLE)); @@ -351,7 +375,6 @@ BOOL WINAPI PickIconDlg( // Set the default value StringCchCopyW(IconContext.szPath, _countof(IconContext.szPath), s_pszDefaultPath); - ExpandEnvironmentStringsW(s_pszDefaultPath, IconContext.szPath, _countof(IconContext.szPath)); } // Show the dialog @@ -359,12 +382,10 @@ BOOL WINAPI PickIconDlg( if (res) { // Store the selected icon - StringCchCopyW(lpstrFile, nMaxFile, IconContext.szExpandedPath); + StringCchCopyW(lpstrFile, nMaxFile, IconContext.szPath); *lpdwIconIndex = IconContext.Index; } - if (IconContext.hLibrary) - FreeLibrary(IconContext.hLibrary); return res; }