* Sync up to trunk head (r60691).
[reactos.git] / base / applications / mscutils / devmgmt_new / MainWindow.cpp
1 #include "StdAfx.h"
2 #include "devmgmt.h"
3 #include "MainWindow.h"
4
5 /* menu hints */
6 static const MENU_HINT MainMenuHintTable[] =
7 {
8 /* File Menu */
9 {IDC_EXIT, IDS_HINT_EXIT},
10
11 /* Action Menu */
12 {IDC_REFRESH, IDS_HINT_REFRESH},
13 {IDC_PROP, IDS_HINT_PROP},
14
15 {IDC_ABOUT, IDS_HINT_ABOUT}
16 };
17
18 /* system menu hints */
19 static const MENU_HINT SystemMenuHintTable[] =
20 {
21 {SC_RESTORE, IDS_HINT_SYS_RESTORE},
22 {SC_MOVE, IDS_HINT_SYS_MOVE},
23 {SC_SIZE, IDS_HINT_SYS_SIZE},
24 {SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE},
25 {SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE},
26 {SC_CLOSE, IDS_HINT_SYS_CLOSE},
27 };
28
29
30
31 CMainWindow::CMainWindow(void) :
32 m_hMainWnd(NULL),
33 m_hStatusBar(NULL),
34 m_hToolBar(NULL),
35 m_CmdShow(0)
36 {
37 m_szMainWndClass = L"DevMgmtWndClass";
38 }
39
40 CMainWindow::~CMainWindow(void)
41 {
42 }
43
44 BOOL
45 CMainWindow::CreateToolBar()
46 {
47 HIMAGELIST hImageList;
48 HBITMAP hBitmap;
49 UINT StartResource, EndResource;
50 INT NumButtons;
51 BOOL bRet = FALSE;
52
53 static TBBUTTON ToolbarButtons [] =
54 {
55 {TBICON_PROP, IDC_PROP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0},
56 {TBICON_REFRESH, IDC_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0},
57
58 /* Add a seperator: First item for a seperator is its width in pixels */
59 {15, 0, TBSTATE_ENABLED, BTNS_SEP, {0}, 0, 0},
60 };
61
62 /* Get the number of buttons */
63 NumButtons = sizeof(ToolbarButtons) / sizeof(ToolbarButtons[0]);
64
65 /* Create the toolbar window */
66 m_hToolBar = CreateWindowExW(0,
67 TOOLBARCLASSNAME,
68 NULL,
69 WS_CHILD | WS_VISIBLE | TBSTYLE_FLAT | TBSTYLE_TOOLTIPS,
70 0, 0, 0, 0,
71 m_hMainWnd,
72 (HMENU)IDC_TOOLBAR,
73 g_hInstance,
74 NULL);
75 if (m_hToolBar)
76 {
77 /* Don't show clipped buttons */
78 SendMessageW(m_hToolBar,
79 TB_SETEXTENDEDSTYLE,
80 0,
81 TBSTYLE_EX_HIDECLIPPEDBUTTONS);
82
83 /* Set the struct size, the toobar needs this... */
84 SendMessageW(m_hToolBar,
85 TB_BUTTONSTRUCTSIZE,
86 sizeof(ToolbarButtons[0]),
87 0);
88
89 /* Create the toolbar icon image list */
90 hImageList = ImageList_Create(16,
91 16,
92 ILC_MASK | ILC_COLOR24,
93 NumButtons,
94 0);
95 if (hImageList)
96 {
97 /* Set the index endpoints */
98 StartResource = IDB_PROP;
99 EndResource = IDB_REFRESH;
100
101 /* Add all icons to the image list */
102 for (UINT i = StartResource; i <= EndResource; i++)
103 {
104 /* Load the image resource */
105 hBitmap = (HBITMAP)LoadImage(g_hInstance,
106 MAKEINTRESOURCE(i),
107 IMAGE_BITMAP,
108 16,
109 16,
110 LR_LOADTRANSPARENT);
111 if (hBitmap)
112 {
113 /* Add it to the image list */
114 ImageList_AddMasked(hImageList,
115 hBitmap,
116 RGB(255, 0, 128));
117
118 /* Delete the bitmap */
119 DeleteObject(hBitmap);
120 }
121 }
122
123 /* Set the new image list */
124 hImageList = (HIMAGELIST)SendMessageW(m_hToolBar,
125 TB_SETIMAGELIST,
126 0,
127 (LPARAM)hImageList);
128
129 /* Destroy any previous list */
130 if (hImageList) ImageList_Destroy(hImageList);
131
132 /* Add the buttons */
133 bRet = (BOOL)SendMessageW(m_hToolBar,
134 TB_ADDBUTTONS,
135 NumButtons,
136 (LPARAM)ToolbarButtons);
137 }
138 }
139
140 return bRet;
141 }
142
143 BOOL
144 CMainWindow::CreateStatusBar()
145 {
146 INT StatWidths[] = {110, -1}; /* widths of status bar */
147 BOOL bRet = FALSE;
148
149 /* Create the status bar */
150 m_hStatusBar = CreateWindowExW(0,
151 STATUSCLASSNAME,
152 NULL,
153 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
154 0, 0, 0, 0,
155 m_hMainWnd,
156 (HMENU)IDC_STATUSBAR,
157 g_hInstance,
158 NULL);
159 if (m_hStatusBar)
160 {
161 /* Set the width */
162 bRet = (BOOL)SendMessage(m_hStatusBar,
163 SB_SETPARTS,
164 sizeof(StatWidths) / sizeof(INT),
165 (LPARAM)StatWidths);
166 }
167
168 return bRet;
169 }
170
171 BOOL
172 CMainWindow::StatusBarLoadString(IN HWND hStatusBar,
173 IN INT PartId,
174 IN HINSTANCE hInstance,
175 IN UINT uID)
176 {
177 CAtlString szMessage;
178 BOOL bRet = FALSE;
179
180 /* Load the string */
181 if (szMessage.LoadStringW(hInstance, uID))
182 {
183 /* Send the message to the status bar */
184 bRet = (BOOL)SendMessageW(hStatusBar,
185 SB_SETTEXT,
186 (WPARAM)PartId,
187 (LPARAM)szMessage.GetBuffer());
188 }
189
190 return bRet;
191 }
192
193 LRESULT
194 CMainWindow::OnCreate(HWND hwnd)
195 {
196 LRESULT RetCode;
197
198 /* Assume failure */
199 RetCode = -1;
200
201 /* Store the window handle */
202 m_hMainWnd = hwnd;
203
204 /* Create the toolbar */
205 if (CreateToolBar())
206 {
207 /* Create the statusbar */
208 if (CreateStatusBar())
209 {
210 /* Create the device view object */
211 m_DeviceView = new CDeviceView(m_hMainWnd);
212
213 /* Initialize it */
214 if (m_DeviceView->Initialize())
215 {
216 /* Display the window according to the user request */
217 ShowWindow(hwnd, m_CmdShow);
218
219 /* Set as handled */
220 RetCode = 0;
221 }
222 }
223 }
224
225 return RetCode;
226 }
227
228 LRESULT
229 CMainWindow::OnSize()
230 {
231 RECT rcClient, rcTool, rcStatus;
232 INT lvHeight, iToolHeight, iStatusHeight;
233
234 /* Autosize the toolbar */
235 SendMessage(m_hToolBar, TB_AUTOSIZE, 0, 0);
236
237 /* Get the toolbar rect and save the height */
238 GetWindowRect(m_hToolBar, &rcTool);
239 iToolHeight = rcTool.bottom - rcTool.top;
240
241 /* Resize the status bar */
242 SendMessage(m_hStatusBar, WM_SIZE, 0, 0);
243
244 /* Get the statusbar rect and save the height */
245 GetWindowRect(m_hStatusBar, &rcStatus);
246 iStatusHeight = rcStatus.bottom - rcStatus.top;
247
248 /* Get the full client rect */
249 GetClientRect(m_hMainWnd, &rcClient);
250
251 /* Calculate the remaining height for the treeview */
252 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
253
254 /* Resize the device view */
255 m_DeviceView->Size(0,
256 iToolHeight,
257 rcClient.right,
258 lvHeight);
259
260 return 0;
261 }
262
263 LRESULT
264 CMainWindow::OnNotify(LPARAM lParam)
265 {
266
267 return 0;
268 }
269
270 LRESULT
271 CMainWindow::OnContext(LPARAM lParam)
272 {
273 return 0;
274 }
275
276 LRESULT
277 CMainWindow::OnCommand(WPARAM wParam,
278 LPARAM lParam)
279 {
280 LRESULT RetCode = 0;
281 WORD Msg;
282
283 /* Get the message */
284 Msg = LOWORD(wParam);
285
286 switch (Msg)
287 {
288 case IDC_PROP:
289 {
290 /* Display the device property sheet */
291 m_DeviceView->DisplayPropertySheet();
292 break;
293 }
294
295 case IDC_REFRESH:
296 {
297 /* Refresh the device list */
298 m_DeviceView->Refresh();
299 break;
300 }
301
302 case IDC_ABOUT:
303 {
304 /* Blow my own trumpet */
305 MessageBoxW(m_hMainWnd,
306 L"ReactOS Device Manager\r\nCopyright Ged Murphy 2011",
307 L"About",
308 MB_OK);
309
310 /* Set focus back to the treeview */
311 m_DeviceView->SetFocus();
312 break;
313 }
314
315 case IDC_EXIT:
316 {
317 /* Post a close message to the window */
318 PostMessageW(m_hMainWnd,
319 WM_CLOSE,
320 0,
321 0);
322 break;
323 }
324
325 default:
326 break;
327 }
328
329 return RetCode;
330 }
331
332 LRESULT
333 CMainWindow::OnDestroy()
334 {
335 /* Uninitialize the device view */
336 m_DeviceView->Uninitialize();
337
338 /* Kill the object */
339 delete m_DeviceView;
340 m_DeviceView = NULL;
341
342 /* Clear the user data pointer */
343 SetWindowLongPtr(m_hMainWnd, GWLP_USERDATA, 0);
344
345 /* Break the message loop */
346 PostQuitMessage(0);
347
348 return 0;
349 }
350
351 LRESULT CALLBACK
352 CMainWindow::MainWndProc(HWND hwnd,
353 UINT msg,
354 WPARAM wParam,
355 LPARAM lParam)
356 {
357 CMainWindow *pThis;
358 LRESULT RetCode = 0;
359
360 /* Get the object pointer from window context */
361 pThis = (CMainWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
362
363 /* Check for an invalid pointer */
364 if (!pThis)
365 {
366 /* Check that this isn't a create message */
367 if (msg != WM_CREATE)
368 {
369 /* Don't handle null info pointer */
370 goto HandleDefaultMessage;
371 }
372 }
373
374 switch(msg)
375 {
376 case WM_CREATE:
377 {
378 /* Get the object pointer from the create param */
379 pThis = (CMainWindow *)((LPCREATESTRUCT)lParam)->lpCreateParams;
380
381 /* Store the info pointer in the window's global user data */
382 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
383
384 /* Call the create handler */
385 RetCode = pThis->OnCreate(hwnd);
386 break;
387 }
388
389 case WM_SIZE:
390 {
391 RetCode = pThis->OnSize();
392 break;
393 }
394
395 case WM_NOTIFY:
396 {
397 /* Handle the notify message */
398 RetCode = pThis->OnNotify(lParam);
399 break;
400 }
401
402 case WM_CONTEXTMENU:
403 {
404 /* Handle creating the context menu */
405 RetCode = pThis->OnContext(lParam);
406 break;
407 }
408
409 case WM_COMMAND:
410 {
411 /* Handle the command message */
412 RetCode = pThis->OnCommand(wParam, lParam);
413
414 /* Hand it off to the default message handler */
415 goto HandleDefaultMessage;
416 }
417
418 case WM_CLOSE:
419 {
420 /* Destroy the main window */
421 DestroyWindow(hwnd);
422 }
423 break;
424
425 case WM_DESTROY:
426 {
427 /* Call the destroy handler */
428 RetCode = pThis->OnDestroy();
429 break;
430 }
431
432 default:
433 {
434 HandleDefaultMessage:
435 RetCode = DefWindowProc(hwnd, msg, wParam, lParam);
436 break;
437 }
438 }
439
440 return RetCode;
441 }
442
443 BOOL
444 CMainWindow::Initialize(LPCTSTR lpCaption,
445 int nCmdShow)
446 {
447 CAtlString szCaption;
448 WNDCLASSEXW wc = {0};
449
450 /* Store the show window value */
451 m_CmdShow = nCmdShow;
452
453 /* Setup the window class struct */
454 wc.cbSize = sizeof(WNDCLASSEXW);
455 wc.lpfnWndProc = MainWndProc;
456 wc.hInstance = g_hInstance;
457 wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCEW(IDI_MAIN_ICON));
458 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
459 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
460 wc.lpszMenuName = MAKEINTRESOURCEW(IDR_MAINMENU);
461 wc.lpszClassName = m_szMainWndClass;
462 wc.hIconSm = (HICON)LoadImage(g_hInstance,
463 MAKEINTRESOURCE(IDI_MAIN_ICON),
464 IMAGE_ICON,
465 16,
466 16,
467 LR_SHARED);
468
469 /* Register the window */
470 if (RegisterClassExW(&wc))
471 {
472 /* Create the main window and store the info pointer */
473 m_hMainWnd = CreateWindowExW(WS_EX_WINDOWEDGE,
474 m_szMainWndClass,
475 lpCaption,
476 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
477 CW_USEDEFAULT,
478 CW_USEDEFAULT,
479 600,
480 450,
481 NULL,
482 NULL,
483 g_hInstance,
484 this);
485 }
486
487 /* Return creation result */
488 return !!(m_hMainWnd);
489 }
490
491 VOID
492 CMainWindow::Uninitialize()
493 {
494 /* Unregister the window class */
495 UnregisterClassW(m_szMainWndClass, g_hInstance);
496 }
497
498 INT
499 CMainWindow::Run()
500 {
501 MSG Msg;
502
503 /* Pump the message queue */
504 while (GetMessageW(&Msg, NULL, 0, 0 ) != 0)
505 {
506 TranslateMessage(&Msg);
507 DispatchMessageW(&Msg);
508 }
509
510 return 0;
511 }