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