大家都见过在windows下各种气泡窗口、输入法窗口以及其他一些窗口,这些窗口看起来不像传统的windows窗那样,上面是标题栏,下面是窗口的客户区。这些窗口形状各异,可以是一个多边形,一幅图,甚至是一个人物画像等。这些异形窗口是怎么实现的呢?下面我们就来实现这个奇异形状的窗口。

其实在windows下实现特殊的窗口并不困难,有两种办法可以实现:

  1. 通过创建路径和区域、合并区域的办法。创建区域的API有很多,比如CreateRectRgnCreateRoundRectRgnCreateEllipticRgn以及其他创建区域函数等,具体参考MSDN。然后使用SetWindowRgn函数设置窗口区域,将区域转化为窗口。这种方式适合通过程序控制实现一些形状定制窗口。
  2. 通过位图画刷设置窗口背景,然后过滤掉指定的颜色,剩下的部分就是窗口。这种方式即简单,又适合位图化的任意窗口,用的最多,具有更炫的效果。实现方式就是将窗口属性设置分层,然后使用SetLayeredWindowAttributes这个API函数将特定颜色设置为透明色,该函数不仅可以设置为透明色,还可以设置整体窗口的透明度,将上一篇文章中设置半透明窗口效果,也是用的这个函数。

下面我们就来采用第二种方法来实现一个特殊的windows窗口。

首先我们要准备一张用于特殊窗口样子的位图,我们选择的图片如下:

为了实现这个位图的窗口形状,我们先对这个位图进行处理,将窗口以为的部分用一种特殊的颜色来填充,这个颜色需要与窗口保留部分不一样,因为只要是这种特定的颜色就会变成非窗口的部分,当然这种特殊颜色可以随便选择。从这种图来看,我们选择红色比较好,因为需要保留的部分没有红色出现。填充特殊颜色后的图片如下:

SetLayeredWindowAttributes函数原型如下:

BOOL SetLayeredWindowAttributes( HWND hwnd,

COLORREF crKey,

BYTE bAlpha,

DWORD dwFlags

);

hwnd:窗口句柄

crKey:特定的color key,就是要被透明的颜色

bAlpha:窗体的整体透明度

dwFlags:指定透明方式

下面就是实现的示意代码及注释:

#include <windows.h>

staticTCHAR szAppName[] = TEXT("异形窗口");

staticLRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAMlParm);

intWINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

{

HWNDhwnd;

MSGmsg;

WNDCLASSwndclass;

HBITMAPhBitmap;

BITMAPbm;

hBitmap= (HBITMAP)LoadImage(NULL, TEXT("cartoon_win.bmp"),IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); // 该图用于创建窗口背景画刷,我们的窗口形状就是它了

if (hBitmap == NULL)

{

MessageBox(NULL,TEXT("位图加载失败"), TEXT("Error"), MB_ICONERROR);

return 0;

}

wndclass.style = CS_VREDRAW | CS_HREDRAW;

wndclass.lpfnWndProc= MainWndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);

wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);

wndclass.hbrBackground= CreatePatternBrush(hBitmap);//加载准备好的位图作为画刷

wndclass.lpszMenuName = NULL;

wndclass.lpszClassName= szAppName;

if (!RegisterClass(&wndclass))

{

return FALSE;

}

GetObject(hBitmap,sizeof(bm), &bm);

hwnd= CreateWindowEx(WS_EX_TOPMOST,

szAppName,

szAppName,

WS_POPUP,

CW_USEDEFAULT,

CW_USEDEFAULT,

bm.bmWidth,

bm.bmHeight,

NULL,

NULL,

hInstance,

NULL);

if (hwnd == NULL)

{

return 0;

}

ShowWindow(hwnd,nShowCmd);

UpdateWindow(hwnd);

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

DeleteObject(hBitmap);

return msg.wParam;

}

staticLRESULT CALLBACK MainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAMlParm)

{

switch (message)

{

case WM_CREATE:

{

// 设置分层属性

SetWindowLong(hwnd,GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);

// 设置透明色以及分层窗口属性,关键就是这个函数!

COLORREFclTransparent = RGB(255, 0, 0);

SetLayeredWindowAttributes(hwnd,clTransparent, 0, LWA_COLORKEY);

}

return 0;

case WM_KEYDOWN:

switch (wParam)

{

case VK_ESCAPE: //按下Esc键时退出

SendMessage(hwnd,WM_DESTROY, 0, 0);

return 0;

}

break;

case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口

PostMessage(hwnd,WM_SYSCOMMAND, SC_MOVE | HTCAPTION, 0);

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0;

}

return DefWindowProc(hwnd, message, wParam, lParm);

}

程序运行后,结果如下,该窗口的形状就跟图片上我们设定的一样,是不是很新鲜呢?赶快在你的电脑上试一下吧,你还可以换成你自己的图片,只要设置正确的透明色即可。

