mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00

Although the new layout that I committed in the previous commit was favored by community ratings votes 8:0, some devs still preferred the old layout with the bigger logo because they liked the easteregg. So this commit restores that. But it syncs to that features latest&greatest implementation we have in 0.4.15-dev-1685-gd0c237a instead of reverting the previous commit to not unnecessarily have many bugs with it that were still affecting the older releases beforehand. Aside from the general tabs dialogs layout this commit does also fix some minor issues in the translations for the oldest branches in pl-PL, jp-JA, zh-CN and zh-TW. And it fixes an x64 issue in general.c for 0.4.7 and 0.4.8.
634 lines
20 KiB
C
634 lines
20 KiB
C
/*
|
|
* PROJECT: ReactOS System Control Panel Applet
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: dll/cpl/sysdm/general.c
|
|
* PURPOSE: General System Information
|
|
* COPYRIGHT: Copyright Thomas Weidenmueller <w3seek@reactos.org>
|
|
* Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
|
|
* Copyright 2006-2007 Colin Finck <mail@colinfinck.de>
|
|
*
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#include <winnls.h>
|
|
#include <powrprof.h>
|
|
#include <buildno.h>
|
|
#include <strsafe.h>
|
|
|
|
#define ANIM_STEP 2
|
|
#define ANIM_TIME 50
|
|
|
|
typedef struct _IMGINFO
|
|
{
|
|
HBITMAP hBitmap;
|
|
INT cxSource;
|
|
INT cySource;
|
|
INT iPlanes;
|
|
INT iBits;
|
|
} IMGINFO, *PIMGINFO;
|
|
|
|
PIMGINFO pImgInfo = NULL;
|
|
BLENDFUNCTION BlendFunc = {AC_SRC_OVER, 0, 255, AC_SRC_ALPHA};
|
|
|
|
VOID ShowLastWin32Error(HWND hWndOwner)
|
|
{
|
|
LPTSTR lpMsg;
|
|
DWORD LastError;
|
|
|
|
LastError = GetLastError();
|
|
if (LastError == ERROR_SUCCESS)
|
|
return;
|
|
|
|
if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
LastError,
|
|
LANG_USER_DEFAULT,
|
|
(LPTSTR)&lpMsg,
|
|
0, NULL))
|
|
{
|
|
return;
|
|
}
|
|
|
|
MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
|
|
LocalFree(lpMsg);
|
|
}
|
|
|
|
|
|
static VOID InitLogo(HWND hwndDlg)
|
|
{
|
|
BITMAP logoBitmap;
|
|
BITMAP maskBitmap;
|
|
BITMAPINFO bmpi;
|
|
HDC hDC = GetDC(hwndDlg);
|
|
HDC hDCLogo = CreateCompatibleDC(NULL);
|
|
HDC hDCMask = CreateCompatibleDC(NULL);
|
|
HBITMAP hMask, hLogo, hAlphaLogo = NULL;
|
|
COLORREF *pBits;
|
|
INT line, column;
|
|
|
|
if (hDC == NULL || hDCLogo == NULL || hDCMask == NULL)
|
|
goto Cleanup;
|
|
|
|
ZeroMemory(pImgInfo, sizeof(*pImgInfo));
|
|
ZeroMemory(&bmpi, sizeof(bmpi));
|
|
|
|
hLogo = (HBITMAP)LoadImageW(hApplet, MAKEINTRESOURCEW(IDB_ROSBMP), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
|
hMask = (HBITMAP)LoadImageW(hApplet, MAKEINTRESOURCEW(IDB_ROSMASK), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
|
|
|
|
if (hLogo != NULL && hMask != NULL)
|
|
{
|
|
GetObject(hLogo, sizeof(logoBitmap), &logoBitmap);
|
|
GetObject(hMask, sizeof(maskBitmap), &maskBitmap);
|
|
|
|
if (logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth != maskBitmap.bmWidth)
|
|
goto Cleanup;
|
|
|
|
bmpi.bmiHeader.biSize = sizeof(BITMAPINFO);
|
|
bmpi.bmiHeader.biWidth = logoBitmap.bmWidth;
|
|
bmpi.bmiHeader.biHeight = logoBitmap.bmHeight;
|
|
bmpi.bmiHeader.biPlanes = 1;
|
|
bmpi.bmiHeader.biBitCount = 32;
|
|
bmpi.bmiHeader.biCompression = BI_RGB;
|
|
bmpi.bmiHeader.biSizeImage = 4 * logoBitmap.bmWidth * logoBitmap.bmHeight;
|
|
|
|
/* Create a premultiplied bitmap */
|
|
hAlphaLogo = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, (PVOID*)&pBits, 0, 0);
|
|
if (!hAlphaLogo)
|
|
goto Cleanup;
|
|
|
|
SelectObject(hDCLogo, hLogo);
|
|
SelectObject(hDCMask, hMask);
|
|
|
|
for (line = logoBitmap.bmHeight - 1; line >= 0; line--)
|
|
{
|
|
for (column = 0; column < logoBitmap.bmWidth; column++)
|
|
{
|
|
COLORREF alpha = GetPixel(hDCMask, column, line) & 0xFF;
|
|
COLORREF Color = GetPixel(hDCLogo, column, line);
|
|
DWORD r, g, b;
|
|
|
|
r = GetRValue(Color) * alpha / 255;
|
|
g = GetGValue(Color) * alpha / 255;
|
|
b = GetBValue(Color) * alpha / 255;
|
|
|
|
*pBits++ = b | (g << 8) | (r << 16) | (alpha << 24);
|
|
}
|
|
}
|
|
|
|
pImgInfo->hBitmap = hAlphaLogo;
|
|
pImgInfo->cxSource = logoBitmap.bmWidth;
|
|
pImgInfo->cySource = logoBitmap.bmHeight;
|
|
pImgInfo->iBits = logoBitmap.bmBitsPixel;
|
|
pImgInfo->iPlanes = logoBitmap.bmPlanes;
|
|
}
|
|
|
|
Cleanup:
|
|
if (hMask != NULL) DeleteObject(hMask);
|
|
if (hLogo != NULL) DeleteObject(hLogo);
|
|
if (hDCMask != NULL) DeleteDC(hDCMask);
|
|
if (hDCLogo != NULL) DeleteDC(hDCLogo);
|
|
if (hDC != NULL) ReleaseDC(hwndDlg, hDC);
|
|
}
|
|
|
|
LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static UINT timerid = 0, top = 0, offset;
|
|
static HBITMAP hCreditsBitmap;
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_LBUTTONDBLCLK:
|
|
if (wParam & (MK_CONTROL | MK_SHIFT))
|
|
{
|
|
if (timerid == 0)
|
|
{
|
|
HDC hCreditsDC, hLogoDC;
|
|
HDC hDC = GetDC(NULL);
|
|
HFONT hFont = NULL;
|
|
NONCLIENTMETRICS ncm;
|
|
RECT rcCredits;
|
|
TCHAR szCredits[2048];
|
|
INT iDevsHeight;
|
|
|
|
if (hDC == NULL)
|
|
goto Cleanup;
|
|
|
|
top = 0;
|
|
offset = 0;
|
|
hCreditsDC = CreateCompatibleDC(hDC);
|
|
hLogoDC = CreateCompatibleDC(hCreditsDC);
|
|
|
|
if (hCreditsDC == NULL || hLogoDC == NULL)
|
|
goto Cleanup;
|
|
|
|
SetRect(&rcCredits, 0, 0, 0, 0);
|
|
|
|
ncm.cbSize = sizeof(NONCLIENTMETRICS);
|
|
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
|
|
|
|
hFont = CreateFontIndirect(&ncm.lfMessageFont);
|
|
if (!hFont)
|
|
goto Cleanup;
|
|
SelectObject(hCreditsDC, hFont);
|
|
|
|
LoadString(hApplet, IDS_DEVS, szCredits, sizeof(szCredits) / sizeof(TCHAR));
|
|
DrawText(hCreditsDC, szCredits, -1, &rcCredits, DT_CALCRECT);
|
|
|
|
iDevsHeight = rcCredits.bottom - rcCredits.top;
|
|
|
|
hCreditsBitmap = CreateBitmap(pImgInfo->cxSource, (2 * pImgInfo->cySource) + iDevsHeight + 1, pImgInfo->iPlanes, pImgInfo->iBits, NULL);
|
|
|
|
if (!hCreditsBitmap)
|
|
goto Cleanup;
|
|
|
|
SelectObject(hLogoDC, pImgInfo->hBitmap);
|
|
SelectObject(hCreditsDC, hCreditsBitmap);
|
|
|
|
offset += pImgInfo->cySource;
|
|
|
|
SetRect(&rcCredits, 0, 0, pImgInfo->cxSource, (2 * pImgInfo->cySource) + iDevsHeight + 1);
|
|
FillRect(hCreditsDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
|
|
|
|
SetRect(&rcCredits, 0, offset, pImgInfo->cxSource, offset + iDevsHeight + 1);
|
|
SetBkMode(hCreditsDC, TRANSPARENT);
|
|
|
|
OffsetRect(&rcCredits, 1, 1);
|
|
SetTextColor(hCreditsDC, GetSysColor(COLOR_BTNSHADOW));
|
|
DrawText(hCreditsDC, szCredits, -1, &rcCredits, DT_CENTER);
|
|
|
|
OffsetRect(&rcCredits, -1, -1);
|
|
SetTextColor(hCreditsDC, GetSysColor(COLOR_WINDOWTEXT));
|
|
DrawText(hCreditsDC, szCredits, -1, &rcCredits, DT_CENTER);
|
|
|
|
offset += iDevsHeight;
|
|
|
|
AlphaBlend(hCreditsDC, 0, 0, pImgInfo->cxSource, pImgInfo->cySource, hLogoDC, 0, 0, pImgInfo->cxSource, pImgInfo->cySource, BlendFunc);
|
|
AlphaBlend(hCreditsDC, 0, offset, pImgInfo->cxSource, pImgInfo->cySource, hLogoDC, 0, 0, pImgInfo->cxSource, pImgInfo->cySource, BlendFunc);
|
|
|
|
timerid = SetTimer(hwnd, 1, ANIM_TIME, NULL);
|
|
|
|
Cleanup:
|
|
if (hFont != NULL) DeleteObject(hFont);
|
|
if (hLogoDC != NULL) DeleteDC(hLogoDC);
|
|
if (hCreditsDC != NULL) DeleteDC(hCreditsDC);
|
|
if (hDC != NULL) ReleaseDC(NULL, hDC);
|
|
}
|
|
}
|
|
break;
|
|
case WM_LBUTTONDOWN:
|
|
if (timerid)
|
|
{
|
|
RECT rcCredits;
|
|
HDC hDC = GetDC(hwnd);
|
|
if (hDC != NULL)
|
|
{
|
|
GetClientRect(hwnd, &rcCredits);
|
|
SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
|
|
FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
|
|
ReleaseDC(hwnd, hDC);
|
|
}
|
|
KillTimer(hwnd, timerid);
|
|
if (hCreditsBitmap != NULL)
|
|
DeleteObject(hCreditsBitmap);
|
|
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
top = 0;
|
|
timerid = 0;
|
|
}
|
|
break;
|
|
case WM_TIMER:
|
|
top += ANIM_STEP;
|
|
|
|
if (top > offset)
|
|
{
|
|
RECT rcCredits;
|
|
HDC hDC = GetDC(hwnd);
|
|
if (hDC != NULL)
|
|
{
|
|
GetClientRect(hwnd, &rcCredits);
|
|
SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
|
|
FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
|
|
ReleaseDC(hwnd, hDC);
|
|
}
|
|
KillTimer(hwnd, timerid);
|
|
if (hCreditsBitmap != NULL)
|
|
DeleteObject(hCreditsBitmap);
|
|
|
|
top = 0;
|
|
timerid = 0;
|
|
}
|
|
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
break;
|
|
case WM_PAINT:
|
|
{
|
|
PAINTSTRUCT PS;
|
|
HDC hdcMem, hdc;
|
|
LONG left;
|
|
|
|
hdc = wParam != 0 ? (HDC)wParam : BeginPaint(hwnd, &PS);
|
|
|
|
GetClientRect(hwnd, &PS.rcPaint);
|
|
|
|
/* Position image in center of dialog */
|
|
left = (PS.rcPaint.right - pImgInfo->cxSource) / 2;
|
|
hdcMem = CreateCompatibleDC(hdc);
|
|
|
|
if (hdcMem != NULL)
|
|
{
|
|
if(timerid != 0)
|
|
{
|
|
SelectObject(hdcMem, hCreditsBitmap);
|
|
BitBlt(hdc, left, PS.rcPaint.top, PS.rcPaint.right - PS.rcPaint.left, PS.rcPaint.top + pImgInfo->cySource, hdcMem, 0, top, SRCCOPY);
|
|
}
|
|
else
|
|
{
|
|
SelectObject(hdcMem, pImgInfo->hBitmap);
|
|
AlphaBlend(hdc, left, PS.rcPaint.top, pImgInfo->cxSource, pImgInfo->cySource, hdcMem, 0, 0, pImgInfo->cxSource, pImgInfo->cySource, BlendFunc);
|
|
}
|
|
|
|
DeleteDC(hdcMem);
|
|
}
|
|
|
|
if (wParam == 0)
|
|
EndPaint(hwnd,&PS);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static VOID SetRegTextData(HWND hwnd, HKEY hKey, LPTSTR Value, UINT uID)
|
|
{
|
|
LPTSTR lpBuf = NULL;
|
|
DWORD BufSize = 0;
|
|
DWORD Type;
|
|
|
|
if (RegQueryValueEx(hKey, Value, NULL, &Type, NULL, &BufSize) == ERROR_SUCCESS)
|
|
{
|
|
lpBuf = HeapAlloc(GetProcessHeap(), 0, BufSize);
|
|
|
|
if (!lpBuf)
|
|
return;
|
|
|
|
if (RegQueryValueEx(hKey, Value, NULL, &Type, (PBYTE)lpBuf, &BufSize) == ERROR_SUCCESS)
|
|
SetDlgItemText(hwnd, uID, lpBuf);
|
|
|
|
HeapFree(GetProcessHeap(), 0, lpBuf);
|
|
}
|
|
}
|
|
|
|
static INT SetProcNameString(HWND hwnd, HKEY hKey, LPTSTR Value, UINT uID1, UINT uID2)
|
|
{
|
|
LPTSTR lpBuf = NULL;
|
|
DWORD BufSize = 0;
|
|
DWORD Type;
|
|
INT Ret = 0;
|
|
TCHAR szBuf[31];
|
|
TCHAR* szLastSpace;
|
|
INT LastSpace = 0;
|
|
|
|
if (RegQueryValueEx(hKey, Value, NULL, &Type, NULL, &BufSize) == ERROR_SUCCESS)
|
|
{
|
|
lpBuf = HeapAlloc(GetProcessHeap(), 0, BufSize);
|
|
|
|
if (!lpBuf)
|
|
return 0;
|
|
|
|
if (RegQueryValueEx(hKey, Value, NULL, &Type, (PBYTE)lpBuf, &BufSize) == ERROR_SUCCESS)
|
|
{
|
|
if (BufSize > ((30 + 1) * sizeof(TCHAR)))
|
|
{
|
|
/* Wrap the Processor Name String like XP does: *
|
|
* - Take the first 30 characters and look for the last space. *
|
|
* Then wrap the string after this space. *
|
|
* - If no space is found, wrap the string after character 30. *
|
|
* *
|
|
* For example the Processor Name String of a Pentium 4 is right-aligned. *
|
|
* With this wrapping the first line looks centered. */
|
|
|
|
_tcsncpy(szBuf, lpBuf, 30);
|
|
szBuf[30] = 0;
|
|
szLastSpace = _tcsrchr(szBuf, ' ');
|
|
|
|
if (szLastSpace == 0)
|
|
{
|
|
LastSpace = 30;
|
|
}
|
|
else
|
|
{
|
|
LastSpace = (szLastSpace - szBuf);
|
|
szBuf[LastSpace] = 0;
|
|
}
|
|
|
|
_tcsncpy(szBuf, lpBuf, LastSpace);
|
|
|
|
SetDlgItemText(hwnd, uID1, szBuf);
|
|
SetDlgItemText(hwnd, uID2, lpBuf+LastSpace+1);
|
|
|
|
/* Return the number of used lines */
|
|
Ret = 2;
|
|
}
|
|
else
|
|
{
|
|
SetDlgItemText(hwnd, uID1, lpBuf);
|
|
Ret = 1;
|
|
}
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, lpBuf);
|
|
}
|
|
|
|
return Ret;
|
|
}
|
|
|
|
static VOID MakeFloatValueString(DOUBLE* dFloatValue, LPTSTR szOutput, LPTSTR szAppend)
|
|
{
|
|
TCHAR szDecimalSeparator[4];
|
|
|
|
/* Get the decimal separator for the current locale */
|
|
if (GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, szDecimalSeparator, sizeof(szDecimalSeparator) / sizeof(TCHAR)) > 0)
|
|
{
|
|
UCHAR uDecimals;
|
|
UINT uIntegral;
|
|
|
|
/* Show the value with two decimals */
|
|
uIntegral = (UINT)*dFloatValue;
|
|
uDecimals = (UCHAR)((UINT)(*dFloatValue * 100) - uIntegral * 100);
|
|
|
|
wsprintf(szOutput, _T("%u%s%02u %s"), uIntegral, szDecimalSeparator, uDecimals, szAppend);
|
|
}
|
|
}
|
|
|
|
static VOID SetProcSpeed(HWND hwnd, HKEY hKey, LPTSTR Value, UINT uID)
|
|
{
|
|
TCHAR szBuf[64];
|
|
DWORD BufSize = sizeof(DWORD);
|
|
DWORD Type = REG_SZ;
|
|
PROCESSOR_POWER_INFORMATION ppi;
|
|
|
|
ZeroMemory(&ppi, sizeof(ppi));
|
|
|
|
if ((CallNtPowerInformation(ProcessorInformation,
|
|
NULL,
|
|
0,
|
|
(PVOID)&ppi,
|
|
sizeof(ppi)) == STATUS_SUCCESS &&
|
|
ppi.CurrentMhz != 0) || RegQueryValueEx(hKey, Value, NULL, &Type, (PBYTE)&ppi.CurrentMhz, &BufSize) == ERROR_SUCCESS)
|
|
{
|
|
if (ppi.CurrentMhz < 1000)
|
|
{
|
|
wsprintf(szBuf, _T("%lu MHz"), ppi.CurrentMhz);
|
|
}
|
|
else
|
|
{
|
|
double flt = ppi.CurrentMhz / 1000.0;
|
|
MakeFloatValueString(&flt, szBuf, _T("GHz"));
|
|
}
|
|
|
|
SetDlgItemText(hwnd, uID, szBuf);
|
|
}
|
|
}
|
|
|
|
static VOID GetSystemInformation(HWND hwnd)
|
|
{
|
|
HKEY hKey;
|
|
TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
|
|
MEMORYSTATUSEX MemStat;
|
|
TCHAR Buf[32];
|
|
INT CurMachineLine = IDC_MACHINELINE1;
|
|
|
|
/*
|
|
* Get Processor information
|
|
* although undocumented, this information is being pulled
|
|
* directly out of the registry instead of via setupapi as it
|
|
* contains all the info we need, and should remain static
|
|
*/
|
|
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, ProcKey, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
|
|
{
|
|
SetRegTextData(hwnd, hKey, _T("VendorIdentifier"), CurMachineLine);
|
|
CurMachineLine++;
|
|
|
|
CurMachineLine += SetProcNameString(hwnd,
|
|
hKey,
|
|
_T("ProcessorNameString"),
|
|
CurMachineLine,
|
|
CurMachineLine + 1);
|
|
|
|
SetProcSpeed(hwnd, hKey, _T("~MHz"), CurMachineLine);
|
|
CurMachineLine++;
|
|
}
|
|
|
|
/* Get total physical RAM */
|
|
MemStat.dwLength = sizeof(MemStat);
|
|
|
|
if (GlobalMemoryStatusEx(&MemStat))
|
|
{
|
|
TCHAR szStr[32];
|
|
double dTotalPhys;
|
|
|
|
if (MemStat.ullTotalPhys > 1024 * 1024 * 1024)
|
|
{
|
|
UINT i = 0;
|
|
static const UINT uStrId[] = { IDS_GIGABYTE, IDS_TERABYTE, IDS_PETABYTE};
|
|
|
|
// We're dealing with GBs or more
|
|
MemStat.ullTotalPhys /= 1024 * 1024;
|
|
|
|
if (MemStat.ullTotalPhys > 1024 * 1024)
|
|
{
|
|
// We're dealing with TBs or more
|
|
MemStat.ullTotalPhys /= 1024;
|
|
i++;
|
|
|
|
if (MemStat.ullTotalPhys > 1024 * 1024)
|
|
{
|
|
// We're dealing with PBs or more
|
|
MemStat.ullTotalPhys /= 1024;
|
|
i++;
|
|
|
|
dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
|
|
}
|
|
else
|
|
{
|
|
dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dTotalPhys = (double)MemStat.ullTotalPhys / 1024;
|
|
}
|
|
|
|
LoadString(hApplet, uStrId[i], szStr, sizeof(szStr) / sizeof(TCHAR));
|
|
MakeFloatValueString(&dTotalPhys, Buf, szStr);
|
|
}
|
|
else
|
|
{
|
|
// We're dealing with MBs, don't show any decimals
|
|
LoadString(hApplet, IDS_MEGABYTE, szStr, sizeof(szStr) / sizeof(TCHAR));
|
|
wsprintf(Buf, _T("%u %s"), (UINT)MemStat.ullTotalPhys / 1024 / 1024, szStr);
|
|
}
|
|
|
|
SetDlgItemText(hwnd, CurMachineLine, Buf);
|
|
}
|
|
}
|
|
|
|
static VOID GetSystemVersion(HWND hwnd)
|
|
{
|
|
HWND hRosVersion;
|
|
SIZE_T lenStr, lenVersion;
|
|
PCWSTR pwszVersion = L" " TEXT(KERNEL_VERSION_RC);
|
|
PWSTR pwszStr;
|
|
|
|
lenVersion = wcslen(pwszVersion);
|
|
if (lenVersion == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
hRosVersion = GetDlgItem(hwnd, IDC_ROSVERSION);
|
|
if (!hRosVersion)
|
|
{
|
|
return;
|
|
}
|
|
lenStr = GetWindowTextLengthW(hRosVersion);
|
|
lenStr += lenVersion + 1;
|
|
pwszStr = HeapAlloc(GetProcessHeap(), 0, lenStr * sizeof(WCHAR));
|
|
if (!pwszStr)
|
|
{
|
|
return;
|
|
}
|
|
GetWindowText(hRosVersion, pwszStr, lenStr);
|
|
|
|
StringCchCatW(pwszStr, lenStr, pwszVersion);
|
|
SetWindowText(hRosVersion, pwszStr);
|
|
|
|
HeapFree(GetProcessHeap(), 0, pwszStr);
|
|
}
|
|
|
|
/* Property page dialog callback */
|
|
INT_PTR CALLBACK GeneralPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
UNREFERENCED_PARAMETER(lParam);
|
|
UNREFERENCED_PARAMETER(wParam);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
pImgInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMGINFO));
|
|
if (pImgInfo == NULL)
|
|
{
|
|
EndDialog(hwndDlg, 0);
|
|
return FALSE;
|
|
}
|
|
|
|
InitLogo(hwndDlg);
|
|
SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ROSIMG), GWLP_WNDPROC, (LONG_PTR)RosImageProc);
|
|
GetSystemInformation(hwndDlg);
|
|
GetSystemVersion(hwndDlg);
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
HeapFree(GetProcessHeap(), 0, pImgInfo);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
if (LOWORD(wParam) == IDC_LICENCE)
|
|
{
|
|
DialogBox(hApplet, MAKEINTRESOURCE(IDD_LICENCE), hwndDlg, LicenceDlgProc);
|
|
|
|
return TRUE;
|
|
}
|
|
break;
|
|
|
|
case WM_DRAWITEM:
|
|
{
|
|
LPDRAWITEMSTRUCT lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
|
|
|
|
if (lpDrawItem->CtlID == IDC_ROSIMG)
|
|
{
|
|
HDC hdcMem;
|
|
LONG left;
|
|
|
|
/* Position image in centre of dialog */
|
|
left = (lpDrawItem->rcItem.right - pImgInfo->cxSource) / 2;
|
|
|
|
hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
|
|
if (hdcMem != NULL)
|
|
{
|
|
SelectObject(hdcMem, pImgInfo->hBitmap);
|
|
BitBlt(lpDrawItem->hDC,
|
|
left,
|
|
lpDrawItem->rcItem.top,
|
|
lpDrawItem->rcItem.right - lpDrawItem->rcItem.left,
|
|
lpDrawItem->rcItem.bottom - lpDrawItem->rcItem.top,
|
|
hdcMem,
|
|
0,
|
|
0,
|
|
SRCCOPY);
|
|
DeleteDC(hdcMem);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
NMHDR *nmhdr = (NMHDR *)lParam;
|
|
|
|
if (nmhdr->idFrom == IDC_ROSHOMEPAGE_LINK && nmhdr->code == NM_CLICK)
|
|
{
|
|
PNMLINK nml = (PNMLINK)nmhdr;
|
|
|
|
ShellExecuteW(hwndDlg, L"open", nml->item.szUrl, NULL, NULL, SW_SHOWNORMAL);
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
}
|