模拟Chrome皮肤
话不多说,先验货:
(原始状态)

(最大化状态)

(对比图)

为自己鼓掌!!!
哈哈,捣鼓2天终于把这个搞出来了!虽然代码一团糟,但是不难理解!
要实现这个功能需要几个组件:DWM,GDI+
在实现这个代码中我认为最困难的就是chrome边框的阴影部分~

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

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

好了,上代码:
# include <windows.h>
#include <windowsx.h>
# include <stdio.h>
# include <stdlib.h>
#include "dwmapi.h"
#include "resource.h"
#include <gdiplus.h>
using namespace Gdiplus; const int TOPEXTENDWIDTH = ;
const int TOPEXTENDWIDTHMAX = ;
const int BOTTOMEXTENDWIDTH = ;
const int LEFTEXTENDWIDTH = ;
const int RIGHTEXTENDWIDTH = ; LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
LRESULT AppWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CustomCaptionProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool* pfCallDWP); bool formstateMax=false; LRESULT HitTestNCA(HWND hWnd, WPARAM wParam, LPARAM lParam)
{ POINT ptMouse = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)}; RECT rcWindow;
GetWindowRect(hWnd, &rcWindow); RECT rcFrame = { };
AdjustWindowRectEx(&rcFrame, WS_OVERLAPPEDWINDOW & ~WS_CAPTION, FALSE, NULL); USHORT uRow = ;
USHORT uCol = ;
bool fOnResizeBorder = false; if (ptMouse.y >= rcWindow.top && ptMouse.y < rcWindow.top + (formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH) )
{
fOnResizeBorder = (ptMouse.y < (rcWindow.top - rcFrame.top));
uRow = ;
}
else if (ptMouse.y < rcWindow.bottom && ptMouse.y >= rcWindow.bottom - BOTTOMEXTENDWIDTH)
{
uRow = ;
} if (ptMouse.x >= rcWindow.left && ptMouse.x < rcWindow.left + LEFTEXTENDWIDTH)
{
uCol = ;
}
else if (ptMouse.x < rcWindow.right && ptMouse.x >= rcWindow.right - RIGHTEXTENDWIDTH)
{
uCol = ;
} // Hit test (HTTOPLEFT, ... HTBOTTOMRIGHT)
LRESULT hitTests[][] =
{
{ HTTOPLEFT, fOnResizeBorder ? HTTOP : HTCAPTION, HTTOPRIGHT },
{ HTLEFT, HTNOWHERE, HTRIGHT },
{ HTBOTTOMLEFT, HTBOTTOM, HTBOTTOMRIGHT },
}; return hitTests[uRow][uCol];
} int RECTWIDTH(RECT trec)
{
int rWidth = ;
rWidth = trec.right - trec.left;
return rWidth;
} int RECTHEIGHT(RECT trec)
{
int rHeight = ;
rHeight = trec.bottom - trec.top;
return rHeight;
} void ReDrawExtendFrame(HWND hWnd)
{
MARGINS margins; margins.cxLeftWidth = LEFTEXTENDWIDTH;
margins.cxRightWidth = RIGHTEXTENDWIDTH;
margins.cyBottomHeight = BOTTOMEXTENDWIDTH;
if (formstateMax)
margins.cyTopHeight = TOPEXTENDWIDTHMAX;
else
margins.cyTopHeight = TOPEXTENDWIDTH; int hr = DwmExtendFrameIntoClientArea(hWnd, &margins); if (!SUCCEEDED(hr))
{ }
} int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
{
static TCHAR szAppName [] = TEXT("Pavkoo SChrome");
int address = (int)hInstance;
HWND hwnd;
MSG msg;
WNDCLASS wndclass;
GdiplusStartupInput gdiplusStartupInput;
ULONG_PTR gdiplusToken;
GdiplusStartup(&gdiplusToken,&gdiplusStartupInput,NULL);
wndclass.style = CS_HREDRAW|CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = ;
wndclass.cbWndExtra = ;
wndclass.hInstance = hInstance;
wndclass.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
wndclass.lpszMenuName=NULL;
wndclass.lpszClassName=szAppName;
if(!RegisterClass(&wndclass))
{
MessageBox(NULL,TEXT("This program requires Windows NT!"),szAppName,MB_ICONERROR);
return ;
}
hwnd=CreateWindow(szAppName,TEXT("Schrome"),WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,
NULL,NULL,hInstance,NULL);
ShowWindow(hwnd,iCmdShow);
UpdateWindow(hwnd); while(GetMessage(&msg,NULL,,))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
GdiplusShutdown(gdiplusToken);
return msg.wParam;
} LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
bool fCallDWP = true; //是否需要将消息传递给默认的窗口处理程序,如果是重绘窗体框架就不用传递消息了!
BOOL fDwmEnabled = FALSE;
LRESULT lRet = ;
HRESULT hr = S_OK; // 判断Aero Glass是否开启
hr = DwmIsCompositionEnabled(&fDwmEnabled);
if (SUCCEEDED(hr))
{
lRet = CustomCaptionProc(hWnd, message, wParam, lParam, &fCallDWP);
} // 处理其他默认的消息
if (fCallDWP)
{
lRet = AppWinProc(hWnd, message, wParam, lParam);
}
return lRet;
} //
// 绘制自定义窗体框架的处理程序
//
LRESULT CustomCaptionProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool* pfCallDWP)
{
LRESULT lRet = ;
HRESULT hr = S_OK;
bool fCallDWP = true; // 传递给DefWindowProc //是否需要DWM绘制非客户区
fCallDWP = !DwmDefWindowProc(hWnd, message, wParam, lParam, &lRet); if (message == WM_CREATE)
{
RECT rcClient;
GetWindowRect(hWnd, &rcClient); SetWindowPos(hWnd,
NULL,
rcClient.left, rcClient.top,
RECTWIDTH(rcClient), RECTHEIGHT(rcClient),
SWP_FRAMECHANGED);//触发一条WM_NCCALCSIZE消息,通吃应用程序框架大小发生改变 fCallDWP = true;
lRet = ;
} // 窗口激活
if (message == WM_ACTIVATE)
{
ReDrawExtendFrame(hWnd);
fCallDWP = true;
lRet = ;
} if (message == WM_PAINT)
{
HDC hdc;
PAINTSTRUCT ps;
{
hdc = BeginPaint(hWnd, &ps); //使用gdi+绘制
Graphics graphicsInstance(hdc);
Rect rect = Rect(ps.rcPaint.left + LEFTEXTENDWIDTH,
ps.rcPaint.top + (formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH),
ps.rcPaint.right - ps.rcPaint.left - RIGHTEXTENDWIDTH-LEFTEXTENDWIDTH ,
ps.rcPaint.bottom -ps.rcPaint.top -BOTTOMEXTENDWIDTH-(formstateMax?TOPEXTENDWIDTHMAX:TOPEXTENDWIDTH));
SolidBrush solidBrush(Color(,,,));
rect.Inflate(,);
graphicsInstance.FillRectangle(&solidBrush,rect);
Pen pen(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rect);
rect.Inflate(,);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rect);
rect.Inflate(,);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rect); //画标签
Rect rectTab= Rect(,rect.Y-TOPEXTENDWIDTHMAX++,,TOPEXTENDWIDTHMAX-);
solidBrush.SetColor(Color(,,,));
graphicsInstance.FillRectangle(&solidBrush,rectTab);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rectTab);
pen.SetColor(Color(,,,));
graphicsInstance.DrawLine(&pen,rectTab.X,rectTab.Y+rectTab.Height,rectTab.X+rectTab.Width,rectTab.Y+rectTab.Height); Rect * add = rectTab.Clone();
add->Offset(add->Width +,);
add->Width = ;
add->Height = ;
add->Y = add->Y +;
solidBrush.SetColor(Color(,,,));
graphicsInstance.FillRectangle(&solidBrush,*add);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,*add); SolidBrush brush(Color(, , , ));
FontFamily fontFamily(L"微软雅黑");
Font font(&fontFamily, , FontStyleRegular, UnitPixel);
PointF pointF(rectTab.X +,rectTab.Y+); graphicsInstance.DrawString(L"打开新的标签页", -, &font, pointF, &brush);
FontFamily fontFamily2(L"Gautami");
Font font2(&fontFamily2,, FontStyleBold, UnitPixel);
PointF pointF2(rectTab.X + rectTab.Width - - ,rectTab.Y+);
brush.SetColor(Color(, , , ));
graphicsInstance.DrawString(L"x", -, &font2, pointF2, &brush); Rect rectAddress = Rect(rect.X+,rectTab.Y+rectTab.Height,rect.Width-,TOPEXTENDWIDTHMAX);
LinearGradientBrush linGrBrush(
Point(rectAddress.X,rectAddress.Y),
Point(rectAddress.X, rectAddress.Y+rectAddress.Height-), //不包含边框
Color(, ,, ),
Color(, , , )
);
graphicsInstance.FillRectangle(&linGrBrush,rectAddress);
pen.SetColor(Color(,,,));
graphicsInstance.DrawLine(&pen,rectAddress.X,rectAddress.Y+rectAddress.Height-,rectAddress.X +rectAddress.Width,rectAddress.Y+rectAddress.Height-); Rect * left= rectAddress.Clone();
left->X = left->X +;
left->Y = left->Y + ;
left ->Width = ;
left->Height = ;
Image imageLeft(L"D:\\Code\\WINAPI\\chrome\\alpha\\Windowstyle\\RES\\left.png");
graphicsInstance.DrawImage(&imageLeft,left->X,left->Y,left->Width,left->Height); Image imageRight(L"D:\\Code\\WINAPI\\chrome\\alpha\\Windowstyle\\RES\\right.png");
graphicsInstance.DrawImage(&imageRight,left->X+left->Width+,left->Y,left->Width,left->Height); Image imageRefresh(L"D:\\Code\\WINAPI\\chrome\\alpha\\Windowstyle\\RES\\refresh.png");
graphicsInstance.DrawImage(&imageRefresh,left->X+left->Width++left->X+left->Width,left->Y,left->Width,left->Height);
int leftSparate = left->X+left->Width++left->X+left->Width+ + left->Width;
Rect rectSearch = Rect(leftSparate,rectAddress.Y +,rectAddress.Width-leftSparate,rectAddress.Height -);
solidBrush.SetColor(Color(,,,));
graphicsInstance.FillRectangle(&solidBrush,rectSearch.X,rectSearch.Y,rectSearch.Width,rectSearch.Height);
rectSearch.Inflate(,);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rectSearch);
rectSearch.Inflate(-,-);
pen.SetColor(Color(,,,));
graphicsInstance.DrawRectangle(&pen,rectSearch); Image image(L"D:\\Code\\WINAPI\\chrome\\alpha\\Windowstyle\\RES\\center.png");
PointF point3(((ps.rcPaint.right-ps.rcPaint.left) - image.GetWidth()) / ,((ps.rcPaint.bottom-ps.rcPaint.top) - image.GetHeight()) / );
graphicsInstance.DrawImage(&image,point3.X,point3.Y,image.GetWidth(),image.GetHeight()); EndPaint(hWnd, &ps);
} fCallDWP = true;
lRet = ;
} // 接受非客户区大小发生改变
if ((message == WM_NCCALCSIZE) && (wParam == TRUE))
{
// 计算新的NCCALCSIZE_PARAMS大小
NCCALCSIZE_PARAMS *pncsp = reinterpret_cast<NCCALCSIZE_PARAMS*>(lParam); pncsp->rgrc[].left = pncsp->rgrc[].left + ;
pncsp->rgrc[].top = pncsp->rgrc[].top + ;
pncsp->rgrc[].right = pncsp->rgrc[].right - ;
pncsp->rgrc[].bottom = pncsp->rgrc[].bottom - ; lRet = ; // 这个消息没有必要传递给Defwindowproc
fCallDWP = false;
} // 处理DwmDefWindowProc没有处理到的hit testing消息
if ((message == WM_NCHITTEST) && (lRet == ))
{
lRet = HitTestNCA(hWnd, wParam, lParam); if ((lRet != HTNOWHERE) )
{
fCallDWP = false;
}
}
*pfCallDWP = fCallDWP; return lRet;
} LRESULT AppWinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
HRESULT hr;
LRESULT result = ; switch (message)
{
case WM_CREATE:
{}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
{
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_SIZE:
{
if (wParam==SIZE_MAXIMIZED)
{
formstateMax = true;
}
else
{
formstateMax = false;
}
ReDrawExtendFrame(hWnd);
}
break;
case WM_DESTROY:
PostQuitMessage();
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return ;
}
参考链接:
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
模拟Chrome皮肤的更多相关文章
- RobotFrameWork--selenium2模拟chrome的user agent
${options}= Evaluate sys.modules['selenium.webdriver'].ChromeOptions() sys, selenium.webdriver ${opt ...
- [HTML] IE=edge,chrome=1的META标签详解
文件兼容性用于定义让IE如何编译你的网页.此文件解释文件兼容性,如何指定你网站的文件兼容性模式以及如何判断一个网页该使用的文件模式. meta信息中常有这么一句: <meta content=& ...
- IE=edge,chrome=1的META信息详解
这几天在玩 HTML5 ★ Boilerplate,注意到meta信息中有这么一句: 复制代码 代码如下: <meta http-equiv="X-UA-Compatible" ...
- content = "IE=edge,chrome=1" 详解
content = "IE=edge,chrome=1" 详解 < meta http-equiv = "X-UA-Compatible" content ...
- < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />的作用
< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" /> 介绍:这 ...
- < meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />
目录(?)[-] 1 meta http-equiv X-UA-Compatible content chrome1 1 meta http-equiv X-UA-Compatible cont ...
- 配置Nutch模拟浏览器以绕过反爬虫限制
原文链接:http://yangshangchuan.iteye.com/blog/2030741 当我们配置Nutch抓取 http://yangshangchuan.iteye.com 的时候,抓 ...
- 详解< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" />
< meta http-equiv = "X-UA-Compatible" content = "IE=edge,chrome=1" /> 这是个是 ...
- 写给对<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">迷惑不解的小伙伴
1.X-UA-Compatible X-UA-Compatible是自从IE8新加的一个设置,对于IE8以下的浏览器是不识别的. 通过在meta中设置X-UA-Compatible的值,可以指定网页的 ...
随机推荐
- 新建maven 父子模块项目
第一步: 第二步: 先创建个简单的空架结构作为父项目 第三步: 创建子项目 第四步: 切换显示不同的maven子项目显示方式 关于maven中的parent聚合一直都有没好好总结,固有这篇. ---- ...
- redis之常用Set和ZSet命令
redis五种数据类型:String,Hash,List,Set,ZSet.五种数据类型各有优点,各司其职.最后两种数据类型Set和ZSet基本上是一种,ZSet就是给Set加了个排序而已(相当于加了 ...
- 去除List集合中的重复值(四种好用的方法)
最近项目中需要对list集合中的重复值进行处理,大部分是采用两种方法,一种是用遍历list集合判断后赋给另一个list集合,一种是用赋给set集合再返回给list集合. 但是赋给set集合后,由于se ...
- Josephus环的四种解法(约瑟夫环)
约瑟夫环 约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3…n分别表示)围坐在一张圆桌周围.从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个 ...
- Codeforces-B-Game with string(模拟栈)
Two people are playing a game with a string ss, consisting of lowercase latin letters. On a player's ...
- java中Runtime类和Process类的简单介绍
在java.lang包当中定义了一个Runtime类,在java中对于Runtime类的定义如下: Java code public class Runtime extends Object 每个 J ...
- mongodb 基础语法
参考原文:菜鸟教程 目录 一.数据库二.文档三.索引四.聚合 一.数据库 show dbs -- 查看所有数据库 use DATABASE_NAME -- 如果数据库不存在,则创建数据库,否则切换到指 ...
- my.变身卡
中级 1620 (4--6级) 高级 8323 (7--9级) 赤炎: 1.老鼠精 135 / 150 2.白骨精 750 3.情丝娘子 264 / 294 4.沙和尚 500 5.九头虫 1835 ...
- spark第一篇:RDD Programming Guide
预览 在高层次上,每一个Spark应用(application)都包含一个驱动程序(driver program),该程序运行用户的主函数(main function),并在集群上执行各种并行操作. ...
- Java-IO读写文件简单操作2
承接Java-IO读写文件简单操作,这里再次写个小demo巩固一下知识点. 代码文件:demo.java package com.test.demo; import java.io.*; public ...