Changeset 6709 for trunk/src/shell32/control.c
- Timestamp:
- Sep 15, 2001, 11:26:26 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/shell32/control.c
r6650 r6709 1 /* $Id: control.c,v 1.2 2001-09-05 13:46:56 bird Exp $ */2 1 /* Control Panel management */ 3 2 /* Eric Pouech 2001 */ … … 17 16 18 17 typedef struct CPlApplet { 19 struct CPlApplet* next; 20 HWND 21 unsigned count;/* number of subprograms */22 HMODULE hModule;/* module of loaded applet */23 APPLET_PROC proc;/* entry point address */24 NEWCPLINFOA info[1]; /* array of count information.25 18 struct CPlApplet* next; /* linked list */ 19 HWND hWnd; 20 unsigned count; /* number of subprograms */ 21 HMODULE hModule; /* module of loaded applet */ 22 APPLET_PROC proc; /* entry point address */ 23 NEWCPLINFOA info[1]; /* array of count information. 24 * dwSize field is 0 if entry is invalid */ 26 25 } CPlApplet; 27 26 28 27 typedef struct CPanel { 29 CPlApplet* first;/* linked list */30 HWND 28 CPlApplet* first; /* linked list */ 29 HWND hWnd; 31 30 unsigned status; 32 CPlApplet* 31 CPlApplet* clkApplet; 33 32 unsigned clkSP; 34 33 } CPanel; 35 34 36 static CPlApplet*Control_UnloadApplet(CPlApplet* applet)37 { 38 unsigned 39 CPlApplet* 35 static CPlApplet* Control_UnloadApplet(CPlApplet* applet) 36 { 37 unsigned i; 38 CPlApplet* next; 40 39 41 40 for (i = 0; i < applet->count; i++) { … … 50 49 } 51 50 52 static CPlApplet* 53 { 54 CPlApplet* 55 unsigned 56 CPLINFO 51 static CPlApplet* Control_LoadApplet(HWND hWnd, LPCSTR cmd, CPanel* panel) 52 { 53 CPlApplet* applet; 54 unsigned i; 55 CPLINFO info; 57 56 58 57 if (!(applet = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*applet)))) … … 63 62 if (!(applet->hModule = LoadLibraryA(cmd))) { 64 63 WARN("Cannot load control panel applet %s\n", cmd); 65 64 goto theError; 66 65 } 67 66 if (!(applet->proc = (APPLET_PROC)GetProcAddress(applet->hModule, "CPlApplet"))) { 68 67 WARN("Not a valid control panel applet %s\n", cmd); 69 68 goto theError; 70 69 } 71 70 if (!applet->proc(hWnd, CPL_INIT, 0L, 0L)) { 72 71 WARN("Init of applet has failed\n"); 73 72 goto theError; 74 73 } 75 74 if ((applet->count = applet->proc(hWnd, CPL_GETCOUNT, 0L, 0L)) == 0) { 76 75 WARN("No subprogram in applet\n"); 77 78 } 79 80 applet = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet, 81 82 76 goto theError; 77 } 78 79 applet = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, applet, 80 sizeof(*applet) + (applet->count - 1) * sizeof(NEWCPLINFOA)); 81 83 82 for (i = 0; i < applet->count; i++) { 84 83 applet->info[i].dwSize = sizeof(NEWCPLINFOA); 85 84 /* proc is supposed to return a null value upon success for 86 87 88 89 85 * CPL_INQUIRE and CPL_NEWINQUIRE 86 * However, real drivers don't seem to behave like this 87 * So, use introspection rather than return value 88 */ 90 89 applet->proc(hWnd, CPL_NEWINQUIRE, i, (LPARAM)&applet->info[i]); 91 90 if (applet->info[i].hIcon == 0) { 92 93 94 95 96 97 98 99 100 101 applet->info[i].hIcon = LoadIconA(applet->hModule, 102 103 LoadStringA(applet->hModule, info.idName, 104 105 LoadStringA(applet->hModule, info.idInfo, 106 107 108 91 applet->proc(hWnd, CPL_INQUIRE, i, (LPARAM)&info); 92 if (info.idIcon == 0 || info.idName == 0) { 93 WARN("Couldn't get info from sp %u\n", i); 94 applet->info[i].dwSize = 0; 95 } else { 96 /* convert the old data into the new structure */ 97 applet->info[i].dwFlags = 0; 98 applet->info[i].dwHelpContext = 0; 99 applet->info[i].lData = info.lData; 100 applet->info[i].hIcon = LoadIconA(applet->hModule, 101 MAKEINTRESOURCEA(info.idIcon)); 102 LoadStringA(applet->hModule, info.idName, 103 applet->info[i].szName, sizeof(applet->info[i].szName)); 104 LoadStringA(applet->hModule, info.idInfo, 105 applet->info[i].szInfo, sizeof(applet->info[i].szInfo)); 106 applet->info[i].szHelpFile[0] = '\0'; 107 } 109 108 } 110 109 } … … 120 119 } 121 120 122 static void 123 { 124 CPanel* 121 static void Control_WndProc_Create(HWND hWnd, const CREATESTRUCTA* cs) 122 { 123 CPanel* panel = (CPanel*)cs->lpCreateParams; 125 124 126 125 SetWindowLongA(hWnd, 0, (LPARAM)panel); … … 129 128 } 130 129 131 #define XICON32132 #define XSTEP 133 #define YICON32134 #define YSTEP 135 136 static BOOL 137 138 { 139 unsigned 140 CPlApplet* 141 RECT 142 130 #define XICON 32 131 #define XSTEP 128 132 #define YICON 32 133 #define YSTEP 64 134 135 static BOOL Control_Localize(const CPanel* panel, unsigned cx, unsigned cy, 136 CPlApplet** papplet, unsigned* psp) 137 { 138 unsigned i, x = (XSTEP-XICON)/2, y = 0; 139 CPlApplet* applet; 140 RECT rc; 141 143 142 GetClientRect(panel->hWnd, &rc); 144 143 for (applet = panel->first; applet; applet = applet = applet->next) { 145 144 for (i = 0; i < applet->count; i++) { 146 147 148 149 150 151 152 153 154 155 156 157 145 if (!applet->info[i].dwSize) continue; 146 if (x + XSTEP >= rc.right - rc.left) { 147 x = (XSTEP-XICON)/2; 148 y += YSTEP; 149 } 150 if (cx >= x && cx < x + XICON && cy >= y && cy < y + YSTEP) { 151 *papplet = applet; 152 *psp = i; 153 return TRUE; 154 } 155 x += XSTEP; 156 } 158 157 } 159 158 return FALSE; … … 162 161 static LRESULT Control_WndProc_Paint(const CPanel* panel, WPARAM wParam) 163 162 { 164 HDC 165 PAINTSTRUCT 166 RECT 167 unsigned 168 CPlApplet* 169 HGDIOBJ 163 HDC hdc; 164 PAINTSTRUCT ps; 165 RECT rc, txtRect; 166 unsigned i, x = 0, y = 0; 167 CPlApplet* applet; 168 HGDIOBJ hOldFont; 170 169 171 170 hdc = (wParam) ? (HDC)wParam : BeginPaint(panel->hWnd, &ps); … … 174 173 for (applet = panel->first; applet; applet = applet = applet->next) { 175 174 for (i = 0; i < applet->count; i++) { 176 177 178 179 180 181 182 183 184 185 186 DrawTextA(hdc, applet->info[i].szName, -1, &txtRect, 187 188 189 175 if (x + XSTEP >= rc.right - rc.left) { 176 x = 0; 177 y += YSTEP; 178 } 179 if (!applet->info[i].dwSize) continue; 180 DrawIcon(hdc, x + (XSTEP-XICON)/2, y, applet->info[i].hIcon); 181 txtRect.left = x; 182 txtRect.right = x + XSTEP; 183 txtRect.top = y + YICON; 184 txtRect.bottom = y + YSTEP; 185 DrawTextA(hdc, applet->info[i].szName, -1, &txtRect, 186 DT_CENTER | DT_VCENTER); 187 x += XSTEP; 188 } 190 189 } 191 190 SelectObject(hdc, hOldFont); … … 196 195 static LRESULT Control_WndProc_LButton(CPanel* panel, LPARAM lParam, BOOL up) 197 196 { 198 unsigned 199 CPlApplet* 200 197 unsigned i; 198 CPlApplet* applet; 199 201 200 if (Control_Localize(panel, LOWORD(lParam), HIWORD(lParam), &applet, &i)) { 202 201 if (up) { 203 if (panel->clkApplet == applet && panel->clkSP == i) { 204 applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData); 202 if (panel->clkApplet == applet && panel->clkSP == i) { 203 applet->proc(applet->hWnd, CPL_DBLCLK, i, applet->info[i].lData); 204 } 205 } else { 206 panel->clkApplet = applet; 207 panel->clkSP = i; 205 208 } 206 } else {207 panel->clkApplet = applet;208 panel->clkSP = i;209 }210 209 } 211 210 return 0; 212 211 } 213 212 214 static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg,215 216 { 217 CPanel* 213 static LRESULT WINAPI Control_WndProc(HWND hWnd, UINT wMsg, 214 WPARAM lParam1, LPARAM lParam2) 215 { 216 CPanel* panel = (CPanel*)GetWindowLongA(hWnd, 0); 218 217 219 218 if (panel || wMsg == WM_CREATE) { 220 219 switch (wMsg) { 221 220 case WM_CREATE: 222 223 221 Control_WndProc_Create(hWnd, (CREATESTRUCTA*)lParam2); 222 return 0; 224 223 case WM_DESTROY: 225 226 224 while ((panel->first = Control_UnloadApplet(panel->first))); 225 break; 227 226 case WM_PAINT: 228 227 return Control_WndProc_Paint(panel, lParam1); 229 228 case WM_LBUTTONUP: 230 229 return Control_WndProc_LButton(panel, lParam2, TRUE); 231 230 case WM_LBUTTONDOWN: 232 231 return Control_WndProc_LButton(panel, lParam2, FALSE); 233 232 /* EPP case WM_COMMAND: */ 234 /* EPP 233 /* EPP return Control_WndProc_Command(mwi, lParam1, lParam2); */ 235 234 } 236 235 } … … 241 240 static void Control_DoInterface(CPanel* panel, HWND hWnd, HINSTANCE hInst) 242 241 { 243 WNDCLASSA 244 MSG 242 WNDCLASSA wc; 243 MSG msg; 245 244 246 245 wc.style = CS_HREDRAW|CS_VREDRAW; … … 257 256 if (!RegisterClassA(&wc)) return; 258 257 259 CreateWindowExA(0, wc.lpszClassName, "Wine Control Panel", 260 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 261 CW_USEDEFAULT, CW_USEDEFAULT, 262 CW_USEDEFAULT, CW_USEDEFAULT, 263 258 CreateWindowExA(0, wc.lpszClassName, "Wine Control Panel", 259 WS_OVERLAPPEDWINDOW | WS_VISIBLE, 260 CW_USEDEFAULT, CW_USEDEFAULT, 261 CW_USEDEFAULT, CW_USEDEFAULT, 262 hWnd, (HMENU)0, hInst, panel); 264 263 if (!panel->hWnd) return; 265 264 while (GetMessageA(&msg, panel->hWnd, 0, 0)) { 266 265 TranslateMessage(&msg); 267 266 DispatchMessageA(&msg); 268 269 } 270 } 271 272 static voidControl_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst)273 { 274 HANDLE 275 WIN32_FIND_DATAA 276 char 267 if (!panel->first) break; 268 } 269 } 270 271 static void Control_DoWindow(CPanel* panel, HWND hWnd, HINSTANCE hInst) 272 { 273 HANDLE h; 274 WIN32_FIND_DATAA fd; 275 char buffer[MAX_PATH]; 277 276 278 277 /* FIXME: should grab path somewhere from configuration */ 279 278 if ((h = FindFirstFileA("c:\\windows\\system\\*.cpl", &fd)) != 0) { 280 279 do { 281 282 283 284 280 sprintf(buffer, "c:\\windows\\system\\%s", fd.cFileName); 281 Control_LoadApplet(hWnd, buffer, panel); 282 } while (FindNextFileA(h, &fd)); 283 FindClose(h); 285 284 } 286 285 … … 288 287 } 289 288 290 static voidControl_DoLaunch(CPanel* panel, HWND hWnd, LPCSTR cmd)289 static void Control_DoLaunch(CPanel* panel, HWND hWnd, LPCSTR cmd) 291 290 /* forms to parse: 292 * 293 * 294 * 295 * 296 * 291 * foo.cpl,@sp,str 292 * foo.cpl,@sp 293 * foo.cpl,,str 294 * foo.cpl @sp 295 * foo.cpl str 297 296 */ 298 297 { 299 char* 300 char* 301 char* 302 char 303 unsigned 304 char* 298 char* buffer; 299 char* beg = NULL; 300 char* end; 301 char ch; 302 unsigned sp = 0; 303 char* extraPmts = NULL; 305 304 306 305 buffer = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1); … … 310 309 311 310 for (;;) { 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 311 ch = *end; 312 if (ch == ' ' || ch == ',' || ch == '\0') { 313 *end = '\0'; 314 if (beg) { 315 if (*beg == '@') { 316 sp = atoi(beg + 1); 317 } else if (*beg == '\0') { 318 sp = 0; 319 } else { 320 extraPmts = beg; 321 } 322 } 323 if (ch == '\0') break; 324 beg = end + 1; 325 if (ch == ' ') while (end[1] == ' ') end++; 326 } 327 end++; 329 328 } 330 329 Control_LoadApplet(hWnd, buffer, panel); … … 335 334 assert(applet && applet->next == NULL); 336 335 if (sp >= applet->count) { 337 338 336 WARN("Out of bounds (%u >= %u), setting to 0\n", sp, applet->count); 337 sp = 0; 339 338 } 340 339 if (applet->info[sp].dwSize) { 341 342 340 if (!applet->proc(applet->hWnd, CPL_STARTWPARMSA, sp, (LPARAM)extraPmts)) 341 applet->proc(applet->hWnd, CPL_DBLCLK, sp, applet->info[sp].lData); 343 342 } 344 343 Control_UnloadApplet(applet); … … 348 347 349 348 /************************************************************************* 350 * Control_RunDLL 349 * Control_RunDLL [SHELL32.12] 351 350 * 352 351 */ 353 352 void WINAPI Control_RunDLL(HWND hWnd, HINSTANCE hInst, LPCSTR cmd, DWORD nCmdShow) 354 353 { 355 CPanel 356 357 TRACE("(0x%08x, 0x%08lx, %s, 0x%08lx)\n", 358 354 CPanel panel; 355 356 TRACE("(0x%08x, 0x%08lx, %s, 0x%08lx)\n", 357 hWnd, (DWORD)hInst, debugstr_a(cmd), nCmdShow); 359 358 360 359 memset(&panel, 0, sizeof(panel)); … … 368 367 369 368 /************************************************************************* 370 * Control_FillCache_RunDLL 369 * Control_FillCache_RunDLL [SHELL32.8] 371 370 * 372 371 */ … … 378 377 379 378 /************************************************************************* 380 * RunDLL_CallEntry16 379 * RunDLL_CallEntry16 [SHELL32.122] 381 380 * the name is propably wrong 382 381 */
Note:
See TracChangeset
for help on using the changeset viewer.