D
wenn du es flackerfrei haben willst, solltest du dir das mal anschauen:
#pragma comment(lib, "msimg32.lib")
#include <windows.h>
BOOL CALLBACK ChildEnumProc(HWND hWnd, LPARAM lParam)
{
InvalidateRect(hWnd, NULL, TRUE);
return TRUE;
}
HDC BeginScene(HWND hWnd, HBITMAP* pBitmap)
{
RECT r = { 0 };
GetClientRect(hWnd, &r);
r.right -= r.left;
r.bottom -= r.top;
HDC hWindowDC = GetDC(hWnd);
HDC hDoubleBufferDC = CreateCompatibleDC(hWindowDC);
*pBitmap = CreateCompatibleBitmap(hWindowDC, r.right, r.bottom);
SelectObject(hDoubleBufferDC, (*pBitmap));
ReleaseDC(hWnd, hWindowDC);
wchar_t szClassName[1024];
GetClassName(hWnd, szClassName, 1024);
WNDCLASSEX wce = { 0 };
GetClassInfoEx(GetModuleHandle(NULL), szClassName, &wce);
FillRect(hDoubleBufferDC, &r, wce.hbrBackground);
return hDoubleBufferDC;
}
void EndScene(HWND hWnd, HDC hDoubleBufferDC, HBITMAP hBitmap)
{
RECT r = { 0 };
GetUpdateRect(hWnd, &r, FALSE);
if ((r.bottom == 0) && (r.left == 0) && (r.right == 0) && (r.top == 0))
GetClientRect(hWnd, &r);
PAINTSTRUCT ps = { 0 };
HDC hWindowDC = BeginPaint(hWnd, &ps);
StretchBlt(hWindowDC, r.left, r.top, r.right, r.bottom, hDoubleBufferDC, r.left, r.top, r.right, r.bottom, SRCCOPY);
EndPaint(hWnd, &ps);
DeleteObject(hBitmap);
DeleteDC(hDoubleBufferDC);
ValidateRect(hWnd, &r);
EnumChildWindows(hWnd, ChildEnumProc, 0);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_CLOSE:
{
DestroyWindow(hWnd);
return 0;
} break;
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
case WM_ERASEBKGND:
{
return 1;
} break;
case WM_PAINT:
{
RECT client;
GetClientRect(hWnd, &client);
client.bottom -= client.top;
client.right -= client.left;
TRIVERTEX vert [4] ;
GRADIENT_TRIANGLE gTri[2];
vert [0] .x = 0;
vert [0] .y = 0;
vert [0] .Red = 0x0000;
vert [0] .Green = 0x0000;
vert [0] .Blue = 0xFF00;
vert [0] .Alpha = 0x0000;
vert [1] .x = client.right;
vert [1] .y = 0;
vert [1] .Red = 0x7F80;
vert [1] .Green = 0x7F80;
vert [1] .Blue = 0xFF00;
vert [1] .Alpha = 0x0000;
vert [2] .x = client.right;
vert [2] .y = client.bottom;
vert [2] .Red = 0xFF00;
vert [2] .Green = 0xFF00;
vert [2] .Blue = 0xFF00;
vert [2] .Alpha = 0x0000;
vert [3] .x = 0;
vert [3] .y = client.bottom;
vert [3] .Red = 0x7F80;
vert [3] .Green = 0x7F80;
vert [3] .Blue = 0xFF00;
vert [3] .Alpha = 0x0000;
gTri[0].Vertex1 = 0;
gTri[0].Vertex2 = 1;
gTri[0].Vertex3 = 2;
gTri[1].Vertex1 = 0;
gTri[1].Vertex2 = 2;
gTri[1].Vertex3 = 3;
HBITMAP hBmp;
HDC hDC = BeginScene(hWnd, &hBmp);
GradientFill(hDC, vert, 4, gTri, 2, GRADIENT_FILL_TRIANGLE);
EndScene(hWnd, hDC, hBmp);
return 0;
} break;
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLine, int iCmdShow)
{
WNDCLASS wc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = reinterpret_cast<HBRUSH>(GetStockObject(WHITE_BRUSH));
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = L"Gradient Window";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW|CS_VREDRAW;
RegisterClass(&wc);
HWND hWnd = CreateWindowEx(0, L"Gradient Window", L"Gradient", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWnd)
return -1;
ShowWindow(hWnd, SW_SHOW);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return static_cast<int>(msg.wParam);
}