[KSPROXY]
[reactos.git] / reactos / dll / cpl / sysdm / general.c
index bbb3b25..7c2eea6 100644 (file)
@@ -5,13 +5,16 @@
  * PURPOSE:     General System Information
  * COPYRIGHT:   Copyright Thomas Weidenmueller <w3seek@reactos.org>
  *              Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
- *              Copyright 2006 Colin Finck <mail@colinfinck.de>
+ *              Copyright 2006-2007 Colin Finck <mail@colinfinck.de>
  *
  */
 
 
 #include "precomp.h"
 
+#define ANIM_STEP 2
+#define ANIM_TIME 50
+
 typedef struct _IMGINFO
 {
     HBITMAP hBitmap;
@@ -19,31 +22,32 @@ typedef struct _IMGINFO
     INT cySource;
 } IMGINFO, *PIMGINFO;
 
+PIMGINFO pImgInfo = NULL;
 
 void
 ShowLastWin32Error(HWND hWndOwner)
 {
-  LPTSTR lpMsg;
-  DWORD LastError;
-
-  LastError = GetLastError();
-
-  if((LastError == 0) ||
-      !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                       FORMAT_MESSAGE_FROM_SYSTEM,
-                     NULL,
-                     LastError,
-                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-                     (LPTSTR)&lpMsg,
-                     0,
-                     NULL))
-  {
-    return;
-  }
+    LPTSTR lpMsg;
+    DWORD LastError;
+
+    LastError = GetLastError();
+
+    if ((LastError == 0) ||
+         !FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                        FORMAT_MESSAGE_FROM_SYSTEM,
+                        NULL,
+                        LastError,
+                        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                        (LPTSTR)&lpMsg,
+                        0,
+                        NULL))
+    {
+        return;
+    }
 
-  MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
+    MessageBox(hWndOwner, lpMsg, NULL, MB_OK | MB_ICONERROR);
 
-  LocalFree((LPVOID)lpMsg);
+    LocalFree((LPVOID)lpMsg);
 }
 
 
@@ -70,6 +74,124 @@ InitImageInfo(PIMGINFO ImgInfo)
     }
 }
 
+LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+       static UINT timerid = 0, top = 0, offset;
+       static HBITMAP hBitmap2;
+       RECT r;
+       NONCLIENTMETRICS ncm;
+       HFONT hfont;
+       BITMAP bitmap;
+       HDC dc, sdc;
+       TCHAR devtext[2048];
+       switch (uMsg)
+       {
+               case WM_LBUTTONDBLCLK:
+                       if (wParam & (MK_CONTROL | MK_SHIFT))
+                       {
+                               if (timerid == 0)
+                               {
+                                       top = 0; // set top
+                                       
+                                       // build new bitmap
+                                       GetObject(pImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
+                                       dc = CreateCompatibleDC(GetDC(NULL));
+                                       sdc = CreateCompatibleDC(dc);
+                                       ncm.cbSize = sizeof(NONCLIENTMETRICS);
+                                       SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0);
+
+                                       hfont = CreateFontIndirect(&ncm.lfMessageFont);
+                                       SelectObject(dc, hfont);
+                                       SetRect(&r, 0, 0, 0, 0);
+                                       LoadString(hApplet, IDS_DEVS, devtext, sizeof(devtext) / sizeof(TCHAR));
+                                       DrawText(dc, devtext, -1, &r, DT_CALCRECT);
+                                       hBitmap2 = CreateBitmap(pImgInfo->cxSource, (2 * pImgInfo->cySource) + (r.bottom + 1 - r.top), bitmap.bmPlanes, bitmap.bmBitsPixel, NULL);
+                                       SelectObject(sdc, pImgInfo->hBitmap);
+                                       SelectObject(dc, hBitmap2);
+                                       offset = 0;
+                                       BitBlt(dc, 0, offset, bitmap.bmWidth, bitmap.bmHeight, sdc, 0, 0, SRCCOPY);
+                                       offset += bitmap.bmHeight;
+
+                                       SetRect(&r, 0, offset, bitmap.bmWidth, offset + (r.bottom - r.top) + 1);
+                                       FillRect(dc, &r, GetSysColorBrush(COLOR_3DFACE));
+                                       SetBkMode(dc, TRANSPARENT);
+                                       OffsetRect(&r, 1, 1);
+                                       SetTextColor(dc, GetSysColor(COLOR_BTNSHADOW));
+                                       DrawText(dc, devtext, -1, &r, DT_CENTER);
+                                       OffsetRect(&r, -1, -1);
+                                       SetTextColor(dc, GetSysColor(COLOR_WINDOWTEXT));
+                                       DrawText(dc, devtext, -1, &r, DT_CENTER);
+                                       offset += r.bottom - r.top;
+
+                                       BitBlt(dc, 0, offset, bitmap.bmWidth, bitmap.bmHeight, sdc, 0, 0, SRCCOPY);
+                                       offset += bitmap.bmHeight;
+                                       DeleteDC(sdc);
+                                       DeleteDC(dc);
+
+                                       timerid = SetTimer(hwnd, 1, ANIM_TIME, NULL);
+                               }
+                       }
+                       break;
+               case WM_LBUTTONDOWN:
+                       if (timerid)
+                       {
+                               KillTimer(hwnd, timerid);
+                               top = 0;
+                               timerid = 0;
+                               DeleteObject(hBitmap2);
+                               InvalidateRect(hwnd, NULL, FALSE);
+                       }
+                       break;
+               case WM_TIMER:
+                       top += ANIM_STEP;
+                       if (top > offset - pImgInfo->cySource)
+                       {
+                               KillTimer(hwnd, timerid);
+                               top = 0;
+                               timerid = 0;
+                               DeleteObject(hBitmap2);
+                       }
+                       InvalidateRect(hwnd, NULL, FALSE);
+                       break;
+               case WM_PAINT:
+               {
+                       PAINTSTRUCT PS;
+                       HDC hdcMem, hdc;
+                       LONG left;
+                       if (wParam != 0)
+                       {
+                               hdc = (HDC)wParam;
+                       } else
+                       {       
+                          hdc = 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)
+                       {
+                               SelectObject(hdcMem, timerid ? hBitmap2 : pImgInfo->hBitmap);
+                               BitBlt(hdc,
+                                  left,
+                                  PS.rcPaint.top,
+                                  PS.rcPaint.right - PS.rcPaint.left,
+                                  PS.rcPaint.top + pImgInfo->cySource,
+                                  hdcMem,
+                                  0,
+                                  top,
+                                  SRCCOPY);
+                               DeleteDC(hdcMem);
+                       }
+                       if (wParam == 0)
+                               EndPaint(hwnd,&PS);
+                 break;
+               }
+       }
+       return TRUE;
+}
 
 static VOID
 SetRegTextData(HWND hwnd,
@@ -91,7 +213,8 @@ SetRegTextData(HWND hwnd,
         lpBuf = HeapAlloc(GetProcessHeap(),
                           0,
                           BufSize);
-        if (!lpBuf) return;
+        if (!lpBuf)
+            return;
 
         if (RegQueryValueEx(hKey,
                             Value,
@@ -125,7 +248,7 @@ SetProcNameString(HWND hwnd,
     TCHAR szBuf[31];
     TCHAR* szLastSpace;
     INT LastSpace = 0;
-    
+
     if (RegQueryValueEx(hKey,
                         Value,
                         NULL,
@@ -135,8 +258,9 @@ SetProcNameString(HWND hwnd,
     {
         lpBuf = HeapAlloc(GetProcessHeap(),
                           0,
-                          BufSize);   
-        if (!lpBuf) return 0;
+                          BufSize);
+        if (!lpBuf)
+            return 0;
 
         if (RegQueryValueEx(hKey,
                             Value,
@@ -145,85 +269,117 @@ SetProcNameString(HWND hwnd,
                             (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);
-              szLastSpace = _tcsrchr(szBuf, ' ');
-              
-              if(szLastSpace == 0)
-                LastSpace = 30;
-              else
-                LastSpace = (szLastSpace - szBuf);
-              
-              _tcsncpy(szBuf, lpBuf, LastSpace);
-              szBuf[LastSpace] = 0;
-              
-              SetDlgItemText(hwnd,
-                             uID1,
-                             szBuf);
-                       
-              SetDlgItemText(hwnd,
-                             uID2,
-                             lpBuf+LastSpace+1);
-                       
-              /* Return the number of used lines */
-              Ret = 2;
+            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,
+                SetDlgItemText(hwnd,
                              uID1,
                              lpBuf);
-              
-              Ret = 1;
+
+                Ret = 1;
             }
         }
 
         HeapFree(GetProcessHeap(),
                  0,
                  lpBuf);
-        
-        return Ret;
     }
-    
-    return 0;
+
+    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
+static VOID
 SetProcSpeed(HWND hwnd,
              HKEY hKey,
              LPTSTR Value,
              UINT uID)
-
 {
     TCHAR szBuf[64];
-    DWORD dwBuf;
     DWORD BufSize = sizeof(DWORD);
     DWORD Type = REG_SZ;
-
-    if (RegQueryValueEx(hKey,
-                        Value,
-                        NULL,
-                        &Type,
-                        (PBYTE)&dwBuf,
-                        &BufSize) == ERROR_SUCCESS)
+    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 (dwBuf < 1000)
+        if (ppi.CurrentMhz < 1000)
         {
-            _stprintf(szBuf, _T("%.2f MHz"), dwBuf);
+            wsprintf(szBuf, _T("%lu MHz"), ppi.CurrentMhz);
         }
         else
         {
-            double flt = dwBuf / 1000.0;
-            _stprintf(szBuf, _T("%.2f GHz"), flt);
+            double flt = ppi.CurrentMhz / 1000.0;
+            MakeFloatValueString(&flt, szBuf, _T("GHz"));
         }
 
         SetDlgItemText(hwnd,
@@ -239,11 +395,10 @@ GetSystemInformation(HWND hwnd)
     TCHAR ProcKey[] = _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0");
     MEMORYSTATUSEX MemStat;
     TCHAR Buf[32];
-    INT Ret = 0;
     INT CurMachineLine = IDC_MACHINELINE1;
 
-
-    /* Get Processor information *
+    /*
+     * 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
@@ -254,22 +409,21 @@ GetSystemInformation(HWND hwnd)
                      KEY_READ,
                      &hKey) == ERROR_SUCCESS)
     {
-        SetRegTextData(hwnd, 
-                       hKey, 
-                       _T("VendorIdentifier"), 
+        SetRegTextData(hwnd,
+                       hKey,
+                       _T("VendorIdentifier"),
                        CurMachineLine);
         CurMachineLine++;
-        
-        Ret = SetProcNameString(hwnd, 
-                                hKey, 
-                                _T("ProcessorNameString"), 
-                                CurMachineLine,
-                                CurMachineLine+1);
-        CurMachineLine += Ret;
-        
-        SetProcSpeed(hwnd, 
-                     hKey, 
-                     _T("~MHz"), 
+
+        CurMachineLine += SetProcNameString(hwnd,
+                                            hKey,
+                                            _T("ProcessorNameString"),
+                                            CurMachineLine,
+                                            CurMachineLine + 1);
+
+        SetProcSpeed(hwnd,
+                     hKey,
+                     _T("~MHz"),
                      CurMachineLine);
         CurMachineLine++;
     }
@@ -281,58 +435,54 @@ GetSystemInformation(HWND hwnd)
     {
         TCHAR szStr[32];
         double dTotalPhys;
-        UINT i = 0;
-        static const UINT uStrId[] = {
-            IDS_MEGABYTE,
-            IDS_GIGABYTE,
-            IDS_TERABYTE,
-            IDS_PETABYTE
-        };
 
         if (MemStat.ullTotalPhys > 1024 * 1024 * 1024)
         {
-            /* We're dealing with GBs or more */
+            UINT i = 0;
+            static const UINT uStrId[] = {
+                IDS_GIGABYTE,
+                IDS_TERABYTE,
+                IDS_PETABYTE
+            };
+
+            // We're dealing with GBs or more
             MemStat.ullTotalPhys /= 1024 * 1024;
-            i++;
 
             if (MemStat.ullTotalPhys > 1024 * 1024)
             {
-                /* We're dealing with TBs or more */
+                // We're dealing with TBs or more
                 MemStat.ullTotalPhys /= 1024;
                 i++;
 
                 if (MemStat.ullTotalPhys > 1024 * 1024)
                 {
-                    /* We're dealing with PBs or more */
-
+                    // 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 daling with MBs */
-            dTotalPhys = (double)MemStat.ullTotalPhys / 1024 / 1024;
+            // 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);
         }
 
-        if (LoadString(hApplet, uStrId[i], szStr, sizeof(szStr) / sizeof(szStr[0])))
-        {
-            Ret = _stprintf(Buf, _T("%.2f %s"), dTotalPhys, szStr);
-        }
-    }
-
-    if (Ret)
-    {
-        SetDlgItemText(hwnd,
-                       CurMachineLine,
-                       Buf);
+        SetDlgItemText(hwnd, CurMachineLine, Buf);
     }
 }
 
@@ -344,22 +494,30 @@ GeneralPageProc(HWND hwndDlg,
                 WPARAM wParam,
                 LPARAM lParam)
 {
-    static IMGINFO ImgInfo;
 
     UNREFERENCED_PARAMETER(lParam);
     UNREFERENCED_PARAMETER(wParam);
 
-    switch(uMsg)
+    switch (uMsg)
     {
         case WM_INITDIALOG:
-        {
-            InitImageInfo(&ImgInfo);
+            pImgInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMGINFO));
+            if (pImgInfo == NULL)
+            {
+                EndDialog(hwndDlg, 0);
+                return FALSE;
+            }
+
+            InitImageInfo(pImgInfo);
+            SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ROSIMG), GWL_WNDPROC, (LONG)RosImageProc);
             GetSystemInformation(hwndDlg);
-        }
-        break;
+            break;
+
+        case WM_DESTROY:
+            HeapFree(GetProcessHeap(), 0, pImgInfo);
+            break;
 
         case WM_COMMAND:
-        {
             if (LOWORD(wParam) == IDC_LICENCE)
             {
                 DialogBox(hApplet,
@@ -369,25 +527,24 @@ GeneralPageProc(HWND hwndDlg,
 
                 return TRUE;
             }
-        }
-        break;
+            break;
 
         case WM_DRAWITEM:
         {
             LPDRAWITEMSTRUCT lpDrawItem;
             lpDrawItem = (LPDRAWITEMSTRUCT) lParam;
-            if(lpDrawItem->CtlID == IDC_ROSIMG)
+            if (lpDrawItem->CtlID == IDC_ROSIMG)
             {
                 HDC hdcMem;
                 LONG left;
 
                 /* position image in centre of dialog */
-                left = (lpDrawItem->rcItem.right - ImgInfo.cxSource) / 2;
+                left = (lpDrawItem->rcItem.right - pImgInfo->cxSource) / 2;
 
                 hdcMem = CreateCompatibleDC(lpDrawItem->hDC);
                 if (hdcMem != NULL)
                 {
-                    SelectObject(hdcMem, ImgInfo.hBitmap);
+                    SelectObject(hdcMem, pImgInfo->hBitmap);
                     BitBlt(lpDrawItem->hDC,
                            left,
                            lpDrawItem->rcItem.top,
@@ -425,8 +582,3 @@ GeneralPageProc(HWND hwndDlg,
 
     return FALSE;
 }
-
-
-
-
-