Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygengeneral.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS System Control Panel Applet 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/cpl/sysdm/general.c 00005 * PURPOSE: General System Information 00006 * COPYRIGHT: Copyright Thomas Weidenmueller <w3seek@reactos.org> 00007 * Copyright 2006 Ged Murphy <gedmurphy@gmail.com> 00008 * Copyright 2006-2007 Colin Finck <mail@colinfinck.de> 00009 * 00010 */ 00011 00012 00013 #include "precomp.h" 00014 00015 #define ANIM_STEP 2 00016 #define ANIM_TIME 50 00017 00018 typedef struct _IMGINFO 00019 { 00020 HBITMAP hBitmap; 00021 INT cxSource; 00022 INT cySource; 00023 } IMGINFO, *PIMGINFO; 00024 00025 PIMGINFO pImgInfo = NULL; 00026 00027 void 00028 ShowLastWin32Error(HWND hWndOwner) 00029 { 00030 LPTSTR lpMsg; 00031 DWORD LastError; 00032 00033 LastError = GetLastError(); 00034 00035 if ((LastError == 0) || 00036 !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 00037 FORMAT_MESSAGE_FROM_SYSTEM, 00038 NULL, 00039 LastError, 00040 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 00041 (LPTSTR)&lpMsg, 00042 0, 00043 NULL)) 00044 { 00045 return; 00046 } 00047 00048 MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR); 00049 00050 LocalFree((LPVOID)lpMsg); 00051 } 00052 00053 00054 static VOID 00055 InitImageInfo(PIMGINFO ImgInfo) 00056 { 00057 BITMAP bitmap; 00058 00059 ZeroMemory(ImgInfo, sizeof(*ImgInfo)); 00060 00061 ImgInfo->hBitmap = LoadImage(hApplet, 00062 MAKEINTRESOURCE(IDB_ROSBMP), 00063 IMAGE_BITMAP, 00064 0, 00065 0, 00066 LR_DEFAULTCOLOR); 00067 00068 if (ImgInfo->hBitmap != NULL) 00069 { 00070 GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap); 00071 00072 ImgInfo->cxSource = bitmap.bmWidth; 00073 ImgInfo->cySource = bitmap.bmHeight; 00074 } 00075 } 00076 00077 LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 00078 { 00079 static UINT timerid = 0, top = 0, offset; 00080 static HBITMAP hBitmap2; 00081 RECT r; 00082 NONCLIENTMETRICS ncm; 00083 HFONT hfont; 00084 BITMAP bitmap; 00085 HDC dc, sdc; 00086 TCHAR devtext[2048]; 00087 switch (uMsg) 00088 { 00089 case WM_LBUTTONDBLCLK: 00090 if (wParam & (MK_CONTROL | MK_SHIFT)) 00091 { 00092 if (timerid == 0) 00093 { 00094 top = 0; // Set top 00095 00096 // Build new bitmap 00097 GetObject(pImgInfo->hBitmap, sizeof(BITMAP), &bitmap); 00098 dc = CreateCompatibleDC(GetDC(NULL)); 00099 if (dc == NULL) 00100 { 00101 break; 00102 } 00103 sdc = CreateCompatibleDC(dc); 00104 if (sdc == NULL) 00105 { 00106 DeleteDC(dc); 00107 break; 00108 } 00109 ncm.cbSize = sizeof(NONCLIENTMETRICS); 00110 SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0); 00111 00112 hfont = CreateFontIndirect(&ncm.lfMessageFont); 00113 SelectObject(dc, hfont); 00114 SetRect(&r, 0, 0, 0, 0); 00115 LoadString(hApplet, IDS_DEVS, devtext, sizeof(devtext) / sizeof(TCHAR)); 00116 DrawText(dc, devtext, -1, &r, DT_CALCRECT); 00117 hBitmap2 = CreateBitmap(pImgInfo->cxSource, (2 * pImgInfo->cySource) + (r.bottom + 1 - r.top), bitmap.bmPlanes, bitmap.bmBitsPixel, NULL); 00118 SelectObject(sdc, pImgInfo->hBitmap); 00119 SelectObject(dc, hBitmap2); 00120 offset = 0; 00121 BitBlt(dc, 0, offset, bitmap.bmWidth, bitmap.bmHeight, sdc, 0, 0, SRCCOPY); 00122 offset += bitmap.bmHeight; 00123 00124 SetRect(&r, 0, offset, bitmap.bmWidth, offset + (r.bottom - r.top) + 1); 00125 FillRect(dc, &r, GetSysColorBrush(COLOR_3DFACE)); 00126 SetBkMode(dc, TRANSPARENT); 00127 OffsetRect(&r, 1, 1); 00128 SetTextColor(dc, GetSysColor(COLOR_BTNSHADOW)); 00129 DrawText(dc, devtext, -1, &r, DT_CENTER); 00130 OffsetRect(&r, -1, -1); 00131 SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT)); 00132 DrawText(dc, devtext, -1, &r, DT_CENTER); 00133 offset += r.bottom - r.top; 00134 00135 BitBlt(dc, 0, offset, bitmap.bmWidth, bitmap.bmHeight, sdc, 0, 0, SRCCOPY); 00136 offset += bitmap.bmHeight; 00137 DeleteDC(sdc); 00138 DeleteDC(dc); 00139 00140 timerid = SetTimer(hwnd, 1, ANIM_TIME, NULL); 00141 } 00142 } 00143 break; 00144 case WM_LBUTTONDOWN: 00145 if (timerid) 00146 { 00147 KillTimer(hwnd, timerid); 00148 top = 0; 00149 timerid = 0; 00150 DeleteObject(hBitmap2); 00151 InvalidateRect(hwnd, NULL, FALSE); 00152 } 00153 break; 00154 case WM_TIMER: 00155 top += ANIM_STEP; 00156 if (top > offset - pImgInfo->cySource) 00157 { 00158 KillTimer(hwnd, timerid); 00159 top = 0; 00160 timerid = 0; 00161 DeleteObject(hBitmap2); 00162 } 00163 InvalidateRect(hwnd, NULL, FALSE); 00164 break; 00165 case WM_PAINT: 00166 { 00167 PAINTSTRUCT PS; 00168 HDC hdcMem, hdc; 00169 LONG left; 00170 if (wParam != 0) 00171 { 00172 hdc = (HDC)wParam; 00173 } 00174 else 00175 { 00176 hdc = BeginPaint(hwnd,&PS); 00177 } 00178 GetClientRect(hwnd,&PS.rcPaint); 00179 00180 /* Position image in center of dialog */ 00181 left = (PS.rcPaint.right - pImgInfo->cxSource) / 2; 00182 hdcMem = CreateCompatibleDC(hdc); 00183 00184 if (hdcMem != NULL) 00185 { 00186 SelectObject(hdcMem, timerid ? hBitmap2 : pImgInfo->hBitmap); 00187 BitBlt(hdc, 00188 left, 00189 PS.rcPaint.top, 00190 PS.rcPaint.right - PS.rcPaint.left, 00191 PS.rcPaint.top + pImgInfo->cySource, 00192 hdcMem, 00193 0, 00194 top, 00195 SRCCOPY); 00196 DeleteDC(hdcMem); 00197 } 00198 00199 if (wParam == 0) 00200 EndPaint(hwnd,&PS); 00201 break; 00202 } 00203 } 00204 return TRUE; 00205 } 00206 00207 static VOID 00208 SetRegTextData(HWND hwnd, 00209 HKEY hKey, 00210 LPTSTR Value, 00211 UINT uID) 00212 { 00213 LPTSTR lpBuf = NULL; 00214 DWORD BufSize = 0; 00215 DWORD Type; 00216 00217 if (RegQueryValueEx(hKey, 00218 Value, 00219 NULL, 00220 &Type, 00221 NULL, 00222 &BufSize) == ERROR_SUCCESS) 00223 { 00224 lpBuf = HeapAlloc(GetProcessHeap(), 00225 0, 00226 BufSize); 00227 if (!lpBuf) 00228 return; 00229 00230 if (RegQueryValueEx(hKey, 00231 Value, 00232 NULL, 00233 &Type, 00234 (PBYTE)lpBuf, 00235 &BufSize) == ERROR_SUCCESS) 00236 { 00237 SetDlgItemText(hwnd, 00238 uID, 00239 lpBuf); 00240 } 00241 00242 HeapFree(GetProcessHeap(), 00243 0, 00244 lpBuf); 00245 } 00246 } 00247 00248 static INT 00249 SetProcNameString(HWND hwnd, 00250 HKEY hKey, 00251 LPTSTR Value, 00252 UINT uID1, 00253 UINT uID2) 00254 { 00255 LPTSTR lpBuf = NULL; 00256 DWORD BufSize = 0; 00257 DWORD Type; 00258 INT Ret = 0; 00259 TCHAR szBuf[31]; 00260 TCHAR* szLastSpace; 00261 INT LastSpace = 0; 00262 00263 if (RegQueryValueEx(hKey, 00264 Value, 00265 NULL, 00266 &Type, 00267 NULL, 00268 &BufSize) == ERROR_SUCCESS) 00269 { 00270 lpBuf = HeapAlloc(GetProcessHeap(), 00271 0, 00272 BufSize); 00273 if (!lpBuf) 00274 return 0; 00275 00276 if (RegQueryValueEx(hKey, 00277 Value, 00278 NULL, 00279 &Type, 00280 (PBYTE)lpBuf, 00281 &BufSize) == ERROR_SUCCESS) 00282 { 00283 if (BufSize > ((30 + 1) * sizeof(TCHAR))) 00284 { 00285 /* Wrap the Processor Name String like XP does: * 00286 * - Take the first 30 characters and look for the last space. * 00287 * Then wrap the string after this space. * 00288 * - If no space is found, wrap the string after character 30. * 00289 * * 00290 * For example the Processor Name String of a Pentium 4 is right-aligned. * 00291 * With this wrapping the first line looks centered. */ 00292 00293 _tcsncpy(szBuf, lpBuf, 30); 00294 szBuf[30] = 0; 00295 szLastSpace = _tcsrchr(szBuf, ' '); 00296 00297 if (szLastSpace == 0) 00298 { 00299 LastSpace = 30; 00300 } 00301 else 00302 { 00303 LastSpace = (szLastSpace - szBuf); 00304 szBuf[LastSpace] = 0; 00305 } 00306 00307 _tcsncpy(szBuf, lpBuf, LastSpace); 00308 00309 SetDlgItemText(hwnd, 00310 uID1, 00311 szBuf); 00312 00313 SetDlgItemText(hwnd, 00314 uID2, 00315 lpBuf+LastSpace+1); 00316 00317 /* Return the number of used lines */ 00318 Ret = 2; 00319 } 00320 else 00321 { 00322 SetDlgItemText(hwnd, 00323 uID1, 00324 lpBuf); 00325 00326 Ret = 1; 00327 } 00328 } 00329 00330 HeapFree(GetProcessHeap(), 00331 0, 00332 lpBuf); 00333 } 00334 00335 return Ret; 00336 } 00337 00338 static VOID 00339 MakeFloatValueString(double* dFloatValue, 00340 LPTSTR szOutput, 00341 LPTSTR szAppend) 00342 { 00343 TCHAR szDecimalSeparator[4]; 00344 00345 /* Get the decimal separator for the current locale */ 00346 if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSeparator, sizeof(szDecimalSeparator) / sizeof(TCHAR)) > 0) 00347 { 00348 UCHAR uDecimals; 00349 UINT uIntegral; 00350 00351 /* Show the value with two decimals */ 00352 uIntegral = (UINT)*dFloatValue; 00353 uDecimals = (UCHAR)((UINT)(*dFloatValue * 100) - uIntegral * 100); 00354 00355 wsprintf(szOutput, _T("%u%s%02u %s"), uIntegral, szDecimalSeparator, uDecimals, szAppend); 00356 } 00357 } 00358 00359 static VOID 00360 SetProcSpeed(HWND hwnd, 00361 HKEY hKey, 00362 LPTSTR Value, 00363 UINT uID) 00364 { 00365 TCHAR szBuf[64]; 00366 DWORD BufSize = sizeof(DWORD); 00367 DWORD Type = REG_SZ; 00368 PROCESSOR_POWER_INFORMATION ppi; 00369 00370 ZeroMemory(&ppi, 00371 sizeof(ppi)); 00372 00373 if ((CallNtPowerInformation(ProcessorInformation, 00374 NULL, 00375 0, 00376 (PVOID)&ppi, 00377 sizeof(ppi)) == STATUS_SUCCESS && 00378 ppi.CurrentMhz != 0) || 00379 RegQueryValueEx(hKey, 00380 Value, 00381 NULL, 00382 &Type, 00383 (PBYTE)&ppi.CurrentMhz, 00384 &BufSize) == ERROR_SUCCESS) 00385 { 00386 if (ppi.CurrentMhz < 1000) 00387 { 00388 wsprintf(szBuf, _T("%lu MHz"), ppi.CurrentMhz); 00389 } 00390 else 00391 { 00392 double flt = ppi.CurrentMhz / 1000.0; 00393 MakeFloatValueString(&flt, szBuf, _T("GHz")); 00394 } 00395 00396 SetDlgItemText(hwnd, 00397 uID, 00398 szBuf); 00399 } 00400 } 00401 00402 static VOID 00403 GetSystemInformation(HWND hwnd) 00404 { 00405 HKEY hKey; 00406 TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"); 00407 MEMORYSTATUSEX MemStat; 00408 TCHAR Buf[32]; 00409 INT CurMachineLine = IDC_MACHINELINE1; 00410 00411 /* 00412 * Get Processor information 00413 * although undocumented, this information is being pulled 00414 * directly out of the registry instead of via setupapi as it 00415 * contains all the info we need, and should remain static 00416 */ 00417 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, 00418 ProcKey, 00419 0, 00420 KEY_READ, 00421 &hKey) == ERROR_SUCCESS) 00422 { 00423 SetRegTextData(hwnd, 00424 hKey, 00425 _T("VendorIdentifier"), 00426 CurMachineLine); 00427 CurMachineLine++; 00428 00429 CurMachineLine += SetProcNameString(hwnd, 00430 hKey, 00431 _T("ProcessorNameString"), 00432 CurMachineLine, 00433 CurMachineLine + 1); 00434 00435 SetProcSpeed(hwnd, 00436 hKey, 00437 _T("~MHz"), 00438 CurMachineLine); 00439 CurMachineLine++; 00440 } 00441 00442 00443 /* Get total physical RAM */ 00444 MemStat.dwLength = sizeof(MemStat); 00445 if (GlobalMemoryStatusEx(&MemStat)) 00446 { 00447 TCHAR szStr[32]; 00448 double dTotalPhys; 00449 00450 if (MemStat.ullTotalPhys > 1024 * 1024 * 1024) 00451 { 00452 UINT i = 0; 00453 static const UINT uStrId[] = { 00454 IDS_GIGABYTE, 00455 IDS_TERABYTE, 00456 IDS_PETABYTE 00457 }; 00458 00459 // We're dealing with GBs or more 00460 MemStat.ullTotalPhys /= 1024 * 1024; 00461 00462 if (MemStat.ullTotalPhys > 1024 * 1024) 00463 { 00464 // We're dealing with TBs or more 00465 MemStat.ullTotalPhys /= 1024; 00466 i++; 00467 00468 if (MemStat.ullTotalPhys > 1024 * 1024) 00469 { 00470 // We're dealing with PBs or more 00471 MemStat.ullTotalPhys /= 1024; 00472 i++; 00473 00474 dTotalPhys = (double)MemStat.ullTotalPhys / 1024; 00475 } 00476 else 00477 { 00478 dTotalPhys = (double)MemStat.ullTotalPhys / 1024; 00479 } 00480 } 00481 else 00482 { 00483 dTotalPhys = (double)MemStat.ullTotalPhys / 1024; 00484 } 00485 00486 LoadString(hApplet, uStrId[i], szStr, sizeof(szStr) / sizeof(TCHAR)); 00487 MakeFloatValueString(&dTotalPhys, Buf, szStr); 00488 } 00489 else 00490 { 00491 // We're dealing with MBs, don't show any decimals 00492 LoadString(hApplet, IDS_MEGABYTE, szStr, sizeof(szStr) / sizeof(TCHAR)); 00493 wsprintf(Buf, _T("%u %s"), (UINT)MemStat.ullTotalPhys / 1024 / 1024, szStr); 00494 } 00495 00496 SetDlgItemText(hwnd, CurMachineLine, Buf); 00497 } 00498 } 00499 00500 00501 /* Property page dialog callback */ 00502 INT_PTR CALLBACK 00503 GeneralPageProc(HWND hwndDlg, 00504 UINT uMsg, 00505 WPARAM wParam, 00506 LPARAM lParam) 00507 { 00508 00509 UNREFERENCED_PARAMETER(lParam); 00510 UNREFERENCED_PARAMETER(wParam); 00511 00512 switch (uMsg) 00513 { 00514 case WM_INITDIALOG: 00515 pImgInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMGINFO)); 00516 if (pImgInfo == NULL) 00517 { 00518 EndDialog(hwndDlg, 0); 00519 return FALSE; 00520 } 00521 00522 InitImageInfo(pImgInfo); 00523 SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ROSIMG), GWL_WNDPROC, (LONG)RosImageProc); 00524 GetSystemInformation(hwndDlg); 00525 break; 00526 00527 case WM_DESTROY: 00528 HeapFree(GetProcessHeap(), 0, pImgInfo); 00529 break; 00530 00531 case WM_COMMAND: 00532 if (LOWORD(wParam) == IDC_LICENCE) 00533 { 00534 DialogBox(hApplet, 00535 MAKEINTRESOURCE(IDD_LICENCE), 00536 hwndDlg, 00537 LicenceDlgProc); 00538 00539 return TRUE; 00540 } 00541 break; 00542 00543 case WM_DRAWITEM: 00544 { 00545 LPDRAWITEMSTRUCT lpDrawItem; 00546 lpDrawItem = (LPDRAWITEMSTRUCT) lParam; 00547 if (lpDrawItem->CtlID == IDC_ROSIMG) 00548 { 00549 HDC hdcMem; 00550 LONG left; 00551 00552 /* Position image in centre of dialog */ 00553 left = (lpDrawItem->rcItem.right - pImgInfo->cxSource) / 2; 00554 00555 hdcMem = CreateCompatibleDC(lpDrawItem->hDC); 00556 if (hdcMem != NULL) 00557 { 00558 SelectObject(hdcMem, pImgInfo->hBitmap); 00559 BitBlt(lpDrawItem->hDC, 00560 left, 00561 lpDrawItem->rcItem.top, 00562 lpDrawItem->rcItem.right - lpDrawItem->rcItem.left, 00563 lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top, 00564 hdcMem, 00565 0, 00566 0, 00567 SRCCOPY); 00568 DeleteDC(hdcMem); 00569 } 00570 } 00571 return TRUE; 00572 } 00573 00574 case WM_NOTIFY: 00575 { 00576 NMHDR *nmhdr = (NMHDR *)lParam; 00577 00578 if (nmhdr->idFrom == IDC_ROSHOMEPAGE_LINK && nmhdr->code == NM_CLICK) 00579 { 00580 PNMLINK nml = (PNMLINK)nmhdr; 00581 00582 ShellExecuteW(hwndDlg, 00583 L"open", 00584 nml->item.szUrl, 00585 NULL, 00586 NULL, 00587 SW_SHOWNORMAL); 00588 } 00589 break; 00590 } 00591 00592 } 00593 00594 return FALSE; 00595 } Generated on Sun May 27 2012 04:20:50 for ReactOS by
1.7.6.1
|