При перекрытии окна другими окнами исчезает нарисованное... Как быть?
Я рисую сначала в MemDC, потом то, что получилось отправляю в HDC.
При перемещении окна нарисованное не пропадает, а при перекрытии/выходе окна за пределы монитора/свертывании/развертывании/изменении размеров окна - при всё при этом исчезает нарисованное.
Почему при этих действиях не вызывается WM_PAINT? Как перерисовать?
//#include <windows.h>
#include "KWnd.h"
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
MSG msg;
KWnd mainWnd(TEXT("An application"), hInstance, nShowCmd, WndProc);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
HDC hDC;
PAINTSTRUCT ps;
RECT rect;
static HDC hMemDC;
int xrand;
int yrand;
int Rrand;
int Grand;
int Brand;
int iWidthRand;
int iStyleRand;
HPEN myPen;
switch(uMsg)
{
case WM_CREATE:
hDC = GetDC(hWnd);
hMemDC = CreateCompatibleDC(hDC);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &ps);
GetClientRect(hWnd, &rect);
// Теперь копируем растр из памяти на экран
BitBlt(hDC, 0, 0, rect.right, rect.bottom, hMemDC, 0, 0, SRCCOPY);
EndPaint(hWnd, &ps);
break;
case WM_LBUTTONDOWN:
hDC = GetDC(hWnd);
if (hDC)
{
// рисуем что требуется
MoveToEx(hDC, 50, 60, NULL);
GetClientRect(hWnd, &rect);
for (int i=0; i<10; i++)
{
// позиция по х и у, куда проводить линию
xrand = rand()%(rect.right-100)+50;
yrand = rand()%(rect.bottom-100)+50;
// стиль (начертание) линии
iStyleRand = rand()%7;
// толщина линии
iWidthRand = rand()%7;
// цвет линии
Rrand = rand()%256;
Grand = rand()%256;
Brand = rand()%256;
// создаем карандаш
myPen = CreatePen(iStyleRand, iWidthRand, RGB(Rrand, Grand, Brand));
// выбираем наш карандаш
SelectObject(hDC, myPen);
// нарисовать линию
LineTo(hDC, xrand, yrand);
// освобождаем память из под созданного карандаша
DeleteObject(myPen);
}
// освобождаем контекст
ReleaseDC(hWnd, hDC);
}
break;
case WM_DESTROY:
DeleteDC(hMemDC);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
Тут создание окна, ничего интересного:
#include <windows.h>
class KWnd
{
public:
KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
LRESULT (WINAPI *pWndProc)(HWND, UINT, WPARAM, LPARAM),
LPCTSTR menuname = NULL,
int x = CW_USEDEFAULT, int y = 0,
int width = CW_USEDEFAULT, int height = 0,
UINT classStyle = CS_HREDRAW | CS_VREDRAW,
DWORD windowStyle = WS_OVERLAPPEDWINDOW,
HWND hParent = NULL);
HWND GetHWnd() { return hWnd; }
protected:
HWND hWnd;
WNDCLASSEX wc;
};
KWnd::KWnd(LPCTSTR windowName, HINSTANCE hInst, int cmdShow,
LRESULT (WINAPI *pWndProc)(HWND, UINT, WPARAM, LPARAM),
LPCTSTR menuName, int x, int y, int width, int height,
UINT classStyle, DWORD windowStyle, HWND hParent)
{
TCHAR szClassName[] = TEXT("KWndClass");
wc.cbSize = sizeof(wc);
wc.style = classStyle;
wc.lpfnWndProc = pWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInst;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
//wc.hbrBackground = (HBRUSH)GetStockObject(COLOR_APPWORKSPACE+1);
//wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = menuName;
wc.lpszClassName = szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (!RegisterClassEx(&wc))
{
TCHAR msg[100] = TEXT("Cannot register class: ");
wcscat_s(msg, 100, szClassName);
MessageBox(NULL, msg, TEXT("Error"), MB_OK | MB_ICONERROR);
return;
}
// по умолчанию окно располагается по центру
// и имеет фиксированную высоту/ширину
if (x == CW_USEDEFAULT && width == CW_USEDEFAULT)
{
// получаем разрешение монитора (1024х768)
int xFullScreen = GetSystemMetrics(SM_CXSCREEN);
int yFullScreen = GetSystemMetrics(SM_CYSCREEN);
// размеры окна по умолчанию
width = 720;
height = 540;
// вычисляем позицию левого верхнего угла окна
x = int(xFullScreen/2 - width/2);
y = int(yFullScreen/2 - height/2);
}
hWnd = CreateWindow(szClassName, windowName, windowStyle,
x, y, width, height, hParent, (HMENU)NULL, hInst, NULL);
if (!hWnd)
{
TCHAR text[100] = TEXT("Cannot create window: ");
wcscat_s(text, 100, szClassName);
MessageBox(NULL, text, TEXT("Error"), MB_OK | MB_ICONERROR);
return;
}
ShowWindow(hWnd, cmdShow);
UpdateWindow(hWnd);
}