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