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