[SHELL32]: Run dialog box: FillList was ANSI, now it's UNICODE! Partly rewrite Wine code.

svn path=/trunk/; revision=71595
This commit is contained in:
Hermès Bélusca-Maïto 2016-06-08 21:53:34 +00:00
parent 2f53cccf2f
commit cdae0d1bf7

View file

@ -33,8 +33,8 @@ typedef struct
typedef BOOL (WINAPI * LPFNOFN) (OPENFILENAMEW *) ; typedef BOOL (WINAPI * LPFNOFN) (OPENFILENAMEW *) ;
WINE_DEFAULT_DEBUG_CHANNEL(shell); WINE_DEFAULT_DEBUG_CHANNEL(shell);
static INT_PTR CALLBACK RunDlgProc (HWND, UINT, WPARAM, LPARAM) ; static INT_PTR CALLBACK RunDlgProc(HWND, UINT, WPARAM, LPARAM);
static void FillList (HWND, char *, BOOL) ; static void FillList(HWND, LPWSTR, BOOL);
/************************************************************************* /*************************************************************************
@ -393,26 +393,26 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
// SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)prfdp->hIcon); // SendMessageW(hwnd, WM_SETICON, ICON_SMALL, (LPARAM)prfdp->hIcon);
SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_ICON), STM_SETICON, (WPARAM)prfdp->hIcon, 0); SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_ICON), STM_SETICON, (WPARAM)prfdp->hIcon, 0);
FillList (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), NULL, (prfdp->uFlags & RFF_NODEFAULT) == 0); FillList(GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH), NULL, (prfdp->uFlags & RFF_NODEFAULT) == 0);
EnableOkButtonFromEditContents(hwnd); EnableOkButtonFromEditContents(hwnd);
SetFocus (GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH)); SetFocus(GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH));
return TRUE; return TRUE;
case WM_COMMAND: case WM_COMMAND:
switch (LOWORD (wParam)) switch (LOWORD(wParam))
{ {
case IDOK: case IDOK:
{ {
int ic; int ic;
HWND htxt = GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH); HWND htxt = GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH);
if ((ic = GetWindowTextLengthW (htxt))) if ((ic = GetWindowTextLengthW(htxt)))
{ {
WCHAR *psz, *parent = NULL; WCHAR *psz, *parent = NULL;
SHELLEXECUTEINFOW sei; SHELLEXECUTEINFOW sei;
ZeroMemory (&sei, sizeof(sei)); ZeroMemory(&sei, sizeof(sei));
sei.cbSize = sizeof(sei); sei.cbSize = sizeof(sei);
psz = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR)); psz = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR));
if (psz) if (psz)
{ {
@ -438,19 +438,18 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
return TRUE; return TRUE;
} }
/* FillList is still ANSI */ GetWindowTextW(htxt, psz, ic + 1);
GetWindowTextA (htxt, (LPSTR)psz, ic + 1); FillList(htxt, psz, FALSE);
FillList (htxt, (LPSTR)psz, FALSE);
HeapFree(GetProcessHeap(), 0, psz); HeapFree(GetProcessHeap(), 0, psz);
HeapFree(GetProcessHeap(), 0, parent); HeapFree(GetProcessHeap(), 0, parent);
EndDialog (hwnd, 0); EndDialog(hwnd, 0);
} }
} }
} }
case IDCANCEL: case IDCANCEL:
EndDialog (hwnd, 0); EndDialog(hwnd, 0);
return TRUE; return TRUE;
case IDC_RUNDLG_BROWSE: case IDC_RUNDLG_BROWSE:
@ -466,17 +465,17 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_CAPTION, szCaption, MAX_PATH); LoadStringW(shell32_hInstance, IDS_RUNDLG_BROWSE_CAPTION, szCaption, MAX_PATH);
ZeroMemory(&ofn, sizeof(ofn)); ZeroMemory(&ofn, sizeof(ofn));
ofn.lStructSize = sizeof(OPENFILENAMEW); ofn.lStructSize = sizeof(ofn);
ofn.hwndOwner = hwnd; ofn.hwndOwner = hwnd;
ofn.lpstrFilter = filter; ofn.lpstrFilter = filter;
ofn.lpstrFile = szFName; ofn.lpstrFile = szFName;
ofn.nMaxFile = 1023; ofn.nMaxFile = _countof(szFName) - 1;
ofn.lpstrTitle = szCaption; ofn.lpstrTitle = szCaption;
ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST; ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST;
ofn.lpstrInitialDir = prfdp->lpstrDirectory; ofn.lpstrInitialDir = prfdp->lpstrDirectory;
if (NULL == (hComdlg = LoadLibraryExW (comdlg32W, NULL, 0)) || if (NULL == (hComdlg = LoadLibraryExW(comdlg32W, NULL, 0)) ||
NULL == (ofnProc = (LPFNOFN)GetProcAddress (hComdlg, "GetOpenFileNameW"))) NULL == (ofnProc = (LPFNOFN)GetProcAddress(hComdlg, "GetOpenFileNameW")))
{ {
ERR("Couldn't get GetOpenFileName function entry (lib=%p, proc=%p)\n", hComdlg, ofnProc); ERR("Couldn't get GetOpenFileName function entry (lib=%p, proc=%p)\n", hComdlg, ofnProc);
ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_RUNDLG_BROWSE_ERROR), NULL, MB_OK | MB_ICONERROR); ShellMessageBoxW(shell32_hInstance, hwnd, MAKEINTRESOURCEW(IDS_RUNDLG_BROWSE_ERROR), NULL, MB_OK | MB_ICONERROR);
@ -485,14 +484,14 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
if (ofnProc(&ofn)) if (ofnProc(&ofn))
{ {
SetFocus(GetDlgItem (hwnd, IDOK)); SetFocus(GetDlgItem(hwnd, IDOK));
SetWindowTextW(GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), szFName); SetWindowTextW(GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH), szFName);
SendMessageW(GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH), CB_SETEDITSEL, 0, MAKELPARAM (0, -1)); SendMessageW(GetDlgItem(hwnd, IDC_RUNDLG_EDITPATH), CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
EnableOkButtonFromEditContents(hwnd); EnableOkButtonFromEditContents(hwnd);
SetFocus (GetDlgItem (hwnd, IDOK)); SetFocus(GetDlgItem(hwnd, IDOK));
} }
FreeLibrary (hComdlg); FreeLibrary(hComdlg);
return TRUE; return TRUE;
} }
@ -510,145 +509,207 @@ static INT_PTR CALLBACK RunDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARA
return FALSE; return FALSE;
} }
/* This grabs the MRU list from the registry and fills the combo for the "Run" dialog above */ /*
/* fShowDefault ignored if pszLatest != NULL */ * This function grabs the MRU list from the registry and fills the combo-list
static void FillList(HWND hCb, char *pszLatest, BOOL fShowDefault) * for the "Run" dialog above. fShowDefault is ignored if pszLatest != NULL.
*/
static void FillList(HWND hCb, LPWSTR pszLatest, BOOL fShowDefault)
{ {
HKEY hkey ; HKEY hkey;
/* char szDbgMsg[256] = "" ; */ WCHAR *pszList = NULL, *pszCmd = NULL, *pszTmp = NULL, cMatch = 0, cMax = 0x60;
char *pszList = NULL, *pszCmd = NULL, cMatch = 0, cMax = 0x60, szIndex[2] = "-" ; WCHAR szIndex[2] = L"-";
DWORD icList = 0, icCmd = 0 ; DWORD dwType, icList = 0, icCmd = 0;
UINT Nix ; LRESULT lRet;
UINT Nix;
SendMessageA (hCb, CB_RESETCONTENT, 0, 0) ; SendMessageW(hCb, CB_RESETCONTENT, 0, 0);
if (ERROR_SUCCESS != RegCreateKeyExA ( lRet = RegCreateKeyExW(HKEY_CURRENT_USER,
HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU", L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\RunMRU",
0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL)) 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL);
MessageBoxA (hCb, "Unable to open registry key !", "Nix", MB_OK) ; if (lRet != ERROR_SUCCESS)
RegQueryValueExA (hkey, "MRUList", NULL, NULL, NULL, &icList) ;
if (icList > 0)
{ {
pszList = (char *)HeapAlloc( GetProcessHeap(), 0, icList) ; TRACE("Unable to open or create the RunMRU key, error %d\n", GetLastError());
return;
if (pszList)
{
if (ERROR_SUCCESS != RegQueryValueExA (hkey, "MRUList", NULL, NULL, (LPBYTE)pszList, &icList))
MessageBoxA (hCb, "Unable to grab MRUList !", "Nix", MB_OK);
} }
else
lRet = RegQueryValueExW(hkey, L"MRUList", NULL, &dwType, NULL, &icList);
if (lRet == ERROR_SUCCESS && dwType == REG_SZ && icList > sizeof(WCHAR))
{
pszList = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, icList);
if (!pszList)
{ {
TRACE("HeapAlloc failed to allocate %d bytes\n", icList); TRACE("HeapAlloc failed to allocate %d bytes\n", icList);
goto Continue;
}
pszList[0] = L'\0';
lRet = RegQueryValueExW(hkey, L"MRUList", NULL, NULL, (LPBYTE)pszList, &icList);
if (lRet != ERROR_SUCCESS)
{
TRACE("Unable to grab MRUList, error %d\n", GetLastError());
pszList[0] = L'\0';
} }
} }
else else
{ {
icList = 1 ; Continue:
pszList = (char *)HeapAlloc( GetProcessHeap(), 0, icList) ; icList = sizeof(WCHAR);
pszList[0] = 0 ; pszList = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, icList);
if (!pszList)
{
TRACE("HeapAlloc failed to allocate %d bytes\n", icList);
RegCloseKey(hkey);
return;
}
pszList[0] = L'\0';
} }
for (Nix = 0 ; Nix < icList - 1 ; Nix++) /* Convert the number of bytes from MRUList into number of characters (== number of indices) */
icList /= sizeof(WCHAR);
for (Nix = 0; Nix < icList - 1; Nix++)
{ {
if (pszList[Nix] > cMax) if (pszList[Nix] > cMax)
cMax = pszList[Nix] ; cMax = pszList[Nix];
szIndex[0] = pszList[Nix] ; szIndex[0] = pszList[Nix];
if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, NULL, &icCmd)) lRet = RegQueryValueExW(hkey, szIndex, NULL, &dwType, NULL, &icCmd);
MessageBoxA (hCb, "Unable to grab size of index", "Nix", MB_OK) ; if (lRet != ERROR_SUCCESS || dwType != REG_SZ)
if( pszCmd ) {
pszCmd = (char *)HeapReAlloc(GetProcessHeap(), 0, pszCmd, icCmd) ; TRACE("Unable to grab size of index, error %d\n", GetLastError());
continue;
}
if (pszCmd)
{
pszTmp = (WCHAR*)HeapReAlloc(GetProcessHeap(), 0, pszCmd, icCmd);
if (!pszTmp)
{
TRACE("HeapReAlloc failed to reallocate %d bytes\n", icCmd);
continue;
}
pszCmd = pszTmp;
}
else else
pszCmd = (char *)HeapAlloc(GetProcessHeap(), 0, icCmd) ;
if (ERROR_SUCCESS != RegQueryValueExA (hkey, szIndex, NULL, NULL, (LPBYTE)pszCmd, &icCmd))
MessageBoxA (hCb, "Unable to grab index", "Nix", MB_OK) ;
if (NULL != pszLatest)
{ {
if (!lstrcmpiA(pszCmd, pszLatest)) pszCmd = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, icCmd);
if (!pszCmd)
{ {
/* TRACE("HeapAlloc failed to allocate %d bytes\n", icCmd);
sprintf (szDbgMsg, "Found existing (%d).\n", Nix) ; continue;
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ;
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd) ;
SetWindowTextA (hCb, pszCmd) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = pszList[Nix] ;
memmove (&pszList[1], pszList, Nix) ;
pszList[0] = cMatch ;
continue ;
} }
} }
if (26 != icList - 1 || icList - 2 != Nix || cMatch || NULL == pszLatest) lRet = RegQueryValueExW(hkey, szIndex, NULL, NULL, (LPBYTE)pszCmd, &icCmd);
if (lRet != ERROR_SUCCESS)
{ {
TRACE("Unable to grab index, error %d\n", GetLastError());
continue;
}
/* /*
sprintf (szDbgMsg, "Happily appending (%d).\n", Nix) ; * Generally the command string will end up with "\\1".
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; * Find the last backslash in the string and NULL-terminate.
* Windows does not seem to check for what comes next, so that
* a command of the form:
* c:\\my_dir\\myfile.exe
* will be cut just after "my_dir", whereas a command of the form:
* c:\\my_dir\\myfile.exe\\1
* will be cut just after "myfile.exe".
*/ */
SendMessageA (hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd) ; pszTmp = wcsrchr(pszCmd, L'\\');
if (pszTmp)
*pszTmp = L'\0';
/*
* In the following we try to add pszLatest to the MRU list.
* We suppose that our caller has already correctly allocated
* the string with enough space for us to append a "\\1".
*
* FIXME: TODO! (At the moment we don't append it!)
*/
if (pszLatest)
{
if (wcsicmp(pszCmd, pszLatest) == 0)
{
SendMessageW(hCb, CB_INSERTSTRING, 0, (LPARAM)pszCmd);
SetWindowTextW(hCb, pszCmd);
SendMessageW(hCb, CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
cMatch = pszList[Nix];
memmove(&pszList[1], pszList, Nix * sizeof(WCHAR));
pszList[0] = cMatch;
continue;
}
}
if (icList - 1 != 26 || icList - 2 != Nix || cMatch || pszLatest == NULL)
{
SendMessageW(hCb, CB_ADDSTRING, 0, (LPARAM)pszCmd);
if (!Nix && fShowDefault) if (!Nix && fShowDefault)
{ {
SetWindowTextA (hCb, pszCmd) ; SetWindowTextW(hCb, pszCmd);
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ; SendMessageW(hCb, CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
} }
} }
else else
{ {
/* SendMessageW(hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest);
sprintf (szDbgMsg, "Doing loop thing.\n") ; SetWindowTextW(hCb, pszLatest);
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; SendMessageW(hCb, CB_SETEDITSEL, 0, MAKELPARAM(0, -1));
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
SetWindowTextA (hCb, pszLatest) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = pszList[Nix] ; cMatch = pszList[Nix];
memmove (&pszList[1], pszList, Nix) ; memmove(&pszList[1], pszList, Nix * sizeof(WCHAR));
pszList[0] = cMatch ; pszList[0] = cMatch;
szIndex[0] = cMatch ; szIndex[0] = cMatch;
RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ; RegSetValueExW(hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, (wcslen(pszLatest) + 1) * sizeof(WCHAR));
} }
} }
if (!cMatch && NULL != pszLatest) if (!cMatch && pszLatest != NULL)
{ {
/* SendMessageW(hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest);
sprintf (szDbgMsg, "Simply inserting (increasing list).\n") ; SetWindowTextW(hCb, pszLatest);
MessageBoxA (hCb, szDbgMsg, "Nix", MB_OK) ; SendMessageW(hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1));
*/
SendMessageA (hCb, CB_INSERTSTRING, 0, (LPARAM)pszLatest) ;
SetWindowTextA (hCb, pszLatest) ;
SendMessageA (hCb, CB_SETEDITSEL, 0, MAKELPARAM (0, -1)) ;
cMatch = ++cMax ; cMatch = ++cMax;
if (pszList)
pszList = (char *)HeapReAlloc(GetProcessHeap(), 0, pszList, ++icList) ;
else
pszList = (char *)HeapAlloc(GetProcessHeap(), 0, ++icList) ;
if (pszList) if (pszList)
{ {
memmove (&pszList[1], pszList, icList - 1) ; pszTmp = (WCHAR*)HeapReAlloc(GetProcessHeap(), 0, pszList, (++icList) * sizeof(WCHAR));
pszList[0] = cMatch ; if (!pszTmp)
szIndex[0] = cMatch ; {
RegSetValueExA (hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, strlen (pszLatest) + 1) ; TRACE("HeapReAlloc failed to reallocate enough bytes\n");
goto Cleanup;
}
pszList = pszTmp;
} }
else else
{ {
TRACE("HeapAlloc or HeapReAlloc failed to allocate enough bytes\n"); pszList = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, (++icList) * sizeof(WCHAR));
if (!pszList)
{
TRACE("HeapAlloc failed to allocate enough bytes\n");
goto Cleanup;
} }
} }
RegSetValueExA (hkey, "MRUList", 0, REG_SZ, (LPBYTE)pszList, strlen (pszList) + 1) ; memmove(&pszList[1], pszList, (icList - 1) * sizeof(WCHAR));
pszList[0] = cMatch;
szIndex[0] = cMatch;
RegSetValueExW(hkey, szIndex, 0, REG_SZ, (LPBYTE)pszLatest, (wcslen(pszLatest) + 1) * sizeof(WCHAR));
}
HeapFree( GetProcessHeap(), 0, pszCmd) ; Cleanup:
HeapFree( GetProcessHeap(), 0, pszList) ; RegSetValueExW(hkey, L"MRUList", 0, REG_SZ, (LPBYTE)pszList, (wcslen(pszList) + 1) * sizeof(WCHAR));
HeapFree(GetProcessHeap(), 0, pszCmd);
HeapFree(GetProcessHeap(), 0, pszList);
RegCloseKey(hkey);
} }