- Load 16x16 and 32x32 icons.
[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.3 2004/06/29 12:03:56 ekohl 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 <stdlib.h>
30 #include <stdio.h>
31 #include <stdarg.h>
32 #include <tchar.h>
33 #include <windows.h>
34
35 #ifdef _MSC_VER
36 #include <commctrl.h>
37 #include <cpl.h>
38 #endif
39
40 #include "resource.h"
41
42 //#define CONTROL_DEBUG_ENABLE
43
44 #ifdef CONTROL_DEBUG_ENABLE
45 #define CTL_DEBUG(x) dbgprint x
46 #else
47 #define CTL_DEBUG(x)
48 #endif
49
50
51 #define MYWNDCLASS _T("CTLPANELCLASS")
52
53 typedef LONG (CALLBACK *CPLAPPLETFUNC)(HWND hwndCPL, UINT uMsg, LPARAM lParam1, LPARAM lParam2);
54
55 typedef struct CPLLISTENTRY
56 {
57 TCHAR pszPath[MAX_PATH];
58 HMODULE hDLL;
59 CPLAPPLETFUNC pFunc;
60 CPLINFO CPLInfo;
61 int nIndex;
62 } CPLLISTENTRY;
63
64
65 HWND hListView;
66 HINSTANCE hInst;
67 HWND hMainWnd;
68
69 void dbgprint(TCHAR *format,...)
70 {
71 TCHAR buf[1000];
72 va_list va;
73 va_start(va,format);
74 _vstprintf(buf,format,va);
75 OutputDebugString(buf);
76 va_end(va);
77 }
78
79 void PopulateCPLList(HWND hLisCtrl)
80 {
81 WIN32_FIND_DATA fd;
82 HANDLE hFind;
83 TCHAR pszSearchPath[MAX_PATH];
84 HIMAGELIST hImgListSmall;
85 HIMAGELIST hImgListLarge;
86 GetSystemDirectory(pszSearchPath,MAX_PATH);
87 _tcscat(pszSearchPath,_T("\\*.cpl"));
88 hFind = FindFirstFile(pszSearchPath,&fd);
89 hImgListSmall = ImageList_Create(16,16,ILC_COLOR | ILC_MASK,256,1000);
90 hImgListLarge = ImageList_Create(32,32,ILC_COLOR | ILC_MASK,256,1000);
91 while(hFind != INVALID_HANDLE_VALUE)
92 {
93 CPLLISTENTRY *pEntry;
94 CTL_DEBUG((_T("Found %s\r\n"),fd.cFileName));
95 pEntry = (CPLLISTENTRY*)malloc(sizeof(CPLLISTENTRY));
96 if(!pEntry)
97 break;
98 _tcscpy(pEntry->pszPath,pszSearchPath);
99 *_tcsrchr(pEntry->pszPath,'\\')=0;
100 _tcscat(pEntry->pszPath,_T("\\"));
101 _tcscat(pEntry->pszPath,fd.cFileName);
102
103 pEntry->hDLL = LoadLibrary(pEntry->pszPath);
104 CTL_DEBUG((_T("Handle %08X\r\n"),pEntry->hDLL));
105 pEntry->pFunc = (CPLAPPLETFUNC)GetProcAddress(pEntry->hDLL,"CPlApplet");
106 CTL_DEBUG((_T("CPLFunc %08X\r\n"),pEntry->pFunc));
107 if(pEntry->pFunc && pEntry->pFunc(hLisCtrl,CPL_INIT,0,0))
108 {
109 int i;
110 for(i=0;i<pEntry->pFunc(hLisCtrl,CPL_GETCOUNT,0,0);i++)
111 {
112 HICON hIcon;
113 TCHAR Name[MAX_PATH];
114 int index;
115 pEntry->pFunc(hLisCtrl,CPL_INQUIRE,0,(LPARAM)&pEntry->CPLInfo);
116
117 hIcon = LoadImage(pEntry->hDLL,MAKEINTRESOURCE(pEntry->CPLInfo.idIcon),IMAGE_ICON,16,16,LR_DEFAULTCOLOR);
118 index = ImageList_AddIcon(hImgListSmall,hIcon);
119 DestroyIcon(hIcon);
120 hIcon = LoadImage(pEntry->hDLL,MAKEINTRESOURCE(pEntry->CPLInfo.idIcon),IMAGE_ICON,32,32,LR_DEFAULTCOLOR);
121 ImageList_AddIcon(hImgListLarge,hIcon);
122 DestroyIcon(hIcon);
123
124 LoadString(pEntry->hDLL,pEntry->CPLInfo.idName,Name,MAX_PATH);
125 if(_tcslen(Name))
126 {
127 LV_ITEM lvi;
128
129 memset(&lvi,0x00,sizeof(lvi));
130 lvi.mask=LVIF_TEXT|LVIF_PARAM|LVIF_STATE|LVIF_IMAGE;
131 lvi.pszText = Name;
132 lvi.state=0;
133 lvi.iImage=index;
134 lvi.lParam = (LPARAM)pEntry;
135 pEntry->nIndex = ListView_InsertItem(hLisCtrl,&lvi);
136
137 LoadString(pEntry->hDLL,pEntry->CPLInfo.idInfo,Name,MAX_PATH);
138 ListView_SetItemText(hLisCtrl,pEntry->nIndex,1,Name);
139
140 ListView_SetImageList(hLisCtrl,hImgListSmall,LVSIL_SMALL);
141 ListView_SetImageList(hLisCtrl,hImgListLarge,LVSIL_NORMAL);
142 }
143 }
144 }
145
146 if(!FindNextFile(hFind,&fd))
147 hFind = INVALID_HANDLE_VALUE;
148 }
149 }
150
151 LRESULT CALLBACK MyWindowProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
152 {
153 switch(uMsg)
154 {
155 case WM_CREATE:
156 {
157 RECT rect;
158 LV_COLUMN column;
159 GetClientRect(hWnd,&rect);
160 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);
161 CTL_DEBUG((_T("Listview Window %08X\r\n"),hListView));
162
163 memset(&column,0x00,sizeof(column));
164 column.mask=LVCF_FMT | LVCF_WIDTH | LVCF_SUBITEM|LVCF_TEXT;
165 column.fmt=LVCFMT_LEFT;
166 column.cx = (rect.right - rect.left) / 3;
167 column.iSubItem = 0;
168 column.pszText = _T("Name");
169 ListView_InsertColumn(hListView,0,&column);
170 column.cx = (rect.right - rect.left) - ((rect.right - rect.left) / 3) - 1;
171 column.iSubItem = 1;
172 column.pszText = _T("Comment");
173 ListView_InsertColumn(hListView,1,&column);
174 PopulateCPLList(hListView);
175 ListView_SetColumnWidth(hListView,2,LVSCW_AUTOSIZE_USEHEADER);
176 ListView_Update(hListView,0);
177 }
178 break;
179 case WM_DESTROY:
180 PostQuitMessage(0);
181 break;
182 case WM_SIZE:
183 {
184 RECT rect;
185 GetClientRect(hWnd,&rect);
186 MoveWindow(hListView,0,0,rect.right,rect.bottom,TRUE);
187 }
188 break;
189 case WM_NOTIFY:
190 {
191 NMHDR *phdr;
192 phdr = (NMHDR*)lParam;
193 switch(phdr->code)
194 {
195 case NM_DBLCLK:
196 {
197 int nSelect;
198 LV_ITEM lvi;
199 CPLLISTENTRY *pEntry;
200 nSelect=SendMessage(hListView,LVM_GETNEXTITEM,(WPARAM)-1,LVNI_FOCUSED);
201
202 if(nSelect==-1) // no items
203 {
204 MessageBox(hWnd,_T("No Items in ListView"),_T("Error"),MB_OK|MB_ICONINFORMATION);
205 break;
206 }
207 CTL_DEBUG((_T("Select %d\r\n"),nSelect));
208 memset(&lvi,0x00,sizeof(lvi));
209 lvi.iItem = nSelect;
210 lvi.mask = LVIF_PARAM;
211 ListView_GetItem(hListView,&lvi);
212 pEntry = (CPLLISTENTRY *)lvi.lParam;
213 CTL_DEBUG((_T("Listview DblClk Entry %08X\r\n"),pEntry));
214 if(pEntry) {
215 CTL_DEBUG((_T("Listview DblClk Entry Func %08X\r\n"),pEntry->pFunc));
216 }
217 if(pEntry && pEntry->pFunc)
218 pEntry->pFunc(hListView,CPL_DBLCLK,pEntry->CPLInfo.lData,0);
219 }
220 }
221 }
222 break;
223 case WM_COMMAND:
224 switch(LOWORD(wParam))
225 {
226 case IDM_LARGEICONS:
227 SetWindowLong(hListView,GWL_STYLE,LVS_ICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
228 break;
229 case IDM_SMALLICONS:
230 SetWindowLong(hListView,GWL_STYLE,LVS_SMALLICON | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
231 break;
232 case IDM_LIST:
233 SetWindowLong(hListView,GWL_STYLE,LVS_LIST | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
234 break;
235 case IDM_DETAILS:
236 SetWindowLong(hListView,GWL_STYLE,LVS_REPORT | LVS_ALIGNLEFT | LVS_AUTOARRANGE | LVS_SINGLESEL | WS_VISIBLE | WS_CHILD|WS_BORDER|WS_TABSTOP);
237 break;
238 case IDM_CLOSE:
239 DestroyWindow(hWnd);
240 break;
241 case IDM_ABOUT:
242 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);
243 break;
244 }
245 break;
246 default:
247 return DefWindowProc(hWnd,uMsg,wParam,lParam);
248 }
249 return 0;
250 }
251
252 #ifdef _MSVC
253 int WINAPI wWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,WCHAR *lpCmdLine,int nCmdShow)
254 #else
255 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,char *lpCmdLine,int nCmdShow)
256 #endif
257 {
258 MSG msg;
259 WNDCLASS wc;
260 hInst = hInstance;
261 CTL_DEBUG((_T("My Control Panel\r\n")));
262 memset(&wc,0x00,sizeof(wc));
263 wc.hIcon = LoadIcon(hInst,MAKEINTRESOURCE(IDI_MAINICON));
264 wc.lpszClassName = MYWNDCLASS;
265 wc.lpszMenuName = _T("MAINMENU");
266 wc.lpfnWndProc = MyWindowProc;
267 RegisterClass(&wc);
268 InitCommonControls();
269 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);
270 if(!hMainWnd) {
271 CTL_DEBUG((_T("Unable to create window\r\n")));
272 return -1;
273 }
274 ShowWindow(hMainWnd,nCmdShow);
275 while(GetMessage(&msg,0,0,0))
276 {
277 TranslateMessage(&msg);
278 DispatchMessage(&msg);
279 }
280
281 return 0;
282 }