[DEVMGMT] Free this module from the devil. Addendum to r68185. Spotted by fox_anthony.
[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_DEVBYTYPE:
594 {
595 RefreshView(DevicesByType);
596 break;
597 }
598
599 case IDC_DEVBYCONN:
600 {
601 RefreshView(DevicesByConnection);
602 break;
603 }
604
605 case IDC_SHOWHIDDEN:
606 {
607 // Get the current state
608 UINT CurCheckState = GetMenuState(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND);
609 if (CurCheckState == MF_CHECKED)
610 {
611 m_DeviceView->SetHiddenDevices(false);
612 CheckMenuItem(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND | MF_UNCHECKED);
613 }
614 else if (CurCheckState == MF_UNCHECKED)
615 {
616 m_DeviceView->SetHiddenDevices(true);
617 CheckMenuItem(m_hMenu, IDC_SHOWHIDDEN, MF_BYCOMMAND | MF_CHECKED);
618 }
619 // Refresh the device view
620 m_DeviceView->Refresh(m_DeviceView->GetCurrentView(),
621 false,
622 true,
623 NULL);
624 break;
625 }
626
627 case IDC_ABOUT:
628 {
629 // Apportion blame
630 MessageBoxW(m_hMainWnd,
631 L"ReactOS Device Manager\r\nCopyright Ged Murphy 2015",
632 L"About",
633 MB_OK | MB_APPLMODAL);
634
635 // Set focus back to the treeview
636 m_DeviceView->SetFocus();
637 break;
638 }
639
640 case IDC_EXIT:
641 {
642 // Post a close message to the window
643 PostMessageW(m_hMainWnd,
644 WM_CLOSE,
645 0,
646 0);
647 break;
648 }
649
650 default:
651 // We didn't handle it
652 RetCode = -1;
653 break;
654 }
655
656 return RetCode;
657 }
658
659 LRESULT
660 CMainWindow::OnDestroy()
661 {
662 // Uninitialize the device view
663 m_DeviceView->Uninitialize();
664
665 // Kill the object
666 delete m_DeviceView;
667 m_DeviceView = NULL;
668
669 // Clear the user data pointer
670 SetWindowLongPtr(m_hMainWnd, GWLP_USERDATA, 0);
671
672 // Break the message loop
673 PostQuitMessage(0);
674
675 return 0;
676 }
677
678 LRESULT CALLBACK
679 CMainWindow::MainWndProc(HWND hwnd,
680 UINT msg,
681 WPARAM wParam,
682 LPARAM lParam)
683 {
684 CMainWindow *This;
685 LRESULT RetCode = 0;
686
687 // Get the object pointer from window context
688 This = (CMainWindow *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
689 if (This == NULL)
690 {
691 // Check that this isn't a create message
692 if (msg != WM_CREATE)
693 {
694 // Don't handle null info pointer
695 goto HandleDefaultMessage;
696 }
697 }
698
699 switch(msg)
700 {
701 case WM_CREATE:
702 {
703 // Get the object pointer from the create param
704 This = (CMainWindow *)((LPCREATESTRUCT)lParam)->lpCreateParams;
705
706 // Store the pointer in the window's global user data
707 SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)This);
708
709 // Call the create handler
710 RetCode = This->OnCreate(hwnd);
711 break;
712 }
713
714 case WM_SIZE:
715 {
716 RetCode = This->OnSize();
717 break;
718 }
719
720 case WM_NOTIFY:
721 {
722 RetCode = This->OnNotify(lParam);
723 break;
724 }
725
726 case WM_CONTEXTMENU:
727 {
728 RetCode = This->OnContext(lParam);
729 break;
730 }
731
732 case WM_MENUSELECT:
733 {
734 if (This->m_hStatusBar != NULL)
735 {
736 if (!This->MainWndMenuHint(LOWORD(wParam),
737 MainMenuHintTable,
738 sizeof(MainMenuHintTable) / sizeof(MainMenuHintTable[0]),
739 IDS_HINT_BLANK))
740 {
741 This->MainWndMenuHint(LOWORD(wParam),
742 SystemMenuHintTable,
743 sizeof(SystemMenuHintTable) / sizeof(SystemMenuHintTable[0]),
744 IDS_HINT_BLANK);
745 }
746 }
747
748 break;
749 }
750
751 case WM_COMMAND:
752 {
753 // Handle the command message
754 RetCode = This->OnCommand(wParam, lParam);
755 if (RetCode == -1)
756 {
757 // Hand it off to the default message handler
758 goto HandleDefaultMessage;
759 }
760 break;
761 }
762
763 case WM_ENTERMENULOOP:
764 {
765 This->UpdateStatusBar(true);
766 break;
767 }
768
769 case WM_EXITMENULOOP:
770 {
771 This->UpdateStatusBar(false);
772 break;
773 }
774
775 case WM_CLOSE:
776 {
777 // Destroy the main window
778 DestroyWindow(hwnd);
779 break;
780 }
781
782
783 case WM_DESTROY:
784 {
785 // Call the destroy handler
786 RetCode = This->OnDestroy();
787 break;
788 }
789
790 default:
791 {
792 HandleDefaultMessage:
793 RetCode = DefWindowProc(hwnd, msg, wParam, lParam);
794 break;
795 }
796 }
797
798 return RetCode;
799 }
800
801
802 //////// MOVE ME ////////////////
803
804 HINSTANCE g_hInstance = NULL;
805 HANDLE ProcessHeap = NULL;
806
807 BOOL
808 WINAPI
809 DeviceManager_ExecuteW(HWND hWndParent,
810 HINSTANCE hInst,
811 LPCWSTR lpMachineName,
812 int nCmdShow)
813 {
814 CMainWindow MainWindow;
815 INITCOMMONCONTROLSEX icex;
816 CAtlStringW szAppName;
817 int Ret = 1;
818
819 // Store the global values
820 g_hInstance = hInst;
821 ProcessHeap = GetProcessHeap();
822
823 // Initialize common controls
824 icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
825 icex.dwICC = ICC_BAR_CLASSES | ICC_COOL_CLASSES;
826 InitCommonControlsEx(&icex);
827
828 // Load the application name
829 if (szAppName.LoadStringW(g_hInstance, IDS_APPNAME))
830 {
831 // Initialize the main window
832 if (MainWindow.Initialize(szAppName, nCmdShow))
833 {
834 // Run the application
835 Ret = MainWindow.Run();
836
837 // Uninitialize the main window
838 MainWindow.Uninitialize();
839 }
840 }
841
842 return Ret;
843 }