2 * ReactOS Device Manager Applet
3 * Copyright (C) 2004 - 2005 ReactOS Team
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 * PROJECT: ReactOS devmgr.dll
21 * FILE: lib/devmgr/hwpage.c
22 * PURPOSE: ReactOS Device Manager
23 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
29 #include <devmgr\devmgr.h>
30 #include "properties.h"
34 typedef struct _HWDEVINFO
36 struct _HWCLASSDEVINFO
*ClassDevInfo
;
37 SP_DEVINFO_DATA DevInfoData
;
39 } HWDEVINFO
, *PHWDEVINFO
;
41 typedef struct _HWCLASSDEVINFO
48 } HWCLASSDEVINFO
, *PHWCLASSDEVINFO
;
50 typedef struct _HARDWARE_PAGE_DATA
54 HINSTANCE hComCtl32
; /* only save this to keep track of the references */
55 INT DevListViewHeight
;
56 SP_CLASSIMAGELIST_DATA ClassImageListData
;
57 HWPAGE_DISPLAYMODE DisplayMode
;
59 /* parent window subclass info */
60 WNDPROC ParentOldWndProc
;
64 HWCLASSDEVINFO ClassDevInfo
[1];
65 /* struct may be dynamically expanded here! */
66 } HARDWARE_PAGE_DATA
, *PHARDWARE_PAGE_DATA
;
68 #define CX_TYPECOLUMN_WIDTH 80
71 InitializeDevicesList(IN PHARDWARE_PAGE_DATA hpd
)
78 /* set the list view style */
79 (void)ListView_SetExtendedListViewStyle(hpd
->hWndDevList
,
80 LVS_EX_FULLROWSELECT
);
82 /* set the list view image list */
83 if (hpd
->ClassImageListData
.ImageList
!= NULL
)
85 (void)ListView_SetImageList(hpd
->hWndDevList
,
86 hpd
->ClassImageListData
.ImageList
,
90 GetClientRect(hpd
->hWndDevList
,
93 /* add the list view columns */
94 lvc
.mask
= LVCF_TEXT
| LVCF_WIDTH
;
95 lvc
.fmt
= LVCFMT_LEFT
;
96 lvc
.pszText
= szColName
;
98 if (LoadString(hDllInstance
,
101 sizeof(szColName
) / sizeof(szColName
[0])))
103 lvc
.cx
= rcClient
.right
- CX_TYPECOLUMN_WIDTH
-
104 GetSystemMetrics(SM_CXVSCROLL
);
105 (void)ListView_InsertColumn(hpd
->hWndDevList
,
109 if (LoadString(hDllInstance
,
112 sizeof(szColName
) / sizeof(szColName
[0])))
114 lvc
.cx
= CX_TYPECOLUMN_WIDTH
;
115 (void)ListView_InsertColumn(hpd
->hWndDevList
,
123 DisplaySelectedDeviceProperties(IN PHARDWARE_PAGE_DATA hpd
)
125 PHWDEVINFO HwDevInfo
;
126 SP_DEVINFO_DATA DevInfoData
;
129 HwDevInfo
= (PHWDEVINFO
)ListViewGetSelectedItemData(hpd
->hWndDevList
);
130 if (HwDevInfo
!= NULL
)
132 /* make a copy of the SP_DEVINFO_DATA structure on the stack, it may
133 become invalid in case the devices are updated */
134 DevInfoData
= HwDevInfo
->DevInfoData
;
136 /* display the advanced properties */
137 Ret
= DisplayDeviceAdvancedProperties(hpd
->hWnd
,
139 HwDevInfo
->ClassDevInfo
->hDevInfo
,
151 UpdateControlStates(IN PHARDWARE_PAGE_DATA hpd
)
153 PHWDEVINFO HwDevInfo
;
154 HWND hBtnTroubleShoot
, hBtnProperties
;
156 hBtnTroubleShoot
= GetDlgItem(hpd
->hWnd
,
158 hBtnProperties
= GetDlgItem(hpd
->hWnd
,
161 HwDevInfo
= (PHWDEVINFO
)ListViewGetSelectedItemData(hpd
->hWndDevList
);
162 if (HwDevInfo
!= NULL
)
164 /* update static controls */
166 LPWSTR szFormatted
= NULL
;
168 /* get the manufacturer string */
169 if (GetDeviceManufacturerString(HwDevInfo
->ClassDevInfo
->hDevInfo
,
170 &HwDevInfo
->DevInfoData
,
172 sizeof(szBuffer
) / sizeof(szBuffer
[0])) &&
173 LoadAndFormatString(hDllInstance
,
178 SetDlgItemText(hpd
->hWnd
,
181 LocalFree((HLOCAL
)szFormatted
);
184 /* get the location string */
185 if (GetDeviceLocationString(HwDevInfo
->ClassDevInfo
->hDevInfo
,
186 &HwDevInfo
->DevInfoData
,
189 sizeof(szBuffer
) / sizeof(szBuffer
[0])) &&
190 LoadAndFormatString(hDllInstance
,
195 SetDlgItemText(hpd
->hWnd
,
198 LocalFree((HLOCAL
)szFormatted
);
201 if (GetDeviceStatusString(HwDevInfo
->DevInfoData
.DevInst
,
204 sizeof(szBuffer
) / sizeof(szBuffer
[0])) &&
205 LoadAndFormatString(hDllInstance
,
210 SetDlgItemText(hpd
->hWnd
,
213 LocalFree((HLOCAL
)szFormatted
);
218 /* clear static controls */
219 SetDlgItemText(hpd
->hWnd
,
222 SetDlgItemText(hpd
->hWnd
,
225 SetDlgItemText(hpd
->hWnd
,
230 EnableWindow(hBtnTroubleShoot
,
232 EnableWindow(hBtnProperties
,
238 FreeDevicesList(IN PHARDWARE_PAGE_DATA hpd
)
240 PHWCLASSDEVINFO ClassDevInfo
, LastClassDevInfo
;
242 ClassDevInfo
= hpd
->ClassDevInfo
;
243 LastClassDevInfo
= ClassDevInfo
+ hpd
->NumberOfGuids
;
245 /* free the device info set handles and structures */
246 while (ClassDevInfo
!= LastClassDevInfo
)
248 if (ClassDevInfo
->hDevInfo
!= INVALID_HANDLE_VALUE
)
250 SetupDiDestroyDeviceInfoList(ClassDevInfo
->hDevInfo
);
251 ClassDevInfo
->hDevInfo
= INVALID_HANDLE_VALUE
;
254 ClassDevInfo
->ItemCount
= 0;
255 ClassDevInfo
->ImageIndex
= 0;
257 if (ClassDevInfo
->HwDevInfo
!= NULL
)
259 HeapFree(GetProcessHeap(),
261 ClassDevInfo
->HwDevInfo
);
262 ClassDevInfo
->HwDevInfo
= NULL
;
271 BuildDevicesList(IN PHARDWARE_PAGE_DATA hpd
)
273 PHWCLASSDEVINFO ClassDevInfo
, LastClassDevInfo
;
274 SP_DEVINFO_DATA DevInfoData
;
276 DevInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
278 ClassDevInfo
= hpd
->ClassDevInfo
;
279 LastClassDevInfo
= ClassDevInfo
+ hpd
->NumberOfGuids
;
281 while (ClassDevInfo
!= LastClassDevInfo
)
283 ClassDevInfo
->ImageIndex
= -1;
285 /* open a class device handle for the GUID we're processing */
286 ClassDevInfo
->hDevInfo
= SetupDiGetClassDevs(&ClassDevInfo
->Guid
,
289 DIGCF_PRESENT
| DIGCF_PROFILE
);
290 if (ClassDevInfo
->hDevInfo
!= INVALID_HANDLE_VALUE
)
292 DWORD MemberIndex
= 0;
294 SetupDiGetClassImageIndex(&hpd
->ClassImageListData
,
296 &ClassDevInfo
->ImageIndex
);
298 /* enumerate all devices in the class */
299 while (SetupDiEnumDeviceInfo(ClassDevInfo
->hDevInfo
,
303 BOOL HideDevice
= FALSE
;
305 if (ClassDevInfo
->HwDevInfo
!= NULL
)
307 PHWDEVINFO HwNewDevInfo
= (PHWDEVINFO
)HeapReAlloc(GetProcessHeap(),
309 ClassDevInfo
->HwDevInfo
,
310 (ClassDevInfo
->ItemCount
+ 1) *
312 if (HwNewDevInfo
!= NULL
)
314 ClassDevInfo
->HwDevInfo
= HwNewDevInfo
;
318 ERR("Unable to allocate memory for %d SP_DEVINFO_DATA structures!\n",
319 ClassDevInfo
->ItemCount
+ 1);
325 ClassDevInfo
->HwDevInfo
= (PHWDEVINFO
)HeapAlloc(GetProcessHeap(),
328 if (ClassDevInfo
->HwDevInfo
== NULL
)
330 ERR("Unable to allocate memory for a SP_DEVINFO_DATA structures!\n");
335 /* Find out if the device should be hidden by default */
336 IsDeviceHidden(DevInfoData
.DevInst
,
340 /* save all information for the current device */
341 ClassDevInfo
->HwDevInfo
[ClassDevInfo
->ItemCount
].ClassDevInfo
= ClassDevInfo
;
342 ClassDevInfo
->HwDevInfo
[ClassDevInfo
->ItemCount
].DevInfoData
= DevInfoData
;
343 ClassDevInfo
->HwDevInfo
[ClassDevInfo
->ItemCount
++].HideDevice
= HideDevice
;
353 DeviceIdMatch(IN HDEVINFO DeviceInfoSet
,
354 IN PSP_DEVINFO_DATA DeviceInfoData
,
355 IN LPCWSTR lpDeviceId
)
358 LPWSTR lpQueriedDeviceId
;
361 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet
,
366 GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
368 if (DevIdLen
== wcslen(lpDeviceId
) + 1)
370 lpQueriedDeviceId
= (LPWSTR
)HeapAlloc(GetProcessHeap(),
372 DevIdLen
* sizeof(WCHAR
));
373 if (lpQueriedDeviceId
!= NULL
)
375 if (SetupDiGetDeviceInstanceId(DeviceInfoSet
,
381 Ret
= (wcscmp(lpDeviceId
,
382 lpQueriedDeviceId
) == 0);
385 HeapFree(GetProcessHeap(),
397 FillDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd
,
398 IN LPCWSTR lpSelectDeviceId OPTIONAL
,
399 IN GUID
*SelectedClassGuid OPTIONAL
)
401 PHWCLASSDEVINFO ClassDevInfo
, LastClassDevInfo
;
402 PHWDEVINFO HwDevInfo
, LastHwDevInfo
;
404 BOOL SelectedInClass
;
407 BuildDevicesList(hpd
);
409 ClassDevInfo
= hpd
->ClassDevInfo
;
410 LastClassDevInfo
= ClassDevInfo
+ hpd
->NumberOfGuids
;
412 while (ClassDevInfo
!= LastClassDevInfo
)
414 if (ClassDevInfo
->HwDevInfo
!= NULL
)
416 HwDevInfo
= ClassDevInfo
->HwDevInfo
;
417 LastHwDevInfo
= HwDevInfo
+ ClassDevInfo
->ItemCount
;
419 SelectedInClass
= (SelectedClassGuid
!= NULL
&&
420 IsEqualGUID(*SelectedClassGuid
,
421 ClassDevInfo
->Guid
));
422 while (HwDevInfo
!= LastHwDevInfo
)
427 /* get the device name */
428 if (!HwDevInfo
->HideDevice
&&
429 GetDeviceDescriptionString(ClassDevInfo
->hDevInfo
,
430 &HwDevInfo
->DevInfoData
,
432 sizeof(szBuffer
) / sizeof(szBuffer
[0])))
434 li
.mask
= LVIF_PARAM
| LVIF_STATE
| LVIF_TEXT
| LVIF_IMAGE
;
435 li
.iItem
= ItemCount
;
436 if ((ItemCount
== 0 && lpSelectDeviceId
== NULL
) ||
438 DeviceIdMatch(ClassDevInfo
->hDevInfo
,
439 &HwDevInfo
->DevInfoData
,
442 li
.state
= LVIS_SELECTED
;
444 li
.stateMask
= LVIS_SELECTED
;
445 li
.pszText
= szBuffer
;
446 li
.iImage
= ClassDevInfo
->ImageIndex
;
447 li
.lParam
= (LPARAM
)HwDevInfo
;
449 iItem
= ListView_InsertItem(hpd
->hWndDevList
,
455 /* get the device type for the second column */
456 if (GetDeviceTypeString(&HwDevInfo
->DevInfoData
,
458 sizeof(szBuffer
) / sizeof(szBuffer
[0])))
464 (void)ListView_SetItem(hpd
->hWndDevList
,
477 /* update the controls */
478 UpdateControlStates(hpd
);
483 UpdateDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd
)
485 PHWDEVINFO HwDevInfo
;
486 GUID SelectedClassGuid
= {0};
487 LPWSTR lpDeviceId
= NULL
;
489 /* if a device currently is selected, remember the device id so we can
490 select the device after the update if still present */
491 HwDevInfo
= (PHWDEVINFO
)ListViewGetSelectedItemData(hpd
->hWndDevList
);
492 if (HwDevInfo
!= NULL
)
495 if (!SetupDiGetDeviceInstanceId(HwDevInfo
->ClassDevInfo
->hDevInfo
,
496 &HwDevInfo
->DevInfoData
,
500 GetLastError() == ERROR_INSUFFICIENT_BUFFER
)
502 SelectedClassGuid
= HwDevInfo
->DevInfoData
.ClassGuid
;
503 lpDeviceId
= (LPWSTR
)HeapAlloc(GetProcessHeap(),
505 DevIdLen
* sizeof(WCHAR
));
506 if (lpDeviceId
!= NULL
&&
507 !SetupDiGetDeviceInstanceId(HwDevInfo
->ClassDevInfo
->hDevInfo
,
508 &HwDevInfo
->DevInfoData
,
513 HeapFree(GetProcessHeap(),
521 /* clear the devices list view control */
522 (void)ListView_DeleteAllItems(hpd
->hWndDevList
);
524 /* free the device list */
525 FreeDevicesList(hpd
);
527 /* build rebuild the device list and fill the list box again */
528 FillDevicesListViewControl(hpd
,
530 (lpDeviceId
!= NULL
?
534 if (lpDeviceId
!= NULL
)
536 HeapFree(GetProcessHeap(),
545 ParentSubWndProc(IN HWND hwnd
,
550 PHARDWARE_PAGE_DATA hpd
;
552 hpd
= (PHARDWARE_PAGE_DATA
)GetProp(hwnd
,
553 L
"DevMgrSubClassInfo");
558 /* resize the hardware page */
559 SetWindowPos(hpd
->hWnd
,
567 else if (uMsg
== WM_DEVICECHANGE
&& IsWindowVisible(hpd
->hWnd
))
569 /* forward a WM_DEVICECHANGE message to the hardware
570 page which wouldn't get the message itself as it is
572 SendMessage(hpd
->hWnd
,
578 /* pass the message the the old window proc */
579 return CallWindowProc(hpd
->ParentOldWndProc
,
587 /* this is not a good idea if the subclassed window was an ansi
588 window, but we failed finding out the previous window proc
589 so we can't use CallWindowProc. This should rarely - if ever -
592 return DefWindowProc(hwnd
,
601 HardwareDlgResize(IN PHARDWARE_PAGE_DATA hpd
,
606 HWND hControl
, hButton
;
610 POINT ptMargin
= {0};
611 POINT ptMarginGroup
= {0};
613 /* use left margin of the IDC_DEVICES label as the right
614 margin of all controls outside the group box */
615 hControl
= GetDlgItem(hpd
->hWnd
,
617 GetWindowRect(hControl
,
619 MapWindowPoints(hControl
,
624 Width
= cx
- (2 * ptMargin
.x
);
626 if ((dwp
= BeginDeferWindowPos(8)))
628 /* rc already has the window rect of IDC_DEVICES! */
629 if (!(dwp
= DeferWindowPos(dwp
,
636 SWP_NOMOVE
| SWP_NOZORDER
)))
641 /* resize the devices list view control */
642 GetWindowRect(hpd
->hWndDevList
,
644 MapWindowPoints(hpd
->hWndDevList
,
648 y
= pt
.y
+ hpd
->DevListViewHeight
+ ptMargin
.y
;
649 if (!(dwp
= DeferWindowPos(dwp
,
655 hpd
->DevListViewHeight
,
656 SWP_NOMOVE
| SWP_NOZORDER
)))
661 /* resize the group box control */
662 hControl
= GetDlgItem(hpd
->hWnd
,
663 IDC_PROPERTIESGROUP
);
664 GetWindowRect(hControl
,
666 if (!(dwp
= DeferWindowPos(dwp
,
678 /* use left margin of the IDC_MANUFACTURER label as the right
679 margin of all controls inside the group box */
680 hControl
= GetDlgItem(hpd
->hWnd
,
682 GetWindowRect(hControl
,
684 MapWindowPoints(hControl
,
689 ptMarginGroup
.y
= ptMargin
.y
* 2;
690 Width
= cx
- (2 * ptMarginGroup
.x
);
691 y
+= ptMarginGroup
.y
;
692 if (!(dwp
= DeferWindowPos(dwp
,
703 y
+= rc
.bottom
- rc
.top
+ (ptMargin
.y
/ 2);
705 /* resize the IDC_LOCATION label */
706 hControl
= GetDlgItem(hpd
->hWnd
,
708 GetWindowRect(hControl
,
710 if (!(dwp
= DeferWindowPos(dwp
,
721 y
+= rc
.bottom
- rc
.top
+ (ptMargin
.y
/ 2);
723 /* measure the size of the buttons */
724 hButton
= GetDlgItem(hpd
->hWnd
,
726 GetWindowRect(hButton
,
729 /* resize the IDC_STATUS label */
730 hControl
= GetDlgItem(hpd
->hWnd
,
732 GetWindowRect(hControl
,
734 if (!(dwp
= DeferWindowPos(dwp
,
740 cy
- y
- (3 * ptMargin
.y
) -
741 (rcButton
.bottom
- rcButton
.top
),
747 /* move the IDC_PROPERTIES button */
748 y
= cy
- (2 * ptMargin
.y
) - (rcButton
.bottom
- rcButton
.top
);
749 x
= cx
- ptMarginGroup
.x
- (rcButton
.right
- rcButton
.left
);
750 if (!(dwp
= DeferWindowPos(dwp
,
757 SWP_NOSIZE
| SWP_NOZORDER
)))
762 /* move the IDC_TROUBLESHOOT button */
763 hButton
= GetDlgItem(hpd
->hWnd
,
765 GetWindowRect(hButton
,
767 x
-= (ptMargin
.x
/ 2) + (rcButton
.right
- rcButton
.left
);
768 if (!(dwp
= DeferWindowPos(dwp
,
775 SWP_NOSIZE
| SWP_NOZORDER
)))
780 EndDeferWindowPos(dwp
);
786 EnableTroubleShoot(PHARDWARE_PAGE_DATA hpd
,
789 HWND hBtnTroubleShoot
= GetDlgItem(hpd
->hWnd
,
792 ShowWindow(hBtnTroubleShoot
,
793 Enable
? SW_SHOW
: SW_HIDE
);
799 HardwareDlgProc(IN HWND hwndDlg
,
804 PHARDWARE_PAGE_DATA hpd
;
807 hpd
= (PHARDWARE_PAGE_DATA
)GetWindowLongPtr(hwndDlg
,
810 if (hpd
!= NULL
|| uMsg
== WM_INITDIALOG
)
816 NMHDR
*pnmh
= (NMHDR
*)lParam
;
817 if (pnmh
->hwndFrom
== hpd
->hWndDevList
)
821 case LVN_ITEMCHANGED
:
823 LPNMLISTVIEW pnmv
= (LPNMLISTVIEW
)lParam
;
825 if ((pnmv
->uChanged
& LVIF_STATE
) &&
826 ((pnmv
->uOldState
& (LVIS_FOCUSED
| LVIS_SELECTED
)) ||
827 (pnmv
->uNewState
& (LVIS_FOCUSED
| LVIS_SELECTED
))))
829 UpdateControlStates(hpd
);
836 DisplaySelectedDeviceProperties(hpd
);
846 switch (LOWORD(wParam
))
848 case IDC_TROUBLESHOOT
:
850 /* FIXME - start the help using the command in the window text */
856 DisplaySelectedDeviceProperties(hpd
);
864 HardwareDlgResize(hpd
,
866 (INT
)HIWORD(lParam
));
871 LPCWSTR szWndText
= (LPCWSTR
)lParam
;
872 EnableTroubleShoot(hpd
,
873 (szWndText
!= NULL
&& szWndText
[0] != L
'\0'));
877 case WM_DEVICECHANGE
:
879 /* FIXME - don't call UpdateDevicesListViewControl for all events */
880 UpdateDevicesListViewControl(hpd
);
887 hpd
= (PHARDWARE_PAGE_DATA
)lParam
;
893 SetWindowLongPtr(hwndDlg
,
897 hpd
->ClassImageListData
.cbSize
= sizeof(SP_CLASSIMAGELIST_DATA
);
899 SetupDiGetClassImageList(&hpd
->ClassImageListData
);
901 /* calculate the size of the devices list view control */
902 hpd
->hWndDevList
= GetDlgItem(hwndDlg
,
904 if (hpd
->hWndDevList
!= NULL
)
907 GetClientRect(hpd
->hWndDevList
,
909 hpd
->DevListViewHeight
= rcClient
.bottom
;
911 if (hpd
->DisplayMode
== HWPD_LARGELIST
)
913 hpd
->DevListViewHeight
= (hpd
->DevListViewHeight
* 3) / 2;
917 /* subclass the parent window */
918 hWndParent
= GetAncestor(hwndDlg
,
920 if (hWndParent
!= NULL
)
924 if (GetClientRect(hWndParent
,
926 SetWindowPos(hwndDlg
,
934 /* subclass the parent window. This is not safe
935 if the parent window belongs to another thread! */
936 hpd
->ParentOldWndProc
= (WNDPROC
)SetWindowLongPtr(hWndParent
,
938 (LONG_PTR
)ParentSubWndProc
);
940 if (hpd
->ParentOldWndProc
!= NULL
&&
942 L
"DevMgrSubClassInfo",
945 hpd
->hWndParent
= hWndParent
;
950 /* initialize the devices list view control */
951 InitializeDevicesList(hpd
);
953 /* fill the devices list view control */
954 FillDevicesListViewControl(hpd
,
958 /* decide whether to show or hide the troubleshoot button */
959 EnableTroubleShoot(hpd
,
960 GetWindowTextLength(hwndDlg
) != 0);
968 /* zero hpd pointer in window data, because it can be used later (WM_DESTROY has not to be last message) */
969 SetWindowLongPtr(hwndDlg
, DWL_USER
, (DWORD_PTR
)NULL
);
971 /* free devices list */
972 FreeDevicesList(hpd
);
974 /* restore the old window proc of the subclassed parent window */
975 if (hpd
->hWndParent
!= NULL
&& hpd
->ParentOldWndProc
!= NULL
)
977 SetWindowLongPtr(hpd
->hWndParent
,
979 (LONG_PTR
)hpd
->ParentOldWndProc
);
982 if (hpd
->ClassImageListData
.ImageList
!= NULL
)
984 SetupDiDestroyClassImageList(&hpd
->ClassImageListData
);
987 /* free the reference to comctl32 */
988 FreeLibrary(hpd
->hComCtl32
);
989 hpd
->hComCtl32
= NULL
;
991 /* free the allocated resources */
992 HeapFree(GetProcessHeap(),
1004 /***************************************************************************
1006 * DeviceCreateHardwarePageEx
1009 * Creates a hardware page
1012 * hWndParent: Handle to the parent window
1013 * lpGuids: An array of guids of devices that are to be listed
1014 * uNumberOfGuids: Numbers of guids in the Guids array
1015 * DisplayMode: Sets the size of the device list view control
1018 * Returns the handle of the hardware page window that has been created or
1019 * NULL if it failed.
1025 DeviceCreateHardwarePageEx(IN HWND hWndParent
,
1027 IN UINT uNumberOfGuids
,
1028 IN HWPAGE_DISPLAYMODE DisplayMode
)
1030 PHARDWARE_PAGE_DATA hpd
;
1032 /* allocate the HARDWARE_PAGE_DATA structure. Make sure it is
1033 zeroed because the initialization code assumes that in
1035 hpd
= (PHARDWARE_PAGE_DATA
)HeapAlloc(GetProcessHeap(),
1037 FIELD_OFFSET(HARDWARE_PAGE_DATA
,
1038 ClassDevInfo
[uNumberOfGuids
]));
1044 hpd
->DisplayMode
= ((DisplayMode
> HWPD_MAX
) ? HWPD_STANDARDLIST
: DisplayMode
);
1046 /* initialize the HARDWARE_PAGE_DATA structure */
1047 hpd
->NumberOfGuids
= uNumberOfGuids
;
1052 hpd
->ClassDevInfo
[i
].hDevInfo
= INVALID_HANDLE_VALUE
;
1053 hpd
->ClassDevInfo
[i
].Guid
= lpGuids
[i
];
1056 /* load comctl32.dll dynamically */
1057 hpd
->hComCtl32
= LoadAndInitComctl32();
1058 if (hpd
->hComCtl32
== NULL
)
1063 /* create the dialog */
1064 hWnd
= CreateDialogParam(hDllInstance
,
1065 MAKEINTRESOURCE(IDD_HARDWARE
),
1071 HeapFree(GetProcessHeap(), 0, hpd
);
1077 /* oops, something went wrong... */
1078 if (hpd
->hComCtl32
!= NULL
)
1080 FreeLibrary(hpd
->hComCtl32
);
1083 HeapFree(GetProcessHeap(),
1093 /***************************************************************************
1095 * DeviceCreateHardwarePage
1098 * Creates a hardware page
1101 * hWndParent: Handle to the parent window
1102 * lpGuid: Guid of the device
1105 * Returns the handle of the hardware page window that has been created or
1106 * NULL if it failed.
1112 DeviceCreateHardwarePage(IN HWND hWndParent
,
1115 return DeviceCreateHardwarePageEx(hWndParent
,