Re: Problem with Double Buffering (win32+GDI)
- From: Sylvain SF <sylvain@xxxxxxxxxxxxxxx>
- Date: Mon, 09 Mar 2009 14:40:17 +0100
me4dtrade a écrit :
Most of the app code are about classes and are not related to drawing.
The following is the old code that draws graphics directly to the app
window. It works. But it causes flickering.
HDC hdc = GetDC(hWnd); // hWnd is valid
SelectObject(hdcMem, hRedPen); // a pen of red color
MoveToEx(hdcMem, 10, 10);
LineTo(hdcMem, 100, 10); // testing a line
ReleaseDC(hWnd, hdc);
this working code is not that clear.
if it's part of the WM_PAINT process, the HDC should be
obtained by a call to BeginPaint(), GetDC & ReleaseDC
are so unexpected.
usual code is:
hdc = BeginPaint(hWnd, &ps);
SelectObject(hdc, hRedPen);
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 100, 10);
EndPaint(hWnd, &ps);
I turned this chunk of code to double buffering as shown in my first
posting.
that code created a memory bitmap but draw a line on it.
if the red line is not visible for first display, it's because
the hRedPen is not created at this moment, to fix it, create
the pen in the WM_CREATE handler, eg:
(in WndProc)
switch (message){
case WM_CREATE:
hRedPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
return DefWindowProc(hWnd, message, wParam, lParam);
regarding flickering, if you're working with a template code
created with the wizard, the default MyRegisterClass function
registers a window class with style attribute sets to:
CS_HREDRAW | CS_VREDRAW
this style causes the window to update its full content when
the window is resized, BitBlt then causes flickering, to
avoid that simply set the wcex.style to 0.
According to MSDN doc, defining a pen with width 0 is the same as
defining it with width of 1 (default width).
perfectly right, the test purpose I would prefer a big wide
pen of 5 or 10 pixels, just to check if the red line blinks
or not.
At this point, my guess is that the hBmMem or hdcMem has a problem,
whatever you draw into it, it just shows a black background. No
forground graphics.
it's black because you don't fill it with another color (says white).
the foreground graphics (the red line) is visible if the pen is created.
Sylvain.
--
ATOM MyRegisterClass(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
LRESULT __stdcall WndProc(HWND, UINT, WPARAM, LPARAM);
HPEN hRedPen;
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE, LPTSTR, int nCmdShow)
{
MyRegisterClass(hInstance);
if (!InitInstance (hInstance, nCmdShow))
return FALSE;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = 0; // CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = L"TestDraw";
wcex.hIconSm = NULL;
return RegisterClassEx(&wcex);
}
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hWnd = CreateWindow(L"TestDraw", L"Draw", WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hWnd)
return FALSE;
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
return TRUE;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
HBITMAP hBmMem, hBmOld;
HDC hdcMem;
HGDIOBJ pen;
switch (message){
case WM_CREATE:
hRedPen = CreatePen(PS_SOLID, 0, RGB(255,0,0));
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
/*
SelectObject(hdc, hRedPen);
MoveToEx(hdc, 10, 10, NULL);
LineTo(hdc, 100, 10);
*/
hdcMem = CreateCompatibleDC(hdc);
hBmMem = CreateCompatibleBitmap(hdc, 250, 250);
hBmOld = (HBITMAP) SelectObject(hdcMem, hBmMem);
pen = SelectObject(hdcMem, hRedPen);
MoveToEx(hdcMem, 10, 10, NULL);
LineTo(hdcMem, 100, 100);
SelectObject(hdcMem, pen);
BitBlt(hdc, 0, 0, 250, 250, hdcMem, 0, 0, SRCCOPY);
SelectObject(hdcMem, hBmOld);
DeleteObject(hBmMem);
DeleteDC(hdcMem);
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
.
- References:
- Problem with Double Buffering (win32+GDI)
- From: me4dtrade
- Re: Problem with Double Buffering (win32+GDI)
- From: Norman Bullen
- Re: Problem with Double Buffering (win32+GDI)
- From: me4dtrade
- Re: Problem with Double Buffering (win32+GDI)
- From: Sylvain SF
- Re: Problem with Double Buffering (win32+GDI)
- From: me4dtrade
- Problem with Double Buffering (win32+GDI)
- Prev by Date: Re: Problem with Double Buffering (win32+GDI)
- Next by Date: Re: LVN_GETDISPINFO - What Benefit Does It Provide?
- Previous by thread: Re: Problem with Double Buffering (win32+GDI)
- Next by thread: Re: Problem with Double Buffering (win32+GDI)
- Index(es):
Relevant Pages
|