Code:
#include <windows.h>
#include <windowsx.h>
static BOOL state;
void PaintWindow(HWND hwnd, HDC hdc) {
HDC hdc2;
HBITMAP theBitmap;
HBITMAP hOldBitmap;
HPEN thePen;
HPEN hOldPen;
HBRUSH theBrush;
HBRUSH hOldBrush;
hdc2 = CreateCompatibleDC(hdc);
// Note: We pass the hdc of the original window - not the
// created hdc which is still monochrome...
theBitmap = CreateCompatibleBitmap(hdc,640,480);
// Save old bitmap so we can restore it later...
hOldBitmap = SelectObject(hdc2,theBitmap);
// Create a pen and brush to draw with...
thePen = CreatePen(PS_SOLID,1,RGB(0,255,0)); // Green
theBrush = CreateSolidBrush(RGB(0,255,0)); // Green
// Put new objects into our hdc2.
// Save old objects so we can restore them later...
hOldPen = SelectObject(hdc2,thePen);
hOldBrush = SelectObject(hdc2,theBrush);
// Draw a rectangle on the bitmap...
Rectangle(hdc2,0,0,640,480);
// On the key C blit the bitmap to the screen
// Note that all of this code should be surrounded with
// if (state)... Otherwise it is a total waste.
if (state) BitBlt(hdc,0,0,640,680,hdc2,0,0,SRCCOPY);
// Now put back the old stuff into hdc2...
SelectObject(hdc2, hOldBitmap);
SelectObject(hdc2, hOldPen);
SelectObject(hdc2, hOldBrush);
// Destroy the stuff we created...
DeleteObject(theBitmap);
DeleteObject(thePen);
DeleteObject(theBrush);
DeleteDC(hdc2);
}
LRESULT CALLBACK messageHandler (HWND winHandle, UINT theMsg, WPARAM wParam, LPARAM lParam)
{
switch (theMsg)
{
case WM_KEYDOWN:
if (wParam == VK_DOWN)
{
state = TRUE;
InvalidateRect(winHandle, NULL, TRUE);
}
else if (wParam == VK_UP) {
state = FALSE;
InvalidateRect(winHandle, NULL, TRUE);
}
return 0;
case WM_CREATE:
return 0;
case WM_PAINT: {
PAINTSTRUCT ps;
HDC hdc;
// Note that BeginPaint will fill the update region
// with the background brush. This will cause flicker and
// defeats the purpose of double buffering!!
hdc = BeginPaint(winHandle,&ps);
PaintWindow(winHandle, hdc);
// NOTE: We do not call ReleaseDC on hdc.
// This is only required when we obtained it with GetDC, etc.
EndPaint(winHandle,&ps);
return 0;
}
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return (DefWindowProc(winHandle,theMsg,wParam,lParam));
}
}
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
WNDCLASSEX winclass;
HWND windowsHandle1;
MSG theMsg;
BOOL bRet;
winclass.cbSize = sizeof (WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.lpfnWndProc = messageHandler;
winclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = NULL;
winclass.lpszClassName = "windyClass";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!(RegisterClassEx(&winclass)))
return 1; // you should return 1 to indicate an error
if (!(windowsHandle1 = CreateWindowEx(0, "windyClass", "The First Window",
WS_OVERLAPPEDWINDOW| WS_VISIBLE , 0, 0 ,
640, 480, NULL, NULL, hInstance, NULL)))
return 1; // you should return 1 to indicate an error
// Unless you have a good reason, use GetMessage loop
// and not PeekMessage...
while ( bRet = GetMessage(&theMsg, NULL, 0, 0) ) {
if (bRet == -1) break;
TranslateMessage(&theMsg);
DispatchMessage(&theMsg);
}
return 0;
}