VC----SDK下对窗口非客户区的操作
窗口分成两大部分:客户区和非客户区。非客户区再次细分:标题栏,如图片中顶部深蓝色;左边框,如图片中红色部分;上边框,如图片中绿色部分;右边框,如图片中右侧天蓝色部分;底边框,如图片中下面棕色部分。
之所以要有这样的区分,是因为,我在用函数SystemParametersInfo得到窗口的非客户区参数时,标题栏高度确实是上面深蓝色部分,不能达到客户区,在标题栏和客户区之间还有一个白色区域,我想这可能就是上边框吧。
需要用到的几个函数:
PatBlt:作用是在指定的矩形区域用指定的Brush画刷来填充这个区域。
SystemParametersInfo:得到系统的一些参数,比如标题栏的高度,边框宽度等。
GetSystemMetrics:有点和上面函数相同,但是感觉没有上面的SystemParametersInfo函数精确。
思路:在消息WM_NCPAINT,WM_NCACTIVATE,WM_MOVE响应时得到非客户区的DC(区别于客户区的DC),再得到矩形区域,用函数来填充颜色。拦截系统对这几个消息的处理。
注意:使用的DC一定要是非客户区的DC,用GetWindowDC来得到句柄,不能用GetDC,因为GetDC得到的是客户区的DC,这个DC只能用来涂鸦客户区。得到边框的宽度时,比如顶部边框,绿色部分,要在得到的基础上+4,否则的话不能完全填充为指定的绿色,也是个疑问。
case WM_NOTIFY:
case WM_MOVE:
case WM_NCACTIVATE:
case WM_NCPAINT:
{ //得到系统标题栏的信息:宽度、高度、矩形区域
int tbheight,tbwidth;
RECT wndrect,clientrect;
GetWindowRect(hwnd,&wndrect);
GetClientRect(hwnd,&clientrect);
tbheight= GetSystemMetrics(SM_CYSIZE);//标题栏宽度
//end 得到系统标题栏的信息
//填充标题栏
RECT rcWindow ;
GetWindowRect(hwnd,&rcWindow);
HDC hDc = GetWindowDC(hwnd);
HBRUSH hBrush = CreateSolidBrush(RGB(25,0,255));
HBRUSH hOldbrush =(HBRUSH) SelectObject(hDc,(HGDIOBJ)hBrush);
PatBlt(hDc,0,0,wndrect.right-wndrect.left,tbheight,PATCOPY);
//end 填充标题栏
//填充边框
NONCLIENTMETRICS nonmet;
nonmet.cbSize=sizeof(NONCLIENTMETRICS);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&nonmet,0); RECT borderleft,borderright,bordertop,borderbottom;
borderleft.left = 0;
borderleft.right = wndrect.left+7;
borderleft.top=tbheight;
borderleft.bottom=wndrect.bottom;
hBrush = CreateSolidBrush(RGB(200,0,0));
SelectObject(hDc,(HGDIOBJ)hBrush);
PatBlt(hDc,borderleft.left,borderleft.top,nonmet.iPaddedBorderWidth+4,borderleft.bottom-borderleft.top,PATCOPY);
SelectObject(hDc,(HGDIOBJ)hOldbrush); bordertop.left=0;
bordertop.bottom=wndrect.top+nonmet.iCaptionHeight+nonmet.iPaddedBorderWidth+4;
bordertop.right = wndrect.right;
bordertop.top=nonmet.iCaptionHeight;
hBrush = CreateSolidBrush(RGB(0,200,0));
SelectObject(hDc,(HGDIOBJ)hBrush);
PatBlt(hDc,bordertop.left,bordertop.top,bordertop.right-bordertop.left,nonmet.iPaddedBorderWidth+5,PATCOPY);
SelectObject(hDc,(HGDIOBJ)hOldbrush); borderright.left=wndrect.right-wndrect.left-nonmet.iPaddedBorderWidth-4;
borderright.top=nonmet.iCaptionHeight;
borderright.bottom=wndrect.bottom;
borderright.right = wndrect.right-wndrect.left;
hBrush = CreateSolidBrush(RGB(0,100,200));
SelectObject(hDc,(HGDIOBJ)hBrush);
PatBlt(hDc,borderright.left,borderright.top,nonmet.iPaddedBorderWidth+4,borderright.bottom-borderright.top,PATCOPY); borderbottom.bottom = wndrect.bottom;
borderbottom.left=nonmet.iPaddedBorderWidth+4;
borderbottom.right = wndrect.right-wndrect.left-nonmet.iPaddedBorderWidth-4;
borderbottom.top = wndrect.bottom-wndrect.top-nonmet.iPaddedBorderWidth-4;
hBrush = CreateSolidBrush(RGB(100,80,80));
SelectObject(hDc,(HGDIOBJ)hBrush);
PatBlt(hDc,borderbottom.left,borderbottom.top,borderbottom.right-borderbottom.left,nonmet.iPaddedBorderWidth+4,PATCOPY);
//end 填充边框
SelectObject(hDc,(HGDIOBJ)hOldbrush);
ReleaseDC(hwnd,hDc);
//DefWindowProc(hwnd,uMsg,wParam,lParam);
return 0;//拦截系统的处理
break;
} 对DC的解释参考文章:
http://www.codeproject.com/Articles/89996/Drawing-in-Windows-101
对标题栏的理解:
在Win7下,设置主题为Basic类型的,得到一个界面如下:
外圈棕色部分就是边框,和上面说的上边框的位置不同,在对QQ窗口进行最大化也会看到红色的部分,这个部分是标题栏的位置。
几点注意:
1、三个系统按钮是为标题按钮,标题按钮和标题栏的宽度是一样大小的。
2、当最大化时,边框会消失。标准大小时,恢复状态。
调整后上边框为上绿色,结果如下:
而三个系统按钮就在最左边的位置 如图。
像Aero主题 和QQ 、迅雷等的按钮会发生变化,是因为是对这三个按钮处理的结果,上面的程序也有一个问题:当在单击到三个按钮的位置时会出现这三个按钮。如下:
就这个问题。
调整后的结果,:
对标题栏的理解:
在Win7下,设置主题为Basic类型的,得到一个界面如下:
外圈棕色部分就是边框,和上面说的上边框的位置不同,在对QQ窗口进行最大化也会看到红色的部分,这个部分是标题栏的位置。
而三个系统按钮就在最左边的位置 如图。
像Aero主题 和QQ 、迅雷等的按钮会发生变化,是因为是对这三个按钮处理的结果,上面的程序也有一个问题:当在单击到三个按钮的位置时会出现这三个按钮。如下:
就这个问题。
用位图来填充矩形:
目标是把三个按钮给覆盖:
//处理三个按钮
//第一步:定位位置--在右边框的左边,右侧贴右边框,左侧可通过SystemParametersInfo得到按钮宽度iCaptionHeight,再*3;上下边框在标题栏内。
//第二步:用图片或者颜色给盖上,拦截NCLBUTTONDOWN消息。在单击位置在按钮区域时,分别发送3个消息,
RECT btnrect;
btnrect.bottom=nonmet.iCaptionHeight+nonmet.iBorderWidth;
btnrect.left=wndrect.right-wndrect.left-nonmet.iCaptionHeight*3-nonmet.iBorderWidth;
btnrect.right=btnrect.left+nonmet.iCaptionHeight*3;
btnrect.top=nonmet.iBorderWidth; HDC hcomdc = CreateCompatibleDC(hDc);
HBITMAP hbmp = LoadBitmap(g_hInstance,MAKEINTRESOURCE(IDB_BITMAP4));
HBITMAP holdbmp=(HBITMAP)SelectObject(hcomdc,(HGDIOBJ)hbmp);
StretchBlt(hDc,btnrect.left-nonmet.iPaddedBorderWidth-14,btnrect.top+nonmet.iPaddedBorderWidth+4,nonmet.iCaptionHeight*3+12,nonmet.iCaptionHeight,hcomdc,0,0,60,20,SRCCOPY); //end处理三个按钮
结果如图:
拦截消息如下:
GetWindowRect(hwnd,&wndrect);
POINT *lpoint=(POINT *)lParam;
int xPos = GET_X_LPARAM(lParam);
int yPos = GET_Y_LPARAM(lParam);
if(xPos>wndrect.left+btnrect.left-10&&xPos<wndrect.left+btnrect.right-10&&yPos>wndrect.top+btnrect.top+8&&yPos<wndrect.top+btnrect.bottom)
return 0;
break;
把窗口进行圆角操作:
需要在窗口大小变化后进行圆角操作。捕捉大小变化的消息是WM_SIZE, 这是窗口变化后的消息。代码如下:
case WM_SIZE:
{
RECT wndRect;
GetWindowRect(hWnd,&wndRect);
HRGN hRgn=CreateRoundRectRgn(0,0,wndRect.right-wndRect.left,wndRect.bottom-wndRect.top,50,50);
SetWindowRgn(hWnd,hRgn,true);
if(hRgn)
DeleteObject((HGDIOBJ)hRgn);
break;
}
VC----SDK下对窗口非客户区的操作的更多相关文章
- 调用API函数,在窗口非客户区绘图(通过GetWindowDC获得整个窗口的DC,就可以随意作画了)
http://hi.baidu.com/3582077/item/77d3c1ff60f9fa5ec9f33754 调用API函数,在窗口非客户区绘图 GDI+的Graphics类里有个FromHdc ...
- C# 绘制窗体客户非客户区要用WM_PAINT和WM_NCPAINT
窗体分为两部分:客户区(Client area)和非客户区(Non-Client area) WM_PAINT消息.OnPaint()方法.GetDC()API函数都是处理窗体客户区绘制的 而标题 ...
- windows 屏幕坐标 窗口坐标 客户区坐标 逻辑坐标 设备坐标之间的关系及转换
设置坐标映射 (1)Windows坐标系统 Windows坐标系分为逻辑坐标系和设备坐标系两种,GDI支持这两种坐标系.一般而言, GDI的文本和图形输出函数使用逻辑坐标,而在客户区移动或按下鼠 ...
- 老话题:自己编写只截窗口客户区的截屏软件(VB2010)
现在能实现截屏的软件很多,就不一一列举了,连WIN7都自带截屏软件,甚至OFFICE2010开始都有截屏的功能. 截屏软件虽多,无外乎三种截屏方式:全屏截图.窗口截图.自定义矩形截图. 其中,窗口截图 ...
- 2019-11-29-WPF-非客户区的触摸和鼠标点击响应
原文:2019-11-29-WPF-非客户区的触摸和鼠标点击响应 title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi ...
- 2019-8-8-WPF-非客户区的触摸和鼠标点击响应
title author date CreateTime categories WPF 非客户区的触摸和鼠标点击响应 lindexi 2019-08-08 16:48:31 +0800 2019-07 ...
- 一句话为当前窗口客户区捉图: GetFormImage 来自万一的博客
一句话为当前窗口客户区捉图: GetFormImage http://www.cnblogs.com/del/archive/2008/10/24/1318738.html unit Unit1; i ...
- VC编程之设置客户区背景图片
在很多系统中出于美观的需要常常要设置背景图片.下面我介绍一种在客户区设置背景图片的简单方法. 1 .将背景bmp 图片导入到工程,资源ID 这里假设为 IDB_BITMAP1 2 .在视图类添加如下代 ...
- 元素大小-偏移量(offset)客户区大小(client)滚动大小(scroll)
一.偏移量---offset 1.定位父级 在理解偏移大小之前,首先要理解offsetParent.人们并没有把offsetParent翻译为偏移父级,而是翻译成定位父级,很大原因是offsetPar ...
随机推荐
- iOS开发小技巧--实现毛玻璃效果的方法
一.美工出图 二.第三方框架 -- DRNRealTimeBlur,框架继承自UIView.使用方法:创建UIView直接继承自框架的View,就有了毛玻璃效果 三.CoreImage -- 图片加高 ...
- iOS开发小技巧--TableView中headerView的循环利用,以及自定义的headerView
一.首先要搞清楚,tableView中有两种headerView,一个是tableHeaderView,另一个是headerView.前者就一个;后者根据session决定个数 headerView的 ...
- jQ1.5中的事件系统(低版本的事件系统)
jQ的一个个版本事系统都在修正着bug和不断优化, 而且看了事件系统对事件的兼容更加熟悉, 更加了解jQ内部的事件机制. 因为jQ对事件系统引入了事件命名空间,事件的代理, 事件的手动触发,事件描述等 ...
- mysql解决无法远程客户端连接
1. 改表法.可能是你的帐号不允许从远程登陆,只能在localhost.这个时候只要在localhost的那台电脑,登入mysql后,更改 "mysql" 数据库里的 " ...
- Json-遍历
1.js遍历 var data=[{name:"a",age:12},{name:"b",age:11},{name:"c",age:13} ...
- 控件 UI: VisualState, VisualStateManager, 控件的默认 UI
VisualState 和 VisualStateManager 控件的默认 Style, ControlTemplate, VisualState 示例1.演示“VisualState 和 Visu ...
- UNIX命令,统计当前目录(含子目录)下所有后缀为.log的文件中ERROR出现的行数
shell程序如下所示: # cat xarg.txt #! /usr/bin/ksh for logfile in `find . -name "*.log*"` do echo ...
- HTTP/2.0与HTTP/1.1协议区别
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)是互联网上应用最为广泛的一种网络协议.设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法.通 ...
- Win7下如何设置护眼的电脑豆沙绿界面?保护眼睛的颜色设置教程
关爱心灵的窗户——眼睛! 随着科技发展,使用电脑的人越来越多,由于使用电脑时间过长,我们的眼睛也越发容易疲劳,干燥.如何才能使电脑对人眼的伤害减小到最 小. 小编建议大家可以把窗口背景色设置成护眼色. ...
- slim
Slim 是一个非常优雅的 PHP 微框架,非常适合做API,支持多种http请求方式,比如get,post,delete,put等 安装使用Composer composer require sli ...