*/
#include <assert.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
+#include "wine/winbase16.h"
+#include "wownt32.h"
#include "wine/debug.h"
#include "cpl.h"
+#include "wine/unicode.h"
+
+#define NO_SHLWAPI_REG
+#include "shlwapi.h"
+
+#include "cpanel.h"
WINE_DEFAULT_DEBUG_CHANNEL(shlctrl);
-typedef struct CPlApplet {
- struct CPlApplet* next; /* linked list */
- HWND hWnd;
- unsigned count; /* number of subprograms */
- HMODULE hModule; /* module of loaded applet */
- APPLET_PROC proc; /* entry point address */
- NEWCPLINFOA info[1]; /* array of count information.
- * dwSize field is 0 if entry is invalid */
-} CPlApplet;
-
-typedef struct CPanel {
- CPlApplet* first; /* linked list */
- HWND hWnd;
- unsigned status;
- CPlApplet* clkApplet;
- unsigned clkSP;
-} CPanel;
-
-static CPlApplet* Control_UnloadApplet(CPlApplet* applet)
+CPlApplet* Control_UnloadApplet(CPlApplet* applet)
{
unsigned i;
CPlApplet* next;
return next;
}
-static CPlApplet* Control_LoadApplet(HWND hWnd, LPCSTR cmd, CPanel* panel)
+CPlApplet* Control_LoadApplet(HWND hWnd, LPCWSTR cmd, CPanel* panel)
{
CPlApplet* applet;
unsigned i;
CPLINFO info;
+ NEWCPLINFOW newinfo;
if (!(applet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet))))
return applet;
applet->hWnd = hWnd;
- if (!(applet->hModule = LoadLibraryA(cmd))) {
- WARN("Cannot load control panel applet %s\n", cmd);
+ if (!(applet->hModule = LoadLibraryW(cmd))) {
+ WARN("Cannot load control panel applet %s\n", debugstr_w(cmd));
goto theError;
}
if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) {
- WARN("Not a valid control panel applet %s\n", cmd);
+ WARN("Not a valid control panel applet %s\n", debugstr_w(cmd));
goto theError;
}
if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) {
}
applet = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet,
- sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOA));
+ sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOW));
for (i = 0; i < applet->count; i++) {
- applet->info[i].dwSize = sizeof(NEWCPLINFOA);
+ ZeroMemory(&newinfo, sizeof(newinfo));
+ newinfo.dwSize = sizeof(NEWCPLINFOA);
+ applet->info[i].dwSize = sizeof(NEWCPLINFOW);
/* proc is supposed to return a null value upon success for
* CPL_INQUIRE and CPL_NEWINQUIRE
* However, real drivers don't seem to behave like this
* So, use introspection rather than return value
*/
- applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&applet->info[i]);
- if (applet->info[i].hIcon == 0) {
+ applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&newinfo);
+ if (newinfo.hIcon == 0) {
applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info);
if (info.idIcon == 0 || info.idName == 0) {
WARN("Couldn't get info from sp %u\n", i);
applet->info[i].dwFlags = 0;
applet->info[i].dwHelpContext = 0;
applet->info[i].lData = info.lData;
- applet->info[i].hIcon = LoadIconA(applet->hModule,
- MAKEINTRESOURCEA(info.idIcon));
- LoadStringA(applet->hModule, info.idName,
- applet->info[i].szName, sizeof(applet->info[i].szName));
- LoadStringA(applet->hModule, info.idInfo,
- applet->info[i].szInfo, sizeof(applet->info[i].szInfo));
+ applet->info[i].hIcon = LoadIconW(applet->hModule,
+ MAKEINTRESOURCEW(info.idIcon));
+ LoadStringW(applet->hModule, info.idName,
+ applet->info[i].szName, sizeof(applet->info[i].szName) / sizeof(WCHAR));
+ LoadStringW(applet->hModule, info.idInfo,
+ applet->info[i].szInfo, sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
applet->info[i].szHelpFile[0] = '\0';
}
}
+ else
+ {
+ CopyMemory(&applet->info[i], &newinfo, newinfo.dwSize);
+ if (newinfo.dwSize != sizeof(NEWCPLINFOW))
+ {
+ applet->info[i].dwSize = sizeof(NEWCPLINFOW);
+ MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szName,
+ sizeof(((LPNEWCPLINFOA)&newinfo)->szName) / sizeof(CHAR),
+ applet->info[i].szName,
+ sizeof(applet->info[i].szName) / sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szInfo,
+ sizeof(((LPNEWCPLINFOA)&newinfo)->szInfo) / sizeof(CHAR),
+ applet->info[i].szInfo,
+ sizeof(applet->info[i].szInfo) / sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, ((LPNEWCPLINFOA)&newinfo)->szHelpFile,
+ sizeof(((LPNEWCPLINFOA)&newinfo)->szHelpFile) / sizeof(CHAR),
+ applet->info[i].szHelpFile,
+ sizeof(applet->info[i].szHelpFile) / sizeof(WCHAR));
+ }
+ }
}
applet->next = panel->first;
{
CPanel* panel = (CPanel*)cs->lpCreateParams;
- SetWindowLongA(hWnd, 0, (LPARAM)panel);
+ SetWindowLongPtrA(hWnd, 0, (LONG_PTR)panel);
panel->status = 0;
panel->hWnd = hWnd;
}
RECT rc;
GetClientRect(panel->hWnd, &rc);
- for (applet = panel->first; applet; 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;
if (x + XSTEP >= rc.right - rc.left) {
hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps);
hOldFont = SelectObject(hdc, GetStockObject(ANSI_VAR_FONT));
GetClientRect(panel->hWnd, &rc);
- for (applet = panel->first; applet; applet = applet = applet->next) {
+ for (applet = panel->first; applet; applet = applet->next) {
for (i = 0; i < applet->count; i++) {
if (x + XSTEP >= rc.right - rc.left) {
x = 0;
txtRect.right = x + XSTEP;
txtRect.top = y + YICON;
txtRect.bottom = y + YSTEP;
- DrawTextA(hdc, applet->info[i].szName, -1, &txtRect,
+ DrawTextW(hdc, applet->info[i].szName, -1, &txtRect,
DT_CENTER | DT_VCENTER);
x += XSTEP;
}
static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg,
WPARAM lParam1, LPARAM lParam2)
{
- CPanel* panel = (CPanel*)GetWindowLongA(hWnd, 0);
+ CPanel* panel = (CPanel*)GetWindowLongPtrA(hWnd, 0);
if (panel || wMsg == WM_CREATE) {
switch (wMsg) {
Control_WndProc_Create(hWnd, (CREATESTRUCTA*)lParam2);
return 0;
case WM_DESTROY:
- while ((panel->first = Control_UnloadApplet(panel->first)));
+ {
+ CPlApplet* applet = panel->first;
+ while (applet)
+ applet = Control_UnloadApplet(applet);
+ }
+ PostQuitMessage(0);
break;
case WM_PAINT:
return Control_WndProc_Paint(panel, lParam1);
{
WNDCLASSA wc;
MSG msg;
-
+ const CHAR* appName = "Wine Control Panel";
wc.style = CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc = Control_WndProc;
wc.cbClsExtra = 0;
if (!RegisterClassA(&wc)) return;
- CreateWindowExA(0, wc.lpszClassName, "Wine Control Panel",
+ CreateWindowExA(0, wc.lpszClassName, appName,
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
hWnd, NULL, hInst, panel);
if (!panel->hWnd) return;
+
+ if (!panel->first) {
+ /* FIXME appName & message should be localized */
+ MessageBoxA(panel->hWnd, "Cannot load any applets", appName, MB_OK);
+ return;
+ }
+
while (GetMessageA(&msg, panel->hWnd, 0, 0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
- if (!panel->first) break;
}
}
static void Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)
{
HANDLE h;
- WIN32_FIND_DATAA fd;
- char buffer[MAX_PATH];
+ WIN32_FIND_DATAW fd;
+ WCHAR buffer[MAX_PATH];
+ static const WCHAR wszAllCpl[] = {'*','.','c','p','l',0};
+ WCHAR *p;
+
+ GetSystemDirectoryW( buffer, MAX_PATH );
+ p = buffer + strlenW(buffer);
+ *p++ = '\\';
+ lstrcpyW(p, wszAllCpl);
- /* FIXME: should grab path somewhere from configuration */
- if ((h = FindFirstFileA("c:\\windows\\system\\*.cpl", &fd)) != 0) {
+ if ((h = FindFirstFileW(buffer, &fd)) != INVALID_HANDLE_VALUE) {
do {
- sprintf(buffer, "c:\\windows\\system\\%s", fd.cFileName);
+ lstrcpyW(p, fd.cFileName);
Control_LoadApplet(hWnd, buffer, panel);
- } while (FindNextFileA(h, &fd));
+ } while (FindNextFileW(h, &fd));
FindClose(h);
}
- if (panel->first) Control_DoInterface(panel, hWnd, hInst);
+ Control_DoInterface(panel, hWnd, hInst);
}
-static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCSTR cmd)
+static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCWSTR wszCmd)
/* forms to parse:
* foo.cpl,@sp,str
* foo.cpl,@sp
* "a path\foo.cpl"
*/
{
- char* buffer;
- char* beg = NULL;
- char* end;
- char ch;
- char* ptr;
+ LPWSTR buffer;
+ LPWSTR beg = NULL;
+ LPWSTR end;
+ WCHAR ch;
+ LPWSTR ptr;
unsigned sp = 0;
- char* extraPmts = NULL;
+ LPWSTR extraPmts = NULL;
int quoted = 0;
- buffer = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1);
+ buffer = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(wszCmd) + 1) * sizeof(*wszCmd));
if (!buffer) return;
- end = strcpy(buffer, cmd);
+ end = lstrcpyW(buffer, wszCmd);
for (;;) {
ch = *end;
*end = '\0';
if (beg) {
if (*beg == '@') {
- sp = atoi(beg + 1);
+ sp = atoiW(beg + 1);
} else if (*beg == '\0') {
sp = 0;
} else {
}
end++;
}
- while ((ptr = strchr(buffer, (int) '"')))
- memmove(ptr, ptr+1, strlen(ptr));
+ while ((ptr = StrChrW(buffer, '"')))
+ memmove(ptr, ptr+1, lstrlenW(ptr)*sizeof(WCHAR));
- TRACE("cmd %s, extra %s, sp %d\n", buffer, debugstr_a(extraPmts), sp);
+ TRACE("cmd %s, extra %s, sp %d\n", debugstr_w(buffer), debugstr_w(extraPmts), sp);
Control_LoadApplet(hWnd, buffer, panel);
}
/*************************************************************************
- * Control_RunDLL [SHELL32.@]
+ * Control_RunDLLW [SHELL32.@]
*
*/
-void WINAPI Control_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
+void WINAPI Control_RunDLLW(HWND hWnd, HINSTANCE hInst, LPCWSTR cmd, DWORD nCmdShow)
{
CPanel panel;
- TRACE("(%p, 0x%08lx, %s, 0x%08lx)\n",
- hWnd, (DWORD)hInst, debugstr_a(cmd), nCmdShow);
+ TRACE("(%p, %p, %s, 0x%08lx)\n",
+ hWnd, hInst, debugstr_w(cmd), nCmdShow);
memset(&panel, 0, sizeof(panel));
}
/*************************************************************************
- * Control_FillCache_RunDLL [SHELL32.@]
+ * Control_RunDLLA [SHELL32.@]
*
*/
-HRESULT WINAPI Control_FillCache_RunDLL(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
+void WINAPI Control_RunDLLA(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow)
{
- FIXME("%p %p 0x%04lx 0x%04lx stub\n", hWnd, hModule, w, x);
+ DWORD len = MultiByteToWideChar(CP_ACP, 0, cmd, -1, NULL, 0 );
+ LPWSTR wszCmd = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (wszCmd && MultiByteToWideChar(CP_ACP, 0, cmd, -1, wszCmd, len ))
+ {
+ Control_RunDLLW(hWnd, hInst, wszCmd, nCmdShow);
+ }
+ HeapFree(GetProcessHeap(), 0, wszCmd);
+}
+
+/*************************************************************************
+ * Control_FillCache_RunDLLW [SHELL32.@]
+ *
+ */
+HRESULT WINAPI Control_FillCache_RunDLLW(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
+{
+ FIXME("%p %p 0x%08lx 0x%08lx stub\n", hWnd, hModule, w, x);
return 0;
}
+/*************************************************************************
+ * Control_FillCache_RunDLLA [SHELL32.@]
+ *
+ */
+HRESULT WINAPI Control_FillCache_RunDLLA(HWND hWnd, HANDLE hModule, DWORD w, DWORD x)
+{
+ return Control_FillCache_RunDLLW(hWnd, hModule, w, x);
+}
+
+
/*************************************************************************
* RunDLL_CallEntry16 [SHELL32.122]
* the name is probably wrong
*/
-HRESULT WINAPI RunDLL_CallEntry16(DWORD v, DWORD w, DWORD x, DWORD y, DWORD z)
+void WINAPI RunDLL_CallEntry16( DWORD proc, HWND hwnd, HINSTANCE inst,
+ LPCSTR cmdline, INT cmdshow )
{
- FIXME("0x%04lx 0x%04lx 0x%04lx 0x%04lx 0x%04lx stub\n",v,w,x,y,z);
- return 0;
+ WORD args[5];
+ SEGPTR cmdline_seg;
+
+ TRACE( "proc %lx hwnd %p inst %p cmdline %s cmdshow %d\n",
+ proc, hwnd, inst, debugstr_a(cmdline), cmdshow );
+
+ cmdline_seg = MapLS( cmdline );
+ args[4] = HWND_16(hwnd);
+ args[3] = MapHModuleLS(inst);
+ args[2] = SELECTOROF(cmdline_seg);
+ args[1] = OFFSETOF(cmdline_seg);
+ args[0] = cmdshow;
+ WOWCallback16Ex( proc, WCB16_PASCAL, sizeof(args), args, NULL );
+ UnMapLS( cmdline_seg );
}
/*************************************************************************