d8b0e5a566284ed1747bf33bf391d232afa99e69
[reactos.git] / reactos / lib / cpl / control / control.c
1 /*
2 * ReactOS
3 * Copyright (C) 2004 ReactOS Team
4 * Copyright (C) 2004 GkWare e.K.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 /* $Id: control.c,v 1.5 2004/09/15 16:03:09 fireball Exp $
21 *
22 * PROJECT: ReactOS System Control Panel
23 * FILE: lib/cpl/system/control.c
24 * PURPOSE: ReactOS System Control Panel
25 * PROGRAMMER: Gero Kuehn (reactos.filter@gkware.com)
26 * UPDATE HISTORY:
27 * 06-13-2004 Created
28 */
29 #include <windows.h>
30 #include <commctrl.h>
31 #include <cpl.h>
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 #include <stdarg.h>
36 #include <tchar.h>
37
38 #include "resource.h"
39
40 //#define CONTROL_DEBUG_ENABLE
41
42 #ifdef CONTROL_DEBUG_ENABLE
43 #define CTL_DEBUG(x) dbgprint x
44 #else
45 #define CTL_DEBUG(x)
46 #endif
47
48 #define MYWNDCLASS _T("CTLPANELCLASS")
49
50 typedef LONG (CALLBACK *CPLAPPLETFUNC)(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
51
52 typedef struct CPLLISTENTRY
53 {
54 TCHAR pszPath[MAX_PATH];
55 HMODULE hDLL;
56 CPLAPPLETFUNC pFunc;
57 CPLINFO CPLInfo;
58 int nIndex;
59 } CPLLISTENTRY;
60
61
62 HWND hListView;
63 HINSTANCE hInst;
64 HWND hMainWnd;
65 DEVMODE pDevMode;
66
67 void dbgprint(TCHAR *format,...)
68 {
69 TCHAR buf[1000];
70 va_list va;
71 va_start(va,format);
72 _vstprintf(buf,format,va);
73 OutputDebugString(buf);
74 va_end(va);
75 }
76
77 void PopulateCPLList(HWND hLisCtrl)
78 {
79 WIN32_FIND_DATA fd;
80 HANDLE hFind;
81 TCHAR pszSearchPath[MAX_PATH];
82 HIMAGELIST hImgListSmall;
83 HIMAGELIST hImgListLarge;
84 int C_Depth;
85
86 GetSystemDirectory(pszSearchPath,MAX_PATH);
87 _tcscat(pszSearchPath,_T("\\*.cpl"));
88 hFind = FindFirstFile(pszSearchPath,&fd);
89
90 /* Icon drawing mode */
91 pDevMode.dmSize = sizeof(DEVMODE);
92 pDevMode.dmDriverExtra = 0;
93
94 EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&pDevMode);
95 switch(pDevMode.dmBitsPerPel)
96 {
97 case 32: C_Depth = ILC_COLOR32; break;
98 case 24: C_Depth = ILC_COLOR24; break;
99 case 16: C_Depth = ILC_COLOR16; break;
100 case 8: C_Depth = ILC_COLOR8; break;
101 case 4: C_Depth = ILC_COLOR4; break;
102 default: C_Depth = ILC_COLOR; break;
103 }
104
105 hImgListSmall = ImageList_Create(16,16,C_Depth | ILC_MASK,256,1000);
106 hImgListLarge = ImageList_Create(32,32,C_Depth | ILC_MASK,256,1000);
107
108
109 while(hFind != INVALID_HANDLE_VALUE)
110 {
111 CPLLISTENTRY *pEntry;
112 CTL_DEBUG((_T("Found %s\r\n"),fd.cFileName));
113 pEntry = (CPLLISTENTRY*)malloc(sizeof(CPLLISTENTRY));
114 if(!pEntry)
115 break;
116 _tcscpy(pEntry->pszPath,pszSearchPath);
117 *_tcsrchr(pEntry->pszPath,'\\')=0;
118 _tcscat(pEntry->pszPath,_T("\\"));
119 _tcscat(pEntry->pszPath,fd.cFileName);
120
121 pEntry->hDLL = LoadLibrary(pEntry->pszPath);
122 CTL_DEBUG((_T("Handle %08X\r\n"),pEntry->hDLL));
123 pEntry->pFunc = (CPLAPPLETFUNC)GetProcAddress(pEntry->hDLL,"CPlApplet");
124 CTL_DEBUG((_T("CPLFunc %08X\r\n"),pEntry->pFunc));
125 if(pEntry->pFunc && pEntry->pFunc(hLisCtrl,CPL_INIT,0,0))
126 {
127 int i;
128 for(i=0;i<pEntry->pFunc(hLisCtrl,CPL_GETCOUNT,0,0);i++)
129 {
130 HICON hIcon;
131 TCHAR Name[MAX_PATH];
132 int index;
133 pEntry->pFunc(hLisCtrl,CPL_INQUIRE,0,(LPARAM)&pEntry->CPLInfo);
134
135 hIcon = LoadImage(pEntry->hDLL,MAKEINTRESOURCE(pEntry->CPLInfo.idIcon),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
136 index = ImageList_AddIcon(hImgListSmall,hIcon);
137 DestroyIcon(hIcon);
138 hIcon = LoadImage(pEntry->hDLL,MAKEINTRESOURCE(pEntry->CPLInfo.idIcon),IMAGE_ICON,32,32,LR_DEFAULTCOLOR);
139 ImageList_AddIcon(hImgListLarge,hIcon);
140 DestroyIcon(hIcon);
141
142 LoadString(pEntry->hDLL,pEntry->CPLInfo.idName,Name,MAX_PATH);
143 if(_tcslen(Name))
144 {
145 LV_ITEM lvi;
146
147 memset(&lvi,0x00,sizeof(lvi));
148 lvi.mask=LVIF_TEXT|LVIF_PARAM|LVIF_STATE|LVIF_IMAGE;
149 lvi.pszText = Name;
150 lvi.state=0;
151 lvi.iImage=index;
152 lvi.lParam = (LPARAM)pEntry;
153 pEntry->nIndex = ListView_InsertItem(hLisCtrl,&lvi);
154
155 LoadString(pEntry->hDLL,pEntry->CPLInfo.idInfo,Name,MAX_PATH);
156 ListView_SetItemText(hLisCtrl,pEntry->nIndex,1,Name);
157
158 ListView_SetImageList(hLisCtrl,hImgListSmall,LVSIL_SMALL);
159 ListView_SetImageList(hLisCtrl,hImgListLarge,LVSIL_NORMAL);
160 }
161 }
162 }
163
164 if(!FindNextFile(hFind,&fd))
165 hFind = INVALID_HANDLE_VALUE;
166 }
167 }
168
169 LRESULT CALLBACK MyWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
170 {
171 switch(uMsg)
172 {
173 case WM_CREATE:
174 {
175 RECT rect;
176 LV_COLUMN column;
177 GetClientRect(hWnd,&rect);
178 hListView = CreateWindow(WC_LISTVIEW,_T(""),LVS_REPORT | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD | WS_TABSTOP,0,0,rect.right ,rect.bottom,hWnd,NULL,hInst,0);
179 CTL_DEBUG((_T("Listview Window %08X\r\n"),hListView));
180
181 memset(&column,0x00,sizeof(column));
182 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM|LVCF_TEXT;
183 column.fmt=LVCFMT_LEFT;
184 column.cx = (rect.right - rect.left) / 3;
185 column.iSubItem = 0;
186 column.pszText = _T("Name");
187 ListView_InsertColumn(hListView,0,&column);
188 column.cx = (rect.right - rect.left) - ((rect.right - rect.left) / 3) - 1;
189 column.iSubItem = 1;
190 column.pszText = _T("Comment");
191 ListView_InsertColumn(hListView,1,&column);
192 PopulateCPLList(hListView);
193 ListView_SetColumnWidth(hListView,2,LVSCW_AUTOSIZE_USEHEADER);
194 ListView_Update(hListView,0);
195 }
196 break;
197 case WM_DESTROY:
198 PostQuitMessage(0);
199 break;
200 case WM_SIZE:
201 {
202 RECT rect;
203 GetClientRect(hWnd,&rect);
204 MoveWindow(hListView,0,0,rect.right,rect.bottom,TRUE);
205 }
206 break;
207 case WM_NOTIFY:
208 {
209 NMHDR *phdr;
210 phdr = (NMHDR*)lParam;
211 switch(phdr->code)
212 {
213 case NM_DBLCLK:
214 {
215 int nSelect;
216 LV_ITEM lvi;
217 CPLLISTENTRY *pEntry;
218 nSelect=SendMessage(hListView,LVM_GETNEXTITEM,(WPARAM)-1,LVNI_FOCUSED);
219
220 if(nSelect==-1) // no items
221 {
222 MessageBox(hWnd,_T("No Items in ListView"),_T("Error"),MB_OK|MB_ICONINFORMATION);
223 break;
224 }
225 CTL_DEBUG((_T("Select %d\r\n"),nSelect));
226 memset(&lvi,0x00,sizeof(lvi));
227 lvi.iItem = nSelect;
228 lvi.mask = LVIF_PARAM;
229 ListView_GetItem(hListView,&lvi);
230 pEntry = (CPLLISTENTRY *)lvi.lParam;
231 CTL_DEBUG((_T("Listview DblClk Entry %08X\r\n"),pEntry));
232 if(pEntry) {
233 CTL_DEBUG((_T("Listview DblClk Entry Func %08X\r\n"),pEntry->pFunc));
234 }
235 if(pEntry && pEntry->pFunc)
236 pEntry->pFunc(hListView,CPL_DBLCLK,pEntry->CPLInfo.lData,0);
237 }
238 }
239 }
240 break;
241 case WM_COMMAND:
242 switch(LOWORD(wParam))
243 {
244 case IDM_LARGEICONS:
245 SetWindowLong(hListView,GWL_STYLE,LVS_ICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
246 break;
247 case IDM_SMALLICONS:
248 SetWindowLong(hListView,GWL_STYLE,LVS_SMALLICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
249 break;
250 case IDM_LIST:
251 SetWindowLong(hListView,GWL_STYLE,LVS_LIST | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
252 break;
253 case IDM_DETAILS:
254 SetWindowLong(hListView,GWL_STYLE,LVS_REPORT | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
255 break;
256 case IDM_CLOSE:
257 DestroyWindow(hWnd);
258 break;
259 case IDM_ABOUT:
260 MessageBox(hWnd,_T("Simple Control Panel (not Shell-namespace based)\rCopyright 2004 GkWare e.K.\rhttp://www.gkware.com\rReleased under the GPL"),_T("About the Control Panel"),MB_OK | MB_ICONINFORMATION);
261 break;
262 }
263 break;
264 default:
265 return DefWindowProc(hWnd,uMsg,wParam,lParam);
266 }
267 return 0;
268 }
269
270 #ifdef _MSVC
271 int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,WCHAR *lpCmdLine,int nCmdShow)
272 #else
273 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,char *lpCmdLine,int nCmdShow)
274 #endif
275 {
276 MSG msg;
277 WNDCLASS wc;
278 hInst = hInstance;
279 CTL_DEBUG((_T("My Control Panel\r\n")));
280 memset(&wc,0x00,sizeof(wc));
281 wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAINICON));
282 wc.lpszClassName = MYWNDCLASS;
283 wc.lpszMenuName = _T("MAINMENU");
284 wc.lpfnWndProc = MyWindowProc;
285 RegisterClass(&wc);
286 InitCommonControls();
287 hMainWnd = CreateWindowEx(WS_EX_CLIENTEDGE,MYWNDCLASS,_T("Control Panel"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,LoadMenu(hInst,MAKEINTRESOURCE(IDM_MAINMENU)),hInst,0);
288 if(!hMainWnd) {
289 CTL_DEBUG((_T("Unable to create window\r\n")));
290 return -1;
291 }
292 ShowWindow(hMainWnd,nCmdShow);
293 while(GetMessage(&msg,0,0,0))
294 {
295 TranslateMessage(&msg);
296 DispatchMessage(&msg);
297 }
298
299 return 0;
300 }