Something went wrong. Try again.
Reactos
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115/* * ReactOS Device Manager Applet * Copyright (C) 2004 - 2005 ReactOS Team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//* * PROJECT: ReactOS devmgr.dll * FILE: lib/devmgr/hwpage.c * PURPOSE: ReactOS Device Manager * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> * UPDATE HISTORY: * 04-04-2004 Created */
#include "precomp.h"#include "properties.h"#include "resource.h"
typedef struct _HWDEVINFO{ struct _HWCLASSDEVINFO *ClassDevInfo; SP_DEVINFO_DATA DevInfoData; BOOL HideDevice;} HWDEVINFO, *PHWDEVINFO;
typedef struct _HWCLASSDEVINFO{ GUID Guid; HDEVINFO hDevInfo; INT ImageIndex; INT ItemCount; PHWDEVINFO HwDevInfo;} HWCLASSDEVINFO, *PHWCLASSDEVINFO;
typedef struct _HARDWARE_PAGE_DATA{ HWND hWnd; HWND hWndDevList; HINSTANCE hComCtl32; /* only save this to keep track of the references */ INT DevListViewHeight; SP_CLASSIMAGELIST_DATA ClassImageListData; HWPAGE_DISPLAYMODE DisplayMode;
/* parent window subclass info */ WNDPROC ParentOldWndProc; HWND hWndParent;
UINT NumberOfGuids; HWCLASSDEVINFO ClassDevInfo[1]; /* struct may be dynamically expanded here! */} HARDWARE_PAGE_DATA, *PHARDWARE_PAGE_DATA;
#define CX_TYPECOLUMN_WIDTH 80
static VOIDInitializeDevicesList(IN PHARDWARE_PAGE_DATA hpd){ LVCOLUMN lvc; RECT rcClient; WCHAR szColName[255]; int iCol = 0;
/* set the list view style */ (void)ListView_SetExtendedListViewStyle(hpd->hWndDevList, LVS_EX_FULLROWSELECT);
/* set the list view image list */ if (hpd->ClassImageListData.ImageList != NULL) { (void)ListView_SetImageList(hpd->hWndDevList, hpd->ClassImageListData.ImageList, LVSIL_SMALL); }
GetClientRect(hpd->hWndDevList, &rcClient);
/* add the list view columns */ lvc.mask = LVCF_TEXT | LVCF_WIDTH; lvc.fmt = LVCFMT_LEFT; lvc.pszText = szColName;
if (LoadString(hDllInstance, IDS_NAME, szColName, sizeof(szColName) / sizeof(szColName[0]))) { lvc.cx = rcClient.right - CX_TYPECOLUMN_WIDTH - GetSystemMetrics(SM_CXVSCROLL); (void)ListView_InsertColumn(hpd->hWndDevList, iCol++, &lvc); } if (LoadString(hDllInstance, IDS_TYPE, szColName, sizeof(szColName) / sizeof(szColName[0]))) { lvc.cx = CX_TYPECOLUMN_WIDTH; (void)ListView_InsertColumn(hpd->hWndDevList, iCol++, &lvc); }}
static BOOLDisplaySelectedDeviceProperties(IN PHARDWARE_PAGE_DATA hpd){ PHWDEVINFO HwDevInfo; SP_DEVINFO_DATA DevInfoData; BOOL Ret = FALSE;
HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); if (HwDevInfo != NULL) { /* make a copy of the SP_DEVINFO_DATA structure on the stack, it may become invalid in case the devices are updated */ DevInfoData = HwDevInfo->DevInfoData;
/* display the advanced properties */ Ret = DisplayDeviceAdvancedProperties(hpd->hWnd, NULL, HwDevInfo->ClassDevInfo->hDevInfo, &DevInfoData, hpd->hComCtl32, NULL, 0) != -1; }
return Ret;}
static VOIDUpdateControlStates(IN PHARDWARE_PAGE_DATA hpd){ PHWDEVINFO HwDevInfo; HWND hBtnTroubleShoot, hBtnProperties;
hBtnTroubleShoot = GetDlgItem(hpd->hWnd, IDC_TROUBLESHOOT); hBtnProperties = GetDlgItem(hpd->hWnd, IDC_PROPERTIES);
HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); if (HwDevInfo != NULL) { /* update static controls */ WCHAR szBuffer[256]; LPWSTR szFormatted = NULL;
/* get the manufacturer string */ if (GetDeviceManufacturerString(HwDevInfo->ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])) && LoadAndFormatString(hDllInstance, IDS_MANUFACTURER, &szFormatted, szBuffer) != 0) { SetDlgItemText(hpd->hWnd, IDC_MANUFACTURER, szFormatted); LocalFree((HLOCAL)szFormatted); }
/* get the location string */ if (GetDeviceLocationString(HwDevInfo->ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, 0, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])) && LoadAndFormatString(hDllInstance, IDS_LOCATION, &szFormatted, szBuffer) != 0) { SetDlgItemText(hpd->hWnd, IDC_LOCATION, szFormatted); LocalFree((HLOCAL)szFormatted); }
if (GetDeviceStatusString(HwDevInfo->DevInfoData.DevInst, NULL, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])) && LoadAndFormatString(hDllInstance, IDS_STATUS, &szFormatted, szBuffer) != 0) { SetDlgItemText(hpd->hWnd, IDC_STATUS, szFormatted); LocalFree((HLOCAL)szFormatted); } } else { /* clear static controls */ SetDlgItemText(hpd->hWnd, IDC_MANUFACTURER, NULL); SetDlgItemText(hpd->hWnd, IDC_LOCATION, NULL); SetDlgItemText(hpd->hWnd, IDC_STATUS, NULL); }
EnableWindow(hBtnTroubleShoot, HwDevInfo != NULL); EnableWindow(hBtnProperties, HwDevInfo != NULL);}
static VOIDFreeDevicesList(IN PHARDWARE_PAGE_DATA hpd){ PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo;
ClassDevInfo = hpd->ClassDevInfo; LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids;
/* free the device info set handles and structures */ while (ClassDevInfo != LastClassDevInfo) { if (ClassDevInfo->hDevInfo != INVALID_HANDLE_VALUE) { SetupDiDestroyDeviceInfoList(ClassDevInfo->hDevInfo); ClassDevInfo->hDevInfo = INVALID_HANDLE_VALUE; }
ClassDevInfo->ItemCount = 0; ClassDevInfo->ImageIndex = 0;
if (ClassDevInfo->HwDevInfo != NULL) { HeapFree(GetProcessHeap(), 0, ClassDevInfo->HwDevInfo); ClassDevInfo->HwDevInfo = NULL; }
ClassDevInfo++; }}
static VOIDBuildDevicesList(IN PHARDWARE_PAGE_DATA hpd){ PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo; SP_DEVINFO_DATA DevInfoData;
DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
ClassDevInfo = hpd->ClassDevInfo; LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids;
while (ClassDevInfo != LastClassDevInfo) { ClassDevInfo->ImageIndex = -1;
/* open a class device handle for the GUID we're processing */ ClassDevInfo->hDevInfo = SetupDiGetClassDevs(&ClassDevInfo->Guid, NULL, hpd->hWnd, DIGCF_PRESENT | DIGCF_PROFILE); if (ClassDevInfo->hDevInfo != INVALID_HANDLE_VALUE) { DWORD MemberIndex = 0;
SetupDiGetClassImageIndex(&hpd->ClassImageListData, &ClassDevInfo->Guid, &ClassDevInfo->ImageIndex);
/* enumerate all devices in the class */ while (SetupDiEnumDeviceInfo(ClassDevInfo->hDevInfo, MemberIndex++, &DevInfoData)) { BOOL HideDevice = FALSE;
if (ClassDevInfo->HwDevInfo != NULL) { PHWDEVINFO HwNewDevInfo = (PHWDEVINFO)HeapReAlloc(GetProcessHeap(), 0, ClassDevInfo->HwDevInfo, (ClassDevInfo->ItemCount + 1) * sizeof(HWDEVINFO)); if (HwNewDevInfo != NULL) { ClassDevInfo->HwDevInfo = HwNewDevInfo; } else { ERR("Unable to allocate memory for %d SP_DEVINFO_DATA structures!\n", ClassDevInfo->ItemCount + 1); break; } } else { ClassDevInfo->HwDevInfo = (PHWDEVINFO)HeapAlloc(GetProcessHeap(), 0, sizeof(HWDEVINFO)); if (ClassDevInfo->HwDevInfo == NULL) { ERR("Unable to allocate memory for a SP_DEVINFO_DATA structures!\n"); break; } }
/* Find out if the device should be hidden by default */ IsDeviceHidden(DevInfoData.DevInst, NULL, &HideDevice);
/* save all information for the current device */ ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount].ClassDevInfo = ClassDevInfo; ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount].DevInfoData = DevInfoData; ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount++].HideDevice = HideDevice; } }
ClassDevInfo++; }}
static BOOLDeviceIdMatch(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DeviceInfoData, IN LPCWSTR lpDeviceId){ DWORD DevIdLen; LPWSTR lpQueriedDeviceId; BOOL Ret = FALSE;
if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfoData, NULL, 0, &DevIdLen) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { if (DevIdLen == wcslen(lpDeviceId) + 1) { lpQueriedDeviceId = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DevIdLen * sizeof(WCHAR)); if (lpQueriedDeviceId != NULL) { if (SetupDiGetDeviceInstanceId(DeviceInfoSet, DeviceInfoData, lpQueriedDeviceId, DevIdLen, NULL)) { Ret = (wcscmp(lpDeviceId, lpQueriedDeviceId) == 0); }
HeapFree(GetProcessHeap(), 0, lpQueriedDeviceId); } } }
return Ret;}
static VOIDFillDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd, IN LPCWSTR lpSelectDeviceId OPTIONAL, IN GUID *SelectedClassGuid OPTIONAL){ PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo; PHWDEVINFO HwDevInfo, LastHwDevInfo; WCHAR szBuffer[255]; BOOL SelectedInClass; INT ItemCount = 0;
BuildDevicesList(hpd);
ClassDevInfo = hpd->ClassDevInfo; LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids;
while (ClassDevInfo != LastClassDevInfo) { if (ClassDevInfo->HwDevInfo != NULL) { HwDevInfo = ClassDevInfo->HwDevInfo; LastHwDevInfo = HwDevInfo + ClassDevInfo->ItemCount;
SelectedInClass = (SelectedClassGuid != NULL && IsEqualGUID(*SelectedClassGuid, ClassDevInfo->Guid)); while (HwDevInfo != LastHwDevInfo) { INT iItem; LVITEM li = {0};
/* get the device name */ if (!HwDevInfo->HideDevice && GetDeviceDescriptionString(ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]))) { li.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT | LVIF_IMAGE; li.iItem = ItemCount; if ((ItemCount == 0 && lpSelectDeviceId == NULL) || (SelectedInClass && DeviceIdMatch(ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, lpSelectDeviceId))) { li.state = LVIS_SELECTED; } li.stateMask = LVIS_SELECTED; li.pszText = szBuffer; li.iImage = ClassDevInfo->ImageIndex; li.lParam = (LPARAM)HwDevInfo;
iItem = ListView_InsertItem(hpd->hWndDevList, &li); if (iItem != -1) { ItemCount++;
/* get the device type for the second column */ if (GetDeviceTypeString(&HwDevInfo->DevInfoData, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]))) { li.mask = LVIF_TEXT; li.iItem = iItem; li.iSubItem = 1;
(void)ListView_SetItem(hpd->hWndDevList, &li); } } }
HwDevInfo++; } }
ClassDevInfo++; }
/* update the controls */ UpdateControlStates(hpd);}
static VOIDUpdateDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd){ PHWDEVINFO HwDevInfo; GUID SelectedClassGuid = {0}; LPWSTR lpDeviceId = NULL;
/* if a device currently is selected, remember the device id so we can select the device after the update if still present */ HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); if (HwDevInfo != NULL) { DWORD DevIdLen; if (!SetupDiGetDeviceInstanceId(HwDevInfo->ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, NULL, 0, &DevIdLen) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { SelectedClassGuid = HwDevInfo->DevInfoData.ClassGuid; lpDeviceId = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, DevIdLen * sizeof(WCHAR)); if (lpDeviceId != NULL && !SetupDiGetDeviceInstanceId(HwDevInfo->ClassDevInfo->hDevInfo, &HwDevInfo->DevInfoData, lpDeviceId, DevIdLen, NULL)) { HeapFree(GetProcessHeap(), 0, lpDeviceId); lpDeviceId = NULL; } } }
/* clear the devices list view control */ (void)ListView_DeleteAllItems(hpd->hWndDevList);
/* free the device list */ FreeDevicesList(hpd);
/* build rebuild the device list and fill the list box again */ FillDevicesListViewControl(hpd, lpDeviceId, (lpDeviceId != NULL ? &SelectedClassGuid : NULL));
if (lpDeviceId != NULL) { HeapFree(GetProcessHeap(), 0, lpDeviceId); }}
static LRESULTCALLBACKParentSubWndProc(IN HWND hwnd, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PHARDWARE_PAGE_DATA hpd;
hpd = (PHARDWARE_PAGE_DATA)GetProp(hwnd, L"DevMgrSubClassInfo"); if (hpd != NULL) { if (uMsg == WM_SIZE) { /* resize the hardware page */ SetWindowPos(hpd->hWnd, NULL, 0, 0, LOWORD(lParam), HIWORD(lParam), SWP_NOZORDER); } else if (uMsg == WM_DEVICECHANGE && IsWindowVisible(hpd->hWnd)) { /* forward a WM_DEVICECHANGE message to the hardware page which wouldn't get the message itself as it is a child window */ SendMessage(hpd->hWnd, WM_DEVICECHANGE, wParam, lParam); }
/* pass the message the the old window proc */ return CallWindowProc(hpd->ParentOldWndProc, hwnd, uMsg, wParam, lParam); } else { /* this is not a good idea if the subclassed window was an ansi window, but we failed finding out the previous window proc so we can't use CallWindowProc. This should rarely - if ever - happen. */
return DefWindowProc(hwnd, uMsg, wParam, lParam); }}
static VOIDHardwareDlgResize(IN PHARDWARE_PAGE_DATA hpd, IN INT cx, IN INT cy){ HDWP dwp; HWND hControl, hButton; INT Width, x, y; RECT rc, rcButton; POINT pt = {0}; POINT ptMargin = {0}; POINT ptMarginGroup = {0};
/* use left margin of the IDC_DEVICES label as the right margin of all controls outside the group box */ hControl = GetDlgItem(hpd->hWnd, IDC_DEVICES); GetWindowRect(hControl, &rc); MapWindowPoints(hControl, hpd->hWnd, &ptMargin, 1);
Width = cx - (2 * ptMargin.x);
if ((dwp = BeginDeferWindowPos(8))) { /* rc already has the window rect of IDC_DEVICES! */ if (!(dwp = DeferWindowPos(dwp, hControl, NULL, 0, 0, Width, rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER))) { return; }
/* resize the devices list view control */ GetWindowRect(hpd->hWndDevList, &rc); MapWindowPoints(hpd->hWndDevList, hpd->hWnd, &pt, 1); y = pt.y + hpd->DevListViewHeight + ptMargin.y; if (!(dwp = DeferWindowPos(dwp, hpd->hWndDevList, NULL, 0, 0, Width, hpd->DevListViewHeight, SWP_NOMOVE | SWP_NOZORDER))) { return; }
/* resize the group box control */ hControl = GetDlgItem(hpd->hWnd, IDC_PROPERTIESGROUP); GetWindowRect(hControl, &rc); if (!(dwp = DeferWindowPos(dwp, hControl, NULL, ptMargin.x, y, Width, cy - y - ptMargin.y, SWP_NOZORDER))) { return; }
/* use left margin of the IDC_MANUFACTURER label as the right margin of all controls inside the group box */ hControl = GetDlgItem(hpd->hWnd, IDC_MANUFACTURER); GetWindowRect(hControl, &rc); MapWindowPoints(hControl, hpd->hWnd, &ptMarginGroup, 1);
ptMarginGroup.y = ptMargin.y * 2; Width = cx - (2 * ptMarginGroup.x); y += ptMarginGroup.y; if (!(dwp = DeferWindowPos(dwp, hControl, NULL, ptMarginGroup.x, y, Width, rc.bottom - rc.top, SWP_NOZORDER))) { return; } y += rc.bottom - rc.top + (ptMargin.y / 2);
/* resize the IDC_LOCATION label */ hControl = GetDlgItem(hpd->hWnd, IDC_LOCATION); GetWindowRect(hControl, &rc); if (!(dwp = DeferWindowPos(dwp, hControl, NULL, ptMarginGroup.x, y, Width, rc.bottom - rc.top, SWP_NOZORDER))) { return; } y += rc.bottom - rc.top + (ptMargin.y / 2);
/* measure the size of the buttons */ hButton = GetDlgItem(hpd->hWnd, IDC_PROPERTIES); GetWindowRect(hButton, &rcButton);
/* resize the IDC_STATUS label */ hControl = GetDlgItem(hpd->hWnd, IDC_STATUS); GetWindowRect(hControl, &rc); if (!(dwp = DeferWindowPos(dwp, hControl, NULL, ptMarginGroup.x, y, Width, cy - y - (3 * ptMargin.y) - (rcButton.bottom - rcButton.top), SWP_NOZORDER))) { return; }
/* move the IDC_PROPERTIES button */ y = cy - (2 * ptMargin.y) - (rcButton.bottom - rcButton.top); x = cx - ptMarginGroup.x - (rcButton.right - rcButton.left); if (!(dwp = DeferWindowPos(dwp, hButton, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER))) { return; }
/* move the IDC_TROUBLESHOOT button */ hButton = GetDlgItem(hpd->hWnd, IDC_TROUBLESHOOT); GetWindowRect(hButton, &rcButton); x -= (ptMargin.x / 2) + (rcButton.right - rcButton.left); if (!(dwp = DeferWindowPos(dwp, hButton, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER))) { return; }
EndDeferWindowPos(dwp); }}
static VOIDEnableTroubleShoot(PHARDWARE_PAGE_DATA hpd, BOOL Enable){ HWND hBtnTroubleShoot = GetDlgItem(hpd->hWnd, IDC_TROUBLESHOOT);
ShowWindow(hBtnTroubleShoot, Enable ? SW_SHOW : SW_HIDE);}
static INT_PTRCALLBACKHardwareDlgProc(IN HWND hwndDlg, IN UINT uMsg, IN WPARAM wParam, IN LPARAM lParam){ PHARDWARE_PAGE_DATA hpd; INT_PTR Ret = FALSE;
hpd = (PHARDWARE_PAGE_DATA)GetWindowLongPtr(hwndDlg, DWLP_USER);
if (hpd != NULL || uMsg == WM_INITDIALOG) { switch (uMsg) { case WM_NOTIFY: { NMHDR *pnmh = (NMHDR*)lParam; if (pnmh->hwndFrom == hpd->hWndDevList) { switch (pnmh->code) { case LVN_ITEMCHANGED: { LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
if ((pnmv->uChanged & LVIF_STATE) && ((pnmv->uOldState & (LVIS_FOCUSED | LVIS_SELECTED)) || (pnmv->uNewState & (LVIS_FOCUSED | LVIS_SELECTED)))) { UpdateControlStates(hpd); } break; }
case NM_DBLCLK: { DisplaySelectedDeviceProperties(hpd); break; } } } break; }
case WM_COMMAND: { switch (LOWORD(wParam)) { case IDC_TROUBLESHOOT: { /* FIXME - start the help using the command in the window text */ break; }
case IDC_PROPERTIES: { DisplaySelectedDeviceProperties(hpd); break; } } break; }
case WM_SIZE: HardwareDlgResize(hpd, (INT)LOWORD(lParam), (INT)HIWORD(lParam)); break;
case WM_SETTEXT: { LPCWSTR szWndText = (LPCWSTR)lParam; EnableTroubleShoot(hpd, (szWndText != NULL && szWndText[0] != L'\0')); break; }
case WM_DEVICECHANGE: { /* FIXME - don't call UpdateDevicesListViewControl for all events */ UpdateDevicesListViewControl(hpd); Ret = TRUE; break; }
case WM_INITDIALOG: { hpd = (PHARDWARE_PAGE_DATA)lParam; if (hpd != NULL) { HWND hWndParent;
hpd->hWnd = hwndDlg; SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)hpd);
hpd->ClassImageListData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA);
SetupDiGetClassImageList(&hpd->ClassImageListData);
/* calculate the size of the devices list view control */ hpd->hWndDevList = GetDlgItem(hwndDlg, IDC_LV_DEVICES); if (hpd->hWndDevList != NULL) { RECT rcClient; GetClientRect(hpd->hWndDevList, &rcClient); hpd->DevListViewHeight = rcClient.bottom;
if (hpd->DisplayMode == HWPD_LARGELIST) { hpd->DevListViewHeight = (hpd->DevListViewHeight * 3) / 2; } }
/* subclass the parent window */ hWndParent = GetAncestor(hwndDlg, GA_PARENT); if (hWndParent != NULL) { RECT rcClient;
if (GetClientRect(hWndParent, &rcClient) && SetWindowPos(hwndDlg, NULL, 0, 0, rcClient.right, rcClient.bottom, SWP_NOZORDER)) { /* subclass the parent window. This is not safe if the parent window belongs to another thread! */ hpd->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent, GWLP_WNDPROC, (LONG_PTR)ParentSubWndProc);
if (hpd->ParentOldWndProc != NULL && SetProp(hWndParent, L"DevMgrSubClassInfo", (HANDLE)hpd)) { hpd->hWndParent = hWndParent; } } }
/* initialize the devices list view control */ InitializeDevicesList(hpd);
/* fill the devices list view control */ FillDevicesListViewControl(hpd, NULL, NULL);
/* decide whether to show or hide the troubleshoot button */ EnableTroubleShoot(hpd, GetWindowTextLength(hwndDlg) != 0); } Ret = TRUE; break; }
case WM_DESTROY: { /* zero hpd pointer in window data, because it can be used later (WM_DESTROY has not to be last message) */ SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)NULL);
/* free devices list */ FreeDevicesList(hpd);
/* restore the old window proc of the subclassed parent window */ if (hpd->hWndParent != NULL && hpd->ParentOldWndProc != NULL) { SetWindowLongPtr(hpd->hWndParent, GWLP_WNDPROC, (LONG_PTR)hpd->ParentOldWndProc); }
if (hpd->ClassImageListData.ImageList != NULL) { SetupDiDestroyClassImageList(&hpd->ClassImageListData); }
/* free the reference to comctl32 */ FreeLibrary(hpd->hComCtl32); hpd->hComCtl32 = NULL;
/* free the allocated resources */ HeapFree(GetProcessHeap(), 0, hpd); break; } } }
return Ret;}
/*************************************************************************** * NAME EXPORTED * DeviceCreateHardwarePageEx * * DESCRIPTION * Creates a hardware page * * ARGUMENTS * hWndParent: Handle to the parent window * lpGuids: An array of guids of devices that are to be listed * uNumberOfGuids: Numbers of guids in the Guids array * DisplayMode: Sets the size of the device list view control * * RETURN VALUE * Returns the handle of the hardware page window that has been created or * NULL if it failed. * * @implemented */HWNDWINAPIDeviceCreateHardwarePageEx(IN HWND hWndParent, IN LPGUID lpGuids, IN UINT uNumberOfGuids, IN HWPAGE_DISPLAYMODE DisplayMode){ PHARDWARE_PAGE_DATA hpd;
/* allocate the HARDWARE_PAGE_DATA structure. Make sure it is zeroed because the initialization code assumes that in failure cases! */ hpd = (PHARDWARE_PAGE_DATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, DYNAMIC_FIELD_OFFSET(HARDWARE_PAGE_DATA, ClassDevInfo[uNumberOfGuids])); if (hpd != NULL) { HWND hWnd; UINT i;
hpd->DisplayMode = ((DisplayMode > HWPD_MAX) ? HWPD_STANDARDLIST : DisplayMode);
/* initialize the HARDWARE_PAGE_DATA structure */ hpd->NumberOfGuids = uNumberOfGuids; for (i = 0; i < uNumberOfGuids; i++) { hpd->ClassDevInfo[i].hDevInfo = INVALID_HANDLE_VALUE; hpd->ClassDevInfo[i].Guid = lpGuids[i]; }
/* load comctl32.dll dynamically */ hpd->hComCtl32 = LoadAndInitComctl32(); if (hpd->hComCtl32 == NULL) { goto Cleanup; }
/* create the dialog */ hWnd = CreateDialogParam(hDllInstance, MAKEINTRESOURCE(IDD_HARDWARE), hWndParent, HardwareDlgProc, (LPARAM)hpd); if (hWnd != NULL) { return hWnd; } else {Cleanup: /* oops, something went wrong... */ if (hpd->hComCtl32 != NULL) { FreeLibrary(hpd->hComCtl32); }
HeapFree(GetProcessHeap(), 0, hpd); } }
return NULL;}
/*************************************************************************** * NAME EXPORTED * DeviceCreateHardwarePage * * DESCRIPTION * Creates a hardware page * * ARGUMENTS * hWndParent: Handle to the parent window * lpGuid: Guid of the device * * RETURN VALUE * Returns the handle of the hardware page window that has been created or * NULL if it failed. * * @implemented */HWNDWINAPIDeviceCreateHardwarePage(IN HWND hWndParent, IN LPGUID lpGuid){ return DeviceCreateHardwarePageEx(hWndParent, lpGuid, 1, HWPD_LARGELIST);}