WindowsAPI自绘按钮

来源:互联网 发布:手机word阅读软件 编辑:程序博客网 时间:2024/05/23 13:17

自绘按钮有多种方法,比如创建一个BS_OWNERDRAW风格的按钮,然后就可以自绘了,但是这个好像不能用SetWindowRgn画各种形状。我介绍的这个方法很简单,但是代码量会稍多一点。就是把一个按钮当做一个单独的窗口来处理,但是这就必须要每个按钮都要注册一个类,所以代码会多一点。

总体的思路是:注册主窗口类并创建主窗口–>注册子窗口类并创建子窗口(就是按钮)–>实现各自的窗口过程–>处理对应的消息.

效果如图:


代码详解及注释:

#include <windows.h>#include <tchar.h>#include "resource.h"HINSTANCE hInst = NULL; //全局实例句柄LRESULT CALLBACK WindProc(HWND, UINT, WPARAM, LPARAM);//主窗口过程LRESULT CALLBACK BtnProc1(HWND, UINT, WPARAM, LPARAM); //按钮1窗口过程LRESULT CALLBACK BtnProc2(HWND, UINT, WPARAM, LPARAM);//按钮2窗口过程int WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nShowCmd){    hInst = hInstance;    TCHAR szAppName[] = TEXT("MyApp");   //主窗口类名    TCHAR szBtnName1[] = TEXT("MyBtn1"); //按钮窗口类名    TCHAR szBtnName2[] = TEXT("MyBtn2");    //主窗口类    WNDCLASS wndclass = { 0 };    wndclass.cbClsExtra = 0;    wndclass.cbWndExtra = 0;    wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_BACKGROUND);    wndclass.hCursor = NULL;    wndclass.hIcon = NULL;    wndclass.hInstance = hInstance;    wndclass.lpfnWndProc = WindProc;    wndclass.lpszClassName = szAppName;    wndclass.lpszMenuName = NULL;    wndclass.style = CS_HREDRAW | CS_VREDRAW;    if (!RegisterClass(&wndclass))    {        MessageBox(NULL, TEXT("RegisterClass wndclass failed"), TEXT("ERROR"), 0);        return 0;    }    //主窗口    HWND hwnd = CreateWindow(szAppName, TEXT("MyWindow"), WS_OVERLAPPEDWINDOW,        100, 100, 300, 200, NULL, NULL, hInstance, 0);    ShowWindow(hwnd, SW_SHOW);    UpdateWindow(hwnd);    //自定义按钮类    WNDCLASS wndbtn1 = { 0 };    wndbtn1.cbClsExtra = 0;    wndbtn1.cbWndExtra = 0;  //这个是位图背景,需要自己添加位图资源    wndbtn1.hbrBackground = CreatePatternBrush(LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP)));    wndbtn1.hCursor = NULL;    wndbtn1.hIcon = NULL;    wndbtn1.hInstance = hInstance;    wndbtn1.lpfnWndProc = BtnProc1;    wndbtn1.lpszClassName = szBtnName1;    wndbtn1.lpszMenuName = NULL;    wndbtn1.style = CS_HREDRAW | CS_VREDRAW;    if (!RegisterClass(&wndbtn1))    {        MessageBox(NULL, TEXT("RegisterClass wndbtn failed"), TEXT("ERROR"), 0);        return 0;    }    //自绘按钮    HWND hButton1 = CreateWindow(szBtnName1, TEXT("MyButton1"),        WS_CHILD | WS_VISIBLE,0, 0, 0, 0, hwnd, NULL, hInstance, 0);    ShowWindow(hButton1, SW_SHOW);    UpdateWindow(hButton1);    WNDCLASS wndbtn2 = { 0 };    wndbtn2.cbClsExtra = 0;    wndbtn2.cbWndExtra = 0;    wndbtn2.hbrBackground = CreateSolidBrush(RGB(255,0,0));    wndbtn2.hCursor = NULL;    wndbtn2.hIcon = NULL;    wndbtn2.hInstance = hInstance;    wndbtn2.lpfnWndProc = BtnProc2;    wndbtn2.lpszClassName = szBtnName2;    wndbtn2.lpszMenuName = NULL;    wndbtn2.style = CS_HREDRAW | CS_VREDRAW;    if (!RegisterClass(&wndbtn2))    {        MessageBox(NULL, TEXT("RegisterClass wndbtn failed"), TEXT("ERROR"), 0);        return 0;    }    HWND hButton2 = CreateWindow(szBtnName2, TEXT("MyButton2"),        WS_CHILD | WS_VISIBLE,0, 0, 0, 0, hwnd, NULL, hInstance, 0);    ShowWindow(hButton2, SW_SHOW);    UpdateWindow(hButton2);    MSG msg = { 0 };    while (GetMessage(&msg, NULL, 0, 0))    {        TranslateMessage(&msg);        DispatchMessage(&msg);    }    return msg.wParam;}LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){    PAINTSTRUCT ps = { 0 };    HDC DC = NULL;    switch (message)    {    case WM_CREATE:        break;    case WM_PAINT:        DC = BeginPaint(hwnd, &ps);        break;    case WM_DESTROY:        PostQuitMessage(0);        break;    default:        break;    }    return DefWindowProc(hwnd, message, wParam, lParam);}LRESULT CALLBACK BtnProc1(HWND hBtn1, UINT message, WPARAM wParam, LPARAM lParam){    PAINTSTRUCT ps = { 0 };    HDC DC = NULL;    switch (message)    {    case WM_CREATE:        {            MoveWindow(hBtn1, 10, 10, 100, 100, TRUE);            //画椭圆区域,还可以画圆角,多边形等等,可以自行百度            HRGN hRgn = CreateEllipticRgn(10, 10, 100, 100);            SetWindowRgn(hBtn1, hRgn, TRUE);        }    break;    case WM_LBUTTONDOWN:   //测试是否成功响应消息            MessageBox(NULL, TEXT("MyButton1"), TEXT("提示"), 0);        break;    case WM_PAINT:    {        DC = BeginPaint(hBtn1, &ps);        SetBkColor(DC, RGB(0, 255, 255)); //按钮背景颜色        SetTextColor(DC, RGB(255, 0, 0)); //按钮上的文字颜色        TextOut(DC, 20, 45, TEXT("MyButton1"), 9);//按钮上的文字        EndPaint(hBtn1, &ps);    }    break;    default:        break;    }    return DefWindowProc(hBtn1, message, wParam, lParam);}LRESULT CALLBACK BtnProc2(HWND hBtn2, UINT message, WPARAM wParam, LPARAM lParam){    PAINTSTRUCT ps = { 0 };    HDC DC = NULL;    switch (message)    {    case WM_CREATE:    {        MoveWindow(hBtn2, 160, 10, 250, 100, TRUE);        //画椭圆区域,还可以画圆角,多边形等等,可以自行百度        HRGN hRgn = CreateRoundRectRgn(10, 10, 100, 100,20,20);        SetWindowRgn(hBtn2, hRgn, TRUE);    }    break;    case WM_LBUTTONDOWN:        MessageBox(NULL, TEXT("MyButton2"), TEXT("提示"), 0);        break;    case WM_PAINT:    {        DC = BeginPaint(hBtn2, &ps);        SetBkColor(DC, RGB(0, 255, 255)); //按钮背景颜色        SetTextColor(DC, RGB(255, 0, 0)); //按钮上的文字颜色        TextOut(DC, 20, 45, TEXT("MyButton2"), 9); //按钮上的文字        EndPaint(hBtn2, &ps);    }    break;    default:        break;    }    return DefWindowProc(hBtn2, message, wParam, lParam);}
0 0