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>
12 static BOOL
pCreateToolbar(PMAIN_WND_INFO Info
);
14 static const TCHAR szMainWndClass
[] = TEXT("DevMgmtWndClass");
19 { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
20 {TBICON_PROP
, IDC_PROP
, TBSTATE_INDETERMINATE
, BTNS_BUTTON
, {0}, 0, 0}, /* properties */
21 {TBICON_REFRESH
, IDC_REFRESH
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0}, /* refresh */
23 /* Note: First item for a seperator is its width in pixels */
24 {15, 0, TBSTATE_ENABLED
, BTNS_SEP
, {0}, 0, 0}, /* separator */
26 {TBICON_HELP
, IDC_PROGHELP
,TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0 }, /* help */
27 {TBICON_EXIT
, IDC_EXIT
, TBSTATE_ENABLED
, BTNS_BUTTON
, {0}, 0, 0 }, /* exit */
33 static const MENU_HINT MainMenuHintTable
[] = {
35 {IDC_EXIT
, IDS_HINT_EXIT
},
38 {IDC_REFRESH
, IDS_HINT_REFRESH
},
39 {IDC_PROP
, IDS_HINT_PROP
},
42 {IDC_PROGHELP
, IDS_HINT_HELP
},
43 {IDC_ABOUT
, IDS_HINT_ABOUT
}
46 /* system menu hints */
47 static const MENU_HINT SystemMenuHintTable
[] = {
48 {SC_RESTORE
, IDS_HINT_SYS_RESTORE
},
49 {SC_MOVE
, IDS_HINT_SYS_MOVE
},
50 {SC_SIZE
, IDS_HINT_SYS_SIZE
},
51 {SC_MINIMIZE
, IDS_HINT_SYS_MINIMIZE
},
52 {SC_MAXIMIZE
, IDS_HINT_SYS_MAXIMIZE
},
53 {SC_CLOSE
, IDS_HINT_SYS_CLOSE
},
58 MainWndMenuHint(PMAIN_WND_INFO Info
,
60 const MENU_HINT
*HintArray
,
65 const MENU_HINT
*LastHint
;
66 UINT HintId
= DefHintId
;
68 LastHint
= HintArray
+ HintsCount
;
69 while (HintArray
!= LastHint
)
71 if (HintArray
->CmdId
== CmdId
)
73 HintId
= HintArray
->HintId
;
80 StatusBarLoadString(Info
->hStatus
,
90 UpdateMainStatusBar(PMAIN_WND_INFO Info
)
92 if (Info
->hStatus
!= NULL
)
94 SendMessage(Info
->hStatus
,
96 (WPARAM
)Info
->InMenuLoop
,
103 pCreateToolbar(PMAIN_WND_INFO Info
)
105 INT NumButtons
= sizeof(Buttons
) / sizeof(Buttons
[0]);
107 Info
->hTool
= CreateWindowEx(0,
110 WS_CHILD
| WS_VISIBLE
| TBSTYLE_FLAT
| TBSTYLE_TOOLTIPS
,
116 if(Info
->hTool
!= NULL
)
118 HIMAGELIST hImageList
;
120 SendMessage(Info
->hTool
,
123 TBSTYLE_EX_HIDECLIPPEDBUTTONS
);
125 SendMessage(Info
->hTool
,
130 hImageList
= InitImageList(IDB_PROP
,
134 if (hImageList
== NULL
)
137 ImageList_Destroy((HIMAGELIST
)SendMessage(Info
->hTool
,
140 (LPARAM
)hImageList
));
142 SendMessage(Info
->hTool
,
155 CreateTreeView(PMAIN_WND_INFO Info
)
157 Info
->hTreeView
= CreateWindowEx(WS_EX_CLIENTEDGE
,
160 WS_CHILD
| WS_VISIBLE
| WS_BORDER
| TVS_HASLINES
|
161 TVS_HASBUTTONS
| TVS_SHOWSELALWAYS
| TVS_LINESATROOT
,
167 if (Info
->hTreeView
== NULL
)
169 DisplayString(_T("Could not create TreeView."));
177 CreateStatusBar(PMAIN_WND_INFO Info
)
179 INT StatWidths
[] = {110, -1}; /* widths of status bar */
181 Info
->hStatus
= CreateWindowEx(0,
184 WS_CHILD
| WS_VISIBLE
| SBARS_SIZEGRIP
,
187 (HMENU
)IDC_STATUSBAR
,
190 if(Info
->hStatus
== NULL
)
194 SendMessage(Info
->hStatus
,
196 sizeof(StatWidths
) / sizeof(INT
),
204 DeviceEnumThread(LPVOID lpParameter
)
209 Info
= (PMAIN_WND_INFO
)lpParameter
;
212 FreeDeviceStrings(Info
->hTreeView
);
214 hRoot
= InitTreeView(Info
->hTreeView
);
217 switch (Info
->Display
)
220 ListDevicesByType(Info
->hTreeView
, hRoot
, Info
->bShowHidden
);
223 case DevicesByConnection
:
224 ListDevicesByConnection(Info
->hTreeView
, hRoot
, Info
->bShowHidden
);
238 UpdateViewMenu(PMAIN_WND_INFO Info
)
240 UINT id
= IDC_DEVBYTYPE
;
243 hMenu
= GetMenu(Info
->hMainWnd
);
245 switch (Info
->Display
)
250 case DevicesByConnection
:
253 case RessourcesByType
:
256 case RessourcesByConnection
:
261 CheckMenuRadioItem(hMenu
,
269 MF_BYCOMMAND
| (Info
->bShowHidden
) ? MF_CHECKED
: MF_UNCHECKED
);
274 InitMainWnd(PMAIN_WND_INFO Info
)
276 HANDLE DevEnumThread
;
279 if (!pCreateToolbar(Info
))
280 DisplayString(_T("error creating toolbar"));
282 if (!CreateTreeView(Info
))
284 DisplayString(_T("error creating list view"));
288 if (!CreateStatusBar(Info
))
289 DisplayString(_T("error creating status bar"));
291 UpdateViewMenu(Info
);
293 /* make 'properties' bold */
294 hMenu
= GetMenu(Info
->hMainWnd
);
295 hMenu
= GetSubMenu(hMenu
, 1);
296 SetMenuDefaultItem(hMenu
, IDC_PROP
, FALSE
);
298 /* Create Popup Menu */
299 Info
->hShortcutMenu
= LoadMenu(hInstance
,
300 MAKEINTRESOURCE(IDR_POPUP
));
301 Info
->hShortcutMenu
= GetSubMenu(Info
->hShortcutMenu
,
303 SetMenuDefaultItem(Info
->hShortcutMenu
, IDC_PROP
, FALSE
);
305 /* create seperate thread to emum devices */
306 DevEnumThread
= CreateThread(NULL
,
314 DisplayString(_T("Failed to enumerate devices"));
318 CloseHandle(DevEnumThread
);
324 OnContext(PMAIN_WND_INFO Info
,
331 INT xPos
= GET_X_LPARAM(lParam
);
332 INT yPos
= GET_Y_LPARAM(lParam
);
334 hSelected
= TreeView_GetSelection(Info
->hTreeView
);
336 if (TreeView_GetItemRect(Info
->hTreeView
,
341 if (GetCursorPos(&pt
) &&
342 ScreenToClient(Info
->hTreeView
, &pt
) &&
345 TrackPopupMenuEx(Info
->hShortcutMenu
,
357 OnNotify(PMAIN_WND_INFO Info
,
360 LPNMHDR pnmhdr
= (LPNMHDR
)lParam
;
363 switch (pnmhdr
->code
)
367 LPNM_TREEVIEW pnmtv
= (LPNM_TREEVIEW
)lParam
;
369 if (Info
->Display
== DevicesByType
)
371 if (!TreeView_GetChild(Info
->hTreeView
,
372 pnmtv
->itemNew
.hItem
))
374 SendMessage(Info
->hTool
,
377 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
379 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_ENABLED
);
380 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_ENABLED
);
384 SendMessage(Info
->hTool
,
387 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
389 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
390 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
393 else if (Info
->Display
== DevicesByConnection
)
395 if (pnmtv
->itemNew
.hItem
== TreeView_GetRoot(Info
->hTreeView
))
397 SendMessage(Info
->hTool
,
400 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
402 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
403 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
407 SendMessage(Info
->hTool
,
410 (LPARAM
)MAKELONG(TBSTATE_ENABLED
, 0));
412 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_ENABLED
);
413 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_ENABLED
);
421 HTREEITEM hSelected
= TreeView_GetSelection(Info
->hTreeView
);
422 TV_HITTESTINFO HitTest
;
424 if (Info
->Display
== DevicesByType
)
426 if (!TreeView_GetChild(Info
->hTreeView
,
429 if (GetCursorPos(&HitTest
.pt
) &&
430 ScreenToClient(Info
->hTreeView
, &HitTest
.pt
))
432 if (TreeView_HitTest(Info
->hTreeView
, &HitTest
))
434 if (HitTest
.hItem
== hSelected
)
436 OpenPropSheet(Info
->hTreeView
,
444 else if (Info
->Display
== DevicesByConnection
)
446 if (hSelected
!= TreeView_GetRoot(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
,
468 TV_HITTESTINFO HitTest
;
470 if (GetCursorPos(&HitTest
.pt
) &&
471 ScreenToClient(Info
->hTreeView
, &HitTest
.pt
))
473 if (TreeView_HitTest(Info
->hTreeView
, &HitTest
))
474 (void)TreeView_SelectItem(Info
->hTreeView
, HitTest
.hItem
);
479 case TTN_GETDISPINFO
:
484 lpttt
= (LPTOOLTIPTEXT
)lParam
;
486 idButton
= (UINT
)lpttt
->hdr
.idFrom
;
490 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_PROP
);
494 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_REFRESH
);
498 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_HELP
);
502 lpttt
->lpszText
= MAKEINTRESOURCE(IDS_TOOLTIP_EXIT
);
514 OnRefresh(PMAIN_WND_INFO Info
)
516 HANDLE DevEnumThread
;
518 SendMessage(Info
->hTool
,
521 (LPARAM
)MAKELONG(TBSTATE_INDETERMINATE
, 0));
523 EnableMenuItem(GetMenu(Info
->hMainWnd
), IDC_PROP
, MF_GRAYED
);
524 EnableMenuItem(Info
->hShortcutMenu
, IDC_PROP
, MF_GRAYED
);
526 /* create seperate thread to emum devices */
527 DevEnumThread
= CreateThread(NULL
,
535 DisplayString(_T("Failed to enumerate devices"));
539 CloseHandle(DevEnumThread
);
544 MainWndCommand(PMAIN_WND_INFO Info
,
548 UNREFERENCED_PARAMETER(hControl
);
554 HTREEITEM hSelected
= TreeView_GetSelection(Info
->hTreeView
);
555 OpenPropSheet(Info
->hTreeView
,
568 DisplayString(_T("Help is not yet implemented\n"));
569 SetFocus(Info
->hTreeView
);
575 PostMessage(Info
->hMainWnd
,
585 MAKEINTRESOURCE(IDD_ABOUTBOX
),
589 SetFocus(Info
->hTreeView
);
595 Info
->Display
= DevicesByType
;
596 UpdateViewMenu(Info
);
603 Info
->Display
= DevicesByConnection
;
604 UpdateViewMenu(Info
);
611 Info
->bShowHidden
= !Info
->bShowHidden
;
612 UpdateViewMenu(Info
);
621 MainWndResize(PMAIN_WND_INFO Info
,
625 RECT rcClient
, rcTool
, rcStatus
;
626 int lvHeight
, iToolHeight
, iStatusHeight
;
628 /* Size toolbar and get height */
629 SendMessage(Info
->hTool
, TB_AUTOSIZE
, 0, 0);
630 GetWindowRect(Info
->hTool
, &rcTool
);
631 iToolHeight
= rcTool
.bottom
- rcTool
.top
;
633 /* Size status bar and get height */
634 SendMessage(Info
->hStatus
, WM_SIZE
, 0, 0);
635 GetWindowRect(Info
->hStatus
, &rcStatus
);
636 iStatusHeight
= rcStatus
.bottom
- rcStatus
.top
;
638 /* Calculate remaining height and size list view */
639 GetClientRect(Info
->hMainWnd
, &rcClient
);
640 lvHeight
= rcClient
.bottom
- iToolHeight
- iStatusHeight
;
641 SetWindowPos(Info
->hTreeView
,
651 static LRESULT CALLBACK
652 MainWndProc(HWND hwnd
,
660 /* Get the window context */
661 Info
= (PMAIN_WND_INFO
)GetWindowLongPtr(hwnd
,
663 if (Info
== NULL
&& msg
!= WM_CREATE
)
665 goto HandleDefaultMessage
;
672 Info
= (PMAIN_WND_INFO
)(((LPCREATESTRUCT
)lParam
)->lpCreateParams
);
674 /* Initialize the main window context */
675 Info
->hMainWnd
= hwnd
;
677 SetWindowLongPtr(hwnd
,
681 if (!InitMainWnd(Info
))
682 SendMessage(hwnd
, WM_CLOSE
, 0, 0);
684 /* Show the window */
692 if (Info
->hTreeView
!= NULL
)
693 SetFocus(Info
->hTreeView
);
707 Ret
= OnNotify(Info
, lParam
);
713 OnContext(Info
, lParam
);
722 goto HandleDefaultMessage
;
727 if (Info
->hStatus
!= NULL
)
729 if (!MainWndMenuHint(Info
,
732 sizeof(MainMenuHintTable
) / sizeof(MainMenuHintTable
[0]),
735 MainWndMenuHint(Info
,
738 sizeof(SystemMenuHintTable
) / sizeof(SystemMenuHintTable
[0]),
745 case WM_ENTERMENULOOP
:
747 Info
->InMenuLoop
= TRUE
;
748 UpdateMainStatusBar(Info
);
752 case WM_EXITMENULOOP
:
754 Info
->InMenuLoop
= FALSE
;
755 UpdateMainStatusBar(Info
);
761 FreeDeviceStrings(Info
->hTreeView
);
762 DestroyMenu(Info
->hShortcutMenu
);
769 HeapFree(ProcessHeap
,
772 SetWindowLongPtr(hwnd
,
776 /* Break the message queue loop */
783 HandleDefaultMessage
:
785 Ret
= DefWindowProc(hwnd
,
798 CreateMainWindow(LPCTSTR lpCaption
,
802 HWND hMainWnd
= NULL
;
804 Info
= (PMAIN_WND_INFO
)HeapAlloc(ProcessHeap
,
806 sizeof(MAIN_WND_INFO
));
810 Info
->nCmdShow
= nCmdShow
;
811 Info
->Display
= DevicesByType
;
812 Info
->bShowHidden
= TRUE
;
814 hMainWnd
= CreateWindowEx(WS_EX_WINDOWEDGE
,
817 WS_OVERLAPPEDWINDOW
| WS_CLIPCHILDREN
| WS_CLIPSIBLINGS
,
826 if (hMainWnd
== NULL
)
829 HeapFree(ProcessHeap
,
839 InitMainWindowImpl(VOID
)
843 wc
.cbSize
= sizeof(WNDCLASSEX
);
844 wc
.lpfnWndProc
= MainWndProc
;
845 wc
.hInstance
= hInstance
;
846 wc
.hIcon
= LoadIcon(hInstance
,
847 MAKEINTRESOURCE(IDI_MAIN_ICON
));
848 wc
.hCursor
= LoadCursor(NULL
,
850 wc
.hbrBackground
= (HBRUSH
)(COLOR_BTNFACE
+ 1);
851 wc
.lpszMenuName
= MAKEINTRESOURCE(IDR_MAINMENU
);
852 wc
.lpszClassName
= szMainWndClass
;
853 wc
.hIconSm
= (HICON
)LoadImage(hInstance
,
854 MAKEINTRESOURCE(IDI_MAIN_ICON
),
860 return RegisterClassEx(&wc
) != (ATOM
)0;
865 UninitMainWindowImpl(VOID
)
867 UnregisterClass(szMainWndClass
,