/*关于无闪烁控件自绘的一个小例子,看到网上许多人都讲着需要双缓冲消除闪烁,其实不然,闪烁的处理方式有许多种,但是在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);
}