Windows界面编程第四篇 异形窗体 高富帅版
??? 上一篇《Windows界面编程第三篇 异形窗体 普通版》介绍了异形窗口(异形窗体)的创建,其主要步骤为——先通过创建位图画刷来做窗口的背景画刷,再通过SetWindowLong为窗体加上WS_EX_LAYERED属性,然后使用SetLayeredWindowAttributes指定窗口的透明色来完成窗口形状的调整。并且为了使异形窗口支持鼠标的拖曳,在WM_LBUTTONDOWN消息中作了特殊处理。 然后在下图中有非常相似的两个异形窗体,只不过,左边的异形窗体小,右边的异形窗体大。这个可以怎么实现了? ? 先通过其它软件来缩放位图,然后再让程序加载这种方式来指定异形窗口的大小。这种方法虽然可以完成任务,但毕竟太OUT了。 由《Windows界面编程第一篇位图背景与位图画刷》可以想到不用位图画刷,而直接在窗口背景绘制时使用StretchBlt来缩放位图至窗口大小,这样就可以达到指定窗口大小的功能。 由于异形窗口运行后无法通过鼠标来动态调整窗口大小,因此可以窗口初始化时就可以先缩放位图并加载到一个缓冲HDC中,然后再在窗口背景绘制时使用BitBlt来贴图。这种做法只需要缩放位图一次,在每次背景绘制时只须拷贝位图,对程序的效率会有提高。下面给出完整源代码(下载地址:http://download.csdn.net/download/morewindows/4966819) // 异形窗口2 在WM_ERASEBKGND消息中自贴图
//By MoreWindows-(http://blog.csdn.net/MoreWindows)
#include <windows.h>
const char szAppName[] = "异形窗口2 MoreWindows-(http://blog.csdn.net/MoreWindows)";
/* * 函数名称: GetWindowSize * 函数功能: 得到窗口的宽高 * hwnd 窗口句柄 * pnWidth 窗口宽 * pnHeight 窗口高 */
void GetWindowSize(HWND hwnd,int *pnWidth,int *pnHeight);
/* * 函数名称: InitBitmapWindow * 函数功能: 位图窗口初始化 * hinstance 进程实例 * nWidth 窗口宽 * nHeight 窗口高 * nCmdshow 显示方式-与ShowWindow函数的第二个参数相同 */
BOOL InitBitmapWindow(HINSTANCE hinstance,int nWidth,int nHeight,int nCmdshow);
// 位图窗口消息处理函数
LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParm);
HBITMAP g_hBitmap;
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow) {
//先创建一个无背影画刷窗口,
//然后在WM_CREATE中并指定透明颜色,缩放位图后加载至s_hdcMem中.
//最后在WM_ERASEBKGND中用s_hdcMem贴图即可
g_hBitmap = (HBITMAP)LoadImage(NULL,"Kitty.bmp",IMAGE_BITMAP,0,LR_LOADFROMFILE);
if (g_hBitmap == NULL)
{
MessageBox(NULL,"位图加载失败","Error",MB_ICONERROR);
return 0;
}
// 设置异形窗口大小
BITMAP bm;
GetObject(g_hBitmap,sizeof(bm),&bm);
int nWindowWidth = bm.bmWidth;
int nWindowHeight = bm.bmHeight + 100; //拉高100高度
if (!InitBitmapWindow(hInstance,nWindowWidth,nWindowHeight,nCmdShow))
return 0;
MSG msg;
while (GetMessage(&msg,NULL,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DeleteObject(g_hBitmap);
return msg.wParam;
}
BOOL InitBitmapWindow(HINSTANCE hinstance,int nCmdshow) {
HWND hwnd;
WNDCLASS wndclass;
wndclass.style = CS_VREDRAW | CS_HREDRAW;
wndclass.lpfnWndProc = BitmapWindowWndPrco;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hinstance;
wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);//窗口背影画刷为空
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
if (!RegisterClass(&wndclass))
{
MessageBox(NULL,"Program Need Windows NT!",MB_ICONERROR);
return FALSE;
}
hwnd = CreateWindowEx(WS_EX_TOPMOST,szAppName,WS_POPUP,CW_USEDEFAULT,nWidth,nHeight,hinstance,NULL);
if (hwnd == NULL)
return FALSE;
ShowWindow(hwnd,nCmdshow);
UpdateWindow(hwnd);
return TRUE;
}
LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd,LPARAM lParm) {
static HDC s_hdcMem; //放置缩放后的位图
switch (message)
{
case WM_CREATE:
{
// 设置分层属性
SetWindowLong(hwnd,GWL_EXSTYLE,GetWindowLong(hwnd,GWL_EXSTYLE) | WS_EX_LAYERED);
// 设置透明色
COLORREF clTransparent = RGB(0,0);
SetLayeredWindowAttributes(hwnd,clTransparent,LWA_COLORKEY);
// 缩放位图
// 加载位图到hdcTemp中
HDC hdc = GetDC(hwnd);
HDC hdcTemp = CreateCompatibleDC(hdc);
SelectObject(hdcTemp,g_hBitmap);
// 得到窗口大小
int nWidth,nHeight;
GetWindowSize(hwnd,&nWidth,&nHeight);
// 创建与窗口大小相等且能容纳位图的HDC - s_hdcMem
s_hdcMem = CreateCompatibleDC(hdc);
HBITMAP hbmp = CreateCompatibleBitmap(hdc,nHeight);
SelectObject(s_hdcMem,hbmp);
// 将原位图缩放到窗口大小
BITMAP bm;
GetObject(g_hBitmap,&bm);
StretchBlt(s_hdcMem,hdcTemp,bm.bmWidth,bm.bmHeight,SRCCOPY);
// 释放资源
DeleteDC(hdcTemp);
ReleaseDC(hwnd,hdc);
}
return 0;
case WM_KEYDOWN:
switch (wParam)
{
case VK_ESCAPE: //按下Esc键时退出
SendMessage(hwnd,WM_DESTROY,0);
return TRUE;
}
break;
case WM_LBUTTONDOWN: //当鼠标左键点击时可以拖曳窗口
PostMessage(hwnd,WM_SYSCOMMAND,SC_MOVE | HTCAPTION,0);
return TRUE;
case WM_ERASEBKGND: //在窗口背景中直接贴图
{
HDC hdc = (HDC)wParam;
int nWidth,&nHeight);
BitBlt(hdc,s_hdcMem,SRCCOPY);
return TRUE;
}
case WM_DESTROY:
DeleteDC(s_hdcMem);
PostQuitMessage(0);
return 0;
}
return DefWindowProc(hwnd,message,wParam,lParm);
}
void GetWindowSize(HWND hwnd,int *pnHeight) {
RECT rc;
GetWindowRect(hwnd,&rc);
*pnWidth = rc.right - rc.left;
*pnHeight = rc.bottom - rc.top;
}
运行程序将得到如文章中每一张图右边所示的异形窗口。 ? 最后总结一下异形窗口的“三要素”: 1.WS_EX_LAYERED属性 2.以位图为窗口背景(自贴图或位图画刷) 3.指定透明色 ? 本文配套程序下载地址为:http://download.csdn.net/download/morewindows/4966819 ? 当窗口的背景用彩色图片来装饰时,其它控件如果还是用灰色的背景会显的比较不谐调,《Windows界面编程第五篇 静态控件背景透明化》将介绍如何为静态框设置透明背景。 ? 转载请标明出处,原文地址:http://www.voidcn.com/article/p-rvmjumxh-yt.html 欢迎关注微博:http://weibo.com/MoreWindows ?
? 再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://www.cnblogs.com/captainbed (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- Windows上的Jupyter与Anaconda不会运行单元格
- Operator =不是DLL中导出的C __interface的成员
- 如何从windows 10 pro安装文件获取install.wim
- 如何在Windows中启动子流程?
- windows-xp – 在Windows XP上安装Windows 7启动加载程序
- windows-server-2008-r2 – Windows Server 2008 R2中的远程
- 如何在Windows中列出用户的所有权限?
- Windows rsync支持长文件名,还是一个不错的选择?
- windows7 64位机上配置MinGW+Codeblocks+ wxWidgets
- 事后崩溃转储调试没有在Symbol Server中具有Windows DLL的确
- Windows – 客户端从WSUS服务器下载更新时遇到80
- windows-server-2008 – 更新Windows Production
- .net – 运行sn.exe需要哪些Windows SDK部件
- iscsi – 使用MPIO将Freenas连接到Windows Serve
- windows-server-2003 – 将Active Directory从20
- microsoft-band – Microsoft Health API:获取帐
- 如何在Windows Server上获取本地连接的IP地址?
- Windows – Subversion客户端应用程序[已关闭]
- 在Windows上强制删除文件
- 配置文档的NTFS权限