[SYSDM]
authorKamil Hornicek <kamil.hornicek@reactos.org>
Mon, 21 Apr 2014 18:27:40 +0000 (18:27 +0000)
committerKamil Hornicek <kamil.hornicek@reactos.org>
Mon, 21 Apr 2014 18:27:40 +0000 (18:27 +0000)
- use alpha blend when drawing the ros logo on the general page
- misc code cleanup
CORE-8071

svn path=/trunk/; revision=62856

reactos/dll/cpl/sysdm/general.c
reactos/dll/cpl/sysdm/resource.h
reactos/dll/cpl/sysdm/resources/rosbitmap.bmp
reactos/dll/cpl/sysdm/resources/rosbitmap_mask.bmp [new file with mode: 0644]
reactos/dll/cpl/sysdm/sysdm.rc

index 3060314..efa7784 100644 (file)
@@ -22,12 +22,14 @@ 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)
+VOID ShowLastWin32Error(HWND hWndOwner)
 {
     LPTSTR lpMsg;
     DWORD LastError;
@@ -53,39 +55,86 @@ ShowLastWin32Error(HWND hWndOwner)
 }
 
 
-static VOID
-InitImageInfo(PIMGINFO ImgInfo)
+static VOID InitLogo(HWND hwndDlg)
 {
-    BITMAP bitmap;
+    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;
+
+    ZeroMemory(pImgInfo, sizeof(*pImgInfo));
+    ZeroMemory(&bmpi, sizeof(bmpi));
+
+    hLogo = (HBITMAP)LoadImage(hApplet, MAKEINTRESOURCE(IDB_ROSBMP), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+    hMask = (HBITMAP)LoadImage(hApplet, MAKEINTRESOURCE(IDB_ROSMASK), IMAGE_BITMAP, 0, 0, LR_DEFAULTCOLOR);
+
+    if (hLogo != NULL && hMask != NULL)
+    {
+        GetObject(hLogo, sizeof(BITMAP), &logoBitmap);
+        GetObject(hMask, sizeof(BITMAP), &maskBitmap);
 
-    ZeroMemory(ImgInfo, sizeof(*ImgInfo));
+        if(logoBitmap.bmHeight != maskBitmap.bmHeight || logoBitmap.bmWidth != maskBitmap.bmWidth)
+            return;
 
-    ImgInfo->hBitmap = LoadImage(hApplet,
-                                 MAKEINTRESOURCE(IDB_ROSBMP),
-                                 IMAGE_BITMAP,
-                                 0,
-                                 0,
-                                 LR_DEFAULTCOLOR);
+        pImgInfo->cxSource = logoBitmap.bmWidth;
+        pImgInfo->cySource = logoBitmap.bmHeight;
 
-    if (ImgInfo->hBitmap != NULL)
-    {
-        GetObject(ImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
+        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;
+
+        hAlphaLogo = CreateDIBSection(hDC, &bmpi, DIB_RGB_COLORS, (PVOID*)&pBits, 0, 0);
+
+        if(!hAlphaLogo)
+            return;
+
+        SelectObject(hDCLogo, hLogo);
+        SelectObject(hDCMask, hMask);
 
-        ImgInfo->cxSource = bitmap.bmWidth;
-        ImgInfo->cySource = bitmap.bmHeight;
+        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;
+
+    DeleteObject(hLogo);
+    DeleteObject(hMask);
+    DeleteDC(hDCLogo);
+    DeleteDC(hDCMask);
+
 }
 
 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];
+    static HBITMAP hCreditsBitmap;
+
     switch (uMsg)
     {
         case WM_LBUTTONDBLCLK:
@@ -93,51 +142,65 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
             {
                 if (timerid == 0)
                 {
-                    top = 0; // Set top
+                    HDC hCreditsDC, hLogoDC;
+                    HFONT hFont;
+                    NONCLIENTMETRICS ncm;
+                    RECT rcCredits;
+                    TCHAR szCredits[2048];
+                    INT iDevsHeight;
+
+                    top = 0;
+                    offset = 0;
+                    hCreditsDC = CreateCompatibleDC(GetDC(NULL));
+                    hLogoDC = CreateCompatibleDC(hCreditsDC);
 
-                    // Build new bitmap
-                    GetObject(pImgInfo->hBitmap, sizeof(BITMAP), &bitmap);
-                    dc = CreateCompatibleDC(GetDC(NULL));
-                    if (dc == NULL)
-                    {
-                        break;
-                    }
-                    sdc = CreateCompatibleDC(dc);
-                    if (sdc == NULL)
-                    {
-                        DeleteDC(dc);
+                    if (hCreditsDC == NULL || hLogoDC == NULL)
                         break;
-                    }
+
+                    SetRect(&rcCredits, 0, 0, 0, 0);
+
                     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);
+                    hFont = CreateFontIndirect(&ncm.lfMessageFont);
+                    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)
+                        break;
+
+                    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);
+
+                    DeleteDC(hLogoDC);
+                    DeleteDC(hCreditsDC);
 
                     timerid = SetTimer(hwnd, 1, ANIM_TIME, NULL);
                 }
@@ -146,22 +209,40 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
         case WM_LBUTTONDOWN:
             if (timerid)
             {
+                RECT rcCredits;
+                HDC hDC = GetDC(hwnd);
+
+                GetClientRect(hwnd, &rcCredits);
+                SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
+                FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
+
                 KillTimer(hwnd, timerid);
+                DeleteObject(hCreditsBitmap);
+                InvalidateRect(hwnd, NULL, FALSE);
+
                 top = 0;
                 timerid = 0;
-                DeleteObject(hBitmap2);
-                InvalidateRect(hwnd, NULL, FALSE);
             }
             break;
         case WM_TIMER:
             top += ANIM_STEP;
-            if (top > offset - pImgInfo->cySource)
+
+            if (top > offset)
             {
+                RECT rcCredits;
+                HDC hDC = GetDC(hwnd);
+
+                GetClientRect(hwnd, &rcCredits);
+                SetRect(&rcCredits, 0, 0, rcCredits.right, pImgInfo->cySource);
+                FillRect(hDC, &rcCredits, GetSysColorBrush(COLOR_3DFACE));
+
                 KillTimer(hwnd, timerid);
+                DeleteObject(hCreditsBitmap);
+
                 top = 0;
                 timerid = 0;
-                DeleteObject(hBitmap2);
             }
+
             InvalidateRect(hwnd, NULL, FALSE);
             break;
         case WM_PAINT:
@@ -169,15 +250,10 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
             PAINTSTRUCT PS;
             HDC hdcMem, hdc;
             LONG left;
-            if (wParam != 0)
-            {
-                hdc = (HDC)wParam;
-            }
-            else
-            {
-                hdc = BeginPaint(hwnd,&PS);
-            }
-            GetClientRect(hwnd,&PS.rcPaint);
+
+            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;
@@ -185,16 +261,17 @@ LRESULT CALLBACK RosImageProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam
 
             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);
+                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);
             }
 