Win32创建异形窗口的更多相关文章

  1. [Win32]创建模态窗口

    http://www.cnblogs.com/zplutor/archive/2011/02/20/1958973.html 在Win32编程中,如果要显示一个模态窗口,一般是先创建对话框模板,然后使 ...

  2. vs2010通过添加资源文件,修改win32创建的窗口

    1.右键项目的“资源”,新建资源,生成.rc文件 2.进入资源视图创建icon或menu等资源 3.退出资源视图,编译这个.rc文件 4.项目源代码中添加如下几个头文件 #include " ...

  3. win32手动创建windows窗口的,小记

    摘抄自文档,其中的函数需要以后花时间看 向 WinMain 添加功能 首先,在 WinMain 函数内部创建 WNDCLASSEX 类型的窗口类结构. 此结构包含有关窗口的信息,如应用程序图标.窗口的 ...

  4. win32 htmlayout点击按钮创建新窗口,以及按钮图片样式

    最近在做一个C++ win32的桌面图形程序,我不是C++程序员,做这个只是因为最近没什么java的活. windows api,之前接触的时候,还是大学,那时用这个开发打飞机游戏纯粹是娱乐.现在基本 ...

  5. [转]用多线程方法实现在MFC/WIN32中调用OpenGL函数并创建OpenGL窗口

    原文链接: 1.用多线程方法实现在MFC/WIN32中调用OpenGL函数并创建OpenGL窗口 2.Windows MFC 两个OpenGL窗口显示与线程RC问题

  6. win32 api Windows窗口的创建

    windows窗口的创建有以下几个步骤: 1.创建注册窗口类 2.创建窗口句柄 3.显示更新窗口 4.消息循环 1.创建注册窗口类 所谓创建窗口类就是定义一个WNDCLASS类对象,并将该对象进行初始 ...

  7. ATL封装IE内核启示:使用Win32/ATL建立窗口

    开发大型GUI界面程序MFC当仁不让,但如果是开发图形应用程序,并不需要大规模界面控件,没有必要链接庞大的MFC库,直接使用platform sdk会很麻烦,这时ATL中的关于Windows的封装就是 ...

  8. Duiib 创建不规则窗口(转载)

    方法一: 转载:http://blog.csdn.net/chenlycly/article/details/46447297 转载:http://blog.csdn.net/harvic880925 ...

  9. 1、win32创建窗口函数(windows程序内部运行机制)

    利用win32创建窗口函数,主要操作步骤为: 1.设计一个窗口类 2.注册窗口类 3.创建窗口 4.显示及窗口更新 5.消息循环 6.窗口过程函数   (1)设计一个窗口类 设计窗口类,这样的类型已经 ...

随机推荐

  1. SQL数据透视

    透视是一种通过聚合和旋转把数据行转换成数据列的技术.当透视数据时,需要确定三个要素:要在行(分组元素)中看到的元素,要在列(扩展元素)上看到的元素,要在数据部分看到的元素(聚合元素). SQL Ser ...

  2. yii2项目实战-访问控制过滤器ACF讲解

    作者:白狼 出处:http://www.manks.top/document/yii2-filter-control.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明 ...

  3. 大型Unity手游《英雄之刃-最后之战》源码分析

    英雄之刃之最后一战是国内首款原创精品MOBA手游,是一款由前暴雪文案亲自操刀世界观,日韩专业团队打造美术场景,新加坡团队精心制作战斗音乐的旷世之作! 超快速的匹配对战.默契的团队协作给你带来意犹未尽的 ...

  4. ioctlsocket()函数是干什么用的?它返回值是什么?共有几个参数?它的各个参数是干什么用的?

    1. ioctlsocket()  简述:   控制套接口的模式. #include <winsock.h> int PASCAL FAR ioctlsocket( SOCKET s, l ...

  5. mysql建外键失败

    1. 修改引擎:(设计表-->选项-->引擎:InnoDB) 2. 检查外键类型是否一致:

  6. ssh关于含有外键的传值中无法识别正确的action的原因和解决办法

    在含有外键的表中,要保存一个值到这个外键时:逻辑思路:需要先将jsp页面的值传到相应的action中,在这个action中需要引入这个外键的实体层和DAO层(DAO层只需set方法),在执行函数中对于 ...

  7. 洛谷P2387 [NOI2014]魔法森林(lct维护最小生成树)

    题目描述 为了得到书法大家的真传,小 E 同学下定决心去拜访住在魔法森林中的隐 士.魔法森林可以被看成一个包含 n 个节点 m 条边的无向图,节点标号为 1,2,3,…,n,边标号为 1,2,3,…, ...

  8. centos7 安装dnf包管理器和常用命令

    Installing DNF Currently the DNF package comes from the EPEL repository, so if your Linux system is ...

  9. sampling method

    sampling method 背景 在贝叶斯框架下,利用后验分布对参数进行估计,也即 其中 (1)是参数的先验分布. (2)是似然分布,数据集的生成联合概率 (3)是参数的后验分布. 通常分布很复杂 ...

  10. httpWebRequest请求错误,基础连接已经关闭: 连接被意外关闭

    win10下,C# 用httpWebRequest 执行post请求出现"请求错误,基础连接已经关闭: 连接被意外关闭",经测试设置 //Post请求方式 System.Net.H ...