Win32/WindowsAPI无闪烁控件绘制的一个示例

/*关于无闪烁控件自绘的一个小例子,看到网上许多人都讲着需要双缓冲消除闪烁,其实不然,闪烁的处理方式有许多种,但是在WM_MOUSEMOVE这个消息中处理闪烁是不能用双缓冲的,因为只要鼠标移动就会产生这个消息,从而触发消息的控制代码,所以不管用什么方法都不可能消除闪烁,只有我们绘制一次,这样不管产生多少次这个消息,都不会进行绘制,所以废话省略......*/

 

#include <d3d12.h>
#include <dxgi1_6.h>
#include <wrl.h>

#pragma comment(lib,"D3D12.lib")

/****************************无闪烁绘制按钮,当然也可以使用GDI+,Direct2D,本文只是用GDI测试而已,不需要用到双缓冲***************************/


long __stdcall WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);

int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* lpCmdLine, int nCmdShow)
{

    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX);
    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = reinterpret_cast<WNDPROC>(WindowProc);
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
    wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
    wcex.lpszMenuName = nullptr;
    wcex.lpszClassName = TEXT("Direct3D 12");
    wcex.hIconSm = LoadIcon(nullptr, IDI_WINLOGO);
    RegisterClassEx(&wcex);

    HWND hWnd = CreateWindowEx(WS_EX_LEFT, TEXT("Direct3D 12"), TEXT("Direct3D 12"), WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, nullptr);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    MSG message;
    while (GetMessage(&message, nullptr, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }

    return static_cast<int>(message.wParam);
}

long __stdcall WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    RECT rect{ 80,80,200,200 };
    static bool falog = false;
    switch (uMsg)
    {
    case WM_MOUSEMOVE:
        if (LOWORD(lParam) > rect.left && LOWORD(lParam) < rect.right 
            && HIWORD(lParam) > rect.top && HIWORD(lParam) < rect.bottom)
        {
            if (falog)
                return 0;
            else
            {
                HDC hdc = GetDC(hWnd);
                HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
                FillRect(hdc, &rect, brush);
                SetBkMode(hdc, TRANSPARENT);
                DrawText(hdc, L"按钮", -1, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
                DeleteObject(brush);
                ReleaseDC(hWnd, hdc);
                falog = true;
                return 0;
            }
        }
        else
        {
            if (falog == false)
                return 0;
            HDC hdc = GetDC(hWnd);
            HBRUSH brush = CreateSolidBrush(RGB(255, 70, 0));
            FillRect(hdc, &rect, brush);
            SetBkMode(hdc, TRANSPARENT);
            DrawText(hdc, L"按钮", -1, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
            DeleteObject(brush);
            ReleaseDC(hWnd, hdc);
            falog = false;
        }
        return 0;
    case WM_LBUTTONDOWN:
        if (LOWORD(lParam) > rect.left && LOWORD(lParam) < rect.right
            && HIWORD(lParam) > rect.top && HIWORD(lParam) < rect.bottom)
        {
            HDC hdc = GetDC(hWnd);
            HBRUSH brush = CreateSolidBrush(RGB(0, 0, 255));
            FillRect(hdc, &rect, brush);
            SetBkMode(hdc, TRANSPARENT);
            DrawText(hdc, L"按钮", -1, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
            DeleteObject(brush);
            ReleaseDC(hWnd, hdc);
        }
        return 0;
    case WM_LBUTTONUP:
        if (LOWORD(lParam) > rect.left && LOWORD(lParam) < rect.right
            && HIWORD(lParam) > rect.top && HIWORD(lParam) < rect.bottom)
        {
            HDC hdc = GetDC(hWnd);
            HBRUSH brush = CreateSolidBrush(RGB(0, 255, 0));
            FillRect(hdc, &rect, brush);
            SetBkMode(hdc, TRANSPARENT);
            DrawText(hdc, L"按钮", -1, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
            DeleteObject(brush);
            ReleaseDC(hWnd, hdc);
            return 0;
        }
        return 0;
    case WM_PAINT:
        BeginPaint(hWnd, &ps);
        HBRUSH brush = CreateSolidBrush(RGB(255, 70, 0));
        FillRect(ps.hdc, &rect, brush);
        SetBkMode(ps.hdc, TRANSPARENT);
        DrawText(ps.hdc, L"按钮", -1, &rect, DT_VCENTER | DT_CENTER | DT_SINGLELINE);
        DeleteObject(brush);
        EndPaint(hWnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值