CreateWindow创建异形窗口(不规则窗口) - WINDOWS API 第三弹 异形窗口。
本期将自己从底层中抽离出来,来搞点UI设计相关的,毕竟UI是本人强项(矮子里面拔高个吧)。你的UI界面是不是都是矩形框,你有想过其他形状的界面吗?是不是感觉计算机应用就应该是方方正正的。答案肯定是NO。异形窗体就能打破此限制,异形可不是那个电影里的怪物,异形是形状不规则的意思。在聊异形之前我们先看看如何创建常规的窗体,这里不使用MFC,而是Windows自带api:CreateWindow,本节中其他的api都是围绕这个api展开的。
目录
一、CreateWindow参数介绍
二、WNDCLASS类
三、实现异形的方法
四、总结
demo
一、CreateWindow参数介绍
#define CreateWindowA(lpClassName, lpWindowName, dwStyle, x, y,\
nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam)\
参数 |
含义 |
lpClassName |
1. 窗口类名称,可以是一个指向 NULL 结束的字符串或一个整型数值 |
lpWindowName |
1. 窗口标题,一个指向 NULL 结束的字符串指针 |
dwStyle |
指定创建窗口的风格(详见下方↓) |
x |
1. 指定窗口的初始水平位置(x 坐标) |
y |
1. 指定窗口的初始垂直位置(y 坐标) |
nWidth |
1. 以设备单元指明窗口的宽度 |
nHeight |
1. 以设备单元指明窗口的高度 |
hWndParent |
1. 指向被创建窗口的父窗口或所有者窗口的句柄 |
hMenu |
1. 指向窗口菜单句柄,或依据窗口风格指明一个子窗口标识 |
hInstance |
与窗口相关联的模块实例的句柄 |
lpParam |
1. 指向一个值的指针,该值传递给窗口 WM_CREATE 消息。该值通过在 IParam 参数中的 CREATESTRUCT 结构传递 |
转载来自: | CreateWindow函数详解_lixingyun123的博客-CSDN博客_createwindow |
这其中第三个参数和倒数第二个参数比较重要: dwStyle与hInstance。其中dwStyle为窗口的形式,我目前接触到的就是弹窗和可嵌入窗体。hInstance为窗口句柄,必须传入。
dwStyle:
WS_BORDER:创建一个单边框的窗口。WS_CAPTION:创建一个有标题框的窗口(包括WS_BODER风格)。WS_CHIlD:创建一个子窗口。这个风格不能与WS_POPUP风格合用。WS_CHLDWINDOW:与WS_CHILD相同。WS_CLIPCHILDREN:当在父窗口内绘图时,排除子窗口区域。在创建父窗口时使用这个风格。WS_CLlPBLINGS;排除子窗口之间的相对区域,也就是,当一个特定的窗口接收到WM_PAINT消息时,WS_CLIPSIBLINGS 风格将所有层叠窗口排除在绘图之外,只重绘指定的子窗口。如果未指定WS_CLIPSIBLINGS风格,并且子窗口是层叠的,则在重绘子窗口的客户区时,就会重绘邻近的子窗口。WS_DISABLED:创建一个初始状态为禁止的子窗口。一个禁止状态的窗日不能接受来自用户的输入信息。WS_DLGFRAME:创建一个带对话框边框风格的窗口。这种风格的窗口不能带标题条。WS_GROUP:指定一组控制的第一个控制。这个控制组由第一个控制和随后定义的控制组成,自第二个控制开始每个控制,具有WS_GROUP风格,每个组的第一个控制带有WS_TABSTOP风格,从而使用户可以在组间移动。用户随后可以使用光标在组内的控制间改变键盘焦点。WS_HSCROLL:创建一个有水平滚动条的窗口。WS_ICONIC:创建一个初始状态为最小化状态的窗口。与WS_MINIMIZE风格相同。WS_MAXIMIZE:创建一个具有最大化按钮的窗口。该风格不能与WS_EX_CONTEXTHELP风格同时出现,同时必须指定WS_SYSMENU风格。WS_OVERLAPPED:产生一个层叠的窗口。一个层叠的窗口有一个标题条和一个边框。与WS_TILED风格相同。WS_OVERtAPPEDWINDOW:创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU WS_THICKFRAME,WS_MINIMIZEBOX,WS_MAXMIZEBOX风格的层叠窗口,与WS_TILEDWINDOW风格相同。WS_POPUP;创建一个弹出式窗口。该风格不能与WS_CHLD风格同时使用。WS_POPUWINDOW:创建一个具有WS_BORDER,WS_POPUP,WS_SYSMENU风格的窗口,WS_CAPTION和WS_POPUPWINDOW必须同时设定才能使窗口某单可见。WS_SIZEBOX:创建一个可调边框的窗口,与WS_THICKFRAME风格相同。WS_SYSMENU:创建一个在标题条上带有窗口菜单的窗口,必须同时设定WS_CAPTION风格。WS_TABSTOP:创建一个控制,这个控制在用户按下Tab键时可以获得键盘焦点。按下Tab键后使键盘焦点转移到下一具有WS_TABSTOP风格的控制。WS_THICKFRAME:创建一个具有可调边框的窗口,与WS_SIZEBOX风格相同。WS_TILED:产生一个层叠的窗口。一个层叠的窗口有一个标题和一个边框。与WS_OVERLAPPED风格相同。WS_TILEDWINDOW:创建一个具有WS_OVERLAPPED,WS_CAPTION,WS_SYSMENU MS_THICKFRAME.WS_MINIMIZEBOX,WS_MAXMIZEBOX风格的层叠窗口。与WS_OVERLAPPEDWINDOW风格相同。WS_VISIBLE:创建一个初始状态为可见的窗口。WS_VSCROLL:创建一个有垂直滚动条的窗口。
如果想要一个弹窗,将dwStyle设置为WS_POPUP。如果想要一个可嵌入内容的窗口,设置为WS_OVELAPPEDWINDOW。
hInstance为传入的窗口句柄,一般在WinMain入口传入。
二、WNDCLASS类
在正式创建窗体前,我们需要将其中一些固定参数设定好,也称注册。类中的数据结构如下:
typedef struct tagWNDCLASSW {UINT style;WNDPROC lpfnWndProc;int cbClsExtra;int cbWndExtra;HINSTANCE hInstance;HICON hIcon;HCURSOR hCursor;HBRUSH hbrBackground;LPCWSTR lpszMenuName;LPCWSTR lpszClassName;
} WNDCLASSW, *PWNDCLASSW, NEAR *NPWNDCLASSW, FAR *LPWNDCLASSW;
成员解析:
成员 | 含义 |
---|---|
style | 指定窗口类型,各种“类风格”可以使用按位或操作符组合起来 |
IpfnWndProc | 指定窗口过程(必须是回调函数) |
cbClsExtra | 预留的额外空间,一般为0 |
cbWndExtra | 预留的额外空间,一般为0 |
hInstance | 应为程序的实例句柄 |
hIcon | 为所有基于该窗口类的窗口设定一个图标 |
hCursor | 为所有基于该窗口类的窗口设定一个鼠标指针 |
hbrBackground | 指定窗口背景色 |
IpszMenuName | 指定窗口菜单 |
IpszClassName | 指定窗口类名 |
style成员如下:
类风格 | 含义 |
---|---|
CS_VREDRAW | 移动或者调整窗口的高度(垂直方向)时,重绘整个窗口 |
CW_HREDRAW | 移动或者调整窗口的宽度(水平方向)时,重绘整个窗口 |
CS_DBLCLKS | 当用户光标在窗口内双击时,允许发送双击消息给窗口过程 |
CS_OWNDC | 给予每一个窗口实例分配一个唯一的DC(注意,尽管这样很方便,但它必须慎重使用,因为每一个DC大约要占800个字节的内存) |
CS_CLASSDC | 该窗口类的所有窗口实例都共享一个窗口类DC |
CS_PARENTDC |
1.将子窗口的裁剪区域设置到父窗口的DC中去,这样子窗口便可以在父窗口上绘制自身。(注意:这是子窗口从系统缓存中获取DC,而不是使用父窗口的DC。) 2.指定该分格可以提高系统性能 |
CS_NOCLOSE | 禁止系统菜单的关闭选项 |
CS_SAVEBITS |
1.以位图形式保存被该窗口遮挡的屏幕部分,当该窗口移动以后,系统便可以用该保存的位图恢复屏幕移动的相应部分,从而系统不用向被该窗口遮挡的窗口发送WM_PAINT消息。 2.该特性对于菜单类型的窗口比较合适,因为它通常是简短的显示一下之后便消失。 3.设置该特性将增加显示该窗口的时间,因为它通常要先分配保存位图的内存。 |
CS_BYTEALIGNCLIENT | 在字节边界上(x方向上)定位窗口的用户区域的位置 |
CS_BYTEALIGNWINDOW | 在字符边界上(x方向上)定位窗口的位置 |
CS_GLOBALCLASS |
1.当调用CreateWindow或CreateWindowEx函数来创建窗口时允许它的hInstance参数和注册窗口类时传递给RegisterClass的hInstace参数不同. 2.如果不指定该风格,则这两个hInstace必须相同 |
这些设置要在CreateWindow前,并且最好写一个判断是否设置成功的函数,保险些。(其实我也是看其他人这么写的哈哈哈哈哈)!
IpfnWndProc必须是一个回调函数,非常重要,非常重要,非常重要!也就是必须这样写:
wc.lpfnWndProc = WndProc;
关于回调函数可以看这:
C++学习之回调函数_HAH-M的博客-CSDN博客_c++ 回调函数
一般将需要嵌入窗体的内容、对窗体的操作写在WndProc中。给他传入的参数也需要带上消息类。
嵌入内容时需要获得窗体的大小,这里使用如下代码即可:
RECT rc;
GetClientRect(hWnd, &rc);
传出来的rc即是窗体尺寸,为RECT结构体,结构体内容如下:
typedef struct tagRECT
{LONG left;LONG top;LONG right;LONG bottom;
} RECT, *PRECT, NEAR *NPRECT, FAR *LPRECT;
三、实现异形的方法
别忘了我们的主题是异形窗体,这个困扰了我一段时间的问题,没想到如此简单。。。来,展示。
首先,我们要确定是用已有的形状实现还是散点实现,已有的形状无非就是圆角矩形、椭圆这种,在设计上不是特别出彩。散点实现就很酷了,在CV中,有一种标注数据的方式是polygon,就是散点围成一个圈,在C++函数里竟然也有这个东西,百闻不如一见啊。
在afxwin.h中,有CRgn类,我们来看看其中都有什么方法:
class CRgn : public CGdiObject
{DECLARE_DYNAMIC(CRgn)public:static CRgn* PASCAL FromHandle(HRGN hRgn);operator HRGN() const;// ConstructorsCRgn();BOOL CreateRectRgn(int x1, int y1, int x2, int y2);BOOL CreateRectRgnIndirect(LPCRECT lpRect);BOOL CreateEllipticRgn(int x1, int y1, int x2, int y2);BOOL CreateEllipticRgnIndirect(LPCRECT lpRect);BOOL CreatePolygonRgn(LPPOINT lpPoints, int nCount, int nMode);BOOL CreatePolyPolygonRgn(LPPOINT lpPoints, LPINT lpPolyCounts,int nCount, int nPolyFillMode);BOOL CreateRoundRectRgn(int x1, int y1, int x2, int y2, int x3, int y3);BOOL CreateFromPath(CDC* pDC);BOOL CreateFromData(const XFORM* lpXForm, int nCount,const RGNDATA* pRgnData);// Operationsvoid SetRectRgn(int x1, int y1, int x2, int y2);void SetRectRgn(LPCRECT lpRect);int CombineRgn(const CRgn* pRgn1, const CRgn* pRgn2, int nCombineMode);int CopyRgn(const CRgn* pRgnSrc);BOOL EqualRgn(const CRgn* pRgn) const;int OffsetRgn(int x, int y);int OffsetRgn(POINT point);int GetRgnBox(LPRECT lpRect) const;BOOL PtInRegion(int x, int y) const;BOOL PtInRegion(POINT point) const;BOOL RectInRegion(LPCRECT lpRect) const;int GetRegionData(LPRGNDATA lpRgnData, int nCount) const;// Implementationvirtual ~CRgn();
};
看到CreatePolygonRgn就懂了,我们来试着使用它:
POINT pts[5] ={{ 200, 0},{ 0, 160 },{ 120, 400 },{ 285, 400 },{ 400, 160 }};//五边形散点CRgn wndRgn;wndRgn.CreatePolygonRgn(pts,5, WINDING);//wndRgn.CreateEllipticRgn(rcClient.left, 0, rcClient.right, rcClient.bottom);SetWindowRgn(hWndMain, wndRgn, true);
声明一个CRgn的wndRgn,然后将其执行CreatePolygonRgn方法,然后SetWindowRgn(hWndMain, wndRgn, true);
将消息放入循环体中循环:
while (GetMessage(&msg, NULL, 0, 0)){TranslateMessage(&msg);DispatchMessage(&msg);}
大功告成:
四、总结
windows SDK有很多好用的、好玩的东西等我们去发现!异形窗体可以作为趣味的弹窗来给产品增加活力和乐趣。我们将设计好的内容放入html中,再通过ie网页打开,这种实现方式不用带来额外的开销,相比较于内嵌ie内核与QT等异形实现,可谓是真正的轻装上阵了。
demo
后续贴出源代码,请等待。
CreateWindow创建异形窗口(不规则窗口) - WINDOWS API 第三弹 异形窗口。相关推荐
- C#通过Windows API捕获窗,获取窗口文本(FindWindow、GetWindowText),附录:Windows窗口消息大全、Windows API大全
文章目录 一.前言 二.使用Spy++工具分析窗口 三.C#通过Windows API捕获窗口,获取窗口文本 四.附录:Windows窗口消息 五.Windows API大全 1.API之网络函数 2 ...
- Windows API(三)线程
Windows API笔记(一)内核对象 Windows API笔记(二)进程和进程间通信.进程边界 Windows API笔记(三)线程和线程同步.线程局部存储 Windows API笔记(三)线程 ...
- Windows Phone 7 自定义弹出窗口
Windows Phone内置的MessageBox弹出窗口局限性太大,不能满足各种个性化的弹出窗口的需求,即使使用第三方的控件库也会有一些局限性,又或者封装的东西太多了,那么这时候就需要自己去根据自 ...
- CreateFile | ReadFile | WriteFile - WINDOWS API 第五弹 C++创建任意格式的文件用于读取和写入。
Windows api系列第五弹强烈来袭,本期介绍Windows上c++有关文件创建.读取和写入的api:CreateFile.ReadFile.WriteFile. 目录 一.CreateFile ...
- vc 只有顶级窗口可以弹出窗口_如何在Mac上允许弹出窗口
通常,我们尝试避免弹出窗口,但是有时您需要让它们通过.下面这样做的方法. 由于浏览器阻止了弹出窗口,您是否在macOS上遇到网站问题?幸运的是,您可以在计算机上的主要浏览器(例如Safari,Chro ...
- php屏蔽弹出窗口,可以不被浏览器拦截的弹出窗口JS代码
转载: 一个强制弹出窗口的JavaScript类:ForceWindow 一个可以不被广告拦截器拦截的弹出窗口 ForceWindow.iclass.js代码如下(使用.讲解.相关说明全部在注释中): ...
- Beep() - WINDOWS API 第六弹 C++调用蜂鸣器播放简单的曲调。
今天搞个好玩的东西,windows上自带的蜂鸣器,调用beep()函数即可实现,它位于windows.h中,话说目前我们听到的歌曲似乎都是来自机器,来自纯乐器的声音很奢侈,所以你对机器发出的音色一定不 ...
- Delphi 下用Windows API 创建窗体
Delphi 下用Windows API 创建窗体 副标题: 作者:佚名 文章来源:大富翁 点击数:119 更新时间:2005-2-25 Delphi 下用Windows API 创建窗体 / ...
- swing退出子窗口事件_如何创建有效的退出弹出窗口?
如何创建有效的退出弹出窗口? 下面的退出弹出窗口为电子邮件列表增加了4153个订阅者: 这个提供折扣的弹出窗口,帮助Storiarts在60天之内挽回了96个弃单客户,从而额外创造了5000美元的销售 ...
最新文章
- window下实现在线预览功能
- .NET Core 以及与 .NET Framework的关系
- Linux技巧:自动挂载UDF光盘的技巧
- Opencv显示创建Mat对象的七种方式
- MySQL Hardware--FIO压测
- 出现503错误 怎么办
- 信号与系统sa函数求积分_瞎扯数学分析微积分(1~4)
- javascript访问frame,iframe框架和href的定向
- 计算机专业知识综合应用题,2015年计算机综合考研及解析之综合应用题(一)...
- debug安装包安装在别人手机上闪退?
- 福建农林大学外事处界面设计
- 数学-盲点题:九个点用四条直线连起来
- 【Android实习】20场面试斩获大厂offer,我学会了什么
- wordpress 数据库_如何一键优化您的WordPress数据库
- 一年级上册计算机教学计划,人教版数学一年级上册教学计划
- for循环里面的break;和continue;语句
- [ STK ](十一)STK 中搭建铱星星座
- unity安装问题:启动编译器时出错:许可证无效
- 图像处理之平滑滤波、高斯滤波和中值滤波
- 小米盒子的远程安装实现
热门文章
- 教你如何实现一步完成线上线下一体化的购物体验
- java的choice什么意思_choice是什么意思_choice的翻译_音标_读音_用法_例句_爱词霸在线词典...
- 如何用C++实现一个简易数据库(十一)
- FLASH 中的场景,图层以及层的理解
- 长期稳定的搬砖项目——steam搬砖
- 下一代区块链底层基础设施是什么样的?——Nervos@2019 杭州区块链周
- 京东宣布涨薪,两年内将员工平均年薪从14薪涨到16薪!
- FuzzFactory: Domain-Specific Fuzzing with Waypoints
- 悟空CRM (基于jfinal+vue+ElementUI的前后端分离CRM系统)
- 别等了!下一代操作系统Windows 10X,彻底凉凉了