- 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
MENUITEM "Print", IDC_PRINT, GRAYED
MENUITEM SEPARATOR
MENUITEM "Properties", IDC_PROP
MENUITEM "Properties", IDC_PROP, GRAYED
MENUITEM SEPARATOR
MENUITEM "Help", IDC_PROGHELP, GRAYED
END
@ -30,7 +30,7 @@ IDR_POPUP MENU
BEGIN
POPUP "popup"
BEGIN
MENUITEM "Properties", IDC_PROP
MENUITEM "Properties", IDC_PROP, GRAYED
MENUITEM SEPARATOR
MENUITEM "Help", IDC_PROGHELP
END

View file

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

View file

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

View file

@ -15,7 +15,7 @@ static const TCHAR szMainWndClass[] = TEXT("DevMgmtWndClass");
/* Toolbar buttons */
TBBUTTON Buttons [] =
{ /* 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 */
/* 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)
{
HANDLE DevEnumThread;
HMENU hMenu;
HTREEITEM hRoot;
if (!CreateToolbar(Info))
DisplayString(_T("error creating toolbar"));
@ -211,7 +229,7 @@ InitMainWnd(PMAIN_WND_INFO Info)
if (!CreateTreeView(Info))
{
DisplayString(_T("error creating list view"));
return;
return FALSE;
}
if (!CreateStatusBar(Info))
@ -229,10 +247,21 @@ InitMainWnd(PMAIN_WND_INFO Info)
0);
SetMenuDefaultItem(Info->hShortcutMenu, IDC_PROP, FALSE);
/* emum all devices */
hRoot = InitTreeView(Info);
if (hRoot)
ListDevicesByType(Info, hRoot);
/* create seperate thread to emum devices */
DevEnumThread = CreateThread(NULL,
0,
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,
LPARAM lParam)
{
LPNMHDR pnmhdr = (LPNMHDR)lParam;
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:
{
HTREEITEM hSelected = TreeView_GetSelection(Info->hTreeView);
@ -299,7 +355,7 @@ OnNotify(PMAIN_WND_INFO Info,
ScreenToClient(Info->hTreeView, &HitTest.pt))
{
if (TreeView_HitTest(Info->hTreeView, &HitTest))
(void)TreeView_SelectItem(Info->hTreeView, HitTest.hItem);
TreeView_SelectItem(Info->hTreeView, HitTest.hItem);
}
}
break;
@ -329,7 +385,6 @@ OnNotify(PMAIN_WND_INFO Info,
case IDC_EXIT:
lpttt->lpszText = MAKEINTRESOURCE(IDS_TOOLTIP_EXIT);
break;
}
}
break;
@ -360,9 +415,17 @@ MainWndCommand(PMAIN_WND_INFO Info,
FreeDeviceStrings(Info->hTreeView);
hRoot = InitTreeView(Info);
hRoot = InitTreeView(Info->hTreeView);
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;
@ -458,7 +521,8 @@ MainWndProc(HWND hwnd,
GWLP_USERDATA,
(LONG_PTR)Info);
InitMainWnd(Info);
if (!InitMainWnd(Info))
SendMessage(hwnd, WM_CLOSE, 0, 0);
/* Show the window */
ShowWindow(hwnd,
@ -639,3 +703,4 @@ UninitMainWindowImpl(VOID)
hInstance);
}

View file

@ -258,21 +258,3 @@ VOID DisplayString(PTCHAR Msg)
{
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);
#endif
VOID FreeDeviceStrings(HWND hTV);
VOID OpenPropSheet(HWND hTV, HTREEITEM hItem);
HTREEITEM InitTreeView(PMAIN_WND_INFO Info);
VOID ListDevicesByType(PMAIN_WND_INFO Info, HTREEITEM hRoot);
VOID FreeDeviceStrings(HWND hTreeView);
VOID OpenPropSheet(HWND hTreeView, HTREEITEM hItem);
HTREEITEM InitTreeView(HWND hTreeView);
VOID ListDevicesByType(HWND hTreeView, HTREEITEM hRoot);
/* misc.c */