Windows介面編程第四篇 異形表單

來源:互聯網
上載者:User

標籤:bre   setw   creat   需要   sdn   通過   ret   new   http   

原文轉自 http://blog.csdn.net/morewindows/article/details/8451638

 

上一篇《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, 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, 0))    {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    DeleteObject(g_hBitmap);    return msg.wParam;}BOOL InitBitmapWindow(HINSTANCE hinstance, int nWidth, int nHeight, 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!", "Error", MB_ICONERROR);        return FALSE;    }        hwnd = CreateWindowEx(WS_EX_TOPMOST,                        szAppName,                        szAppName,                         WS_POPUP,                        CW_USEDEFAULT,                         CW_USEDEFAULT,                         nWidth,                         nHeight,                        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; //放置縮放後的位元影像        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);                        //   縮放位元影像            // 載入位元影像到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, nWidth, nHeight);            SelectObject(s_hdcMem, hbmp);            // 將原位元影像縮放到視窗大小            BITMAP bm;            GetObject(g_hBitmap, sizeof(bm), &bm);            StretchBlt(s_hdcMem, 0, 0, nWidth, nHeight, hdcTemp, 0, 0, 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, 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;            GetWindowSize(hwnd, &nWidth, &nHeight);            BitBlt(hdc, 0, 0, nWidth, nHeight, s_hdcMem, 0, 0, SRCCOPY);            return TRUE;        }    case WM_DESTROY:        DeleteDC(s_hdcMem);        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;}

 

運行程式將得到如文章中每一張圖右邊所示的異形視窗。最後總結一下異形視窗的“三要素”:

1.WS_EX_LAYERED屬性

2.以位元影像為視窗背景(自貼圖或位元影像畫刷)

3.指定透明色

 

本文配套程式為:http://download.csdn.net/download/morewindows/4966819

當視窗的背景用彩色圖片來裝飾時,其它控制項如果還是用灰色的背景會顯的比較不諧調,《Windows介面編程第五篇 靜態控制項背景透明化》將介紹如何為靜態框設定透明背景。

 

Windows介面編程第四篇 異形表單(轉)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.