ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hwpage.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.