2 * PROJECT: ReactOS Device Managment
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/devmgmt/mainwnd.c
5 * PURPOSE: Main window message handler
6 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
14 static BOOL
pCreateToolbar(PMAIN_WND_INFO Info
);
16 static const TCHAR szMainWndClass
[] = TEXT("DevMgmtWndClass");
21 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
22 {TBICON_PROP
, IDC_PROP
, TBSTATE_INDETERMINATE
, BTNS_BUTTON
, {0}, 0, 0}, /* properties */
23 {TBICON_REFRESH
, IDC_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0}, /* refresh */
25 /* Note: First item for a seperator is its width in pixels */
26 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0}, /* separator */
28 {TBICON_HELP
, IDC_PROGHELP
,TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0 }, /* help */
29 {TBICON_EXIT
, IDC_EXIT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0 }, /* exit */
35 static const MENU_HINT MainMenuHintTable
[] = {
37 {IDC_EXIT
, IDS_HINT_EXIT
},
40 {IDC_REFRESH
, IDS_HINT_REFRESH
},
41 {IDC_PROP
, IDS_HINT_PROP
},
44 {IDC_PROGHELP
, IDS_HINT_HELP
},
45 {IDC_ABOUT
, IDS_HINT_ABOUT
}
48 /* system menu hints */
49 static const MENU_HINT SystemMenuHintTable
[] = {
50 {SC_RESTORE
, IDS_HINT_SYS_RESTORE
},
51 {SC_MOVE
, IDS_HINT_SYS_MOVE
},
52 {SC_SIZE
, IDS_HINT_SYS_SIZE
},
53 {SC_MINIMIZE
, IDS_HINT_SYS_MINIMIZE
},
54 {SC_MAXIMIZE
, IDS_HINT_SYS_MAXIMIZE
},
55 {SC_CLOSE
, IDS_HINT_SYS_CLOSE
},
60 MainWndMenuHint(PMAIN_WND_INFO Info
,
62 const MENU_HINT
*HintArray
,
67 const MENU_HINT
*LastHint
;
68 UINT HintId
= DefHintId
;
70 LastHint
= HintArray
+ HintsCount
;
71 while (HintArray
!= LastHint
)
73 if (HintArray
->CmdId
== CmdId
)
75 HintId
= HintArray
->HintId
;
82 StatusBarLoadString(Info
->hStatus
,
92 UpdateMainStatusBar(PMAIN_WND_INFO Info
)
94 if (Info
->hStatus
!= NULL
)
96 SendMessage(Info
->hStatus
,
98 (WPARAM
)Info
->InMenuLoop
,
105 pCreateToolbar(PMAIN_WND_INFO Info
)
107 INT NumButtons
= sizeof(Buttons
) / sizeof(Buttons
[0]);
109 Info
->hTool
= CreateWindowEx(0,
112 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
118 if(Info
->hTool
!= NULL
)
120 HIMAGELIST hImageList
;
122 SendMessage(Info
->hTool
,
125 TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
127 SendMessage(Info
->hTool
,
132 hImageList
= InitImageList(IDB_PROP
,
136 if (hImageList
== NULL
)
139 ImageList_Destroy((HIMAGELIST
)SendMessage(Info
->hTool
,
142 (LPARAM
)hImageList
));
144 SendMessage(Info
->hTool
,
157 CreateTreeView(PMAIN_WND_INFO Info
)
159 Info
->hTreeView
= CreateWindowEx(WS_EX_CLIENTEDGE
,
162 WS_CHILD
| WS_VISIBLE
| WS_BORDER
| TVS_HASLINES
|
163 TVS_HASBUTTONS
| TVS_SHOWSELALWAYS
| TVS_LINESATROOT
,
169 if (Info
->hTreeView
== NULL
)
171 DisplayString(_T("Could not create TreeView."));
179 CreateStatusBar(PMAIN_WND_INFO Info
)
181 INT StatWidths
[] = {110, -1}; /* widths of status bar */
183 Info
->hStatus
= CreateWindowEx(0,
186 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
189 (HMENU
)IDC_STATUSBAR
,
192 if(Info
->hStatus
== NULL
)
196 SendMessage(Info
->hStatus
,
198 sizeof(StatWidths
) / sizeof(INT
),
206 DeviceEnumThread(LPVOID lpParameter
)
211 Info
= (PMAIN_WND_INFO
)lpParameter
;
214 FreeDeviceStrings(Info
->hTreeView
);
216 hRoot
= InitTreeView(Info
->hTreeView
);
219 switch (Info
->Display
)
222 ListDevicesByType(Info
->hTreeView
, hRoot
, Info
->bShowHidden
);
225 case DevicesByConnection
:
226 ListDevicesByConnection(Info
->hTreeView
, hRoot
, Info
->bShowHidden
);
240 UpdateViewMenu(PMAIN_WND_INFO Info
)
242 UINT id
= IDC_DEVBYTYPE
;
245 hMenu
= GetMenu(Info
->hMainWnd
);
247 switch (Info
->Display
)
252 case DevicesByConnection
:
255 case RessourcesByType
:
258 case RessourcesByConnection
:
263 CheckMenuRadioItem(hMenu
,
271 MF_BYCOMMAND
| (Info
->bShowHidden
? MF_CHECKED
: MF_UNCHECKED
));
276 InitMainWnd(PMAIN_WND_INFO Info
)
278 HANDLE DevEnumThread
;
281 if (!pCreateToolbar(Info
))
282 DisplayString(_T("error creating toolbar"));
284 if (!CreateTreeView(Info
))
286 DisplayString(_T("error creating list view"));
290 if (!CreateStatusBar(Info
))
291 DisplayString(_T("error creating status bar"));
293 UpdateViewMenu(Info
);
295 /* make 'properties' bold */
296 hMenu
= GetMenu(Info
->hMainWnd
);
297 hMenu
= GetSubMenu(hMenu
, 1);
298 SetMenuDefaultItem(hMenu
, IDC_PROP
, FALSE
);
300 /* Create Popup Menu */
301 Info
->hShortcutMenu
= LoadMenu(hInstance
,
302 MAKEINTRESOURCE(IDR_POPUP
));
303 Info
->hShortcutMenu
= GetSubMenu(Info
->hShortcutMenu
,
305 SetMenuDefaultItem(Info
->hShortcutMenu
, IDC_PROP
, FALSE
);
307 /* create separate thread to emum devices */
308 DevEnumThread
= CreateThread(NULL
,
316 DisplayString(_T("Failed to enumerate devices"));
320 CloseHandle(DevEnumThread
);
326 OnContext(PMAIN_WND_INFO Info
,
333 INT xPos
= GET_X_LPARAM(lParam
);
334 INT yPos
= GET_Y_LPARAM(lParam
);
336 hSelected
= TreeView_GetSelection(Info
->hTreeView
);
338 if (TreeView_GetItemRect(Info
->hTreeView
,
343 if (GetCursorPos(&pt
) &&
344 ScreenToClient(Info
->hTreeView
, &pt
) &&
347 TrackPopupMenuEx(Info
->hShortcutMenu
,
359 OnNotify(PMAIN_WND_INFO Info
,
362 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
365 switch (pnmhdr
->code
)
369 LPNM_TREEVIEW pnmtv
= (LPNM_TREEVIEW
)lParam
;
371 if (Info
->Display
== DevicesByType
)
373 if (!TreeView_GetChild(Info
->hTreeView
,
374 pnmtv
->itemNew
.hItem
))
376 SendMessage(Info
->hTool
,
379 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
381 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_ENABLED
);
382 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_ENABLED
);
386 SendMessage(Info
->hTool
,
389 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
391 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
392 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
395 else if (Info
->Display
== DevicesByConnection
)
397 if (pnmtv
->itemNew
.hItem
== TreeView_GetRoot(Info
->hTreeView
))
399 SendMessage(Info
->hTool
,
402 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
404 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
405 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
409 SendMessage(Info
->hTool
,
412 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
414 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_ENABLED
);
415 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_ENABLED
);
423 HTREEITEM hSelected
= TreeView_GetSelection(Info
->hTreeView
);
424 if (Info
->Display
== DevicesByType
)
426 OpenPropSheet(Info
->hTreeView
, hSelected
);
428 else if (Info
->Display
== DevicesByConnection
)
430 if (hSelected
!= TreeView_GetRoot(Info
->hTreeView
))
432 OpenPropSheet(Info
->hTreeView
, hSelected
);
440 HTREEITEM hSelected
= TreeView_GetSelection(Info
->hTreeView
);
441 TV_HITTESTINFO HitTest
;
443 if (Info
->Display
== DevicesByType
)
445 if (!TreeView_GetChild(Info
->hTreeView
,
448 if (GetCursorPos(&HitTest
.pt
) &&
449 ScreenToClient(Info
->hTreeView
, &HitTest
.pt
))
451 if (TreeView_HitTest(Info
->hTreeView
, &HitTest
))
453 if (HitTest
.hItem
== hSelected
)
455 OpenPropSheet(Info
->hTreeView
,
463 else if (Info
->Display
== DevicesByConnection
)
465 if (hSelected
!= TreeView_GetRoot(Info
->hTreeView
))
467 if (GetCursorPos(&HitTest
.pt
) &&
468 ScreenToClient(Info
->hTreeView
, &HitTest
.pt
))
470 if (TreeView_HitTest(Info
->hTreeView
, &HitTest
))
472 if (HitTest
.hItem
== hSelected
)
474 OpenPropSheet(Info
->hTreeView
,
487 TV_HITTESTINFO HitTest
;
489 if (GetCursorPos(&HitTest
.pt
) &&
490 ScreenToClient(Info
->hTreeView
, &HitTest
.pt
))
492 if (TreeView_HitTest(Info
->hTreeView
, &HitTest
))
493 (void)TreeView_SelectItem(Info
->hTreeView
, HitTest
.hItem
);
498 case TTN_GETDISPINFO
:
503 lpttt
= (LPTOOLTIPTEXT
)lParam
;
505 idButton
= (UINT
)lpttt
->hdr
.idFrom
;
509 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PROP
);
513 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
517 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_HELP
);
521 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXIT
);
533 OnRefresh(PMAIN_WND_INFO Info
)
535 HANDLE DevEnumThread
;
537 SendMessage(Info
->hTool
,
540 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
542 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
543 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
545 /* create seperate thread to emum devices */
546 DevEnumThread
= CreateThread(NULL
,
554 DisplayString(_T("Failed to enumerate devices"));
558 CloseHandle(DevEnumThread
);
563 MainWndCommand(PMAIN_WND_INFO Info
,
567 UNREFERENCED_PARAMETER(hControl
);
573 HTREEITEM hSelected
= TreeView_GetSelection(Info
->hTreeView
);
574 OpenPropSheet(Info
->hTreeView
,
587 DisplayString(_T("Help is not yet implemented\n"));
588 SetFocus(Info
->hTreeView
);
594 PostMessage(Info
->hMainWnd
,
604 MAKEINTRESOURCE(IDD_ABOUTBOX
),
608 SetFocus(Info
->hTreeView
);
614 Info
->Display
= DevicesByType
;
615 UpdateViewMenu(Info
);
622 Info
->Display
= DevicesByConnection
;
623 UpdateViewMenu(Info
);
630 Info
->bShowHidden
= !Info
->bShowHidden
;
631 UpdateViewMenu(Info
);
640 MainWndResize(PMAIN_WND_INFO Info
,
644 RECT rcClient
, rcTool
, rcStatus
;
645 int lvHeight
, iToolHeight
, iStatusHeight
;
647 /* Size toolbar and get height */
648 SendMessage(Info
->hTool
, TB_AUTOSIZE
, 0, 0);
649 GetWindowRect(Info
->hTool
, &rcTool
);
650 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
652 /* Size status bar and get height */
653 SendMessage(Info
->hStatus
, WM_SIZE
, 0, 0);
654 GetWindowRect(Info
->hStatus
, &rcStatus
);
655 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
657 /* Calculate remaining height and size list view */
658 GetClientRect(Info
->hMainWnd
, &rcClient
);
659 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
660 SetWindowPos(Info
->hTreeView
,
670 static LRESULT CALLBACK
671 MainWndProc(HWND hwnd
,
679 /* Get the window context */
680 Info
= (PMAIN_WND_INFO
)GetWindowLongPtr(hwnd
,
682 if (Info
== NULL
&& msg
!= WM_CREATE
)
684 goto HandleDefaultMessage
;
691 Info
= (PMAIN_WND_INFO
)(((LPCREATESTRUCT
)lParam
)->lpCreateParams
);
693 /* Initialize the main window context */
694 Info
->hMainWnd
= hwnd
;
696 SetWindowLongPtr(hwnd
,
700 if (!InitMainWnd(Info
))
701 SendMessage(hwnd
, WM_CLOSE
, 0, 0);
703 /* Show the window */
711 if (Info
->hTreeView
!= NULL
)
712 SetFocus(Info
->hTreeView
);
726 Ret
= OnNotify(Info
, lParam
);
732 OnContext(Info
, lParam
);
741 goto HandleDefaultMessage
;
746 if (Info
->hStatus
!= NULL
)
748 if (!MainWndMenuHint(Info
,
751 sizeof(MainMenuHintTable
) / sizeof(MainMenuHintTable
[0]),
754 MainWndMenuHint(Info
,
757 sizeof(SystemMenuHintTable
) / sizeof(SystemMenuHintTable
[0]),
764 case WM_ENTERMENULOOP
:
766 Info
->InMenuLoop
= TRUE
;
767 UpdateMainStatusBar(Info
);
771 case WM_EXITMENULOOP
:
773 Info
->InMenuLoop
= FALSE
;
774 UpdateMainStatusBar(Info
);
780 FreeDeviceStrings(Info
->hTreeView
);
781 DestroyMenu(Info
->hShortcutMenu
);
788 HeapFree(ProcessHeap
,
791 SetWindowLongPtr(hwnd
,
795 /* Break the message queue loop */
802 HandleDefaultMessage
:
804 Ret
= DefWindowProc(hwnd
,
817 CreateMainWindow(LPCTSTR lpCaption
,
821 HWND hMainWnd
= NULL
;
823 Info
= (PMAIN_WND_INFO
)HeapAlloc(ProcessHeap
,
825 sizeof(MAIN_WND_INFO
));
829 Info
->nCmdShow
= nCmdShow
;
830 Info
->Display
= DevicesByType
;
831 Info
->bShowHidden
= TRUE
;
833 hMainWnd
= CreateWindowEx(WS_EX_WINDOWEDGE
,
836 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
845 if (hMainWnd
== NULL
)
848 HeapFree(ProcessHeap
,
858 InitMainWindowImpl(VOID
)
862 wc
.cbSize
= sizeof(WNDCLASSEX
);
863 wc
.lpfnWndProc
= MainWndProc
;
864 wc
.hInstance
= hInstance
;
865 wc
.hIcon
= LoadIcon(hInstance
,
866 MAKEINTRESOURCE(IDI_MAIN_ICON
));
867 wc
.hCursor
= LoadCursor(NULL
,
869 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
870 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
871 wc
.lpszClassName
= szMainWndClass
;
872 wc
.hIconSm
= (HICON
)LoadImage(hInstance
,
873 MAKEINTRESOURCE(IDI_MAIN_ICON
),
879 return RegisterClassEx(&wc
) != (ATOM
)0;
884 UninitMainWindowImpl(VOID
)
886 UnregisterClass(szMainWndClass
,