首页 > OOP语言 > VC.net > 正文

Windows界面编程(3) 异形窗体 普通版
2014-01-09 00:00:00   来源:www.bianceng.cn   评论:0 点击:

暂时无描述信息

上一篇《Windows界面编程第二篇 半透明窗体》介绍了先使用SetWindowLong为窗体加上WS_EX_LAYERED属 性,再使用SetLayeredWindowAttributes调整窗体的透明度。本篇将使用这二个函数来完成另一个实用的功 能——异形窗口(异形窗体)。

异形窗口的原理很简单,首先加载一张位图画刷作窗口背景,然后设 置透明色就可以使得窗口由矩形变成任意形状。这样使得窗口的显示更加美观。

下面 先简单介绍下Win32 SDK方式创建窗口的流程(按《Windows程序设计》中的大体流程):

1.设置 WNDCLASS类型的变量,这个变量将描述窗口的风格、窗口消息处理函数、程序图标、光标、窗口背景画刷等 待。

2.使用RegisterClass将WNDCLASS类型的变量注册下。

3.使用CreateWindow或 CreateWindowEx创建窗口,这里可以设置窗口的初始位置、初始大小、扩展属性等等。

4.通过 ShowWindow和UpdateWindow将窗口显示出来。

5.窗口显示完成后,在WinMain()函数中添加消息处理 :

MSG msg;

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

{

       TranslateMessage(&msg);

       DispatchMessage (&msg);

}

通过这五步就完成了一个窗口的创建了。

对于窗口消息函数,一般只要 在WM_DESTROY消息中调用下PostQuitMessage(0);其它的消息都可以使用默认消息处理函数DefWindowProc。

对于异形窗口,可以在WM_CREATE即窗口初始化时设置好透明色就完成了窗口形状的改变,不过为了 支持鼠标对窗口的拖曳,还要在WM_LBUTTONDOWN消息中加入:

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

这样,异形窗口就可以在屏幕上像普通窗口一样的移动了。

完整 的源代码如下所示(下载地址:http://download.csdn.net/download/morewindows/4966815):

//   异形窗口1  窗口背景使用位图画刷再指定透明色  
//By MoreWindows-(http://blog.csdn.net/MoreWindows)  
#include <windows.h>  
      
const char szAppName[] = "异形窗口1 MoreWindows-(http://blog.csdn.net/MoreWindows)";  
      
/* 
 * 函数名称: GetWindowSize 
 * 函数功能: 得到窗口的宽高 
 * hwnd      窗口句柄 
 * pnWidth   窗口宽 
 * pnHeight  窗口高 
*/
void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight);  
      
      
/* 
 * 函数名称: InitBitmapWindow 
 * 函数功能: 位图窗口初始化 
 * hinstance 进程实例 
 * hBitmap   位图句柄 
 * nCmdshow  显示方式-与ShowWindow函数的第二个参数相同 
*/
BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, int nCmdshow);  
      
// 位图窗口消息处理函数  
LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm);  
      
      
int APIENTRY WinMain(HINSTANCE hInstance,  
                     HINSTANCE hPrevInstance,  
                     LPSTR     lpCmdLine,  
                     int       nCmdShow)  
{  
    //设置窗口背景画刷为图片画刷,再指定透明颜色即可以创建透明区域。  
    HBITMAP  hBitmap;  
    hBitmap = (HBITMAP)LoadImage(NULL, "Kitty.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);  
    if (hBitmap == NULL)  
    {  
        MessageBox(NULL, "位图加载失败", "Error", MB_ICONERROR);  
        return 0;  
    }  
    if (!InitBitmapWindow(hInstance, hBitmap, nCmdShow))  
        return 0;  
      
    MSG msg;  
    while (GetMessage(&msg, NULL, 0, 0))  
    {  
        TranslateMessage(&msg);  
        DispatchMessage(&msg);  
    }  
    DeleteObject(hBitmap);  
      
    return msg.wParam;  
}  
      
      
BOOL InitBitmapWindow(HINSTANCE hinstance, HBITMAP hBitmap, 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 = CreatePatternBrush(hBitmap);//位图画刷  
    wndclass.lpszMenuName  = NULL;  
    wndclass.lpszClassName = szAppName;  
          
    if (!RegisterClass(&wndclass))  
    {  
        MessageBox(NULL, "Program Need Windows NT!", "Error", MB_ICONERROR);  
        return FALSE;  
    }  
      
    BITMAP bm;  
    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 FALSE;  
          
    ShowWindow(hwnd, nCmdshow);  
    UpdateWindow(hwnd);  
          
    return TRUE;  
}  
      
LRESULT CALLBACK BitmapWindowWndPrco(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParm)  
{  
    static HDC s_hdcMem;  
    static HBRUSH s_hBackBrush;  
          
    switch (message)  
    {  
    case WM_CREATE:  
        {  
            // 设置分层属性  
            SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); 

 
            // 设置透明色  
            COLORREF clTransparent = RGB(0, 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);  
}  
      
void GetWindowSize(HWND hwnd, int *pnWidth, int *pnHeight)  
{  
    RECT rc;  
    GetWindowRect(hwnd, &rc);  
    *pnWidth = rc.right - rc.left;  
    *pnHeight = rc.bottom - rc.top;  
}

相关热词搜索:

上一篇:Windows界面编程(4) 异形窗体 高富帅版
下一篇:Windows界面编程(2) 半透明窗体

分享到: 收藏