@@ -521,7 +598,7 @@ GeneralPageProc(HWND hwndDlg,
                 return FALSE;
             }
 
-            InitImageInfo(pImgInfo);
+            InitLogo(hwndDlg);
             SetWindowLongPtr(GetDlgItem(hwndDlg, IDC_ROSIMG), GWL_WNDPROC, (LONG)RosImageProc);
             GetSystemInformation(hwndDlg);
             break;
index 6557c2c..caddd70 100644 (file)
@@ -10,6 +10,7 @@
 #define IDI_DOWN      2501
 
 #define IDB_ROSBMP 55
+#define IDB_ROSMASK 56
 
 #define IDS_CPLSYSTEMNAME        60
 #define IDS_CPLSYSTEMDESCRIPTION 61
index 8a94a6e..ee5891c 100644 (file)
Binary files a/reactos/dll/cpl/sysdm/resources/rosbitmap.bmp and b/reactos/dll/cpl/sysdm/resources/rosbitmap.bmp differ
diff --git a/reactos/dll/cpl/sysdm/resources/rosbitmap_mask.bmp b/reactos/dll/cpl/sysdm/resources/rosbitmap_mask.bmp
new file mode 100644 (file)
index 0000000..9e0ef21
Binary files /dev/null and b/reactos/dll/cpl/sysdm/resources/rosbitmap_mask.bmp differ
index eadf9b3..a3447d0 100644 (file)
@@ -19,6 +19,7 @@ IDI_DEVMGR ICON "resources/devmgr.ico"
 IDI_UP ICON "resources/up.ico"
 IDI_DOWN ICON "resources/down.ico"
 IDB_ROSBMP BITMAP "resources/rosbitmap.bmp"
+IDB_ROSMASK BITMAP "resources/rosbitmap_mask.bmp"
 
 RC_LICENSE RTDATA "resources/gpl.txt"