Package Manager: fixed HotKeys (thanks to w3seek) *shamed*
[reactos.git] / rosapps / packmgr / gui / main.cpp
1 ////////////////////////////////////////////////////////
2 //
3 // main.cpp
4 //
5 // Implementation of the Package Manager GUI
6 //
7 //
8 // Maarten Bosma, 09.01.2004
9 // maarten.paul@bosma.de
10 //
11 ////////////////////////////////////////////////////////////////////
12
13 #include "main.h"
14
15
16 // Application's Entry Point
17 int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
18 {
19 HWND hwnd;
20 MSG msg;
21 WNDCLASSEX wc = {0};
22
23 // Window creation
24 wc.cbSize = sizeof(WNDCLASSEX);
25 wc.lpszClassName = L"pgkmgr";
26 wc.style = CS_HREDRAW | CS_VREDRAW;
27 wc.lpfnWndProc = (WNDPROC)WndProc;
28 wc.hInstance = hinst;
29 wc.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_MAIN));
30 wc.hbrBackground = (HBRUSH)(COLOR_SCROLLBAR);
31
32 RegisterClassEx(&wc);
33
34 hwnd = CreateWindow(L"pgkmgr",
35 L"ReactOS - Package Manager v0.3",
36 WS_OVERLAPPEDWINDOW,
37 CW_USEDEFAULT,
38 CW_USEDEFAULT,
39 500, 600,
40 NULL, NULL,
41 hinst,
42 NULL);
43
44
45 // Toolbar creation
46 InitCommonControls();
47
48 hTBar = CreateToolbarEx(hwnd, WS_CHILD|WS_VISIBLE|TBSTYLE_FLAT, 0, 8, hinst, IDB_TOOLBAR,
49 Buttons, sizeof(Buttons)/sizeof(TBBUTTON), TBSIZE, TBSIZE, TBSIZE, TBSIZE, sizeof(TBBUTTON));
50
51 // Show the windows
52 ShowWindow(hwnd, SW_SHOW);
53 UpdateWindow(hwnd);
54
55 // Load the tree
56 int error = PML_LoadTree(&tree, "tree.xml", AddItem);
57
58 if(error)
59 {
60 MessageBox(0,PML_TransError(error),0,0);
61 return 0;
62 }
63
64 // Read the help
65 Help();
66
67 // Start getting messages
68 while(GetMessage(&msg,NULL,0,0))
69 {
70 if(!TranslateAccelerator(hwnd, hHotKeys, &msg))
71 {
72 TranslateMessage(&msg);
73 DispatchMessage(&msg);
74 }
75 }
76
77 // Close our handle
78 PML_CloseTree (tree);
79
80 return 0;
81 }
82
83 // Add a item to our tree
84 int AddItem (int id, const char* name, int parent, int icon)
85 {
86 TV_INSERTSTRUCT tvins;
87
88 tvins.item.lParam = (UINT)id;
89 tvins.item.mask = TVIF_TEXT|TVIF_PARAM;
90 tvins.item.pszText = (WCHAR*)name; //that is ok
91 tvins.item.cchTextMax = strlen(name);
92 tvins.hInsertAfter = TVI_LAST;
93
94 if(icon)
95 {
96 tvins.item.iImage = icon;
97 tvins.item.iSelectedImage = icon;
98 tvins.item.mask |= TVIF_IMAGE | TVIF_SELECTEDIMAGE;
99 }
100
101 if (parent==0)
102 tvins.hParent = TVI_ROOT;
103 else
104 tvins.hParent = nodes[parent];
105
106 nodes[id] = (HTREEITEM)SendMessage(hTree, TVM_INSERTITEMA, 0, (LPARAM)&tvins);
107
108 return 0;
109 }
110
111 // Load the Help from file and display it
112 void Help (void)
113 {
114 string source;
115
116 ifstream file("help.txt", ios_base::in);
117 getline(file, source, '\0');
118
119 SetText(source.c_str());
120 }
121
122 // Create our Controls
123 void InitControls (HWND hwnd)
124 {
125
126 HINSTANCE hinst = GetModuleHandle(NULL);
127
128 // Create the controls
129 hTree = CreateWindowEx(0, WC_TREEVIEW, L"TreeView", WS_CHILD|WS_VISIBLE|WS_BORDER|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS,
130 0, 0, 0, 0, hwnd, NULL, hinst, NULL);
131
132 hEdit = CreateWindowEx(WS_EX_CLIENTEDGE, L"edit", PML_TransError(IDS_LOAD), WS_CHILD|WS_VISIBLE|ES_MULTILINE,
133 0, 0, 100, 100, hwnd, NULL, hinst, NULL);
134
135 hPopup = LoadMenu(hinst, MAKEINTRESOURCE(IDR_POPUP));
136
137 // Create Tree Icons
138 HIMAGELIST hIcon = ImageList_Create(16,16,ILC_COLOR32,1,1);
139 SendMessage(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)(HIMAGELIST)hIcon);
140
141 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(1)));
142 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(11)));
143 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(12)));
144 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(13)));
145 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(14)));
146
147 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(2)));
148 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(3)));
149 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(4)));
150 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(5)));
151 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(6)));
152 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(7)));
153 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(8)));
154 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(9)));
155 ImageList_AddIcon(hIcon, LoadIcon(hinst, MAKEINTRESOURCE(10)));
156
157 // Setup Hotkeys
158 hHotKeys = LoadAccelerators (hinst, MAKEINTRESOURCE(IDR_HOTKEYS));
159 }
160
161 // Set the Icons
162 int SetIcon (int id, int icon)
163 {
164 TVITEMEX item;
165
166 item.hItem = nodes[id];
167 item.iImage = icon;
168 item.iSelectedImage = icon;
169 item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
170
171 TreeView_SetItem(hTree, &item);
172
173 return 1;
174 }
175
176 // Set the Icons
177 int Ask (const WCHAR* message)
178 {
179 int ans = MessageBox (0,message,0,MB_YESNO);
180
181 if(ans == IDYES)
182 return 1;
183
184 return 0;
185 }
186
187 // En- or Disable a Button inside of the toolbar and the Context Menu
188 int SetButton (DWORD id, BOOL state)
189 {
190 // Change the Toorbar Button
191 TBBUTTONINFO ti;
192
193 ti.cbSize = sizeof (ti);
194 ti.dwMask = TBIF_STATE;
195 /*
196 if(state&&id==1)
197 MessageBox(0,L"on",0,0);
198 else if(!state&&id==1)
199 MessageBox(0,L"off",0,0);
200 */
201 if(state)
202 ti.fsState = TBSTATE_ENABLED;
203 else
204 ti.fsState = TBSTATE_INDETERMINATE;
205
206 SendMessage (hTBar, TB_SETBUTTONINFO, id, (LPARAM)&ti);
207
208 // Change the Context Menu item
209 MENUITEMINFO mi;
210
211 mi.cbSize = sizeof (mi);
212 mi.fMask = MIIM_STATE;
213
214 if(state)
215 mi.fState = MFS_ENABLED;
216
217 else
218 mi.fState = MFS_GRAYED;
219
220 SetMenuItemInfo(hPopup, id, FALSE, &mi);
221
222 return 0;
223 }
224
225 // Set the text of the text box
226 int SetText (const char* text)
227 {
228 if(!text)
229 return 1;
230
231 int i = 0;
232 string source = text;
233
234 // the windows does not need "\n"
235 // for new lines but "\r\n"
236 for(i=0; source[i]; i++)
237 if(source[i]=='\n' && source[i]!='\r')
238 source.insert (i++, "\r");
239
240 SetWindowTextA(hEdit, source.c_str());
241
242 return 0;
243 }
244
245 // Windows Message Callback (this is where most things happen)
246 LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
247 {
248 switch (message)
249 {
250 // at the very beginning ...
251 case WM_CREATE:
252 {
253 InitControls(hwnd);
254 }
255 break;
256
257 // calculate the size of the controls
258 case WM_SIZE:
259 {
260 RECT rcl;
261 SendMessage(hTBar, TB_AUTOSIZE, 0L, 0L);
262 GetWindowRect(hTBar, &rcl);
263
264 int win_top = rcl.bottom - rcl.top;
265 int win_hight = HIWORD(lParam) - win_top;
266
267 MoveWindow(hTree, 0, win_top, LOWORD(lParam), splitter_pos*win_hight/100, TRUE);
268 MoveWindow(hEdit, 0, (splitter_pos*win_hight/100)+win_top, LOWORD(lParam), win_hight, TRUE);
269 }
270 break;
271
272 // for the treeview
273 case WM_NOTIFY:
274 {
275 if(((LPNMHDR)lParam)->code == TVN_SELCHANGED)
276 {
277 selected = ((LPNMTREEVIEW)lParam)->itemNew.lParam;
278 PML_LoadPackage (tree, selected, SetButton);
279 SetText(PML_GetDescription (tree, selected));
280 }
281
282 else if ((int)(((LPNMHDR)lParam)->code) == NM_RCLICK) // <= ahhh LISP
283 {
284 // which item has been click on
285 HTREEITEM item = TreeView_GetDropHilight(hTree);
286
287 if(item != NULL)
288 {
289 // mark the one as seleacted
290 SendMessage (hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)item);
291 TreeView_EnsureVisible (hTree, item);
292 }
293
294 // create the context menu
295 if(selected != 0)
296 {
297 POINT pt;
298 GetCursorPos (&pt);
299 TrackPopupMenu (GetSubMenu(hPopup, 0), 0, (UINT)pt.x, (UINT)pt.y, 0, hwnd, NULL);
300 }
301 }
302 }
303 break;
304
305 // for the toolbar
306 case WM_COMMAND:
307 {
308 // All Actions
309 if(LOWORD(wParam) <= 5 && LOWORD(wParam) >= 1)
310 {
311 if(selected)
312 if(PML_SetAction(tree, selected, LOWORD(wParam)-1, SetIcon, Ask) == ERR_OK)
313 break;
314
315 MessageBeep(MB_ICONHAND);
316 }
317
318 // DoIt
319 else if(LOWORD(wParam)==6)
320 {
321 if(PML_DoIt(tree, SetStatus, Ask) == ERR_OK)
322 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_DOIT), hwnd, StatusProc);
323 else
324 MessageBeep(MB_ICONHAND);
325 }
326
327 // Help
328 else if(LOWORD(wParam)==7)
329 Help();
330
331 // Options
332 else if(LOWORD(wParam)==8)
333 DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_OPTIONS), hwnd, OptionsProc);
334
335 else
336 MessageBox(0,0,0,0);
337 }
338 break;
339
340 // prozess hotkeys
341 case WM_HOTKEY:
342 {
343 if(PML_SetAction(tree, selected, wParam, SetIcon, Ask) != ERR_OK)
344 MessageBeep(MB_ICONHAND);
345 }
346 break;
347
348 // ... at the very end
349 case WM_DESTROY:
350 {
351 PostQuitMessage(0);
352 return 0;
353 }
354 }
355
356 return DefWindowProc (hwnd, message, wParam, lParam);
357 }
358
359 // Warning: This function is called from another thread
360 int SetStatus (int status1, int status2, WCHAR* text)
361 {
362 // Set the Rage to 1000
363 SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETRANGE32, 0, 1000);
364 SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETRANGE32, 0, 1000);
365
366 // The prozessbars and the text filds
367 if(text)
368 SetDlgItemText(hStatus, IDC_TSTATUS, text);
369
370 if(status1!=-1)
371 SendMessage(GetDlgItem(hStatus, IDC_STATUS1), PBM_SETPOS, status1, 0);
372
373 if(status2!=-1)
374 SendMessage(GetDlgItem(hStatus, IDC_STATUS2), PBM_SETPOS, status2, 0);
375
376 // If the Status is 1000 very thing is done
377 if(status1==1000)
378 {
379 EndDialog(hStatus, TRUE);
380 MessageBox(0,PML_TransError(status2),0,0);
381 }
382
383 return 0;
384 }
385
386 // Callback for the Status Dialog
387 INT_PTR CALLBACK StatusProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
388 {
389 switch (msg)
390 {
391 case WM_INITDIALOG:
392 {
393 hStatus = hwnd;
394
395 } break;
396
397 case WM_COMMAND: // can only be the about button
398 case WM_CLOSE: // the close-window-[x]
399 {
400 PML_Abort();
401 EndDialog(hwnd, TRUE);
402 return 0;
403 }
404 }
405
406 return 0;
407 }
408
409 // Callback for the Options Dialog
410 INT_PTR CALLBACK OptionsProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
411 {
412 switch (msg)
413 {
414 case WM_CLOSE:
415 EndDialog(hwnd, TRUE);
416 return 0;
417 }
418
419 return 0;
420 }