- enumerate devices in a separate thread so it doesn't stall opening of the main window

- check for problems with devices, e.g. disabled devices (currently missing code to display overlay icons)
- enable / disable the properties command dependant on what item is selected
- fix a few potential bugs

svn path=/trunk/; revision=24557
This commit is contained in:
Ged Murphy 2006-10-17 15:56:41 +00:00
parent fead15e683
commit 400f62c0f2
6 changed files with 156 additions and 86 deletions

View file

@ -8,7 +8,7 @@ BEGIN
BEGIN BEGIN
MENUITEM "Print", IDC_PRINT, GRAYED MENUITEM "Print", IDC_PRINT, GRAYED
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Properties", IDC_PROP MENUITEM "Properties", IDC_PROP, GRAYED
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Help", IDC_PROGHELP, GRAYED MENUITEM "Help", IDC_PROGHELP, GRAYED
END END
@ -30,7 +30,7 @@ IDR_POPUP MENU
BEGIN BEGIN
POPUP "popup" POPUP "popup"
BEGIN BEGIN
MENUITEM "Properties", IDC_PROP MENUITEM "Properties", IDC_PROP, GRAYED
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "Help", IDC_PROGHELP MENUITEM "Help", IDC_PROGHELP
END END

View file

@ -38,9 +38,6 @@ WinMain(HINSTANCE hThisInstance,
return 1; return 1;
} }
// FreeConsole();
// AllocConsole();
if (InitMainWindowImpl()) if (InitMainWindowImpl())
{ {
hMainWnd = CreateMainWindow(lpAppName, hMainWnd = CreateMainWindow(lpAppName,

View file

@ -12,21 +12,22 @@
static SP_CLASSIMAGELIST_DATA ImageListData; static SP_CLASSIMAGELIST_DATA ImageListData;
static HDEVINFO hDevInfo; static HDEVINFO hDevInfo;
VOID VOID
FreeDeviceStrings(HWND hTV) FreeDeviceStrings(HWND hTreeView)
{ {
HTREEITEM hItem; HTREEITEM hItem;
hItem = TreeView_GetRoot(hTV); hItem = TreeView_GetRoot(hTreeView);
if (hItem) if (hItem)
{ {
hItem = TreeView_GetChild(hTV, hItem = TreeView_GetChild(hTreeView,
hItem); hItem);
/* loop the parent items */ /* loop the parent items */
while (hItem) while (hItem)
{ {
hItem = TreeView_GetChild(hTV, hItem = TreeView_GetChild(hTreeView,
hItem); hItem);
if (hItem == NULL) if (hItem == NULL)
break; break;
@ -43,7 +44,7 @@ FreeDeviceStrings(HWND hTV)
//tvItem.pszText = Buf; //tvItem.pszText = Buf;
//tvItem.cchTextMax = 99; //tvItem.cchTextMax = 99;
(void)TreeView_GetItem(hTV, &tvItem); (void)TreeView_GetItem(hTreeView, &tvItem);
//MessageBox(NULL, Buf, NULL, 0); //MessageBox(NULL, Buf, NULL, 0);
@ -53,7 +54,7 @@ FreeDeviceStrings(HWND hTV)
hOldItem = hItem; hOldItem = hItem;
hItem = TreeView_GetNextSibling(hTV, hItem = TreeView_GetNextSibling(hTreeView,
hItem); hItem);
if (hItem == NULL) if (hItem == NULL)
{ {
@ -62,9 +63,9 @@ FreeDeviceStrings(HWND hTV)
} }
} }
hItem = TreeView_GetParent(hTV, hItem = TreeView_GetParent(hTreeView,
hItem); hItem);
hItem = TreeView_GetNextSibling(hTV, hItem = TreeView_GetNextSibling(hTreeView,
hItem); hItem);
} }
} }
@ -72,7 +73,7 @@ FreeDeviceStrings(HWND hTV)
VOID VOID
OpenPropSheet(HWND hTV, OpenPropSheet(HWND hTreeView,
HTREEITEM hItem) HTREEITEM hItem)
{ {
TV_ITEM tvItem; TV_ITEM tvItem;
@ -80,10 +81,10 @@ OpenPropSheet(HWND hTV,
tvItem.hItem = hItem; tvItem.hItem = hItem;
tvItem.mask = TVIF_PARAM; tvItem.mask = TVIF_PARAM;
if (TreeView_GetItem(hTV, &tvItem) && if (TreeView_GetItem(hTreeView, &tvItem) &&
(LPTSTR)tvItem.lParam != NULL) (LPTSTR)tvItem.lParam != NULL)
{ {
DevicePropertiesExW(hTV, DevicePropertiesExW(hTreeView,
NULL, NULL,
(LPTSTR)tvItem.lParam, (LPTSTR)tvItem.lParam,
0, 0,
@ -94,11 +95,12 @@ OpenPropSheet(HWND hTV,
static HTREEITEM static HTREEITEM
InsertIntoTreeView(HWND hTV, InsertIntoTreeView(HWND hTreeView,
HTREEITEM hRoot, HTREEITEM hRoot,
LPTSTR lpLabel, LPTSTR lpLabel,
LPTSTR DeviceID, LPTSTR DeviceID,
INT DevImage) INT DevImage,
LONG DevProb)
{ {
TV_ITEM tvi; TV_ITEM tvi;
TV_INSERTSTRUCT tvins; TV_INSERTSTRUCT tvins;
@ -113,10 +115,21 @@ InsertIntoTreeView(HWND hTV,
tvi.iImage = DevImage; tvi.iImage = DevImage;
tvi.iSelectedImage = DevImage; tvi.iSelectedImage = DevImage;
if (DevProb != 0)
{
tvi.stateMask = TVIS_OVERLAYMASK;
if (DevProb == CM_PROB_DISABLED)
{
/* FIXME: set the overlay icon */
}
}
tvins.item = tvi; tvins.item = tvi;
tvins.hParent = hRoot; tvins.hParent = hRoot;
return TreeView_InsertItem(hTV, &tvins); return TreeView_InsertItem(hTreeView, &tvins);
} }
@ -214,13 +227,15 @@ EnumDeviceClasses(INT ClassIndex,
} }
static INT static LONG
EnumDevices(INT index, EnumDevices(INT index,
LPTSTR DeviceClassName, LPTSTR DeviceClassName,
LPTSTR DeviceName, LPTSTR DeviceName,
LPTSTR *DeviceID) LPTSTR *DeviceID)
{ {
SP_DEVINFO_DATA DeviceInfoData; SP_DEVINFO_DATA DeviceInfoData;
CONFIGRET cr;
LONG Status, ProblemNumber;
DWORD DevIdSize; DWORD DevIdSize;
*DeviceName = _T('\0'); *DeviceName = _T('\0');
@ -276,17 +291,23 @@ EnumDevices(INT index,
NULL)) NULL))
{ {
/* if the friendly name fails, try the description instead */ /* if the friendly name fails, try the description instead */
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, SetupDiGetDeviceRegistryProperty(hDevInfo,
&DeviceInfoData, &DeviceInfoData,
SPDRP_DEVICEDESC, SPDRP_DEVICEDESC,
0, 0,
(BYTE*)DeviceName, (BYTE*)DeviceName,
MAX_DEV_LEN, MAX_DEV_LEN,
NULL)) NULL);
{ }
/* if the description fails, just give up! */
return -2; cr = CM_Get_DevNode_Status_Ex(&Status,
} &ProblemNumber,
DeviceInfoData.DevInst,
0,
NULL);
if (cr == CR_SUCCESS && (Status & DN_HAS_PROBLEM))
{
return ProblemNumber;
} }
return 0; return 0;
@ -294,7 +315,7 @@ EnumDevices(INT index,
VOID VOID
ListDevicesByType(PMAIN_WND_INFO Info, ListDevicesByType(HWND hTreeView,
HTREEITEM hRoot) HTREEITEM hRoot)
{ {
HTREEITEM hDevItem; HTREEITEM hDevItem;
@ -317,23 +338,26 @@ ListDevicesByType(PMAIN_WND_INFO Info,
if ((ClassRet != -1) && (DevExist)) if ((ClassRet != -1) && (DevExist))
{ {
TCHAR DeviceName[MAX_DEV_LEN]; TCHAR DeviceName[MAX_DEV_LEN];
INT Ret, DevIndex = 0; INT DevIndex = 0;
LONG Ret;
if (DevDesc[0] != _T('\0')) if (DevDesc[0] != _T('\0'))
{ {
hDevItem = InsertIntoTreeView(Info->hTreeView, hDevItem = InsertIntoTreeView(hTreeView,
hRoot, hRoot,
DevDesc, DevDesc,
NULL, NULL,
DevImage); DevImage,
0);
} }
else else
{ {
hDevItem = InsertIntoTreeView(Info->hTreeView, hDevItem = InsertIntoTreeView(hTreeView,
hRoot, hRoot,
DevName, DevName,
NULL, NULL,
DevImage); DevImage,
0);
} }
do do
@ -342,13 +366,14 @@ ListDevicesByType(PMAIN_WND_INFO Info,
DevName, DevName,
DeviceName, DeviceName,
&DeviceID); &DeviceID);
if (Ret == 0) if (Ret >= 0)
{ {
InsertIntoTreeView(Info->hTreeView, InsertIntoTreeView(hTreeView,
hDevItem, hDevItem,
DeviceName, DeviceName,
DeviceID, DeviceID,
DevImage); DevImage,
Ret);
} }
DevIndex++; DevIndex++;
@ -363,15 +388,15 @@ ListDevicesByType(PMAIN_WND_INFO Info,
} }
/* don't insert classes with no devices */ /* don't insert classes with no devices */
if (!TreeView_GetChild(Info->hTreeView, if (!TreeView_GetChild(hTreeView,
hDevItem)) hDevItem))
{ {
(void)TreeView_DeleteItem(Info->hTreeView, (void)TreeView_DeleteItem(hTreeView,
hDevItem); hDevItem);
} }
else else
{ {
(void)TreeView_SortChildren(Info->hTreeView, (void)TreeView_SortChildren(hTreeView,
hDevItem, hDevItem,
0); 0);
} }
@ -381,18 +406,18 @@ ListDevicesByType(PMAIN_WND_INFO Info,
} while (ClassRet != -1); } while (ClassRet != -1);
(void)TreeView_Expand(Info->hTreeView, (void)TreeView_Expand(hTreeView,
hRoot, hRoot,
TVE_EXPAND); TVE_EXPAND);
(void)TreeView_SortChildren(Info->hTreeView, (void)TreeView_SortChildren(hTreeView,
hRoot, hRoot,
0); 0);
} }
HTREEITEM HTREEITEM
InitTreeView(PMAIN_WND_INFO Info) InitTreeView(HWND hTreeView)
{ {
HTREEITEM hRoot; HTREEITEM hRoot;
HBITMAP hComp; HBITMAP hComp;
@ -400,7 +425,7 @@ InitTreeView(PMAIN_WND_INFO Info)
DWORD dwSize = MAX_PATH; DWORD dwSize = MAX_PATH;
INT RootImage; INT RootImage;
(void)TreeView_DeleteAllItems(Info->hTreeView); (void)TreeView_DeleteAllItems(hTreeView);
/* get the device image List */ /* get the device image List */
ImageListData.cbSize = sizeof(ImageListData); ImageListData.cbSize = sizeof(ImageListData);
@ -415,7 +440,7 @@ InitTreeView(PMAIN_WND_INFO Info)
DeleteObject(hComp); DeleteObject(hComp);
(void)TreeView_SetImageList(Info->hTreeView, (void)TreeView_SetImageList(hTreeView,
ImageListData.ImageList, ImageListData.ImageList,
TVSIL_NORMAL); TVSIL_NORMAL);
@ -428,11 +453,12 @@ InitTreeView(PMAIN_WND_INFO Info)
RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1; RootImage = ImageList_GetImageCount(ImageListData.ImageList) - 1;
/* insert the root item into the tree */ /* insert the root item into the tree */
hRoot = InsertIntoTreeView(Info->hTreeView, hRoot = InsertIntoTreeView(hTreeView,
NULL, NULL,
ComputerName, ComputerName,
NULL, NULL,
RootImage); RootImage,
0);
return hRoot; return hRoot;
} }

View file

@ -15,7 +15,7 @@ static const TCHAR szMainWndClass[] = TEXT("DevMgmtWndClass");
/* Toolbar buttons */ /* Toolbar buttons */
TBBUTTON Buttons [] = TBBUTTON Buttons [] =
{ /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */ { /* iBitmap, idCommand, fsState, fsStyle, bReserved[2], dwData, iString */
{TBICON_PROP, IDC_PROP, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* properties */ {TBICON_PROP, IDC_PROP, TBSTATE_INDETERMINATE, BTNS_BUTTON, {0}, 0, 0}, /* properties */
{TBICON_REFRESH, IDC_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */ {TBICON_REFRESH, IDC_REFRESH, TBSTATE_ENABLED, BTNS_BUTTON, {0}, 0, 0}, /* refresh */
/* Note: First item for a seperator is its width in pixels */ /* Note: First item for a seperator is its width in pixels */
@ -198,12 +198,30 @@ CreateStatusBar(PMAIN_WND_INFO Info)
} }
static DWORD WINAPI
DeviceEnumThread(LPVOID lpParameter)
{
HTREEITEM hRoot;
HWND *hTreeView;
static VOID hTreeView = (HWND *)lpParameter;
hRoot = InitTreeView(*hTreeView);
if (hRoot)
{
ListDevicesByType(*hTreeView, hRoot);
return 0;
}
return -1;
}
static BOOL
InitMainWnd(PMAIN_WND_INFO Info) InitMainWnd(PMAIN_WND_INFO Info)
{ {
HANDLE DevEnumThread;
HMENU hMenu; HMENU hMenu;
HTREEITEM hRoot;
if (!CreateToolbar(Info)) if (!CreateToolbar(Info))
DisplayString(_T("error creating toolbar")); DisplayString(_T("error creating toolbar"));
@ -211,7 +229,7 @@ InitMainWnd(PMAIN_WND_INFO Info)
if (!CreateTreeView(Info)) if (!CreateTreeView(Info))
{ {
DisplayString(_T("error creating list view")); DisplayString(_T("error creating list view"));
return; return FALSE;
} }
if (!CreateStatusBar(Info)) if (!CreateStatusBar(Info))
@ -229,10 +247,21 @@ InitMainWnd(PMAIN_WND_INFO Info)
0); 0);
SetMenuDefaultItem(Info->hShortcutMenu, IDC_PROP, FALSE); SetMenuDefaultItem(Info->hShortcutMenu, IDC_PROP, FALSE);
/* emum all devices */ /* create seperate thread to emum devices */
hRoot = InitTreeView(Info); DevEnumThread = CreateThread(NULL,
if (hRoot) 0,
ListDevicesByType(Info, hRoot); DeviceEnumThread,
&Info->hTreeView,
0,
NULL);
if (!DevEnumThread)
{
DisplayString(_T("Failed to enumerate devices"));
return FALSE;
}
CloseHandle(DevEnumThread);
return TRUE;
} }
@ -273,11 +302,38 @@ static VOID
OnNotify(PMAIN_WND_INFO Info, OnNotify(PMAIN_WND_INFO Info,
LPARAM lParam) LPARAM lParam)
{ {
LPNMHDR pnmhdr = (LPNMHDR)lParam; LPNMHDR pnmhdr = (LPNMHDR)lParam;
switch (pnmhdr->code) switch (pnmhdr->code)
{ {
case TVN_SELCHANGED:
{
LPNM_TREEVIEW pnmtv = (LPNM_TREEVIEW)lParam;
if (!TreeView_GetChild(Info->hTreeView,
pnmtv->itemNew.hItem))
{
SendMessage(Info->hTool,
TB_SETSTATE,
IDC_PROP,
(LPARAM)MAKELONG(TBSTATE_ENABLED, 0));
EnableMenuItem(GetMenu(Info->hMainWnd), IDC_PROP, MF_ENABLED);
EnableMenuItem(Info->hShortcutMenu, IDC_PROP, MF_ENABLED);
}
else
{
SendMessage(Info->hTool,
TB_SETSTATE,
IDC_PROP,
(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
EnableMenuItem(GetMenu(Info->hMainWnd), IDC_PROP, MF_GRAYED);
EnableMenuItem(Info->hShortcutMenu, IDC_PROP, MF_GRAYED);
}
}
break;
case NM_DBLCLK: case NM_DBLCLK:
{ {
HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView); HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView);
@ -299,7 +355,7 @@ OnNotify(PMAIN_WND_INFO Info,
ScreenToClient(Info->hTreeView, &HitTest.pt)) ScreenToClient(Info->hTreeView, &HitTest.pt))
{ {
if (TreeView_HitTest(Info->hTreeView, &HitTest)) if (TreeView_HitTest(Info->hTreeView, &HitTest))
(void)TreeView_SelectItem(Info->hTreeView, HitTest.hItem); TreeView_SelectItem(Info->hTreeView, HitTest.hItem);
} }
} }
break; break;
@ -329,7 +385,6 @@ OnNotify(PMAIN_WND_INFO Info,
case IDC_EXIT: case IDC_EXIT:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT); lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
break; break;
} }
} }
break; break;
@ -360,9 +415,17 @@ MainWndCommand(PMAIN_WND_INFO Info,
FreeDeviceStrings(Info->hTreeView); FreeDeviceStrings(Info->hTreeView);
hRoot = InitTreeView(Info); hRoot = InitTreeView(Info->hTreeView);
if (hRoot) if (hRoot)
ListDevicesByType(Info, hRoot); ListDevicesByType(Info->hTreeView, hRoot);
SendMessage(Info->hTool,
TB_SETSTATE,
IDC_PROP,
(LPARAM)MAKELONG(TBSTATE_INDETERMINATE, 0));
EnableMenuItem(GetMenu(Info->hMainWnd), IDC_PROP, MF_GRAYED);
EnableMenuItem(Info->hShortcutMenu, IDC_PROP, MF_GRAYED);
} }
break; break;
@ -458,7 +521,8 @@ MainWndProc(HWND hwnd,
GWLP_USERDATA, GWLP_USERDATA,
(LONG_PTR)Info); (LONG_PTR)Info);
InitMainWnd(Info); if (!InitMainWnd(Info))
SendMessage(hwnd, WM_CLOSE, 0, 0);
/* Show the window */ /* Show the window */
ShowWindow(hwnd, ShowWindow(hwnd,
@ -639,3 +703,4 @@ UninitMainWindowImpl(VOID)
hInstance); hInstance);
} }

View file

@ -258,21 +258,3 @@ VOID DisplayString(PTCHAR Msg)
{ {
MessageBox(NULL, Msg, _T("Note!"), MB_ICONEXCLAMATION|MB_OK); MessageBox(NULL, Msg, _T("Note!"), MB_ICONEXCLAMATION|MB_OK);
} }
VOID TimerInfo(LPTSTR text)
{
static HANDLE hOut = NULL;
DWORD Count;
TCHAR buf[256];
static DWORD start = 0;
if (!start) start = GetTickCount();
if (!hOut) hOut = GetStdHandle(STD_ERROR_HANDLE);
if (text) _sntprintf(buf, 256, _T("%s\ttime : %d\n"), text, GetTickCount() - start);
else _sntprintf(buf, 256, _T("time : %d\n"), GetTickCount() - start);
WriteConsole(hOut, buf, lstrlen(buf)+1, &Count, NULL);
}

View file

@ -74,10 +74,10 @@ DevicePropertiesExA(IN HWND hWndParent OPTIONAL,
IN BOOL bShowDevMgr); IN BOOL bShowDevMgr);
#endif #endif
VOID FreeDeviceStrings(HWND hTV); VOID FreeDeviceStrings(HWND hTreeView);
VOID OpenPropSheet(HWND hTV, HTREEITEM hItem); VOID OpenPropSheet(HWND hTreeView, HTREEITEM hItem);
HTREEITEM InitTreeView(PMAIN_WND_INFO Info); HTREEITEM InitTreeView(HWND hTreeView);
VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot); VOID ListDevicesByType(HWND hTreeView, HTREEITEM hRoot);
/* misc.c */ /* misc.c */