设为首页 加入收藏

TOP

Windows界面编程:异形窗体
2013-09-24 09:26:08 来源: 作者: 【 】 浏览:237
Tags:Windows 界面 编程 异形 窗体

  本篇将使用这二个函数来完成另一个实用的功能——异形窗口(异形窗体)。

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

  下面先简单介绍下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
    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;
    }

  运行结果如下:

  现在总结下异形窗口的创建,先通过创建位图画刷来做窗口的背景画刷,再通过SetWindowLong为窗体加上WS_EX_LAYERED属性,然后使用SetLayeredWindowAttributes指定窗口的透明色来完成窗口形状的调整。为了支持鼠标的拖曳,在WM_LBUTTONDOWN消息中作了特殊处理,使得异形窗口可以像普通窗口一样在屏幕上移动。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C中的几组指针 下一篇Windows界面编程:半透明窗体

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: