2 * PROJECT: ReactOS Device Manager
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/applications/mscutils/devmgmt/deviceview.cpp
5 * PURPOSE: Implements main window
6 * COPYRIGHT: Copyright 2014 Ged Murphy <gedmurphy@gmail.com>
12 #include "MainWindow.h"
15 /* DATA *****************************************************/
18 static const MENU_HINT MainMenuHintTable
[] =
21 {IDC_EXIT
, IDS_HINT_EXIT
},
24 {IDC_REFRESH
, IDS_HINT_REFRESH
},
25 {IDC_PROP
, IDS_HINT_PROP
},
27 {IDC_ABOUT
, IDS_HINT_ABOUT
},
29 {IDC_DEVBYTYPE
, IDS_HINT_DEV_BY_TYPE
},
30 {IDC_DEVBYCONN
, IDS_HINT_DEV_BY_CONN
},
31 {IDC_RESBYTYPE
, IDS_HINT_RES_BY_TYPE
},
32 {IDC_RESBYCONN
, IDS_HINT_RES_BY_TYPE
}
36 /* system menu hints */
37 static const MENU_HINT SystemMenuHintTable
[] =
39 {SC_RESTORE
, IDS_HINT_SYS_RESTORE
},
40 {SC_MOVE
, IDS_HINT_SYS_MOVE
},
41 {SC_SIZE
, IDS_HINT_SYS_SIZE
},
42 {SC_MINIMIZE
, IDS_HINT_SYS_MINIMIZE
},
43 {SC_MAXIMIZE
, IDS_HINT_SYS_MAXIMIZE
},
44 {SC_CLOSE
, IDS_HINT_SYS_CLOSE
},
48 /* PUBLIC METHODS **********************************************/
50 CMainWindow::CMainWindow(void) :
51 m_ToolbarhImageList(NULL
),
57 m_szMainWndClass
= L
"DevMgmtWndClass";
60 CMainWindow::~CMainWindow(void)
62 /* Destroy any previous list */
63 if (m_ToolbarhImageList
) ImageList_Destroy(m_ToolbarhImageList
);
67 CMainWindow::Initialize(LPCTSTR lpCaption
,
73 /* Store the show window value */
76 /* Setup the window class struct */
77 wc
.cbSize
= sizeof(WNDCLASSEXW
);
78 wc
.lpfnWndProc
= MainWndProc
;
79 wc
.hInstance
= g_hInstance
;
80 wc
.hIcon
= LoadIcon(g_hInstance
, MAKEINTRESOURCEW(IDI_MAIN_ICON
));
81 wc
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
82 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
83 wc
.lpszMenuName
= MAKEINTRESOURCEW(IDR_MAINMENU
);
84 wc
.lpszClassName
= m_szMainWndClass
;
85 wc
.hIconSm
= (HICON
)LoadImage(g_hInstance
,
86 MAKEINTRESOURCE(IDI_MAIN_ICON
),
92 /* Register the window */
93 if (RegisterClassExW(&wc
))
95 /* Create the main window and store the info pointer */
96 m_hMainWnd
= CreateWindowExW(WS_EX_WINDOWEDGE
,
99 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
110 /* Return creation result */
111 return !!(m_hMainWnd
);
115 CMainWindow::Uninitialize()
117 /* Unregister the window class */
118 UnregisterClassW(m_szMainWndClass
, g_hInstance
);
126 /* Pump the message queue */
127 while (GetMessageW(&Msg
, NULL
, 0, 0 ) != 0)
129 TranslateMessage(&Msg
);
130 DispatchMessageW(&Msg
);
137 /* PRIVATE METHODS **********************************************/
141 CMainWindow::MainWndMenuHint(WORD CmdId
,
142 const MENU_HINT
*HintArray
,
147 const MENU_HINT
*LastHint
;
148 UINT HintId
= DefHintId
;
150 LastHint
= HintArray
+ HintsCount
;
151 while (HintArray
!= LastHint
)
153 if (HintArray
->CmdId
== CmdId
)
155 HintId
= HintArray
->HintId
;
162 StatusBarLoadString(m_hStatusBar
,
171 CMainWindow::UpdateDevicesDisplay(ListDevices List
)
176 /* Set the new type*/
177 m_DeviceView
->SetDeviceListType(List
);
179 /* Get the menu item id */
182 case DevicesByType
: CheckId
= IDC_DEVBYTYPE
; break;
183 case DevicesByConnection
: CheckId
= IDC_DEVBYCONN
; break;
184 case ResourcesByType
: CheckId
= IDC_RESBYTYPE
; break;
185 case ResourcesByConnection
: CheckId
= IDC_RESBYCONN
; break;
186 default: ATLASSERT(FALSE
); break;
189 /* Set the new check item */
190 bSuccess
= CheckMenuRadioItem(m_hMenu
,
196 /* Refresh the view */
197 m_DeviceView
->Refresh();
203 CMainWindow::CreateToolBar()
205 HIMAGELIST hImageList
;
207 UINT StartResource
, EndResource
;
211 static TBBUTTON ToolbarButtons
[] =
213 {TBICON_PROP
, IDC_PROP
, TBSTATE_INDETERMINATE
, BTNS_BUTTON
, {0}, 0, 0},
214 {TBICON_REFRESH
, IDC_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0},
216 /* Add a seperator: First item for a seperator is its width in pixels */
217 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0},
220 /* Calculate the number of buttons */
221 NumButtons
= sizeof(ToolbarButtons
) / sizeof(ToolbarButtons
[0]);
223 /* Create the toolbar window */
224 m_hToolBar
= CreateWindowExW(0,
227 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
233 if (m_hToolBar
== NULL
) return FALSE
;
235 /* Don't show clipped buttons */
236 SendMessageW(m_hToolBar
,
239 TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
241 /* Set the struct size, the toobar needs this... */
242 SendMessageW(m_hToolBar
,
244 sizeof(ToolbarButtons
[0]),
247 /* Create the toolbar icon image list */
248 m_ToolbarhImageList
= ImageList_Create(16,
250 ILC_MASK
| ILC_COLOR24
,
253 if (m_ToolbarhImageList
== NULL
) return FALSE
;
255 /* Set the index endpoints */
256 StartResource
= IDB_PROP
;
257 EndResource
= IDB_REFRESH
;
259 /* Add all icons to the image list */
260 for (UINT i
= StartResource
; i
<= EndResource
; i
++)
262 /* Load the image resource */
263 hBitmap
= (HBITMAP
)LoadImage(g_hInstance
,
271 /* Add it to the image list */
272 ImageList_AddMasked(m_ToolbarhImageList
,
276 /* Delete the bitmap */
277 DeleteObject(hBitmap
);
281 /* Set the new image list */
282 hImageList
= (HIMAGELIST
)SendMessageW(m_hToolBar
,
285 (LPARAM
)m_ToolbarhImageList
);
287 /* Destroy any previous list */
288 if (hImageList
) ImageList_Destroy(hImageList
);
290 /* Add the buttons */
291 bRet
= (BOOL
)SendMessageW(m_hToolBar
,
294 (LPARAM
)ToolbarButtons
);
300 CMainWindow::CreateStatusBar()
302 INT StatWidths
[] = {110, -1}; /* widths of status bar */
305 /* Create the status bar */
306 m_hStatusBar
= CreateWindowExW(0,
309 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
312 (HMENU
)IDC_STATUSBAR
,
318 bRet
= (BOOL
)SendMessageW(m_hStatusBar
,
320 sizeof(StatWidths
) / sizeof(INT
),
328 CMainWindow::StatusBarLoadString(IN HWND hStatusBar
,
330 IN HINSTANCE hInstance
,
333 CAtlString szMessage
;
336 /* Load the string */
337 if (szMessage
.LoadStringW(hInstance
, uID
))
339 /* Send the message to the status bar */
340 bRet
= (BOOL
)SendMessageW(hStatusBar
,
343 (LPARAM
)szMessage
.GetBuffer());
350 CMainWindow::OnCreate(HWND hwnd
)
357 /* Store the window handle */
360 /* Get the menu handle */
361 m_hMenu
= GetMenu(m_hMainWnd
);
363 /* Create the toolbar */
364 if (CreateToolBar() && CreateStatusBar())
366 /* Create the device view object */
367 m_DeviceView
= new CDeviceView(m_hMainWnd
, DevicesByType
);
370 if (m_DeviceView
->Initialize())
372 UpdateDevicesDisplay(DevicesByType
);
374 /* Display the window according to the user request */
375 ShowWindow(hwnd
, m_CmdShow
);
386 CMainWindow::OnSize()
388 RECT rcClient
, rcTool
, rcStatus
;
389 INT lvHeight
, iToolHeight
, iStatusHeight
;
391 /* Autosize the toolbar */
392 SendMessage(m_hToolBar
, TB_AUTOSIZE
, 0, 0);
394 /* Get the toolbar rect and save the height */
395 GetWindowRect(m_hToolBar
, &rcTool
);
396 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
398 /* Resize the status bar */
399 SendMessage(m_hStatusBar
, WM_SIZE
, 0, 0);
401 /* Get the statusbar rect and save the height */
402 GetWindowRect(m_hStatusBar
, &rcStatus
);
403 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
405 /* Get the full client rect */
406 GetClientRect(m_hMainWnd
, &rcClient
);
408 /* Calculate the remaining height for the treeview */
409 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
411 /* Resize the device view */
412 m_DeviceView
->Size(0,
421 CMainWindow::OnNotify(LPARAM lParam
)
423 LPNMHDR NmHdr
= (LPNMHDR
)lParam
;
427 case TVN_DELETEITEMW
:
429 LPNMTREEVIEW NmTreeView
= (LPNMTREEVIEW
)lParam
;
431 NmTreeView
->action
= NmTreeView
->action
;
438 LPNM_TREEVIEW pnmtv
= (LPNM_TREEVIEW
)lParam
;
439 ListDevices ListType
= m_DeviceView
->GetDeviceListType();
441 if (ListType
== DevicesByType
)
443 if (!m_DeviceView
->HasChildItem(pnmtv
->itemNew
.hItem
))
445 SendMessage(m_hToolBar
,
448 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
450 EnableMenuItem(GetMenu(m_hMainWnd
), IDC_PROP
, MF_ENABLED
);
451 m_DeviceView
->EnableContextMenuItem(IDC_PROP
, MF_ENABLED
);
455 SendMessage(m_hToolBar
,
458 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
460 EnableMenuItem(GetMenu(m_hMainWnd
), IDC_PROP
, MF_GRAYED
);
461 m_DeviceView
->EnableContextMenuItem(IDC_PROP
, MF_GRAYED
);
464 else if (ListType
== DevicesByConnection
)
466 if (m_DeviceView
->IsRootItem(pnmtv
->itemNew
.hItem
))
468 SendMessage(m_hToolBar
,
471 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
473 EnableMenuItem(GetMenu(m_hMainWnd
), IDC_PROP
, MF_GRAYED
);
474 m_DeviceView
->EnableContextMenuItem(IDC_PROP
, MF_GRAYED
);
478 SendMessage(m_hToolBar
,
481 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
483 EnableMenuItem(GetMenu(m_hMainWnd
), IDC_PROP
, MF_ENABLED
);
484 m_DeviceView
->EnableContextMenuItem(IDC_PROP
, MF_ENABLED
);
492 m_DeviceView
->DisplayPropertySheet();
498 ListDevices ListType
= m_DeviceView
->GetDeviceListType();
499 if (ListType
== DevicesByType
)
501 m_DeviceView
->DisplayPropertySheet();
503 else if (ListType
== DevicesByConnection
)
505 if (!m_DeviceView
->IsRootItemSelected())
507 m_DeviceView
->DisplayPropertySheet();
518 CMainWindow::OnContext(LPARAM lParam
)
520 INT xPos
= GET_X_LPARAM(lParam
);
521 INT yPos
= GET_Y_LPARAM(lParam
);
523 m_DeviceView
->ShowContextMenu(xPos
, yPos
);
528 CMainWindow::OnCommand(WPARAM wParam
,
534 /* Get the message */
535 Msg
= LOWORD(wParam
);
541 /* Display the device property sheet */
542 m_DeviceView
->DisplayPropertySheet();
548 /* Refresh the device list */
549 m_DeviceView
->Refresh();
555 UpdateDevicesDisplay(DevicesByType
);
561 UpdateDevicesDisplay(DevicesByConnection
);
567 UINT CurCheckState
, NewCheckState
;
569 /* Get the current state */
570 CurCheckState
= GetMenuState(m_hMenu
, IDC_SHOWHIDDEN
, MF_BYCOMMAND
);
572 /* Inform the device view of the change */
573 if (CurCheckState
== MF_CHECKED
)
575 NewCheckState
= MF_UNCHECKED
;
576 m_DeviceView
->ShowHiddenDevices(FALSE
);
578 else if (CurCheckState
== MF_UNCHECKED
)
580 NewCheckState
= MF_CHECKED
;
581 m_DeviceView
->ShowHiddenDevices(TRUE
);
589 /* Set the new check state */
590 CheckMenuItem(m_hMenu
, IDC_SHOWHIDDEN
, MF_BYCOMMAND
| NewCheckState
);
592 /* Refresh the device view */
593 m_DeviceView
->Refresh();
599 /* Apportion blame */
600 MessageBoxW(m_hMainWnd
,
601 L
"ReactOS Device Manager\r\nCopyright Ged Murphy 2014",
603 MB_OK
| MB_APPLMODAL
);
605 /* Set focus back to the treeview */
606 m_DeviceView
->SetFocus();
612 /* Post a close message to the window */
613 PostMessageW(m_hMainWnd
,
628 CMainWindow::OnDestroy()
630 /* Uninitialize the device view */
631 m_DeviceView
->Uninitialize();
633 /* Kill the object */
637 /* Clear the user data pointer */
638 SetWindowLongPtr(m_hMainWnd
, GWLP_USERDATA
, 0);
640 /* Break the message loop */
647 CMainWindow::MainWndProc(HWND hwnd
,
655 /* Get the object pointer from window context */
656 pThis
= (CMainWindow
*)GetWindowLongPtr(hwnd
, GWLP_USERDATA
);
658 /* Check for an invalid pointer */
661 /* Check that this isn't a create message */
662 if (msg
!= WM_CREATE
)
664 /* Don't handle null info pointer */
665 goto HandleDefaultMessage
;
673 /* Get the object pointer from the create param */
674 pThis
= (CMainWindow
*)((LPCREATESTRUCT
)lParam
)->lpCreateParams
;
676 /* Store the info pointer in the window's global user data */
677 SetWindowLongPtr(hwnd
, GWLP_USERDATA
, (LONG_PTR
)pThis
);
679 /* Call the create handler */
680 RetCode
= pThis
->OnCreate(hwnd
);
686 RetCode
= pThis
->OnSize();
692 /* Handle the notify message */
693 RetCode
= pThis
->OnNotify(lParam
);
699 /* Handle creating the context menu */
700 RetCode
= pThis
->OnContext(lParam
);
706 if (pThis
->m_hStatusBar
!= NULL
)
708 if (!pThis
->MainWndMenuHint(LOWORD(wParam
),
710 sizeof(MainMenuHintTable
) / sizeof(MainMenuHintTable
[0]),
713 pThis
->MainWndMenuHint(LOWORD(wParam
),
715 sizeof(SystemMenuHintTable
) / sizeof(SystemMenuHintTable
[0]),
725 /* Handle the command message */
726 RetCode
= pThis
->OnCommand(wParam
, lParam
);
728 /* Hand it off to the default message handler */
729 goto HandleDefaultMessage
;
734 /* Destroy the main window */
741 /* Call the destroy handler */
742 RetCode
= pThis
->OnDestroy();
748 HandleDefaultMessage
:
749 RetCode
= DefWindowProc(hwnd
, msg
, wParam
, lParam
);