2 * PROJECT: ReactOS System Control Panel
3 * FILE: base/applications/control/control.c
4 * PURPOSE: ReactOS System Control Panel
5 * PROGRAMMERS: Gero Kuehn (reactos.filter@gkware.com)
6 * Colin Finck (mail@colinfinck.de)
11 static const TCHAR szWindowClass
[] = _T("DummyControlClass");
17 OpenShellFolder(LPTSTR lpFolderCLSID
)
19 TCHAR szParameters
[MAX_PATH
];
21 /* Open a shell folder using "explorer.exe".
22 The passed CLSID's are all subfolders of the "Control Panel" shell folder. */
23 _tcscpy(szParameters
, _T("/n,::{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\::{21EC2020-3AEA-1069-A2DD-08002B30309D}"));
24 _tcscat(szParameters
, lpFolderCLSID
);
26 return (int)ShellExecute(NULL
, _T("open"), _T("explorer.exe"), szParameters
, NULL
, SW_SHOWDEFAULT
) > 32;
30 RunControlPanel(LPTSTR lpCmd
)
32 TCHAR szParameters
[MAX_PATH
];
34 _tcscpy(szParameters
, _T("shell32.dll,Control_RunDLL "));
35 _tcscat(szParameters
, lpCmd
);
37 return RUNDLL(szParameters
);
41 PopulateCPLList(HWND hLisCtrl
)
45 TCHAR pszSearchPath
[MAX_PATH
];
46 HIMAGELIST hImgListSmall
;
47 HIMAGELIST hImgListLarge
;
50 TCHAR pszPath
[MAX_PATH
];
51 TCHAR szPanelNum
[CCH_UINT_MAX
+ 1];
54 /* Icon drawing mode */
55 pDevMode
.dmSize
= sizeof(DEVMODE
);
56 pDevMode
.dmDriverExtra
= 0;
58 EnumDisplaySettings(NULL
, ENUM_CURRENT_SETTINGS
, &pDevMode
);
59 hImgListSmall
= ImageList_Create(16, 16, pDevMode
.dmBitsPerPel
| ILC_MASK
, 5, 5);
60 hImgListLarge
= ImageList_Create(32, 32, pDevMode
.dmBitsPerPel
| ILC_MASK
, 5, 5);
62 GetSystemDirectory(pszSearchPath
, MAX_PATH
);
63 _tcscat(pszSearchPath
, _T("\\*.cpl"));
65 hFind
= FindFirstFile(pszSearchPath
, &fd
);
67 while (hFind
!= INVALID_HANDLE_VALUE
)
69 _tcscpy(pszPath
, pszSearchPath
);
70 *_tcsrchr(pszPath
, '\\') = 0;
71 _tcscat(pszPath
, _T("\\"));
72 _tcscat(pszPath
, fd
.cFileName
);
74 hDll
= LoadLibrary(pszPath
);
75 pFunc
= (CPLAPPLETFUNC
)GetProcAddress(hDll
, "CPlApplet");
77 if (pFunc
&& pFunc(hLisCtrl
, CPL_INIT
, 0, 0))
81 uPanelCount
= (UINT
)pFunc(hLisCtrl
, CPL_GETCOUNT
, 0, 0);
83 for (i
= 0; i
< uPanelCount
; i
++)
91 pszCmd
= (LPTSTR
) HeapAlloc(hProcessHeap
, 0, MAX_PATH
* sizeof(TCHAR
));
95 /* Build the command, which is later passed to RunControlPanel */
96 _tcscpy(pszCmd
, fd
.cFileName
);
97 _tcscat(pszCmd
, _T(" @"));
98 _itot(i
, szPanelNum
, 10);
99 _tcscat(pszCmd
, szPanelNum
);
101 pFunc(hLisCtrl
, CPL_INQUIRE
, (LPARAM
)i
, (LPARAM
)&CplInfo
);
103 hIcon
= LoadImage(hDll
, MAKEINTRESOURCE(CplInfo
.idIcon
), IMAGE_ICON
, 16, 16, LR_DEFAULTCOLOR
);
104 index
= ImageList_AddIcon(hImgListSmall
, hIcon
);
107 hIcon
= LoadImage(hDll
, MAKEINTRESOURCE(CplInfo
.idIcon
), IMAGE_ICON
, 32, 32, LR_DEFAULTCOLOR
);
108 ImageList_AddIcon(hImgListLarge
, hIcon
);
111 if (LoadString(hDll
, CplInfo
.idName
, Name
, MAX_PATH
))
116 lvi
.mask
= LVIF_TEXT
| LVIF_PARAM
| LVIF_STATE
| LVIF_IMAGE
;
120 lvi
.lParam
= (LPARAM
)pszCmd
;
121 nIndex
= ListView_InsertItem(hLisCtrl
, &lvi
);
123 if (LoadString(hDll
, CplInfo
.idInfo
, Name
, MAX_PATH
))
124 ListView_SetItemText(hLisCtrl
, nIndex
, 1, Name
);
129 if (!FindNextFile(hFind
, &fd
))
130 hFind
= INVALID_HANDLE_VALUE
;
133 (void)ListView_SetImageList(hLisCtrl
, hImgListSmall
, LVSIL_SMALL
);
134 (void)ListView_SetImageList(hLisCtrl
, hImgListLarge
, LVSIL_NORMAL
);
138 MyWindowProc(HWND hWnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
140 static HWND hListView
;
148 LV_COLUMN column
= {0};
150 GetClientRect(hWnd
, &rect
);
151 hListView
= CreateWindow(WC_LISTVIEW
, NULL
, LVS_REPORT
| LVS_ALIGNLEFT
| LVS_SORTASCENDING
| LVS_AUTOARRANGE
| LVS_SINGLESEL
| WS_VISIBLE
| WS_CHILD
| WS_TABSTOP
, 0, 0, rect
.right
, rect
.bottom
, hWnd
, NULL
, hInst
, 0);
153 column
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_SUBITEM
| LVCF_TEXT
;
154 column
.fmt
= LVCFMT_LEFT
;
155 column
.cx
= (rect
.right
- rect
.left
) / 3;
157 LoadString(hInst
, IDS_NAME
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
158 column
.pszText
= szBuf
;
159 (void)ListView_InsertColumn(hListView
, 0, &column
);
161 column
.cx
= (rect
.right
- rect
.left
) - ((rect
.right
- rect
.left
) / 3) - 1;
163 LoadString(hInst
, IDS_COMMENT
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
164 column
.pszText
= szBuf
;
165 (void)ListView_InsertColumn(hListView
, 1, &column
);
167 PopulateCPLList(hListView
);
169 (void)ListView_SetColumnWidth(hListView
, 2, LVSCW_AUTOSIZE_USEHEADER
);
170 (void)ListView_Update(hListView
, 0);
182 lvi
.mask
= LVIF_PARAM
;
184 /* Free the memory used for the command strings */
185 for(nItems
= ListView_GetItemCount(hListView
); --nItems
>= 0;)
188 (void)ListView_GetItem(hListView
, &lvi
);
189 HeapFree(hProcessHeap
, 0, (LPVOID
)lvi
.lParam
);
200 GetClientRect(hWnd
, &rect
);
201 MoveWindow(hListView
, 0, 0, rect
.right
, rect
.bottom
, TRUE
);
209 phdr
= (NMHDR
*)lParam
;
220 nSelect
= SendMessage(hListView
, LVM_GETNEXTITEM
, (WPARAM
)-1, LVNI_FOCUSED
);
225 LoadString(hInst
, IDS_NO_ITEMS
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
226 MessageBox(hWnd
, (LPCTSTR
)szBuf
, NULL
, MB_OK
| MB_ICONINFORMATION
);
231 lvi
.mask
= LVIF_PARAM
;
232 (void)ListView_GetItem(hListView
, &lvi
);
234 pszCmd
= (LPTSTR
)lvi
.lParam
;
237 RunControlPanel(pszCmd
);
245 switch (LOWORD(wParam
))
248 SetWindowLong(hListView
,GWL_STYLE
,LVS_ICON
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
| LVS_SINGLESEL
| WS_VISIBLE
| WS_CHILD
|WS_BORDER
|WS_TABSTOP
);
252 SetWindowLong(hListView
,GWL_STYLE
,LVS_SMALLICON
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
| LVS_SINGLESEL
| WS_VISIBLE
| WS_CHILD
|WS_BORDER
|WS_TABSTOP
);
256 SetWindowLong(hListView
,GWL_STYLE
,LVS_LIST
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
| LVS_SINGLESEL
| WS_VISIBLE
| WS_CHILD
|WS_BORDER
|WS_TABSTOP
);
260 SetWindowLong(hListView
,GWL_STYLE
,LVS_REPORT
| LVS_ALIGNLEFT
| LVS_AUTOARRANGE
| LVS_SINGLESEL
| WS_VISIBLE
| WS_CHILD
|WS_BORDER
|WS_TABSTOP
);
271 LoadString(hInst
, IDS_ABOUT
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
272 LoadString(hInst
, IDS_ABOUT_TITLE
, Title
, sizeof(Title
) / sizeof(TCHAR
));
274 MessageBox(hWnd
, (LPCTSTR
)szBuf
, (LPCTSTR
)Title
, MB_OK
| MB_ICONINFORMATION
);
281 return DefWindowProc(hWnd
, uMsg
, wParam
, lParam
);
286 RunControlPanelWindow(int nCmdShow
)
290 INITCOMMONCONTROLSEX icex
;
291 WNDCLASSEX wcex
= {0};
294 wcex
.cbSize
= sizeof(wcex
);
295 wcex
.hIcon
= LoadIcon(hInst
, MAKEINTRESOURCE(IDI_MAINICON
));
296 wcex
.lpszClassName
= MYWNDCLASS
;
297 wcex
.lpfnWndProc
= MyWindowProc
;
298 RegisterClassEx(&wcex
);
300 icex
.dwSize
= sizeof(icex
);
301 icex
.dwICC
= ICC_LISTVIEW_CLASSES
;
302 InitCommonControlsEx(&icex
);
304 LoadString(hInst
, IDS_WINDOW_TITLE
, szBuf
, sizeof(szBuf
) / sizeof(TCHAR
));
306 hMainWnd
= CreateWindowEx(WS_EX_CLIENTEDGE
,
315 LoadMenu(hInst
, MAKEINTRESOURCE(IDM_MAINMENU
)),
321 ShowWindow(hMainWnd
, nCmdShow
);
323 while (GetMessage(&msg
, 0, 0, 0))
325 TranslateMessage(&msg
);
326 DispatchMessage(&msg
);
333 _tWinMain(HINSTANCE hInstance
, HINSTANCE hPrevInstance
, LPTSTR lpCmdLine
, int nCmdShow
)
338 hProcessHeap
= GetProcessHeap();
340 /* Show the control panel window if no argument or "panel" was passed */
341 if(lpCmdLine
[0] == 0 || !_tcsicmp(lpCmdLine
, _T("panel")))
342 return RunControlPanelWindow(nCmdShow
);
344 /* Check one of the built-in control panel handlers */
345 if (!_tcsicmp(lpCmdLine
, _T("admintools"))) return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524153}"));
346 else if (!_tcsicmp(lpCmdLine
, _T("color"))) return RunControlPanel(_T("desk.cpl")); /* TODO: Switch to the "Apperance" tab */
347 else if (!_tcsicmp(lpCmdLine
, _T("date/time"))) return RunControlPanel(_T("timedate.cpl"));
348 else if (!_tcsicmp(lpCmdLine
, _T("desktop"))) return RunControlPanel(_T("desk.cpl"));
349 else if (!_tcsicmp(lpCmdLine
, _T("folders"))) return RUNDLL(_T("shell32.dll,Options_RunDLL"));
350 else if (!_tcsicmp(lpCmdLine
, _T("fonts"))) return OpenShellFolder(_T("\\::{D20EA4E1-3957-11d2-A40B-0C5020524152}"));
351 else if (!_tcsicmp(lpCmdLine
, _T("infrared"))) return RunControlPanel(_T("irprops.cpl"));
352 else if (!_tcsicmp(lpCmdLine
, _T("international"))) return RunControlPanel(_T("intl.cpl"));
353 else if (!_tcsicmp(lpCmdLine
, _T("keyboard"))) return RunControlPanel(_T("main.cpl @1"));
354 else if (!_tcsicmp(lpCmdLine
, _T("mouse"))) return RunControlPanel(_T("main.cpl @0"));
355 else if (!_tcsicmp(lpCmdLine
, _T("netconnections"))) return OpenShellFolder(_T("\\::{7007ACC7-3202-11D1-AAD2-00805FC1270E}"));
356 else if (!_tcsicmp(lpCmdLine
, _T("netware"))) return RunControlPanel(_T("nwc.cpl"));
357 else if (!_tcsicmp(lpCmdLine
, _T("ports"))) return RunControlPanel(_T("sysdm.cpl")); /* TODO: Switch to the "Computer Name" tab */
358 else if (!_tcsicmp(lpCmdLine
, _T("printers"))) return OpenShellFolder(_T("\\::{2227A280-3AEA-1069-A2DE-08002B30309D}"));
359 else if (!_tcsicmp(lpCmdLine
, _T("scannercamera"))) return OpenShellFolder(_T("\\::{E211B736-43FD-11D1-9EFB-0000F8757FCD}"));
360 else if (!_tcsicmp(lpCmdLine
, _T("schedtasks"))) return OpenShellFolder(_T("\\::{D6277990-4C6A-11CF-8D87-00AA0060F5BF}"));
361 else if (!_tcsicmp(lpCmdLine
, _T("telephony"))) return RunControlPanel(_T("telephon.cpl"));
362 else if (!_tcsicmp(lpCmdLine
, _T("userpasswords"))) return RunControlPanel(_T("nusrmgr.cpl")); /* Graphical User Account Manager */
363 else if (!_tcsicmp(lpCmdLine
, _T("userpasswords2"))) return RUNDLL(_T("netplwiz.dll,UsersRunDll")); /* Dialog based advanced User Account Manager */
365 /* It is none of them, so look for a handler in the registry */
366 if(RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("Software\\Microsoft\\Windows\\CurrentVersion\\Control Panel\\Cpls"), 0, KEY_QUERY_VALUE
, &hKey
) == ERROR_SUCCESS
)
370 for(dwIndex
= 0; ; ++dwIndex
)
373 DWORD dwValueSize
= MAX_VALUE_NAME
;
374 TCHAR szValueName
[MAX_VALUE_NAME
];
376 /* Get the value name and data size */
377 if(RegEnumValue(hKey
, dwIndex
, szValueName
, &dwValueSize
, 0, NULL
, NULL
, &dwDataSize
) != ERROR_SUCCESS
)
380 /* Check if the parameter is the value name */
381 if(!_tcsicmp(lpCmdLine
, szValueName
))
385 /* Allocate memory for the data plus two more characters, so we can quote the file name if required */
386 pszData
= (LPTSTR
) HeapAlloc(hProcessHeap
, 0, dwDataSize
+ 2 * sizeof(TCHAR
));
389 /* This value is the one we are looking for, so get the data. It is the path to a .cpl file */
390 if(RegQueryValueEx(hKey
, szValueName
, 0, NULL
, (LPBYTE
)pszData
, &dwDataSize
) == ERROR_SUCCESS
)
394 /* Quote the file name if required */
398 pszData
[dwDataSize
/ sizeof(TCHAR
)] = '\"';
399 pszData
[(dwDataSize
/ sizeof(TCHAR
)) + 1] = 0;
402 nReturnValue
= RunControlPanel(pszData
);
403 HeapFree(hProcessHeap
, 0, pszData
);
409 HeapFree(hProcessHeap
, 0, pszData
);
416 /* It's none of the known parameters, so interpret the parameter as the file name of a control panel applet */
417 return RunControlPanel(lpCmdLine
);