大家都见过在windows下各种气泡窗口、输入法窗口已经其他一些窗口,这些窗口看起来不像传统的windows窗那样,上面是标题栏,下面是窗口的客户区。这些窗口形状各异,可以是一个多边形,一幅图,甚至是一个人物画像等。这些异形窗口是怎么实现的呢?下面我们就来实现这个奇异形状的窗口。
其实在windows下实现特殊的窗口并不困难,有两种办法可以实现:
下面我们就来采用第二种方法来实现一个特殊的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);
}
程序运行后,结果如下,该窗口的形状就跟图片上我们设定的一样,是不是很新鲜呢?赶快在你的电脑上试一下吧,你还可以换成你自己的图片,只要设置争取的透明色即可。