Archived

This topic is now archived and is closed to further replies.

Wrathnut

GDI double buffering question

Recommended Posts

HI everyone, I''ve been trying to go through an learn win 32 programming so I can port my java games into C++. Anyway, I was going through a tutorial in Sams, "Programming windows 98/NT - Unleashed" and though it would be good to try double buffering it. It basically works like the windows "Scribble" tutorial but it doesn''t have all the bells and whistles. Anyway I looked through all of the previous posts from te these forums on GDI double buffering and all of them deal with draw bitmaps to the device context, whereas I am just trying to draw lines. I was hoping someone could tell me what I am doing wrong. Here is te source:
  
// NewHello.cpp : Defines the entry point for the application.

//


#include "stdafx.h"

HDC memDC, hDC;
HBITMAP memBM;
int winWidth, winHeight, left, right, top, bottom;
//RECT sRect;


void AddSegmentAtMessagePos(HDC hDC, HWND hwnd, BOOL bDraw){
	
	DWORD dwPos;
	POINTS points;
	POINT point;

	dwPos = GetMessagePos();
	points = MAKEPOINTS(dwPos);
	point.x = points.x;
	point.y = points.y;
	ScreenToClient(hwnd, &point);
	DPtoLP(memDC, &point, 1);
	if (bDraw) LineTo(memDC, point.x, point.y);
	else MoveToEx(memDC, point.x, point.y, NULL);

	
}

void DrawHello(HWND hwnd){
	
	MSG msg;
	
	if (GetCapture() != NULL) return;
	if (memDC != NULL){
		SetCapture(hwnd);
		AddSegmentAtMessagePos(memDC, hwnd, FALSE);
		
		while(GetMessage(&msg, NULL, 0, 0)){
			if(GetCapture() != hwnd) break;
			switch (msg.message){
			case WM_MOUSEMOVE:
				AddSegmentAtMessagePos(memDC, hwnd, TRUE);
				break;
			case WM_LBUTTONUP:
				goto ExitLoop;
			default:
				DispatchMessage(&msg);
			}
		}
ExitLoop:
		ReleaseCapture();
		//ReleaseDC(hwnd, hDC);

	}
}

void PageFlip(HWND hwnd){
	
	BitBlt(hDC, left, top, right, bottom, memDC, left, top, SRCCOPY);
	
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
	
	switch(uMsg){
	case WM_LBUTTONDOWN:
			DrawHello(hwnd);
			break;
	case WM_PAINT:
		PageFlip(hwnd);
		break;
	case WM_DESTROY:
		ReleaseCapture();
		ReleaseDC(hwnd, hDC);
		DeleteDC(hDC);
		DeleteDC(memDC);
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hwnd, uMsg, wParam, lParam);
	}
	return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
 	// TODO: Place code here.

	
	MSG msg;
	HWND hwnd;
	WNDCLASS wndClass;

	if(hPrevInstance == NULL){
		
		memset(&wndClass, 0, sizeof(wndClass));
		wndClass.style = CS_HREDRAW | CS_VREDRAW;
		wndClass.lpfnWndProc = WndProc;
		wndClass.hInstance = hInstance;
		wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
		wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW +1);
		wndClass.lpszClassName = "HELLO";
		if(!RegisterClass(&wndClass)){
			return false;
		}
	}

	hwnd = CreateWindow("HELLO", "ECTHA SKETCH", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
	
	ShowWindow(hwnd, nCmdShow);
	UpdateWindow(hwnd);
	
	//Create window DC

	hDC = GetDC(hwnd);
	
	//Find window width and height

	RECT sRect;
	GetWindowRect(hwnd, &sRect);

	winWidth = sRect.right - sRect.left;
	winHeight = sRect.bottom - sRect.top;
	left = sRect.left;
	right = sRect.right;
	top = sRect.top;
	bottom = sRect.bottom;
	
	//Create a compatible memory device context

	memDC = CreateCompatibleDC(hDC);
	
	//Create Memory Bitmap

	memBM = CreateCompatibleBitmap(hDC, winWidth, winHeight);

	while(GetMessage(&msg, NULL, 0, 0)){
		DispatchMessage(&msg);
		
	}

	return msg.wParam;
	
}

  
Any help would be greatly appreciated. "And then 2 men appeared... Men in dark suits.. with dark soulless eyes. Men like this could have come from only one place..
The bank."

Share this post


Link to post
Share on other sites
I think your problem is that your "PageFlip()" function is called from WM_PAINT (which is correct), but it is not called while the user is drawing. Assuming all the other windows code is correct (I only scrutinized the GDI stuff), adding a call to pageflip in the WM_MOUSEMOVE message in DrawHello() should fix your app.

Share this post


Link to post
Share on other sites
Hmm I just tried that and it doesn't seem to work I will go back through and double check the rest of the code(It did work fine before I tried to modify it to double buffer..)

The only other thing I could think of was that all of the other previous posts on the subject had a call to:

SelectObject(HDC, HBITMAP);

in their code, but from looking through the MSDN library I don't see how that call would help me..

Heheh and I was actually thinking this would be an easy thing to do ^_^.


"And then 2 men appeared... Men in dark suits.. with dark soulless eyes. Men like this could have come from only one place..
The bank."


[edited by - wrathnut on May 1, 2003 2:56:54 PM]

Share this post


Link to post
Share on other sites
Yes, you have to select memBM into memDC. I didn''t even look at that. If I remember correctly, I believe you have to unselect the bitmap before you destroy it. Speaking of destroying, you should destroy both the DC and bitmap that you created in WinMain after you are done with them.

Share this post


Link to post
Share on other sites