2 * PROJECT: ReactOS System Control Panel Applet
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/cpl/sysdm/general.c
5 * PURPOSE: General System Information
6 * COPYRIGHT: Copyright Thomas Weidenmueller <w3seek@reactos.org>
7 * Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
8 * Copyright 2006-2007 Colin Finck <mail@colinfinck.de>
18 typedef struct _IMGINFO
25 PIMGINFO pImgInfo
= NULL
;
28 ShowLastWin32Error(HWND hWndOwner
)
33 LastError
= GetLastError();
35 if ((LastError
== 0) ||
36 !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
37 FORMAT_MESSAGE_FROM_SYSTEM
,
40 MAKELANGID(LANG_NEUTRAL
, SUBLANG_DEFAULT
),
48 MessageBox(hWndOwner
, lpMsg
, NULL
, MB_OK
| MB_ICONERROR
);
50 LocalFree((LPVOID
)lpMsg
);
55 InitImageInfo(PIMGINFO ImgInfo
)
59 ZeroMemory(ImgInfo
, sizeof(*ImgInfo
));
61 ImgInfo
->hBitmap
= LoadImage(hApplet
,
62 MAKEINTRESOURCE(IDB_ROSBMP
),
68 if (ImgInfo
->hBitmap
!= NULL
)
70 GetObject(ImgInfo
->hBitmap
, sizeof(BITMAP
), &bitmap
);
72 ImgInfo
->cxSource
= bitmap
.bmWidth
;
73 ImgInfo
->cySource
= bitmap
.bmHeight
;
77 LRESULT CALLBACK
RosImageProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
79 static UINT timerid
= 0, top
= 0, offset
;
80 static HBITMAP hBitmap2
;
89 case WM_LBUTTONDBLCLK
:
90 if (wParam
& (MK_CONTROL
| MK_SHIFT
))
97 GetObject(pImgInfo
->hBitmap
, sizeof(BITMAP
), &bitmap
);
98 dc
= CreateCompatibleDC(GetDC(NULL
));
103 sdc
= CreateCompatibleDC(dc
);
109 ncm
.cbSize
= sizeof(NONCLIENTMETRICS
);
110 SystemParametersInfo(SPI_GETNONCLIENTMETRICS
, sizeof(NONCLIENTMETRICS
), &ncm
, 0);
112 hfont
= CreateFontIndirect(&ncm
.lfMessageFont
);
113 SelectObject(dc
, hfont
);
114 SetRect(&r
, 0, 0, 0, 0);
115 LoadString(hApplet
, IDS_DEVS
, devtext
, sizeof(devtext
) / sizeof(TCHAR
));
116 DrawText(dc
, devtext
, -1, &r
, DT_CALCRECT
);
117 hBitmap2
= CreateBitmap(pImgInfo
->cxSource
, (2 * pImgInfo
->cySource
) + (r
.bottom
+ 1 - r
.top
), bitmap
.bmPlanes
, bitmap
.bmBitsPixel
, NULL
);
118 SelectObject(sdc
, pImgInfo
->hBitmap
);
119 SelectObject(dc
, hBitmap2
);
121 BitBlt(dc
, 0, offset
, bitmap
.bmWidth
, bitmap
.bmHeight
, sdc
, 0, 0, SRCCOPY
);
122 offset
+= bitmap
.bmHeight
;
124 SetRect(&r
, 0, offset
, bitmap
.bmWidth
, offset
+ (r
.bottom
- r
.top
) + 1);
125 FillRect(dc
, &r
, GetSysColorBrush(COLOR_3DFACE
));
126 SetBkMode(dc
, TRANSPARENT
);
127 OffsetRect(&r
, 1, 1);
128 SetTextColor(dc
, GetSysColor(COLOR_BTNSHADOW
));
129 DrawText(dc
, devtext
, -1, &r
, DT_CENTER
);
130 OffsetRect(&r
, -1, -1);
131 SetTextColor(dc
, GetSysColor(COLOR_WINDOWTEXT
));
132 DrawText(dc
, devtext
, -1, &r
, DT_CENTER
);
133 offset
+= r
.bottom
- r
.top
;
135 BitBlt(dc
, 0, offset
, bitmap
.bmWidth
, bitmap
.bmHeight
, sdc
, 0, 0, SRCCOPY
);
136 offset
+= bitmap
.bmHeight
;
140 timerid
= SetTimer(hwnd
, 1, ANIM_TIME
, NULL
);
147 KillTimer(hwnd
, timerid
);
150 DeleteObject(hBitmap2
);
151 InvalidateRect(hwnd
, NULL
, FALSE
);
156 if (top
> offset
- pImgInfo
->cySource
)
158 KillTimer(hwnd
, timerid
);
161 DeleteObject(hBitmap2
);
163 InvalidateRect(hwnd
, NULL
, FALSE
);
176 hdc
= BeginPaint(hwnd
,&PS
);
178 GetClientRect(hwnd
,&PS
.rcPaint
);
180 /* Position image in center of dialog */
181 left
= (PS
.rcPaint
.right
- pImgInfo
->cxSource
) / 2;
182 hdcMem
= CreateCompatibleDC(hdc
);
186 SelectObject(hdcMem
, timerid
? hBitmap2
: pImgInfo
->hBitmap
);
190 PS
.rcPaint
.right
- PS
.rcPaint
.left
,
191 PS
.rcPaint
.top
+ pImgInfo
->cySource
,
208 SetRegTextData(HWND hwnd
,
217 if (RegQueryValueEx(hKey
,
222 &BufSize
) == ERROR_SUCCESS
)
224 lpBuf
= HeapAlloc(GetProcessHeap(),
230 if (RegQueryValueEx(hKey
,
235 &BufSize
) == ERROR_SUCCESS
)
242 HeapFree(GetProcessHeap(),
249 SetProcNameString(HWND hwnd
,
263 if (RegQueryValueEx(hKey
,
268 &BufSize
) == ERROR_SUCCESS
)
270 lpBuf
= HeapAlloc(GetProcessHeap(),
276 if (RegQueryValueEx(hKey
,
281 &BufSize
) == ERROR_SUCCESS
)
283 if (BufSize
> ((30 + 1) * sizeof(TCHAR
)))
285 /* Wrap the Processor Name String like XP does: *
286 * - Take the first 30 characters and look for the last space. *
287 * Then wrap the string after this space. *
288 * - If no space is found, wrap the string after character 30. *
290 * For example the Processor Name String of a Pentium 4 is right-aligned. *
291 * With this wrapping the first line looks centered. */
293 _tcsncpy(szBuf
, lpBuf
, 30);
295 szLastSpace
= _tcsrchr(szBuf
, ' ');
297 if (szLastSpace
== 0)
303 LastSpace
= (szLastSpace
- szBuf
);
304 szBuf
[LastSpace
] = 0;
307 _tcsncpy(szBuf
, lpBuf
, LastSpace
);
317 /* Return the number of used lines */
330 HeapFree(GetProcessHeap(),
339 MakeFloatValueString(double* dFloatValue
,
343 TCHAR szDecimalSeparator
[4];
345 /* Get the decimal separator for the current locale */
346 if (GetLocaleInfo(LOCALE_USER_DEFAULT
, LOCALE_SDECIMAL
, szDecimalSeparator
, sizeof(szDecimalSeparator
) / sizeof(TCHAR
)) > 0)
351 /* Show the value with two decimals */
352 uIntegral
= (UINT
)*dFloatValue
;
353 uDecimals
= (UCHAR
)((UINT
)(*dFloatValue
* 100) - uIntegral
* 100);
355 wsprintf(szOutput
, _T("%u%s%02u %s"), uIntegral
, szDecimalSeparator
, uDecimals
, szAppend
);
360 SetProcSpeed(HWND hwnd
,
366 DWORD BufSize
= sizeof(DWORD
);
368 PROCESSOR_POWER_INFORMATION ppi
;
373 if ((CallNtPowerInformation(ProcessorInformation
,
377 sizeof(ppi
)) == STATUS_SUCCESS
&&
378 ppi
.CurrentMhz
!= 0) ||
379 RegQueryValueEx(hKey
,
383 (PBYTE
)&ppi
.CurrentMhz
,
384 &BufSize
) == ERROR_SUCCESS
)
386 if (ppi
.CurrentMhz
< 1000)
388 wsprintf(szBuf
, _T("%lu MHz"), ppi
.CurrentMhz
);
392 double flt
= ppi
.CurrentMhz
/ 1000.0;
393 MakeFloatValueString(&flt
, szBuf
, _T("GHz"));
403 GetSystemInformation(HWND hwnd
)
406 TCHAR ProcKey
[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
407 MEMORYSTATUSEX MemStat
;
409 INT CurMachineLine
= IDC_MACHINELINE1
;
412 * Get Processor information
413 * although undocumented, this information is being pulled
414 * directly out of the registry instead of via setupapi as it
415 * contains all the info we need, and should remain static
417 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
421 &hKey
) == ERROR_SUCCESS
)
425 _T("VendorIdentifier"),
429 CurMachineLine
+= SetProcNameString(hwnd
,
431 _T("ProcessorNameString"),
443 /* Get total physical RAM */
444 MemStat
.dwLength
= sizeof(MemStat
);
445 if (GlobalMemoryStatusEx(&MemStat
))
450 if (MemStat
.ullTotalPhys
> 1024 * 1024 * 1024)
453 static const UINT uStrId
[] = {
459 // We're dealing with GBs or more
460 MemStat
.ullTotalPhys
/= 1024 * 1024;
462 if (MemStat
.ullTotalPhys
> 1024 * 1024)
464 // We're dealing with TBs or more
465 MemStat
.ullTotalPhys
/= 1024;
468 if (MemStat
.ullTotalPhys
> 1024 * 1024)
470 // We're dealing with PBs or more
471 MemStat
.ullTotalPhys
/= 1024;
474 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
478 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
483 dTotalPhys
= (double)MemStat
.ullTotalPhys
/ 1024;
486 LoadString(hApplet
, uStrId
[i
], szStr
, sizeof(szStr
) / sizeof(TCHAR
));
487 MakeFloatValueString(&dTotalPhys
, Buf
, szStr
);
491 // We're dealing with MBs, don't show any decimals
492 LoadString(hApplet
, IDS_MEGABYTE
, szStr
, sizeof(szStr
) / sizeof(TCHAR
));
493 wsprintf(Buf
, _T("%u %s"), (UINT
)MemStat
.ullTotalPhys
/ 1024 / 1024, szStr
);
496 SetDlgItemText(hwnd
, CurMachineLine
, Buf
);
501 /* Property page dialog callback */
503 GeneralPageProc(HWND hwndDlg
,
509 UNREFERENCED_PARAMETER(lParam
);
510 UNREFERENCED_PARAMETER(wParam
);
515 pImgInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IMGINFO
));
516 if (pImgInfo
== NULL
)
518 EndDialog(hwndDlg
, 0);
522 InitImageInfo(pImgInfo
);
523 SetWindowLongPtr(GetDlgItem(hwndDlg
, IDC_ROSIMG
), GWL_WNDPROC
, (LONG
)RosImageProc
);
524 GetSystemInformation(hwndDlg
);
528 HeapFree(GetProcessHeap(), 0, pImgInfo
);
532 if (LOWORD(wParam
) == IDC_LICENCE
)
535 MAKEINTRESOURCE(IDD_LICENCE
),
545 LPDRAWITEMSTRUCT lpDrawItem
;
546 lpDrawItem
= (LPDRAWITEMSTRUCT
) lParam
;
547 if (lpDrawItem
->CtlID
== IDC_ROSIMG
)
552 /* Position image in centre of dialog */
553 left
= (lpDrawItem
->rcItem
.right
- pImgInfo
->cxSource
) / 2;
555 hdcMem
= CreateCompatibleDC(lpDrawItem
->hDC
);
558 SelectObject(hdcMem
, pImgInfo
->hBitmap
);
559 BitBlt(lpDrawItem
->hDC
,
561 lpDrawItem
->rcItem
.top
,
562 lpDrawItem
->rcItem
.right
- lpDrawItem
->rcItem
.left
,
563 lpDrawItem
->rcItem
.bottom
- lpDrawItem
->rcItem
.top
,
576 NMHDR
*nmhdr
= (NMHDR
*)lParam
;
578 if (nmhdr
->idFrom
== IDC_ROSHOMEPAGE_LINK
&& nmhdr
->code
== NM_CLICK
)
580 PNMLINK nml
= (PNMLINK
)nmhdr
;
582 ShellExecuteW(hwndDlg
,