Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhwpage.c
Go to the documentation of this file.
00001 /* 00002 * ReactOS Device Manager Applet 00003 * Copyright (C) 2004 - 2005 ReactOS Team 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 /* $Id: hwpage.c 51105 2011-03-21 14:21:16Z rharabien $ 00020 * 00021 * PROJECT: ReactOS devmgr.dll 00022 * FILE: lib/devmgr/hwpage.c 00023 * PURPOSE: ReactOS Device Manager 00024 * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com> 00025 * UPDATE HISTORY: 00026 * 04-04-2004 Created 00027 */ 00028 #include <precomp.h> 00029 00030 #define NDEBUG 00031 #include <debug.h> 00032 00033 typedef struct _HWDEVINFO 00034 { 00035 struct _HWCLASSDEVINFO *ClassDevInfo; 00036 SP_DEVINFO_DATA DevInfoData; 00037 BOOL HideDevice; 00038 } HWDEVINFO, *PHWDEVINFO; 00039 00040 typedef struct _HWCLASSDEVINFO 00041 { 00042 GUID Guid; 00043 HDEVINFO hDevInfo; 00044 INT ImageIndex; 00045 INT ItemCount; 00046 PHWDEVINFO HwDevInfo; 00047 } HWCLASSDEVINFO, *PHWCLASSDEVINFO; 00048 00049 typedef struct _HARDWARE_PAGE_DATA 00050 { 00051 HWND hWnd; 00052 HWND hWndDevList; 00053 HINSTANCE hComCtl32; /* only save this to keep track of the references */ 00054 INT DevListViewHeight; 00055 SP_CLASSIMAGELIST_DATA ClassImageListData; 00056 HWPAGE_DISPLAYMODE DisplayMode; 00057 00058 /* parent window subclass info */ 00059 WNDPROC ParentOldWndProc; 00060 HWND hWndParent; 00061 00062 UINT NumberOfGuids; 00063 HWCLASSDEVINFO ClassDevInfo[1]; 00064 /* struct may be dynamically expanded here! */ 00065 } HARDWARE_PAGE_DATA, *PHARDWARE_PAGE_DATA; 00066 00067 #define CX_TYPECOLUMN_WIDTH 80 00068 00069 static VOID 00070 InitializeDevicesList(IN PHARDWARE_PAGE_DATA hpd) 00071 { 00072 LVCOLUMN lvc; 00073 RECT rcClient; 00074 WCHAR szColName[255]; 00075 int iCol = 0; 00076 00077 /* set the list view style */ 00078 (void)ListView_SetExtendedListViewStyle(hpd->hWndDevList, 00079 LVS_EX_FULLROWSELECT); 00080 00081 /* set the list view image list */ 00082 if (hpd->ClassImageListData.ImageList != NULL) 00083 { 00084 (void)ListView_SetImageList(hpd->hWndDevList, 00085 hpd->ClassImageListData.ImageList, 00086 LVSIL_SMALL); 00087 } 00088 00089 GetClientRect(hpd->hWndDevList, 00090 &rcClient); 00091 00092 /* add the list view columns */ 00093 lvc.mask = LVCF_TEXT | LVCF_WIDTH; 00094 lvc.fmt = LVCFMT_LEFT; 00095 lvc.pszText = szColName; 00096 00097 if (LoadString(hDllInstance, 00098 IDS_NAME, 00099 szColName, 00100 sizeof(szColName) / sizeof(szColName[0]))) 00101 { 00102 lvc.cx = rcClient.right - CX_TYPECOLUMN_WIDTH - 00103 GetSystemMetrics(SM_CXVSCROLL); 00104 (void)ListView_InsertColumn(hpd->hWndDevList, 00105 iCol++, 00106 &lvc); 00107 } 00108 if (LoadString(hDllInstance, 00109 IDS_TYPE, 00110 szColName, 00111 sizeof(szColName) / sizeof(szColName[0]))) 00112 { 00113 lvc.cx = CX_TYPECOLUMN_WIDTH; 00114 (void)ListView_InsertColumn(hpd->hWndDevList, 00115 iCol++, 00116 &lvc); 00117 } 00118 } 00119 00120 00121 static BOOL 00122 DisplaySelectedDeviceProperties(IN PHARDWARE_PAGE_DATA hpd) 00123 { 00124 PHWDEVINFO HwDevInfo; 00125 SP_DEVINFO_DATA DevInfoData; 00126 BOOL Ret = FALSE; 00127 00128 HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); 00129 if (HwDevInfo != NULL) 00130 { 00131 /* make a copy of the SP_DEVINFO_DATA structure on the stack, it may 00132 become invalid in case the devices are updated */ 00133 DevInfoData = HwDevInfo->DevInfoData; 00134 00135 /* display the advanced properties */ 00136 Ret = DisplayDeviceAdvancedProperties(hpd->hWnd, 00137 NULL, 00138 HwDevInfo->ClassDevInfo->hDevInfo, 00139 &DevInfoData, 00140 hpd->hComCtl32, 00141 NULL, 00142 0) != -1; 00143 } 00144 00145 return Ret; 00146 } 00147 00148 00149 static VOID 00150 UpdateControlStates(IN PHARDWARE_PAGE_DATA hpd) 00151 { 00152 PHWDEVINFO HwDevInfo; 00153 HWND hBtnTroubleShoot, hBtnProperties; 00154 00155 hBtnTroubleShoot = GetDlgItem(hpd->hWnd, 00156 IDC_TROUBLESHOOT); 00157 hBtnProperties = GetDlgItem(hpd->hWnd, 00158 IDC_PROPERTIES); 00159 00160 HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); 00161 if (HwDevInfo != NULL) 00162 { 00163 /* update static controls */ 00164 WCHAR szBuffer[256]; 00165 LPWSTR szFormatted = NULL; 00166 00167 /* get the manufacturer string */ 00168 if (GetDeviceManufacturerString(HwDevInfo->ClassDevInfo->hDevInfo, 00169 &HwDevInfo->DevInfoData, 00170 szBuffer, 00171 sizeof(szBuffer) / sizeof(szBuffer[0])) && 00172 LoadAndFormatString(hDllInstance, 00173 IDS_MANUFACTURER, 00174 &szFormatted, 00175 szBuffer) != 0) 00176 { 00177 SetDlgItemText(hpd->hWnd, 00178 IDC_MANUFACTURER, 00179 szFormatted); 00180 LocalFree((HLOCAL)szFormatted); 00181 } 00182 00183 /* get the location string */ 00184 if (GetDeviceLocationString(HwDevInfo->ClassDevInfo->hDevInfo, 00185 &HwDevInfo->DevInfoData, 00186 0, 00187 szBuffer, 00188 sizeof(szBuffer) / sizeof(szBuffer[0])) && 00189 LoadAndFormatString(hDllInstance, 00190 IDS_LOCATION, 00191 &szFormatted, 00192 szBuffer) != 0) 00193 { 00194 SetDlgItemText(hpd->hWnd, 00195 IDC_LOCATION, 00196 szFormatted); 00197 LocalFree((HLOCAL)szFormatted); 00198 } 00199 00200 if (GetDeviceStatusString(HwDevInfo->DevInfoData.DevInst, 00201 NULL, 00202 szBuffer, 00203 sizeof(szBuffer) / sizeof(szBuffer[0])) && 00204 LoadAndFormatString(hDllInstance, 00205 IDS_STATUS, 00206 &szFormatted, 00207 szBuffer) != 0) 00208 { 00209 SetDlgItemText(hpd->hWnd, 00210 IDC_STATUS, 00211 szFormatted); 00212 LocalFree((HLOCAL)szFormatted); 00213 } 00214 } 00215 else 00216 { 00217 /* clear static controls */ 00218 SetDlgItemText(hpd->hWnd, 00219 IDC_MANUFACTURER, 00220 NULL); 00221 SetDlgItemText(hpd->hWnd, 00222 IDC_LOCATION, 00223 NULL); 00224 SetDlgItemText(hpd->hWnd, 00225 IDC_STATUS, 00226 NULL); 00227 } 00228 00229 EnableWindow(hBtnTroubleShoot, 00230 HwDevInfo != NULL); 00231 EnableWindow(hBtnProperties, 00232 HwDevInfo != NULL); 00233 } 00234 00235 00236 static VOID 00237 FreeDevicesList(IN PHARDWARE_PAGE_DATA hpd) 00238 { 00239 PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo; 00240 00241 ClassDevInfo = hpd->ClassDevInfo; 00242 LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids; 00243 00244 /* free the device info set handles and structures */ 00245 while (ClassDevInfo != LastClassDevInfo) 00246 { 00247 if (ClassDevInfo->hDevInfo != INVALID_HANDLE_VALUE) 00248 { 00249 SetupDiDestroyDeviceInfoList(ClassDevInfo->hDevInfo); 00250 ClassDevInfo->hDevInfo = INVALID_HANDLE_VALUE; 00251 } 00252 00253 ClassDevInfo->ItemCount = 0; 00254 ClassDevInfo->ImageIndex = 0; 00255 00256 if (ClassDevInfo->HwDevInfo != NULL) 00257 { 00258 HeapFree(GetProcessHeap(), 00259 0, 00260 ClassDevInfo->HwDevInfo); 00261 ClassDevInfo->HwDevInfo = NULL; 00262 } 00263 00264 ClassDevInfo++; 00265 } 00266 } 00267 00268 00269 static VOID 00270 BuildDevicesList(IN PHARDWARE_PAGE_DATA hpd) 00271 { 00272 PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo; 00273 SP_DEVINFO_DATA DevInfoData; 00274 00275 DevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 00276 00277 ClassDevInfo = hpd->ClassDevInfo; 00278 LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids; 00279 00280 while (ClassDevInfo != LastClassDevInfo) 00281 { 00282 ClassDevInfo->ImageIndex = -1; 00283 00284 /* open a class device handle for the GUID we're processing */ 00285 ClassDevInfo->hDevInfo = SetupDiGetClassDevs(&ClassDevInfo->Guid, 00286 NULL, 00287 hpd->hWnd, 00288 DIGCF_PRESENT | DIGCF_PROFILE); 00289 if (ClassDevInfo->hDevInfo != INVALID_HANDLE_VALUE) 00290 { 00291 DWORD MemberIndex = 0; 00292 00293 SetupDiGetClassImageIndex(&hpd->ClassImageListData, 00294 &ClassDevInfo->Guid, 00295 &ClassDevInfo->ImageIndex); 00296 00297 /* enumerate all devices in the class */ 00298 while (SetupDiEnumDeviceInfo(ClassDevInfo->hDevInfo, 00299 MemberIndex++, 00300 &DevInfoData)) 00301 { 00302 BOOL HideDevice = FALSE; 00303 00304 if (ClassDevInfo->HwDevInfo != NULL) 00305 { 00306 PHWDEVINFO HwNewDevInfo = HeapReAlloc(GetProcessHeap(), 00307 0, 00308 ClassDevInfo->HwDevInfo, 00309 (ClassDevInfo->ItemCount + 1) * 00310 sizeof(HWDEVINFO)); 00311 if (HwNewDevInfo != NULL) 00312 { 00313 ClassDevInfo->HwDevInfo = HwNewDevInfo; 00314 } 00315 else 00316 { 00317 DPRINT1("Unable to allocate memory for %d SP_DEVINFO_DATA structures!\n", 00318 ClassDevInfo->ItemCount + 1); 00319 break; 00320 } 00321 } 00322 else 00323 { 00324 ClassDevInfo->HwDevInfo = HeapAlloc(GetProcessHeap(), 00325 0, 00326 sizeof(HWDEVINFO)); 00327 if (ClassDevInfo->HwDevInfo == NULL) 00328 { 00329 DPRINT1("Unable to allocate memory for a SP_DEVINFO_DATA structures!\n"); 00330 break; 00331 } 00332 } 00333 00334 /* Find out if the device should be hidden by default */ 00335 IsDeviceHidden(DevInfoData.DevInst, 00336 NULL, 00337 &HideDevice); 00338 00339 /* save all information for the current device */ 00340 ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount].ClassDevInfo = ClassDevInfo; 00341 ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount].DevInfoData = DevInfoData; 00342 ClassDevInfo->HwDevInfo[ClassDevInfo->ItemCount++].HideDevice = HideDevice; 00343 } 00344 } 00345 00346 ClassDevInfo++; 00347 } 00348 } 00349 00350 00351 static BOOL 00352 DeviceIdMatch(IN HDEVINFO DeviceInfoSet, 00353 IN PSP_DEVINFO_DATA DeviceInfoData, 00354 IN LPCWSTR lpDeviceId) 00355 { 00356 DWORD DevIdLen; 00357 LPWSTR lpQueriedDeviceId; 00358 BOOL Ret = FALSE; 00359 00360 if (!SetupDiGetDeviceInstanceId(DeviceInfoSet, 00361 DeviceInfoData, 00362 NULL, 00363 0, 00364 &DevIdLen) && 00365 GetLastError() == ERROR_INSUFFICIENT_BUFFER) 00366 { 00367 if (DevIdLen == wcslen(lpDeviceId) + 1) 00368 { 00369 lpQueriedDeviceId = HeapAlloc(GetProcessHeap(), 00370 0, 00371 DevIdLen * sizeof(WCHAR)); 00372 if (lpQueriedDeviceId != NULL) 00373 { 00374 if (SetupDiGetDeviceInstanceId(DeviceInfoSet, 00375 DeviceInfoData, 00376 lpQueriedDeviceId, 00377 DevIdLen, 00378 NULL)) 00379 { 00380 Ret = (wcscmp(lpDeviceId, 00381 lpQueriedDeviceId) == 0); 00382 } 00383 00384 HeapFree(GetProcessHeap(), 00385 0, 00386 lpQueriedDeviceId); 00387 } 00388 } 00389 } 00390 00391 return Ret; 00392 } 00393 00394 00395 static VOID 00396 FillDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd, 00397 IN LPCWSTR lpSelectDeviceId OPTIONAL, 00398 IN GUID *SelectedClassGuid OPTIONAL) 00399 { 00400 PHWCLASSDEVINFO ClassDevInfo, LastClassDevInfo; 00401 PHWDEVINFO HwDevInfo, LastHwDevInfo; 00402 WCHAR szBuffer[255]; 00403 BOOL SelectedInClass; 00404 INT ItemCount = 0; 00405 00406 BuildDevicesList(hpd); 00407 00408 ClassDevInfo = hpd->ClassDevInfo; 00409 LastClassDevInfo = ClassDevInfo + hpd->NumberOfGuids; 00410 00411 while (ClassDevInfo != LastClassDevInfo) 00412 { 00413 if (ClassDevInfo->HwDevInfo != NULL) 00414 { 00415 HwDevInfo = ClassDevInfo->HwDevInfo; 00416 LastHwDevInfo = HwDevInfo + ClassDevInfo->ItemCount; 00417 00418 SelectedInClass = (SelectedClassGuid != NULL && 00419 IsEqualGUID(SelectedClassGuid, 00420 &ClassDevInfo->Guid)); 00421 while (HwDevInfo != LastHwDevInfo) 00422 { 00423 INT iItem; 00424 LVITEM li = {0}; 00425 00426 /* get the device name */ 00427 if (!HwDevInfo->HideDevice && 00428 GetDeviceDescriptionString(ClassDevInfo->hDevInfo, 00429 &HwDevInfo->DevInfoData, 00430 szBuffer, 00431 sizeof(szBuffer) / sizeof(szBuffer[0]))) 00432 { 00433 li.mask = LVIF_PARAM | LVIF_STATE | LVIF_TEXT | LVIF_IMAGE; 00434 li.iItem = ItemCount; 00435 if ((ItemCount == 0 && lpSelectDeviceId == NULL) || 00436 (SelectedInClass && 00437 DeviceIdMatch(ClassDevInfo->hDevInfo, 00438 &HwDevInfo->DevInfoData, 00439 lpSelectDeviceId))) 00440 { 00441 li.state = LVIS_SELECTED; 00442 } 00443 li.stateMask = LVIS_SELECTED; 00444 li.pszText = szBuffer; 00445 li.iImage = ClassDevInfo->ImageIndex; 00446 li.lParam = (LPARAM)HwDevInfo; 00447 00448 iItem = ListView_InsertItem(hpd->hWndDevList, 00449 &li); 00450 if (iItem != -1) 00451 { 00452 ItemCount++; 00453 00454 /* get the device type for the second column */ 00455 if (GetDeviceTypeString(&HwDevInfo->DevInfoData, 00456 szBuffer, 00457 sizeof(szBuffer) / sizeof(szBuffer[0]))) 00458 { 00459 li.mask = LVIF_TEXT; 00460 li.iItem = iItem; 00461 li.iSubItem = 1; 00462 00463 (void)ListView_SetItem(hpd->hWndDevList, 00464 &li); 00465 } 00466 } 00467 } 00468 00469 HwDevInfo++; 00470 } 00471 } 00472 00473 ClassDevInfo++; 00474 } 00475 00476 /* update the controls */ 00477 UpdateControlStates(hpd); 00478 } 00479 00480 00481 static VOID 00482 UpdateDevicesListViewControl(IN PHARDWARE_PAGE_DATA hpd) 00483 { 00484 PHWDEVINFO HwDevInfo; 00485 GUID SelectedClassGuid = {0}; 00486 LPWSTR lpDeviceId = NULL; 00487 00488 /* if a device currently is selected, remember the device id so we can 00489 select the device after the update if still present */ 00490 HwDevInfo = (PHWDEVINFO)ListViewGetSelectedItemData(hpd->hWndDevList); 00491 if (HwDevInfo != NULL) 00492 { 00493 DWORD DevIdLen; 00494 if (!SetupDiGetDeviceInstanceId(HwDevInfo->ClassDevInfo->hDevInfo, 00495 &HwDevInfo->DevInfoData, 00496 NULL, 00497 0, 00498 &DevIdLen) && 00499 GetLastError() == ERROR_INSUFFICIENT_BUFFER) 00500 { 00501 SelectedClassGuid = HwDevInfo->DevInfoData.ClassGuid; 00502 lpDeviceId = HeapAlloc(GetProcessHeap(), 00503 0, 00504 DevIdLen * sizeof(WCHAR)); 00505 if (lpDeviceId != NULL && 00506 !SetupDiGetDeviceInstanceId(HwDevInfo->ClassDevInfo->hDevInfo, 00507 &HwDevInfo->DevInfoData, 00508 lpDeviceId, 00509 DevIdLen, 00510 NULL)) 00511 { 00512 HeapFree(GetProcessHeap(), 00513 0, 00514 lpDeviceId); 00515 lpDeviceId = NULL; 00516 } 00517 } 00518 } 00519 00520 /* clear the devices list view control */ 00521 (void)ListView_DeleteAllItems(hpd->hWndDevList); 00522 00523 /* free the device list */ 00524 FreeDevicesList(hpd); 00525 00526 /* build rebuild the device list and fill the list box again */ 00527 FillDevicesListViewControl(hpd, 00528 lpDeviceId, 00529 (lpDeviceId != NULL ? 00530 &SelectedClassGuid : 00531 NULL)); 00532 00533 if (lpDeviceId != NULL) 00534 { 00535 HeapFree(GetProcessHeap(), 00536 0, 00537 lpDeviceId); 00538 } 00539 } 00540 00541 00542 static LRESULT 00543 CALLBACK 00544 ParentSubWndProc(IN HWND hwnd, 00545 IN UINT uMsg, 00546 IN WPARAM wParam, 00547 IN LPARAM lParam) 00548 { 00549 PHARDWARE_PAGE_DATA hpd; 00550 00551 hpd = (PHARDWARE_PAGE_DATA)GetProp(hwnd, 00552 L"DevMgrSubClassInfo"); 00553 if (hpd != NULL) 00554 { 00555 if (uMsg == WM_SIZE) 00556 { 00557 /* resize the hardware page */ 00558 SetWindowPos(hpd->hWnd, 00559 NULL, 00560 0, 00561 0, 00562 LOWORD(lParam), 00563 HIWORD(lParam), 00564 SWP_NOZORDER); 00565 } 00566 else if (uMsg == WM_DEVICECHANGE && IsWindowVisible(hpd->hWnd)) 00567 { 00568 /* forward a WM_DEVICECHANGE message to the hardware 00569 page which wouldn't get the message itself as it is 00570 a child window */ 00571 SendMessage(hpd->hWnd, 00572 WM_DEVICECHANGE, 00573 wParam, 00574 lParam); 00575 } 00576 00577 /* pass the message the the old window proc */ 00578 return CallWindowProc(hpd->ParentOldWndProc, 00579 hwnd, 00580 uMsg, 00581 wParam, 00582 lParam); 00583 } 00584 else 00585 { 00586 /* this is not a good idea if the subclassed window was an ansi 00587 window, but we failed finding out the previous window proc 00588 so we can't use CallWindowProc. This should rarely - if ever - 00589 happen. */ 00590 00591 return DefWindowProc(hwnd, 00592 uMsg, 00593 wParam, 00594 lParam); 00595 } 00596 } 00597 00598 00599 static VOID 00600 HardwareDlgResize(IN PHARDWARE_PAGE_DATA hpd, 00601 IN INT cx, 00602 IN INT cy) 00603 { 00604 HDWP dwp; 00605 HWND hControl, hButton; 00606 INT Width, x, y; 00607 RECT rc, rcButton; 00608 POINT pt = {0}; 00609 POINT ptMargin = {0}; 00610 POINT ptMarginGroup = {0}; 00611 00612 /* use left margin of the IDC_DEVICES label as the right 00613 margin of all controls outside the group box */ 00614 hControl = GetDlgItem(hpd->hWnd, 00615 IDC_DEVICES); 00616 GetWindowRect(hControl, 00617 &rc); 00618 MapWindowPoints(hControl, 00619 hpd->hWnd, 00620 &ptMargin, 00621 1); 00622 00623 Width = cx - (2 * ptMargin.x); 00624 00625 if ((dwp = BeginDeferWindowPos(8))) 00626 { 00627 /* rc already has the window rect of IDC_DEVICES! */ 00628 if (!(dwp = DeferWindowPos(dwp, 00629 hControl, 00630 NULL, 00631 0, 00632 0, 00633 Width, 00634 rc.bottom - rc.top, 00635 SWP_NOMOVE | SWP_NOZORDER))) 00636 { 00637 return; 00638 } 00639 00640 /* resize the devices list view control */ 00641 GetWindowRect(hpd->hWndDevList, 00642 &rc); 00643 MapWindowPoints(hpd->hWndDevList, 00644 hpd->hWnd, 00645 &pt, 00646 1); 00647 y = pt.y + hpd->DevListViewHeight + ptMargin.y; 00648 if (!(dwp = DeferWindowPos(dwp, 00649 hpd->hWndDevList, 00650 NULL, 00651 0, 00652 0, 00653 Width, 00654 hpd->DevListViewHeight, 00655 SWP_NOMOVE | SWP_NOZORDER))) 00656 { 00657 return; 00658 } 00659 00660 /* resize the group box control */ 00661 hControl = GetDlgItem(hpd->hWnd, 00662 IDC_PROPERTIESGROUP); 00663 GetWindowRect(hControl, 00664 &rc); 00665 if (!(dwp = DeferWindowPos(dwp, 00666 hControl, 00667 NULL, 00668 ptMargin.x, 00669 y, 00670 Width, 00671 cy - y - ptMargin.y, 00672 SWP_NOZORDER))) 00673 { 00674 return; 00675 } 00676 00677 /* use left margin of the IDC_MANUFACTURER label as the right 00678 margin of all controls inside the group box */ 00679 hControl = GetDlgItem(hpd->hWnd, 00680 IDC_MANUFACTURER); 00681 GetWindowRect(hControl, 00682 &rc); 00683 MapWindowPoints(hControl, 00684 hpd->hWnd, 00685 &ptMarginGroup, 00686 1); 00687 00688 ptMarginGroup.y = ptMargin.y * 2; 00689 Width = cx - (2 * ptMarginGroup.x); 00690 y += ptMarginGroup.y; 00691 if (!(dwp = DeferWindowPos(dwp, 00692 hControl, 00693 NULL, 00694 ptMarginGroup.x, 00695 y, 00696 Width, 00697 rc.bottom - rc.top, 00698 SWP_NOZORDER))) 00699 { 00700 return; 00701 } 00702 y += rc.bottom - rc.top + (ptMargin.y / 2); 00703 00704 /* resize the IDC_LOCATION label */ 00705 hControl = GetDlgItem(hpd->hWnd, 00706 IDC_LOCATION); 00707 GetWindowRect(hControl, 00708 &rc); 00709 if (!(dwp = DeferWindowPos(dwp, 00710 hControl, 00711 NULL, 00712 ptMarginGroup.x, 00713 y, 00714 Width, 00715 rc.bottom - rc.top, 00716 SWP_NOZORDER))) 00717 { 00718 return; 00719 } 00720 y += rc.bottom - rc.top + (ptMargin.y / 2); 00721 00722 /* measure the size of the buttons */ 00723 hButton = GetDlgItem(hpd->hWnd, 00724 IDC_PROPERTIES); 00725 GetWindowRect(hButton, 00726 &rcButton); 00727 00728 /* resize the IDC_STATUS label */ 00729 hControl = GetDlgItem(hpd->hWnd, 00730 IDC_STATUS); 00731 GetWindowRect(hControl, 00732 &rc); 00733 if (!(dwp = DeferWindowPos(dwp, 00734 hControl, 00735 NULL, 00736 ptMarginGroup.x, 00737 y, 00738 Width, 00739 cy - y - (3 * ptMargin.y) - 00740 (rcButton.bottom - rcButton.top), 00741 SWP_NOZORDER))) 00742 { 00743 return; 00744 } 00745 00746 /* move the IDC_PROPERTIES button */ 00747 y = cy - (2 * ptMargin.y) - (rcButton.bottom - rcButton.top); 00748 x = cx - ptMarginGroup.x - (rcButton.right - rcButton.left); 00749 if (!(dwp = DeferWindowPos(dwp, 00750 hButton, 00751 NULL, 00752 x, 00753 y, 00754 0, 00755 0, 00756 SWP_NOSIZE | SWP_NOZORDER))) 00757 { 00758 return; 00759 } 00760 00761 /* move the IDC_TROUBLESHOOT button */ 00762 hButton = GetDlgItem(hpd->hWnd, 00763 IDC_TROUBLESHOOT); 00764 GetWindowRect(hButton, 00765 &rcButton); 00766 x -= (ptMargin.x / 2) + (rcButton.right - rcButton.left); 00767 if (!(dwp = DeferWindowPos(dwp, 00768 hButton, 00769 NULL, 00770 x, 00771 y, 00772 0, 00773 0, 00774 SWP_NOSIZE | SWP_NOZORDER))) 00775 { 00776 return; 00777 } 00778 00779 EndDeferWindowPos(dwp); 00780 } 00781 } 00782 00783 00784 static VOID 00785 EnableTroubleShoot(PHARDWARE_PAGE_DATA hpd, 00786 BOOL Enable) 00787 { 00788 HWND hBtnTroubleShoot = GetDlgItem(hpd->hWnd, 00789 IDC_TROUBLESHOOT); 00790 00791 ShowWindow(hBtnTroubleShoot, 00792 Enable ? SW_SHOW : SW_HIDE); 00793 } 00794 00795 00796 static INT_PTR 00797 CALLBACK 00798 HardwareDlgProc(IN HWND hwndDlg, 00799 IN UINT uMsg, 00800 IN WPARAM wParam, 00801 IN LPARAM lParam) 00802 { 00803 PHARDWARE_PAGE_DATA hpd; 00804 INT_PTR Ret = FALSE; 00805 00806 hpd = (PHARDWARE_PAGE_DATA)GetWindowLongPtr(hwndDlg, 00807 DWL_USER); 00808 00809 if (hpd != NULL || uMsg == WM_INITDIALOG) 00810 { 00811 switch (uMsg) 00812 { 00813 case WM_NOTIFY: 00814 { 00815 NMHDR *pnmh = (NMHDR*)lParam; 00816 if (pnmh->hwndFrom == hpd->hWndDevList) 00817 { 00818 switch (pnmh->code) 00819 { 00820 case LVN_ITEMCHANGED: 00821 { 00822 LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam; 00823 00824 if ((pnmv->uChanged & LVIF_STATE) && 00825 ((pnmv->uOldState & (LVIS_FOCUSED | LVIS_SELECTED)) || 00826 (pnmv->uNewState & (LVIS_FOCUSED | LVIS_SELECTED)))) 00827 { 00828 UpdateControlStates(hpd); 00829 } 00830 break; 00831 } 00832 00833 case NM_DBLCLK: 00834 { 00835 DisplaySelectedDeviceProperties(hpd); 00836 break; 00837 } 00838 } 00839 } 00840 break; 00841 } 00842 00843 case WM_COMMAND: 00844 { 00845 switch (LOWORD(wParam)) 00846 { 00847 case IDC_TROUBLESHOOT: 00848 { 00849 /* FIXME - start the help using the command in the window text */ 00850 break; 00851 } 00852 00853 case IDC_PROPERTIES: 00854 { 00855 DisplaySelectedDeviceProperties(hpd); 00856 break; 00857 } 00858 } 00859 break; 00860 } 00861 00862 case WM_SIZE: 00863 HardwareDlgResize(hpd, 00864 (INT)LOWORD(lParam), 00865 (INT)HIWORD(lParam)); 00866 break; 00867 00868 case WM_SETTEXT: 00869 { 00870 LPCWSTR szWndText = (LPCWSTR)lParam; 00871 EnableTroubleShoot(hpd, 00872 (szWndText != NULL && szWndText[0] != L'\0')); 00873 break; 00874 } 00875 00876 case WM_DEVICECHANGE: 00877 { 00878 /* FIXME - don't call UpdateDevicesListViewControl for all events */ 00879 UpdateDevicesListViewControl(hpd); 00880 Ret = TRUE; 00881 break; 00882 } 00883 00884 case WM_INITDIALOG: 00885 { 00886 hpd = (PHARDWARE_PAGE_DATA)lParam; 00887 if (hpd != NULL) 00888 { 00889 HWND hWndParent; 00890 00891 hpd->hWnd = hwndDlg; 00892 SetWindowLongPtr(hwndDlg, 00893 DWL_USER, 00894 (DWORD_PTR)hpd); 00895 00896 hpd->ClassImageListData.cbSize = sizeof(SP_CLASSIMAGELIST_DATA); 00897 00898 SetupDiGetClassImageList(&hpd->ClassImageListData); 00899 00900 /* calculate the size of the devices list view control */ 00901 hpd->hWndDevList = GetDlgItem(hwndDlg, 00902 IDC_LV_DEVICES); 00903 if (hpd->hWndDevList != NULL) 00904 { 00905 RECT rcClient; 00906 GetClientRect(hpd->hWndDevList, 00907 &rcClient); 00908 hpd->DevListViewHeight = rcClient.bottom; 00909 00910 if (hpd->DisplayMode == HWPD_LARGELIST) 00911 { 00912 hpd->DevListViewHeight = (hpd->DevListViewHeight * 3) / 2; 00913 } 00914 } 00915 00916 /* subclass the parent window */ 00917 hWndParent = GetAncestor(hwndDlg, 00918 GA_PARENT); 00919 if (hWndParent != NULL) 00920 { 00921 RECT rcClient; 00922 00923 if (GetClientRect(hWndParent, 00924 &rcClient) && 00925 SetWindowPos(hwndDlg, 00926 NULL, 00927 0, 00928 0, 00929 rcClient.right, 00930 rcClient.bottom, 00931 SWP_NOZORDER)) 00932 { 00933 /* subclass the parent window. This is not safe 00934 if the parent window belongs to another thread! */ 00935 hpd->ParentOldWndProc = (WNDPROC)SetWindowLongPtr(hWndParent, 00936 GWLP_WNDPROC, 00937 (LONG_PTR)ParentSubWndProc); 00938 00939 if (hpd->ParentOldWndProc != NULL && 00940 SetProp(hWndParent, 00941 L"DevMgrSubClassInfo", 00942 (HANDLE)hpd)) 00943 { 00944 hpd->hWndParent = hWndParent; 00945 } 00946 } 00947 } 00948 00949 /* initialize the devices list view control */ 00950 InitializeDevicesList(hpd); 00951 00952 /* fill the devices list view control */ 00953 FillDevicesListViewControl(hpd, 00954 NULL, 00955 NULL); 00956 00957 /* decide whether to show or hide the troubleshoot button */ 00958 EnableTroubleShoot(hpd, 00959 GetWindowTextLength(hwndDlg) != 0); 00960 } 00961 Ret = TRUE; 00962 break; 00963 } 00964 00965 case WM_DESTROY: 00966 { 00967 /* zero hpd pointer in window data, because it can be used later (WM_DESTROY has not to be last message) */ 00968 SetWindowLongPtr(hwndDlg, DWL_USER, (DWORD_PTR)NULL); 00969 00970 /* free devices list */ 00971 FreeDevicesList(hpd); 00972 00973 /* restore the old window proc of the subclassed parent window */ 00974 if (hpd->hWndParent != NULL && hpd->ParentOldWndProc != NULL) 00975 { 00976 SetWindowLongPtr(hpd->hWndParent, 00977 GWLP_WNDPROC, 00978 (LONG_PTR)hpd->ParentOldWndProc); 00979 } 00980 00981 if (hpd->ClassImageListData.ImageList != NULL) 00982 { 00983 SetupDiDestroyClassImageList(&hpd->ClassImageListData); 00984 } 00985 00986 /* free the reference to comctl32 */ 00987 FreeLibrary(hpd->hComCtl32); 00988 hpd->hComCtl32 = NULL; 00989 00990 /* free the allocated resources */ 00991 HeapFree(GetProcessHeap(), 00992 0, 00993 hpd); 00994 break; 00995 } 00996 } 00997 } 00998 00999 return Ret; 01000 } 01001 01002 01003 /*************************************************************************** 01004 * NAME EXPORTED 01005 * DeviceCreateHardwarePageEx 01006 * 01007 * DESCRIPTION 01008 * Creates a hardware page 01009 * 01010 * ARGUMENTS 01011 * hWndParent: Handle to the parent window 01012 * lpGuids: An array of guids of devices that are to be listed 01013 * uNumberOfGuids: Numbers of guids in the Guids array 01014 * DisplayMode: Sets the size of the device list view control 01015 * 01016 * RETURN VALUE 01017 * Returns the handle of the hardware page window that has been created or 01018 * NULL if it failed. 01019 * 01020 * @implemented 01021 */ 01022 HWND 01023 WINAPI 01024 DeviceCreateHardwarePageEx(IN HWND hWndParent, 01025 IN LPGUID lpGuids, 01026 IN UINT uNumberOfGuids, 01027 IN HWPAGE_DISPLAYMODE DisplayMode) 01028 { 01029 PHARDWARE_PAGE_DATA hpd; 01030 01031 /* allocate the HARDWARE_PAGE_DATA structure. Make sure it is 01032 zeroed because the initialization code assumes that in 01033 failure cases! */ 01034 hpd = HeapAlloc(GetProcessHeap(), 01035 HEAP_ZERO_MEMORY, 01036 FIELD_OFFSET(HARDWARE_PAGE_DATA, 01037 ClassDevInfo[uNumberOfGuids])); 01038 if (hpd != NULL) 01039 { 01040 HWND hWnd; 01041 UINT i; 01042 01043 hpd->DisplayMode = ((DisplayMode > HWPD_MAX) ? HWPD_STANDARDLIST : DisplayMode); 01044 01045 /* initialize the HARDWARE_PAGE_DATA structure */ 01046 hpd->NumberOfGuids = uNumberOfGuids; 01047 for (i = 0; 01048 i < uNumberOfGuids; 01049 i++) 01050 { 01051 hpd->ClassDevInfo[i].hDevInfo = INVALID_HANDLE_VALUE; 01052 hpd->ClassDevInfo[i].Guid = lpGuids[i]; 01053 } 01054 01055 /* load comctl32.dll dynamically */ 01056 hpd->hComCtl32 = LoadAndInitComctl32(); 01057 if (hpd->hComCtl32 == NULL) 01058 { 01059 goto Cleanup; 01060 } 01061 01062 /* create the dialog */ 01063 hWnd = CreateDialogParam(hDllInstance, 01064 MAKEINTRESOURCE(IDD_HARDWARE), 01065 hWndParent, 01066 HardwareDlgProc, 01067 (LPARAM)hpd); 01068 if (hWnd != NULL) 01069 { 01070 return hWnd; 01071 } 01072 else 01073 { 01074 Cleanup: 01075 /* oops, something went wrong... */ 01076 if (hpd->hComCtl32 != NULL) 01077 { 01078 FreeLibrary(hpd->hComCtl32); 01079 } 01080 01081 HeapFree(GetProcessHeap(), 01082 0, 01083 hpd); 01084 } 01085 } 01086 01087 return NULL; 01088 } 01089 01090 01091 /*************************************************************************** 01092 * NAME EXPORTED 01093 * DeviceCreateHardwarePage 01094 * 01095 * DESCRIPTION 01096 * Creates a hardware page 01097 * 01098 * ARGUMENTS 01099 * hWndParent: Handle to the parent window 01100 * lpGuid: Guid of the device 01101 * 01102 * RETURN VALUE 01103 * Returns the handle of the hardware page window that has been created or 01104 * NULL if it failed. 01105 * 01106 * @implemented 01107 */ 01108 HWND 01109 WINAPI 01110 DeviceCreateHardwarePage(IN HWND hWndParent, 01111 IN LPGUID lpGuid) 01112 { 01113 return DeviceCreateHardwarePageEx(hWndParent, 01114 lpGuid, 01115 1, 01116 HWPD_LARGELIST); 01117 } Generated on Sun May 27 2012 04:23:26 for ReactOS by
1.7.6.1
|