[DEVMGR]
[reactos.git] / reactos / dll / win32 / devmgr / devmgmt / MainWindow.cpp
1 /*
2 * PROJECT: ReactOS Device Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/devmgr/devmgr/MainWindow.cpp
5 * PURPOSE: Implements the main container window for the device view
6 * COPYRIGHT: Copyright 2014 - 2015 Ged Murphy <gedmurphy@reactos.org>
7 */
8
9
10 #include "stdafx.h"
11 #include "devmgmt.h"
12 #include "MainWindow.h"
13
14
15 /* DATA *****************************************************/
16
17 #define BTN_PROPERTIES 0
18 #define BTN_SCAN_HARDWARE 1
19 #define BTN_ENABLE_DRV 2
20 #define BTN_DISABLE_DRV 3
21 #define BTN_UPDATE_DRV 4
22 #define BTN_UNINSTALL_DRV 5
23
24
25 // menu hints
26 static const MENU_HINT MainMenuHintTable[] =
27 {
28 // File Menu
29 { IDC_EXIT, IDS_HINT_EXIT },
30
31 // Action Menu
32 { IDC_PROPERTIES, IDS_HINT_PROPERTIES },
33 { IDC_SCAN_HARDWARE, IDS_HINT_SCAN },
34 { IDC_ENABLE_DRV, IDS_HINT_ENABLE },
35 { IDC_DISABLE_DRV, IDS_HINT_DISABLE },
36 { IDC_UPDATE_DRV, IDS_HINT_UPDATE },
37 { IDC_UNINSTALL_DRV, IDS_HINT_UNINSTALL },
38 { IDC_ADD_HARDWARE, IDS_HINT_ADD },
39
40
41 // View Menu
42 { IDC_DEVBYTYPE, IDS_HINT_DEV_BY_TYPE},
43 { IDC_DEVBYCONN, IDS_HINT_DEV_BY_CONN},
44 { IDC_RESBYTYPE, IDS_HINT_RES_BY_TYPE},
45 { IDC_RESBYCONN, IDS_HINT_RES_BY_TYPE},
46 { IDC_SHOWHIDDEN, IDS_HINT_SHOW_HIDDEN },
47
48 { IDC_ABOUT, IDS_HINT_ABOUT }
49
50 };
51
52
53 // system menu hints
54 static const MENU_HINT SystemMenuHintTable[] =
55 {
56 {SC_RESTORE, IDS_HINT_SYS_RESTORE},
57 {SC_MOVE, IDS_HINT_SYS_MOVE},
58 {SC_SIZE, IDS_HINT_SYS_SIZE},
59 {SC_MINIMIZE, IDS_HINT_SYS_MINIMIZE},
60 {SC_MAXIMIZE, IDS_HINT_SYS_MAXIMIZE},
61 {SC_CLOSE, IDS_HINT_SYS_CLOSE},
62 };
63
64 static TBBUTTON TbButtons[] =
65 {
66 { BTN_PROPERTIES, IDC_PROPERTIES, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
67 { BTN_SCAN_HARDWARE, IDC_SCAN_HARDWARE, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
68 { 2, IDC_STATIC, TBSTATE_ENABLED, BTNS_SEP, 0, 0 },
69 { BTN_ENABLE_DRV, IDC_ENABLE_DRV, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
70 { BTN_DISABLE_DRV, IDC_DISABLE_DRV, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
71 { BTN_UPDATE_DRV, IDC_UPDATE_DRV, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 },
72 { BTN_UNINSTALL_DRV, IDC_UNINSTALL_DRV, TBSTATE_ENABLED, BTNS_BUTTON, 0, 0 }
73 };
74
75
76 /* PUBLIC METHODS **********************************************/
77
78 CMainWindow::CMainWindow(void) :
79 m_ToolbarhImageList(NULL),
80 m_hMainWnd(NULL),
81 m_hStatusBar(NULL),
82 m_hToolBar(NULL),
83 m_CmdShow(0)
84 {
85 m_szMainWndClass = L"DevMgmtWndClass";
86 }
87
88 CMainWindow::~CMainWindow(void)
89 {
90 // Destroy any previous list
91 if (m_ToolbarhImageList) ImageList_Destroy(m_ToolbarhImageList);
92 }
93
94 bool
95 CMainWindow::Initialize(LPCTSTR lpCaption,
96 int nCmdShow)
97 {
98 CAtlStringW szCaption;
99 WNDCLASSEXW wc = {0};
100
101 // Store the show window value
102 m_CmdShow = nCmdShow;
103
104 // Setup the window class struct
105 wc.cbSize = sizeof(WNDCLASSEXW);
106 wc.lpfnWndProc = MainWndProc;
107 wc.hInstance = g_hInstance;
108 wc.hIcon = LoadIcon(g_hInstance, MAKEINTRESOURCEW(IDI_MAIN_ICON));
109 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
110 wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
111 wc.lpszMenuName = MAKEINTRESOURCEW(IDR_MAINMENU);
112 wc.lpszClassName = m_szMainWndClass;
113 wc.hIconSm = (HICON)LoadImage(g_hInstance,
114 MAKEINTRESOURCE(IDI_MAIN_ICON),
115 IMAGE_ICON,
116 16,
117 16,
118 LR_SHARED);
119
120 // Register the window
121 if (RegisterClassExW(&wc))
122 {
123 // Create the main window and store the object pointer
124 m_hMainWnd = CreateWindowExW(WS_EX_WINDOWEDGE,
125 m_szMainWndClass,
126 lpCaption,
127 WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
128 CW_USEDEFAULT,
129 CW_USEDEFAULT,
130 550,
131 500,
132 NULL,
133 NULL,
134 g_hInstance,
135 this);
136 }
137
138 // Return creation result
139 return !!(m_hMainWnd);
140 }
141
142 void
143 CMainWindow::Uninitialize()
144 {
145 // Unregister the window class
146 UnregisterClassW(m_szMainWndClass, g_hInstance);
147 }
148
149 int
150 CMainWindow::Run()
151 {
152 MSG Msg;
153
154 // Pump the message queue
155 while (GetMessageW(&Msg, NULL, 0, 0 ) != 0)
156 {
157 TranslateMessage(&Msg);
158 DispatchMessageW(&Msg);
159 }
160
161 return 0;
162 }
163
164
165 /* PRIVATE METHODS **********************************************/
166
167 bool
168 CMainWindow::MainWndMenuHint(WORD CmdId,
169 const MENU_HINT *HintArray,
170 DWORD HintsCount,
171 UINT DefHintId)
172 {
173 bool Found = false;
174 const MENU_HINT *LastHint;
175 UINT HintId = DefHintId;
176
177 LastHint = HintArray + HintsCount;
178 while (HintArray != LastHint)
179 {
180 if (HintArray->CmdId == CmdId)
181 {
182 HintId = HintArray->HintId;
183 Found = true;
184 break;
185 }
186 HintArray++;
187 }
188
189 StatusBarLoadString(m_hStatusBar,
190 SB_SIMPLEID,
191 g_hInstance,
192 HintId);
193
194 return Found;
195 }
196
197 void
198 CMainWindow::UpdateStatusBar(
199 _In_ bool InMenuLoop
200 )
201 {
202 SendMessageW(m_hStatusBar,
203 SB_SIMPLE,
204 (WPARAM)InMenuLoop,
205 0);
206 }
207
208 bool
209 CMainWindow::RefreshView(ViewType Type)
210 {
211 UINT CheckId;
212 BOOL bSuccess;
213
214 // Refreshed the cached view
215 m_DeviceView->Refresh(Type, FALSE, TRUE, NULL);
216
217 // Get the menu item id
218 switch (Type)
219 {
220 case DevicesByType: CheckId = IDC_DEVBYTYPE; break;
221 case DevicesByConnection: CheckId = IDC_DEVBYCONN; break;
222 case ResourcesByType: CheckId = IDC_RESBYTYPE; break;
223 case ResourcesByConnection: CheckId = IDC_RESBYCONN; break;
224 default: ATLASSERT(FALSE); break;
225 }
226
227 // Set the new check item
228 bSuccess = CheckMenuRadioItem(m_hMenu,
229 IDC_DEVBYTYPE,
230 IDC_RESBYCONN,
231 CheckId,
232 MF_BYCOMMAND);
233
234 return TRUE;
235 }
236
237 bool
238 CMainWindow::ScanForHardwareChanges()
239 {
240 // Refresh the cache and and display
241 m_DeviceView->Refresh(m_DeviceView->GetCurrentView(),
242 true,
243 true,
244 NULL);
245 return true;
246 }
247
248 bool
249 CMainWindow::CreateToolBar()
250 {
251 TBADDBITMAP TbAddBitmap;
252 INT Index;
253
254 DWORD dwStyles = WS_CHILDWINDOW | TBSTYLE_FLAT | TBSTYLE_WRAPABLE | TBSTYLE_TOOLTIPS | CCS_NODIVIDER;
255 DWORD dwExStyles = WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR;
256
257 // Create the toolbar window
258 m_hToolBar = CreateWindowExW(dwExStyles,
259 TOOLBARCLASSNAME,
260 NULL,
261 dwStyles,
262 0, 0, 0, 0,
263 m_hMainWnd,
264 (HMENU)IDC_TOOLBAR,
265 g_hInstance,
266 NULL);
267 if (m_hToolBar == NULL) return FALSE;
268
269 // Don't show clipped buttons
270 SendMessageW(m_hToolBar,
271 TB_SETEXTENDEDSTYLE,
272 0,
273 TBSTYLE_EX_HIDECLIPPEDBUTTONS);
274
275 SendMessageW(m_hToolBar, TB_SETBITMAPSIZE, 0, MAKELONG(16, 16));
276
277 // Set the struct size, the toobar needs this...
278 SendMessageW(m_hToolBar,
279 TB_BUTTONSTRUCTSIZE,
280 sizeof(TBBUTTON),
281 0);
282
283 TbAddBitmap.hInst = g_hInstance;
284 TbAddBitmap.nID = IDB_TOOLBAR;
285 Index = SendMessageW(m_hToolBar, TB_ADDBITMAP, _countof(TbButtons), (LPARAM)&TbAddBitmap);
286
287 SendMessageW(m_hToolBar, TB_ADDBUTTONSW, _countof(TbButtons), (LPARAM)TbButtons);
288 SendMessageW(m_hToolBar, TB_AUTOSIZE, 0, 0);
289
290 if (TRUE)
291 {
292 ShowWindow(m_hToolBar, SW_SHOW);
293 }
294
295 return TRUE;
296 }
297
298 bool
299 CMainWindow::CreateStatusBar()
300 {
301 int StatWidths[] = {110, -1}; // widths of status bar
302 bool bRet = FALSE;
303
304 // Create the status bar
305 m_hStatusBar = CreateWindowExW(0,
306 STATUSCLASSNAME,
307 NULL,
308 WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
309 0, 0, 0, 0,
310 m_hMainWnd,
311 (HMENU)IDC_STATUSBAR,
312 g_hInstance,
313 NULL);
314 if (m_hStatusBar)
315 {
316 // Set the width
317 bRet = (SendMessageW(m_hStatusBar,
318 SB_SETPARTS,
319 sizeof(StatWidths) / sizeof(int),
320 (LPARAM)StatWidths) != 0);
321 }
322
323 return bRet;
324 }
325
326 void CMainWindow::UpdateUiContext(_In_ LPTV_ITEMW TvItem)
327 {
328 WORD State;
329
330 // properties button
331 if (m_DeviceView->HasProperties(TvItem))
332 {
333 State = TBSTATE_ENABLED;
334 }
335 else
336 {
337 State = TBSTATE_HIDDEN;
338 }
339 SendMessageW(m_hToolBar, TB_SETSTATE, IDC_PROPERTIES, MAKELPARAM(State, 0));
340 SendMessageW(m_hToolBar, TB_SETSTATE, IDC_UPDATE_DRV, MAKELPARAM(State, 0)); //hack
341 SendMessageW(m_hToolBar, TB_SETSTATE, IDC_UNINSTALL_DRV, MAKELPARAM(State, 0)); // hack
342
343 // enable driver button
344 if (m_DeviceView->IsDisabled(TvItem))
345 {
346 State = TBSTATE_ENABLED;
347 }
348 else
349 {
350 State = TBSTATE_HIDDEN;
351 }
352 SendMessageW(m_hToolBar, TB_SETSTATE, IDC_ENABLE_DRV, MAKELPARAM(State, 0));
353
354 // disable driver button
355 if (m_DeviceView->CanDisable(TvItem) && !m_DeviceView->IsDisabled(TvItem))
356 {
357 State = TBSTATE_ENABLED;
358 }
359 else
360 {
361 State = TBSTATE_HIDDEN;
362 }
363 SendMessageW(m_hToolBar, TB_SETSTATE, IDC_DISABLE_DRV, MAKELPARAM(State, 0));
364
365
366
367
368
369 }
370
371
372
373 bool
374 CMainWindow::StatusBarLoadString(IN HWND hStatusBar,
375 IN INT PartId,
376 IN HINSTANCE hInstance,
377 IN UINT uID)
378 {
379 CAtlStringW szMessage;
380 bool bRet = false;
381
382 // Load the string
383 if (szMessage.LoadStringW(hInstance, uID))
384 {
385 // Show the string on the status bar
386 bRet = (SendMessageW(hStatusBar,
387 SB_SETTEXT,
388 (WPARAM)PartId,
389 (LPARAM)szMessage.GetBuffer()) != 0);
390 }
391
392 return bRet;
393 }
394
395 LRESULT
396 CMainWindow::OnCreate(HWND hwnd)
397 {
398 LRESULT RetCode;
399
400 RetCode = -1;
401 m_hMainWnd = hwnd;
402
403 // Store a handle to the main menu
404 m_hMenu = GetMenu(m_hMainWnd);
405
406 // Create the toolbar and statusbar
407 if (CreateToolBar() && CreateStatusBar())
408 {
409 // Create the device view object
410 m_DeviceView = new CDeviceView(m_hMainWnd);
411 if (m_DeviceView->Initialize())
412 {
413 // Do the initial scan
414 ScanForHardwareChanges();
415
416 // Display the window according to the user request
417 ShowWindow(hwnd, m_CmdShow);
418 RetCode = 0;
419 }
420 }
421
422 return RetCode;
423 }
424
425 LRESULT
426 CMainWindow::OnSize()
427 {
428 RECT rcClient, rcTool, rcStatus;
429 INT lvHeight, iToolHeight, iStatusHeight;
430
431 // Autosize the toolbar
432 SendMessage(m_hToolBar, TB_AUTOSIZE, 0, 0);
433
434 // Get the toolbar rect and save the height
435 GetWindowRect(m_hToolBar, &rcTool);
436 iToolHeight = rcTool.bottom - rcTool.top;
437
438 // Resize the status bar
439 SendMessage(m_hStatusBar, WM_SIZE, 0, 0);
440
441 // Get the statusbar rect and save the height
442 GetWindowRect(m_hStatusBar, &rcStatus);
443 iStatusHeight = rcStatus.bottom - rcStatus.top;
444
445 // Get the full client rect
446 GetClientRect(m_hMainWnd, &rcClient);
447
448 // Calculate the remaining height for the treeview
449 lvHeight = rcClient.bottom - iToolHeight - iStatusHeight;
450
451 // Resize the device view
452 m_DeviceView->OnSize(0,
453 iToolHeight,
454 rcClient.right,
455 lvHeight);
456
457 return 0;
458 }
459
460 LRESULT
461 CMainWindow::OnNotify(LPARAM lParam)
462 {
463 LPNMHDR NmHdr = (LPNMHDR)lParam;
464 LRESULT Ret;
465
466 switch (NmHdr->code)
467 {
468 case TVN_SELCHANGED:
469 {
470 LPNMTREEVIEW NmTreeView = (LPNMTREEVIEW)lParam;
471 UpdateUiContext(&NmTreeView->itemNew);
472 break;
473 }
474
475 case NM_DBLCLK:
476 {
477 LPNMTREEVIEW NmTreeView = (LPNMTREEVIEW)lParam;
478 m_DeviceView->DisplayPropertySheet();
479 break;
480 }
481
482 case NM_RCLICK:
483 {
484 Ret = m_DeviceView->OnRightClick(NmHdr);
485 break;
486 }
487
488 case NM_RETURN:
489 {
490 m_DeviceView->DisplayPropertySheet();
491 break;
492 }
493
494 case TTN_GETDISPINFO:
495 {
496 LPTOOLTIPTEXT lpttt = (LPTOOLTIPTEXT)lParam;
497
498 UINT_PTR idButton = lpttt->hdr.idFrom;
499 switch (idButton)
500 {
501 case IDC_PROPERTIES:
502 lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_PROPERTIES);
503 break;
504 case IDC_SCAN_HARDWARE:
505 lpttt->lpszText = MAKEINTRESOURCEW(IDS_TOOLTIP_SCAN);
506 break;
507 case IDC_ENABLE_DRV:
508 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_ENABLE);
509 break;
510 case IDC_DISABLE_DRV:
511 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_DISABLE);
512 break;
513 case IDC_UPDATE_DRV:
514 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_UPDATE);
515 break;
516 case IDC_UNINSTALL_DRV:
517 lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_UNINSTALL);
518 break;
519 }
520 break;
521 }
522 }
523
524 return 0;
525 }
526
527 LRESULT
528 CMainWindow::OnContext(LPARAM lParam)
529 {
530 return m_DeviceView->OnContextMenu(lParam);
531 }
532
533 LRESULT
534 CMainWindow::OnCommand(WPARAM wParam,
535 LPARAM lParam)
536 {
537 LRESULT RetCode = 0;
538 WORD Msg;
539
540 // Get the message
541 Msg = LOWORD(wParam);
542
543 switch (Msg)
544 {
545 case IDC_PROPERTIES:
546 {
547 m_DeviceView->DisplayPropertySheet();
548 break;
549 }
550
551 case IDC_SCAN_HARDWARE:
552 {
553 ScanForHardwareChanges();
554 break;
555 }
556
557 case IDC_ENABLE_DRV:
558 {
559 bool NeedsReboot;
560 if (m_DeviceView->EnableSelectedDevice(true, NeedsReboot) &&
561 NeedsReboot)
562 {
563 MessageBox(m_hMainWnd, L"Rebooting", L"Enable", MB_OK);
564 }
565 break;
566 }
567
568 case IDC_DISABLE_DRV:
569 {
570 bool NeedsReboot;
571 m_DeviceView->EnableSelectedDevice(false, NeedsReboot);
572 break;
573 }
574
575 case IDC_UPDATE_DRV:
576 {
577 MessageBox(m_hMainWnd, L"Not yet implemented", L"Update Driver", MB_OK);
578 break;
579 }
580
581 case IDC_UNINSTALL_DRV:
582 {
583 MessageBox(m_hMainWnd, L"Not yet implemented", L"Uninstall Driver", MB_OK);
584 break;
585 }
586
587 case IDC_ADD_HARDWARE:
588 {
589 MessageBox(m_hMainWnd, L"Not yet implemented", L"Add Hardware", MB_OK);
590 break;
591 }
592
593 case IDC_ACTIONMENU:
594 {
595 // Create a popup menu with all the actions for the selected node
596 HMENU hMenu = CreatePopupMenu();
597 m_DeviceView->CreateActionMenu(hMenu, true);
598
599 RECT rc;
600 GetMenuItemRect(m_hMainWnd, m_hMenu, 1, &rc);
601
602 LONG Height = rc.bottom - rc.top;
603
604 // Display the menu
605 TrackPopupMenuEx(hMenu,
606 TPM_RIGHTBUTTON,
607 rc.left,
608 rc.top + Height,
609 m_hMainWnd,
610 NULL);
611
612 DestroyMenu(hMenu);
613 break;
614 }
615
616 case IDC_DEVBYTYPE:
617 {
618 RefreshView(DevicesByType);
619 break;
620 }
621
622 case IDC_DEVBYCONN:
623 {
624 RefreshView(DevicesByConnection);
625 break;
626 }
627
628 case IDC_SHOWHIDDEN:
629 {
630 // Get the current state
631 UINT CurCheckState = GetMenuState(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND);
632 if (CurCheckState == MF_CHECKED)
633 {
634 m_DeviceView->SetHiddenDevices(false);
635 CheckMenuItem(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND | MF_UNCHECKED);
636 }
637 else if (CurCheckState == MF_UNCHECKED)
638 {
639 m_DeviceView->SetHiddenDevices(true);
640 CheckMenuItem(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND | MF_CHECKED);
641 }
642 // Refresh the device view
643 m_DeviceView->Refresh(m_DeviceView->GetCurrentView(),
644 false,
645 true,
646 NULL);
647 break;
648 }
649
650 case IDC_ABOUT:
651 {
652 // Apportion blame
653 MessageBoxW(m_hMainWnd,
654 L"ReactOS Device Manager\r\nCopyright Ged Murphy 2015",
655 L"About",
656 MB_OK | MB_APPLMODAL);
657
658 // Set focus back to the treeview
659 m_DeviceView->SetFocus();
660 break;
661 }
662
663 case IDC_EXIT:
664 {
665 // Post a close message to the window
666 PostMessageW(m_hMainWnd,
667 WM_CLOSE,
668 0,
669 0);
670 break;
671 }
672
673 default:
674 // We didn't handle it
675 RetCode = -1;
676 break;
677 }
678
679 return RetCode;
680 }
681
682 LRESULT
683 CMainWindow::OnDestroy()
684 {
685 // Uninitialize the device view
686 m_DeviceView->Uninitialize();
687
688 // Kill the object
689 delete m_DeviceView;
690 m_DeviceView = NULL;
691
692 // Clear the user data pointer
693 SetWindowLongPtr(m_hMainWnd, GWLP_USERDATA, 0);
694
695 // Break the message loop
696 PostQuitMessage(0);
697
698 return 0;
699 }
700
701 LRESULT CALLBACK
702 CMainWindow::MainWndProc(HWND hwnd,
703 UINT msg,
704 WPARAM wParam,
705 LPARAM lParam)
706 {
707 CMainWindow *This;
708 LRESULT RetCode = 0;
709
710 // Get the object pointer from window context
711 This = (CMainWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
712 if (This == NULL)
713 {
714 // Check that this isn't a create message
715 if (msg != WM_CREATE)
716 {
717 // Don't handle null info pointer
718 goto HandleDefaultMessage;
719 }
720 }
721
722 switch(msg)
723 {
724 case WM_CREATE:
725 {
726 // Get the object pointer from the create param
727 This = (CMainWindow *)((LPCREATESTRUCT)lParam)->lpCreateParams;
728
729 // Store the pointer in the window's global user data
730 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)This);
731
732 // Call the create handler
733 RetCode = This->OnCreate(hwnd);
734 break;
735 }
736
737 case WM_SIZE:
738 {
739 RetCode = This->OnSize();
740 break;
741 }
742
743 case WM_NOTIFY:
744 {
745 RetCode = This->OnNotify(lParam);
746 break;
747 }
748
749 case WM_CONTEXTMENU:
750 {
751 RetCode = This->OnContext(lParam);
752 break;
753 }
754
755 case WM_MENUSELECT:
756 {
757 if (This->m_hStatusBar != NULL)
758 {
759 if (!This->MainWndMenuHint(LOWORD(wParam),
760 MainMenuHintTable,
761 sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
762 IDS_HINT_BLANK))
763 {
764 This->MainWndMenuHint(LOWORD(wParam),
765 SystemMenuHintTable,
766 sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
767 IDS_HINT_BLANK);
768 }
769 }
770
771 break;
772 }
773
774 case WM_COMMAND:
775 {
776 // Handle the command message
777 RetCode = This->OnCommand(wParam, lParam);
778 if (RetCode == -1)
779 {
780 // Hand it off to the default message handler
781 goto HandleDefaultMessage;
782 }
783 break;
784 }
785
786 case WM_ENTERMENULOOP:
787 {
788 This->UpdateStatusBar(true);
789 break;
790 }
791
792 case WM_EXITMENULOOP:
793 {
794 This->UpdateStatusBar(false);
795 break;
796 }
797
798 case WM_CLOSE:
799 {
800 // Destroy the main window
801 DestroyWindow(hwnd);
802 break;
803 }
804
805
806 case WM_DESTROY:
807 {
808 // Call the destroy handler
809 RetCode = This->OnDestroy();
810 break;
811 }
812
813 default:
814 {
815 HandleDefaultMessage:
816 RetCode = DefWindowProc(hwnd, msg, wParam, lParam);
817 break;
818 }
819 }
820
821 return RetCode;
822 }
823
824
825 //////// MOVE ME ////////////////
826
827 HINSTANCE g_hInstance = NULL;
828 HANDLE ProcessHeap = NULL;
829
830 BOOL
831 WINAPI
832 DeviceManager_ExecuteW(HWND hWndParent,
833 HINSTANCE hInst,
834 LPCWSTR lpMachineName,
835 int nCmdShow)
836 {
837 CMainWindow MainWindow;
838 INITCOMMONCONTROLSEX icex;
839 CAtlStringW szAppName;
840 int Ret = 1;
841
842 // Store the global values
843 g_hInstance = hInst;
844 ProcessHeap = GetProcessHeap();
845
846 // Initialize common controls
847 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
848 icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
849 InitCommonControlsEx(&icex);
850
851 // Load the application name
852 if (szAppName.LoadStringW(g_hInstance, IDS_APPNAME))
853 {
854 // Initialize the main window
855 if (MainWindow.Initialize(szAppName, nCmdShow))
856 {
857 // Run the application
858 Ret = MainWindow.Run();
859
860 // Uninitialize the main window
861 MainWindow.Uninitialize();
862 }
863 }
864
865 return Ret;
866 }