• 模拟Chrome皮肤


    话不多说,先验货:

    (原始状态)

    image

    (最大化状态)

    image

    (对比图)

    image

    为自己鼓掌!!!

    哈哈,捣鼓2天终于把这个搞出来了!虽然代码一团糟,但是不难理解!

    要实现这个功能需要几个组件:DWM,GDI+

    在实现这个代码中我认为最困难的就是chrome边框的阴影部分~

    image

    (这里的2个像素的阴影)

    和本身客户区边框的1个黑色像素,这1个像素IE11没有处理,而CHROME却没有这个黑边:

    image

    最开始使用GDI,但是GDI不带有Alpha通道,导致在画阴影时画出来的是实线,所以换成GDI+,下面是实现效果(没有采用圆角矩形,因为GDI+没有直接绘制圆角矩形的接口):

    image

    好了,上代码:

      1 # include <windows.h>
      2 #include <windowsx.h>
      3 # include <stdio.h>
      4 # include <stdlib.h>
      5 #include "dwmapi.h"
      6 #include "resource.h"
      7 #include <gdiplus.h>
      8 using namespace Gdiplus;
      9 
     10 
     11 const int TOPEXTENDWIDTH = 44;
     12 const int TOPEXTENDWIDTHMAX = 34;
     13 const int BOTTOMEXTENDWIDTH = 8;
     14 const int LEFTEXTENDWIDTH = 8;
     15 const int RIGHTEXTENDWIDTH = 8;
     16 
     17 
     18 LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
     19 LRESULT AppWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
     20 LRESULT CustomCaptionProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool* pfCallDWP);
     21 
     22 bool formstateMax=false;
     23 
     24 LRESULT HitTestNCA(HWND hWnd, WPARAM wParam, LPARAM lParam)
     25 {
     26     
     27     POINT ptMouse = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)};
     28     
     29     RECT rcWindow;
     30     GetWindowRect(hWnd, &rcWindow);
     31 
     32     
     33     RECT rcFrame = { 0 };
     34     AdjustWindowRectEx(&rcFrame, WS_OVERLAPPEDWINDOW & ~WS_CAPTION, FALSE, NULL);
     35 
     36     
     37     USHORT uRow = 1;
     38     USHORT uCol = 1;
     39     bool fOnResizeBorder = false;
     40 
     41     
     42     if (ptMouse.y >= rcWindow.top && ptMouse.y < rcWindow.top + (formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH) )
     43     {
     44         fOnResizeBorder = (ptMouse.y < (rcWindow.top - rcFrame.top));
     45         uRow = 0;
     46     }
     47     else if (ptMouse.y < rcWindow.bottom && ptMouse.y >= rcWindow.bottom - BOTTOMEXTENDWIDTH)
     48     {
     49         uRow = 2;
     50     }
     51     
     52     if (ptMouse.x >= rcWindow.left && ptMouse.x < rcWindow.left + LEFTEXTENDWIDTH)
     53     {
     54         uCol = 0; 
     55     }
     56     else if (ptMouse.x < rcWindow.right && ptMouse.x >= rcWindow.right - RIGHTEXTENDWIDTH)
     57     {
     58         uCol = 2; 
     59     }
     60 
     61     // Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
     62     LRESULT hitTests[3][3] = 
     63     {
     64         { HTTOPLEFT,    fOnResizeBorder ? HTTOP : HTCAPTION,    HTTOPRIGHT },
     65         { HTLEFT,       HTNOWHERE,     HTRIGHT },
     66         { HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
     67     };
     68 
     69 
     70     return hitTests[uRow][uCol];
     71 }
     72 
     73 int RECTWIDTH(RECT trec)
     74 {
     75     int rWidth = 0;
     76     rWidth = trec.right - trec.left;
     77     return rWidth;
     78 }
     79 
     80 int RECTHEIGHT(RECT trec)
     81 {
     82     int rHeight = 0;
     83     rHeight = trec.bottom - trec.top;
     84     return rHeight;
     85 }
     86 
     87 void ReDrawExtendFrame(HWND hWnd)
     88 {
     89     MARGINS margins;
     90 
     91     margins.cxLeftWidth = LEFTEXTENDWIDTH;      
     92     margins.cxRightWidth = RIGHTEXTENDWIDTH;   
     93     margins.cyBottomHeight = BOTTOMEXTENDWIDTH; 
     94     if (formstateMax)
     95         margins.cyTopHeight = TOPEXTENDWIDTHMAX;      
     96     else
     97         margins.cyTopHeight = TOPEXTENDWIDTH;      
     98 
     99     int hr = DwmExtendFrameIntoClientArea(hWnd, &margins);
    100 
    101     if (!SUCCEEDED(hr))
    102     {
    103         
    104     }
    105 }
    106 
    107 int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
    108 {
    109     static TCHAR szAppName [] = TEXT("Pavkoo SChrome");
    110     int address = (int)hInstance;
    111     HWND hwnd;
    112     MSG msg;
    113     WNDCLASS wndclass;
    114     GdiplusStartupInput gdiplusStartupInput;
    115     ULONG_PTR gdiplusToken;
    116     GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);
    117     wndclass.style = CS_HREDRAW|CS_VREDRAW;
    118     wndclass.lpfnWndProc = WndProc;
    119     wndclass.cbClsExtra = 0 ;
    120     wndclass.cbWndExtra = 0 ;
    121     wndclass.hInstance = hInstance;
    122     wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
    123     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
    124     wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
    125     wndclass.lpszMenuName=NULL;
    126     wndclass.lpszClassName=szAppName;
    127     if(!RegisterClass(&wndclass))
    128     {
    129         MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
    130         return 0;
    131     }
    132     hwnd=CreateWindow(szAppName,TEXT("Schrome"),WS_OVERLAPPEDWINDOW,
    133         CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
    134         NULL,NULL,hInstance,NULL);
    135     ShowWindow(hwnd,iCmdShow);
    136     UpdateWindow(hwnd);
    137 
    138     while(GetMessage(&msg,NULL,0,0))
    139     {
    140         TranslateMessage(&msg);
    141         DispatchMessage(&msg);
    142     }
    143     GdiplusShutdown(gdiplusToken);
    144     return msg.wParam;
    145 }
    146 
    147 
    148 LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    149 {
    150     bool fCallDWP = true;  //是否需要将消息传递给默认的窗口处理程序,如果是重绘窗体框架就不用传递消息了!
    151     BOOL fDwmEnabled = FALSE;
    152     LRESULT lRet = 0;
    153     HRESULT hr = S_OK;
    154 
    155     // 判断Aero Glass是否开启
    156     hr = DwmIsCompositionEnabled(&fDwmEnabled);
    157     if (SUCCEEDED(hr))
    158     {
    159         lRet = CustomCaptionProc(hWnd, message, wParam, lParam, &fCallDWP);
    160     }
    161 
    162     // 处理其他默认的消息
    163     if (fCallDWP)
    164     {
    165         lRet = AppWinProc(hWnd, message, wParam, lParam);
    166     }
    167     return lRet;
    168 }
    169 
    170 //
    171 // 绘制自定义窗体框架的处理程序
    172 //
    173 LRESULT CustomCaptionProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool* pfCallDWP)
    174 {
    175     LRESULT lRet = 0;
    176     HRESULT hr = S_OK;
    177     bool fCallDWP = true; // 传递给DefWindowProc
    178 
    179     //是否需要DWM绘制非客户区
    180     fCallDWP = !DwmDefWindowProc(hWnd, message, wParam, lParam, &lRet);
    181 
    182     if (message == WM_CREATE)
    183     {
    184         RECT rcClient;
    185         GetWindowRect(hWnd, &rcClient);
    186 
    187         SetWindowPos(hWnd, 
    188             NULL, 
    189             rcClient.left, rcClient.top,
    190             RECTWIDTH(rcClient), RECTHEIGHT(rcClient),
    191             SWP_FRAMECHANGED);//触发一条WM_NCCALCSIZE消息,通吃应用程序框架大小发生改变
    192 
    193         fCallDWP = true;
    194         lRet = 0;
    195     }
    196 
    197     // 窗口激活
    198     if (message == WM_ACTIVATE)
    199     {        
    200         ReDrawExtendFrame(hWnd);
    201         fCallDWP = true;
    202         lRet = 0;
    203     }
    204 
    205     if (message == WM_PAINT)
    206     {
    207         HDC hdc;
    208         PAINTSTRUCT ps;
    209         {
    210             hdc = BeginPaint(hWnd, &ps);
    211 
    212             //使用gdi+绘制
    213             Graphics graphicsInstance(hdc);            
    214             Rect rect = Rect(ps.rcPaint.left + LEFTEXTENDWIDTH,
    215                 ps.rcPaint.top + (formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH),
    216                 ps.rcPaint.right - ps.rcPaint.left - RIGHTEXTENDWIDTH-LEFTEXTENDWIDTH ,
    217                 ps.rcPaint.bottom -ps.rcPaint.top -BOTTOMEXTENDWIDTH-(formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH));            
    218             SolidBrush solidBrush(Color(255,255,255,255));
    219             rect.Inflate(1,1);
    220             graphicsInstance.FillRectangle(&solidBrush,rect);
    221             Pen pen(Color(200,100,100,100));        
    222             graphicsInstance.DrawRectangle(&pen,rect);
    223             rect.Inflate(1,1);
    224             pen.SetColor(Color(60,100,100,100));            
    225             graphicsInstance.DrawRectangle(&pen,rect);
    226             rect.Inflate(1,1);
    227             pen.SetColor(Color(20,100,100,100));            
    228             graphicsInstance.DrawRectangle(&pen,rect);
    229 
    230 
    231             //画标签
    232             Rect  rectTab= Rect(20,rect.Y-TOPEXTENDWIDTHMAX+3+7,190,TOPEXTENDWIDTHMAX-7);
    233             solidBrush.SetColor(Color(255,255,255,255));
    234             graphicsInstance.FillRectangle(&solidBrush,rectTab);
    235             pen.SetColor(Color(200,100,100,100));        
    236             graphicsInstance.DrawRectangle(&pen,rectTab);
    237             pen.SetColor(Color(255,255,255,255));
    238             graphicsInstance.DrawLine(&pen,rectTab.X,rectTab.Y+rectTab.Height,rectTab.X+rectTab.Width,rectTab.Y+rectTab.Height);    
    239 
    240             Rect  * add = rectTab.Clone();
    241             add->Offset(add->Width +6,0);
    242             add->Width = 30;
    243             add->Height = 18;
    244             add->Y = add->Y +4;
    245             solidBrush.SetColor(Color(100,255,255,255));
    246             graphicsInstance.FillRectangle(&solidBrush,*add);
    247             pen.SetColor(Color(80,100,100,100));        
    248             graphicsInstance.DrawRectangle(&pen,*add);
    249 
    250             SolidBrush  brush(Color(255, 0, 0, 0)); 
    251             FontFamily  fontFamily(L"微软雅黑"); 
    252             Font        font(&fontFamily, 12, FontStyleRegular, UnitPixel); 
    253             PointF      pointF(rectTab.X +10,rectTab.Y+6); 
    254 
    255             graphicsInstance.DrawString(L"打开新的标签页", -1, &font, pointF, &brush); 
    256             FontFamily  fontFamily2(L"Gautami");         
    257             Font        font2(&fontFamily2,12, FontStyleBold, UnitPixel); 
    258             PointF      pointF2(rectTab.X + rectTab.Width - 10- 10 ,rectTab.Y+4); 
    259             brush.SetColor(Color(255, 60, 60, 60)); 
    260             graphicsInstance.DrawString(L"x", -1, &font2, pointF2, &brush); 
    261 
    262 
    263             Rect rectAddress = Rect(rect.X+3,rectTab.Y+rectTab.Height,rect.Width-6,TOPEXTENDWIDTHMAX);
    264             LinearGradientBrush linGrBrush( 
    265                                                             Point(rectAddress.X,rectAddress.Y),
    266                                                             Point(rectAddress.X, rectAddress.Y+rectAddress.Height-2),  //不包含边框
    267                                                             Color(255, 255,255, 255),   
    268                                                             Color(255, 220, 220, 220)
    269             );  
    270             graphicsInstance.FillRectangle(&linGrBrush,rectAddress);
    271             pen.SetColor(Color(255,160,160,160));
    272             graphicsInstance.DrawLine(&pen,rectAddress.X,rectAddress.Y+rectAddress.Height-2,rectAddress.X +rectAddress.Width,rectAddress.Y+rectAddress.Height-2);
    273 
    274 
    275             Rect * left= rectAddress.Clone();
    276             left->X = left->X +10;
    277             left->Y = left->Y + 8;
    278             left ->Width = 18;
    279             left->Height = 14;
    280             Image imageLeft(L"D:\Code\WINAPI\chrome\alpha\Windowstyle\RES\left.png");
    281             graphicsInstance.DrawImage(&imageLeft,left->X,left->Y,left->Width,left->Height);
    282 
    283             Image imageRight(L"D:\Code\WINAPI\chrome\alpha\Windowstyle\RES\right.png");
    284             graphicsInstance.DrawImage(&imageRight,left->X+left->Width+15,left->Y,left->Width,left->Height);
    285 
    286             Image imageRefresh(L"D:\Code\WINAPI\chrome\alpha\Windowstyle\RES\refresh.png");
    287             graphicsInstance.DrawImage(&imageRefresh,left->X+left->Width+15+left->X+left->Width,left->Y,left->Width,left->Height);
    288             int leftSparate = left->X+left->Width+15+left->X+left->Width+15 + left->Width;
    289             Rect rectSearch = Rect(leftSparate,rectAddress.Y +5,rectAddress.Width-leftSparate,rectAddress.Height -12);
    290             solidBrush.SetColor(Color(255,255,255,255));
    291             graphicsInstance.FillRectangle(&solidBrush,rectSearch.X,rectSearch.Y,rectSearch.Width,rectSearch.Height);
    292             rectSearch.Inflate(1,1);
    293             pen.SetColor(Color(200,200,200,200));
    294             graphicsInstance.DrawRectangle(&pen,rectSearch);
    295             rectSearch.Inflate(-1,-1);
    296             pen.SetColor(Color(10,100,100,100));
    297             graphicsInstance.DrawRectangle(&pen,rectSearch);
    298 
    299             Image image(L"D:\Code\WINAPI\chrome\alpha\Windowstyle\RES\center.png");
    300             PointF point3(((ps.rcPaint.right-ps.rcPaint.left) - image.GetWidth()) / 2,((ps.rcPaint.bottom-ps.rcPaint.top) - image.GetHeight()) / 2);
    301             graphicsInstance.DrawImage(&image,point3.X,point3.Y,image.GetWidth(),image.GetHeight());
    302 
    303             EndPaint(hWnd, &ps);            
    304         }
    305 
    306         fCallDWP = true;
    307         lRet = 0;
    308     }
    309 
    310     // 接受非客户区大小发生改变
    311     if ((message == WM_NCCALCSIZE) && (wParam == TRUE))
    312     {
    313         // 计算新的NCCALCSIZE_PARAMS大小
    314         NCCALCSIZE_PARAMS *pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam);
    315 
    316         pncsp->rgrc[0].left   = pncsp->rgrc[0].left   + 0;
    317         pncsp->rgrc[0].top    = pncsp->rgrc[0].top    + 0;
    318         pncsp->rgrc[0].right  = pncsp->rgrc[0].right  - 0;
    319         pncsp->rgrc[0].bottom = pncsp->rgrc[0].bottom - 0;
    320 
    321         lRet = 0;
    322 
    323         // 这个消息没有必要传递给Defwindowproc
    324         fCallDWP = false;
    325     }
    326 
    327     // 处理DwmDefWindowProc没有处理到的hit testing消息
    328     if ((message == WM_NCHITTEST) && (lRet == 0))
    329     {
    330         lRet = HitTestNCA(hWnd, wParam, lParam);
    331 
    332         if ((lRet != HTNOWHERE) )
    333         {
    334             fCallDWP = false;
    335         }
    336     }    
    337     *pfCallDWP = fCallDWP;
    338 
    339     return lRet;
    340 }
    341 
    342 LRESULT AppWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    343 {
    344     int wmId, wmEvent;
    345     PAINTSTRUCT ps;
    346     HDC hdc;
    347     HRESULT hr; 
    348     LRESULT result = 0;
    349 
    350     switch (message)
    351     {
    352     case WM_CREATE:
    353         {}
    354         break;
    355     case WM_COMMAND:
    356         wmId    = LOWORD(wParam);
    357         wmEvent = HIWORD(wParam);
    358         switch (wmId)
    359         {
    360         default:
    361             return DefWindowProc(hWnd, message, wParam, lParam);
    362         }
    363         break;
    364     case WM_PAINT:
    365         {
    366             hdc = BeginPaint(hWnd, &ps);            
    367             EndPaint(hWnd, &ps);
    368         }
    369         break;
    370     case  WM_SIZE:
    371         {
    372             if (wParam==SIZE_MAXIMIZED)
    373             {
    374                 formstateMax = true;
    375             }
    376             else 
    377             {
    378                 formstateMax = false;
    379             }
    380             ReDrawExtendFrame(hWnd);
    381         }
    382         break;
    383     case WM_DESTROY:
    384         PostQuitMessage(0);
    385         break;
    386     default:
    387         return DefWindowProc(hWnd, message, wParam, lParam);
    388     }
    389     return 0;
    390 }

     要是有兴趣下下来看看吧!

    参考链接:

    http://msdn.microsoft.com/en-us/library/bb688195(VS.85).aspx#appendixc

    http://msdn.microsoft.com/en-us/library/ms632606(VS.85).aspx

    http://blog.csdn.net/oldmtn/article/details/7258003

    http://www.cnblogs.com/kekec/archive/2010/10/08/1845645.html

  • 相关阅读:
    10款面向HTML5 画布(Canvas)的JavaScript库
    lufylegend库 LGraphics扭曲图片
    lufylegend库 LGraphics绘制图片
    lufylegend库 LGraphics
    lufylegend库 LBitmapData LBitmap LSprite
    Web骇客网;外刊IT评论
    HTML5画布(CANVAS)速查简表
    Canvas 画板
    Canvas 阴影效果
    Canvas 图片灰度
  • 原文地址:https://www.cnblogs.com/pavkoo/p/3714037.html
Copyright © 2020-2023  润新知