Right now I am using GetDC() and ReleaseDC() and SetPixel() to draw pixels on a window. My problem is that they disapperar after the window is minimized.
The pixels are plotted according to a set of variables inputted by the user. I know that I can make them redraw it at startup, but is there a way to draw pixels that stay?
Or, if not, i have a switch (LOWORD(wParam)). How do i make it so that I can trigger an action like clicking on a menu via the program?
kirants
October 20th, 2004, 07:19 PM
You may be experiencing that because you are doing that stuff outside of WM_PAINT handler.
Note that, windows will time to time send your window a WM_PAINT message. This is done as Windows deems necessary. Sometimes, Windows will try to cache your windows DC and redraw it on it's own without sending your window a WM_PAINT message. Example could be when you move the mouse over a window.. In that case, since the area affected is small,windows can do the caching and redrawing..
However, at other times ( if the redraw region is large for example , for e.g. minimizing and maximizing ) windows may not be able to do this for you and so will ask your window to paint itself by sending a WM_PAINT message.
One should handle this message and after doing the necessary call EndPaint().. The purpose of calling EndPaint is to let Windows know that the invalidated region is now up to date and windows need not send you a WM_PAINT anymore.
Now, in your case, apart from doing the drawing on demand basis using GetDC and SetPixel, you need to ensure that the same is done in response to WM_PAINT message. You may want to resort to using a memory DC to do the painting. You maintain this one memory DC and then use it as a canvas to do the painting..
Later, when you paint on demand, paint on this memory DC and as a final step copy all this to the screen DC.
And when you get a WM_PAINT, simply copy the current memory DC contents to the DC you get from BeginPaint()
DrIdiot
October 21st, 2004, 04:33 PM
How do I create/set values to/recall a memory DC?
kirants
October 21st, 2004, 04:38 PM
Setting values and drawing into a memory DC is identical you would do for a screen DC. The same APIs like SetPixel etc.. will work as is. Only you pass a handle to the memory DC..
To create a memory CD look up help on CreateCompatibleDC()/DeleteDC(). You need to look up on articles using these APIs on MSDN.
DrIdiot
October 21st, 2004, 05:03 PM
Okay, I found it.
Thanks!
DrIdiot
October 21st, 2004, 06:14 PM
Uh,
I'm still having trouble doing this...
The piece of my code that matters is:
case WM_COMMAND:
switch(LOWORD(wParam)) {
case ID_FILE_EXIT:
PostMessage(hwind, WM_CLOSE, 0, 0);
break;
case ID_GRAPH_CONSTANT:
{
ret = DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_CONSTANT), hwind, ConstantProc);
if (ret == IDOK) {
function = true;
hdc = GetDC(hwind);
NewAxes(hwind);
for (i = left_bound - x_origin; i <= right_bound - x_origin; i++) {
if (InsidePlane(upper_bound, lower_bound, int(y_origin - int(d * y_scale)))) {
SetPixel(hdc, x_origin + i, int(y_origin - int(d * y_scale)), 0x00FF0000);
}
}
TextOut(hdc, 5, 5, "Constant Function ", 27);
ValidateRect(hwind, NULL);
ReleaseDC(hwind, hdc);
screencache = CreateCompatibleDC(hdc);
GetDC(hwind);
}
}
break;
And I also have:
case WM_PAINT:
{
PAINTSTRUCT ps;
hdc = BeginPaint(hwind, &ps);
if (function == true) {
hdc = GetDC(hwind);
RestoreDC(screencache, 1);
ReleaseDC(hwind, hdc);
}
EndPaint(hwind, &ps);
}
break;
What am I doing wrong? (screencache is an HDC defined earlier).
kirants
October 21st, 2004, 07:48 PM
// Create a normal DC and a memory DC for the entire screen. The
// normal DC provides a "snapshot" of the screen contents. The
// memory DC keeps a copy of this "snapshot" in the associated
// bitmap.
In your command handler, do all the drawing and then:
if(screencache != NULL)
{
screencache = CreateCompatibleDC(hdc);
// Create a compatible bitmap for hdcScreen.
hbmScreen = CreateCompatibleBitmap(hdc,
width of the hwind, //get these values from GetClientRect
height of the hwind);
// Select the bitmaps into the compatible DC.
if (!SelectObject(screencache, hbmScreen))
{
//error
}
}
else
{
//do nothing.. since we already have the cache ready
}
/now save the hdc info onto the screencache
BitBlt(screencache,
0,0,
width of the hwind, height of the hwind,
hdc,
0,0,
SRCCOPY);
So, now you have the screencache updated..
Now, why are we doing this bitmap thing ? Reason being when you create a compatible DC, the size of it is just 1 pixel by 1 pixel.
You need to expand it by selecting an appropriately sized bitmap onto it. That is the reason we are doing all that stuff.
In your WM_PAINT handler do this:
PAINTSTRUCT ps;
hdc = BeginPaint(hwind, &ps);
//now, transfer info from the screencache to hdc
BitBlt(hdc,
0,0,
width of the hwind, height of the hwind,
screencache,
0,0,
SRCCOPY);
EndPaint(hwind, &ps);
At the start of the program initialize screencache and hbmScreen to NULL
Also, in the WM_DESTROY handler, do a DeleteDC and DeleteObject on those 2 handles respectively.
DrIdiot
October 21st, 2004, 08:32 PM
It worked!
Thanks!
One last question, when I use GetClientRect, the second argument has to be "LPRECT." How do I get the coordinates from the LPRECT? I know if its a RECT then it lets me do variable.bottom but when I tried that with LPRECT it wouldn't and when i put a RECT into the second argument it wouldn't let me either.
kirants
October 21st, 2004, 08:39 PM
LPRECT is nothing but a pointer to RECT. It is typedefed as RECT*
Now, you can do something like
LPRECT lpClientRect = new LPRECT;
GetClientRect(hWnd,lpClientRect);
use it as lpClientRect->left and so on
and then
delete lpClientRect.
For such a simple application, this new and delete is overkill. You'd rather do:
RECT oClientRect;
GetClientRect(hwnd,&oClientRect);//since it needs a pointer to a RECT that is what we pass here, we pass the address to oClientRect which is the same as pointer to a RECT object
and use it as oClientRect.left.. and so on.
You don't need to delete anymore and the variable will get cleaned up when the stack unwinds.
DrIdiot
October 21st, 2004, 09:07 PM
It's working.
Thanks!
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.