[SHELL32]

* Merge r53700. Point 3 in bug 6481 was fixed by fixing the parser (at line 414) to use only ',' as the delimiter, to match Windows behavior.

svn path=/trunk/; revision=53702
This commit is contained in:
Amine Khaldi 2011-09-13 13:13:35 +00:00
parent 744be47dde
commit 3a93089ba7

View file

@ -27,11 +27,15 @@ CPlApplet* Control_UnloadApplet(CPlApplet* applet)
unsigned i; unsigned i;
CPlApplet* next; CPlApplet* next;
for (i = 0; i < applet->count; i++) { for (i = 0; i < applet->count; i++)
if (!applet->info[i].dwSize) continue; {
if (!applet->info[i].dwSize)
continue;
applet->proc(applet->hWnd, CPL_STOP, i, applet->info[i].lData); applet->proc(applet->hWnd, CPL_STOP, i, applet->info[i].lData);
} }
if (applet->proc) applet->proc(applet->hWnd, CPL_EXIT, 0L, 0L); if (applet->proc)
applet->proc(applet->hWnd, CPL_EXIT, 0L, 0L);
FreeLibrary(applet->hModule); FreeLibrary(applet->hModule);
next = applet->next; next = applet->next;
HeapFree(GetProcessHeap(), 0, applet); HeapFree(GetProcessHeap(), 0, applet);
@ -50,19 +54,23 @@ CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
applet->hWnd = hWnd; applet->hWnd = hWnd;
if (!(applet->hModule = LoadLibraryW(cmd))) { if (!(applet->hModule = LoadLibraryW(cmd)))
{
WARN("Cannot load control panel applet %s\n", debugstr_w(cmd)); WARN("Cannot load control panel applet %s\n", debugstr_w(cmd));
goto theError; goto theError;
} }
if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) { if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet")))
{
WARN("Not a valid control panel applet %s\n", debugstr_w(cmd)); WARN("Not a valid control panel applet %s\n", debugstr_w(cmd));
goto theError; goto theError;
} }
if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) { if (!applet->proc(hWnd, CPL_INIT, 0L, 0L))
{
WARN("Init of applet has failed\n"); WARN("Init of applet has failed\n");
goto theError; goto theError;
} }
if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0) { if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0)
{
WARN("No subprogram in applet\n"); WARN("No subprogram in applet\n");
goto theError; goto theError;
} }
@ -70,7 +78,8 @@ CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
applet = (CPlApplet *)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet, applet = (CPlApplet *)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet,
sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOW)); sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOW));
for (i = 0; i < applet->count; i++) { for (i = 0; i < applet->count; i++)
{
ZeroMemory(&newinfo, sizeof(newinfo)); ZeroMemory(&newinfo, sizeof(newinfo));
newinfo.dwSize = sizeof(NEWCPLINFOW); newinfo.dwSize = sizeof(NEWCPLINFOW);
applet->info[i].dwSize = sizeof(NEWCPLINFOW); applet->info[i].dwSize = sizeof(NEWCPLINFOW);
@ -80,12 +89,16 @@ CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
* So, use introspection rather than return value * So, use introspection rather than return value
*/ */
applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo); applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo);
if (newinfo.hIcon == 0) { if (newinfo.hIcon == 0)
{
applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info); applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info);
if (info.idIcon == 0 || info.idName == 0) { if (info.idIcon == 0 || info.idName == 0)
{
WARN("Couldn't get info from sp %u\n", i); WARN("Couldn't get info from sp %u\n", i);
applet->info[i].dwSize = 0; applet->info[i].dwSize = 0;
} else { }
else
{
/* convert the old data into the new structure */ /* convert the old data into the new structure */
applet->info[i].dwFlags = 0; applet->info[i].dwFlags = 0;
applet->info[i].dwHelpContext = 0; applet->info[i].dwHelpContext = 0;
@ -145,14 +158,19 @@ static BOOL Control_Localize(const CPanel* panel, int cx, int cy,
RECT rc; RECT rc;
GetClientRect(panel->hWnd, &rc); GetClientRect(panel->hWnd, &rc);
for (applet = panel->first; applet; applet = applet->next) { for (applet = panel->first; applet; applet = applet->next)
for (i = 0; i < applet->count; i++) { {
if (!applet->info[i].dwSize) continue; for (i = 0; i < applet->count; i++)
if (x + XSTEP >= rc.right - rc.left) { {
if (!applet->info[i].dwSize)
continue;
if (x + XSTEP >= rc.right - rc.left)
{
x = (XSTEP-XICON)/2; x = (XSTEP-XICON)/2;
y += YSTEP; y += YSTEP;
} }
if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) { if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP)
{
*papplet = applet; *papplet = applet;
*psp = i; *psp = i;
return TRUE; return TRUE;
@ -176,13 +194,18 @@ static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam)
hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps); hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps);
hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT)); hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
GetClientRect(panel->hWnd, &rc); GetClientRect(panel->hWnd, &rc);
for (applet = panel->first; applet; applet = applet->next) {
for (i = 0; i < applet->count; i++) { for (applet = panel->first; applet; applet = applet->next)
if (x + XSTEP >= rc.right - rc.left) { {
for (i = 0; i < applet->count; i++)
{
if (x + XSTEP >= rc.right - rc.left)
{
x = 0; x = 0;
y += YSTEP; y += YSTEP;
} }
if (!applet->info[i].dwSize) continue; if (!applet->info[i].dwSize)
continue;
DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon); DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon);
txtRect.left = x; txtRect.left = x;
txtRect.right = x + XSTEP; txtRect.right = x + XSTEP;
@ -193,8 +216,11 @@ static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam)
x += XSTEP; x += XSTEP;
} }
} }
SelectObject(hdc, hOldFont); SelectObject(hdc, hOldFont);
if (!wParam) EndPaint(panel->hWnd, &ps); if (!wParam)
EndPaint(panel->hWnd, &ps);
return 0; return 0;
} }
@ -203,12 +229,17 @@ static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up)
unsigned i; unsigned i;
CPlApplet* applet; CPlApplet* applet;
if (Control_Localize(panel, (short)LOWORD(lParam), (short)HIWORD(lParam), &applet, &i)) { if (Control_Localize(panel, (short)LOWORD(lParam), (short)HIWORD(lParam), &applet, &i))
if (up) { {
if (panel->clkApplet == applet && panel->clkSP == i) { if (up)
{
if (panel->clkApplet == applet && panel->clkSP == i)
{
applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData); applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData);
} }
} else { }
else
{
panel->clkApplet = applet; panel->clkApplet = applet;
panel->clkSP = i; panel->clkSP = i;
} }
@ -221,19 +252,23 @@ static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg,
{ {
CPanel* panel = (CPanel*)GetWindowLongPtrW(hWnd, 0); CPanel* panel = (CPanel*)GetWindowLongPtrW(hWnd, 0);
if (panel || wMsg == WM_CREATE) { if (panel || wMsg == WM_CREATE)
switch (wMsg) { {
switch (wMsg)
{
case WM_CREATE: case WM_CREATE:
Control_WndProc_Create(hWnd, (CREATESTRUCTW*)lParam2); Control_WndProc_Create(hWnd, (CREATESTRUCTW*)lParam2);
return 0; return 0;
case WM_DESTROY: case WM_DESTROY:
{ {
CPlApplet* applet = panel->first; CPlApplet* applet = panel->first;
while (applet) while (applet)
applet = Control_UnloadApplet(applet); applet = Control_UnloadApplet(applet);
}
PostQuitMessage(0); PostQuitMessage(0);
break; }; break;
case WM_PAINT: case WM_PAINT:
return Control_WndProc_Paint(panel, lParam1); return Control_WndProc_Paint(panel, lParam1);
case WM_LBUTTONUP: case WM_LBUTTONUP:
@ -271,15 +306,19 @@ static void Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst)
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, NULL, hInst, panel); hWnd, NULL, hInst, panel);
if (!panel->hWnd) return;
if (!panel->first) { if (!panel->hWnd)
return;
if (!panel->first)
{
/* FIXME appName & message should be localized */ /* FIXME appName & message should be localized */
MessageBoxW(panel->hWnd, L"Cannot load any applets", appName, MB_OK); MessageBoxW(panel->hWnd, L"Cannot load any applets", appName, MB_OK);
return; return;
} }
while (GetMessageW(&msg, panel->hWnd, 0, 0)) { while (GetMessageW(&msg, panel->hWnd, 0, 0))
{
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessageW(&msg); DispatchMessageW(&msg);
} }
@ -298,8 +337,10 @@ static void Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)
*p++ = '\\'; *p++ = '\\';
wcscpy(p, wszAllCpl); wcscpy(p, wszAllCpl);
if ((h = FindFirstFileW(buffer, &fd)) != INVALID_HANDLE_VALUE) { if ((h = FindFirstFileW(buffer, &fd)) != INVALID_HANDLE_VALUE)
do { {
do
{
wcscpy(p, fd.cFileName); wcscpy(p, fd.cFileName);
Control_LoadApplet(hWnd, buffer, panel); Control_LoadApplet(hWnd, buffer, panel);
} while (FindNextFileW(h, &fd)); } while (FindNextFileW(h, &fd));
@ -360,26 +401,42 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
CloseHandle(hMutex); CloseHandle(hMutex);
return; return;
} }
TRACE("[shell32, Control_DoLaunch] wszCmd = %ws\n", wszCmd);
end = wcscpy(buffer, wszCmd); end = wcscpy(buffer, wszCmd);
for (;;) { for (;;)
{
ch = *end; ch = *end;
if (ch == '"') quoted = !quoted; if (ch == '"')
if (!quoted && (ch == ' ' || ch == ',' || ch == '\0')) { quoted = !quoted;
if (!quoted && (ch == ',' || ch == '\0'))
{
*end = '\0'; *end = '\0';
if (beg) { if (beg)
if (*beg == '@') { {
if (*beg == '@')
{
sp = atoiW(beg + 1); sp = atoiW(beg + 1);
spSet = TRUE; spSet = TRUE;
} else if (*beg == '\0') { }
else if (*beg == '\0')
{
sp = 0; sp = 0;
spSet = TRUE; spSet = TRUE;
} else { }
else
{
extraPmts = beg; extraPmts = beg;
} }
} }
if (ch == '\0') break; if (ch == '\0') break;
beg = end + 1; beg = end + 1;
if (ch == ' ') while (end[1] == ' ') end++; if (ch == ' ')
while (end[1] == ' ')
end++;
} }
end++; end++;
} }
@ -389,15 +446,19 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
while ((ptr = StrChrW(extraPmts, '"'))) while ((ptr = StrChrW(extraPmts, '"')))
memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR)); memmove((LPVOID)ptr, ptr+1, wcslen(ptr)*sizeof(WCHAR));
TRACE("cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp); TRACE("[shell32, Control_DoLaunch] cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp);
Control_LoadApplet(hWnd, buffer, panel); Control_LoadApplet(hWnd, buffer, panel);
if (panel->first) { if (panel->first)
{
CPlApplet* applet = panel->first; CPlApplet* applet = panel->first;
TRACE("[shell32, Control_DoLaunch] applet->count %d, applet->info[sp].szName %ws\n", applet->count, applet->info[sp].szName);
assert(applet && applet->next == NULL); assert(applet && applet->next == NULL);
if (sp >= applet->count) { if (sp >= applet->count)
{
WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count); WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count);
sp = 0; sp = 0;
} }
@ -416,12 +477,16 @@ static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
return; return;
} }
} }
if (applet->info[sp].dwSize) {
if (applet->info[sp].dwSize)
{
if (!applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData)) if (!applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData))
applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts); applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts);
} }
Control_UnloadApplet(applet); Control_UnloadApplet(applet);
} }
ReleaseMutex(hMutex); ReleaseMutex(hMutex);
CloseHandle(hMutex); CloseHandle(hMutex);
HeapFree(GetProcessHeap(), 0, buffer); HeapFree(GetProcessHeap(), 0, buffer);
@ -440,9 +505,14 @@ EXTERN_C void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DW
memset(&panel, 0, sizeof(panel)); memset(&panel, 0, sizeof(panel));
if (!cmd || !*cmd) { if (!cmd || !*cmd)
{
TRACE("[shell32, Control_RunDLLW] Calling Control_DoWindow\n");
Control_DoWindow(&panel, hWnd, hInst); Control_DoWindow(&panel, hWnd, hInst);
} else { }
else
{
TRACE("[shell32, Control_RunDLLW] Calling Control_DoLaunch\n");
Control_DoLaunch(&panel, hWnd, cmd); Control_DoLaunch(&panel, hWnd, cmd);
} }
} }
@ -455,10 +525,12 @@ EXTERN_C void WINAPI Control_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWO
{ {
DWORD len = MultiByteToWideChar(CP_ACP, 0, cmd, -1, NULL, 0 ); DWORD len = MultiByteToWideChar(CP_ACP, 0, cmd, -1, NULL, 0 );
LPWSTR wszCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); LPWSTR wszCmd = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
if (wszCmd && MultiByteToWideChar(CP_ACP, 0, cmd, -1, wszCmd, len )) if (wszCmd && MultiByteToWideChar(CP_ACP, 0, cmd, -1, wszCmd, len ))
{ {
Control_RunDLLW(hWnd, hInst, wszCmd, nCmdShow); Control_RunDLLW(hWnd, hInst, wszCmd, nCmdShow);
} }
HeapFree(GetProcessHeap(), 0, wszCmd); HeapFree(GetProcessHeap(), 0, wszCmd);
} }