Archived

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

SetPixel failure

This topic is 5623 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

what could cause SetPixel to return null? here''s my simplified loop code: while(true) { if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) break; TranslateMessage(&msg); DispatchMessage(&msg); } if (hMainDC = NULL) MessageError(); COLORREF thecolor = RGB(255,0,0); SetPixel(hMainDC, 10,10,thecolor); } I know that the DC is valid...although i dont know what it is. I''ve gotten it to work inside of the WM_PAINT but that''s not useful to me in this case...what im really trying to do is bitblt, but no GDI functions are working here so i decided to solve the problem with SetPixel to simplify things. what am i missing? thanks for any help you can give me.

Share this post


Link to post
Share on other sites
yeah, how do you know the hdc is valid? if you dont kknow what itis, then its most likly not valid. also you set it to NULL in your conditional statement.

the reason it worked in WM_PAINT is probably because you were using a valid DC that the WM_PAINT message gives you. or you possibly used GetDC() on the window handle within the WM_PAINT message, but now are not doing that.

i suggest reading u onw how DCs work in windows as well as the GetDC() and ReleaseDC() functions. SelectObject(), CreateDIBSection(), CreateCompatibleBitmap(), CreateDC(), CreateCompatibleDC() are good functions to read about as well.

Share this post


Link to post
Share on other sites
right after i create my window:

hMainDC = GetDC(hMainWnd);
if (hMainDC = NULL)
MessageError();

hMainWnd is my window. MessageError is a dialog box function that tells me if the call fails...and i've tested it and put a watch on it. It does get initialized to something.

thanks
oh by the way could the fact that i used = instead of == have something to do with it? i just noticed that after your comment, but even without the check code shown it doesn't work. i just put that in after i couldn't make it work. I have read tons on DCs and i cant find a difference in my implementation against several other source files i have that work

[edited by - bjmumblingmiles on July 25, 2002 5:02:35 PM]

[edited by - bjmumblingmiles on July 25, 2002 5:03:32 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by bjmumblingmiles


oh by the way could the fact that i used = instead of == have something to do with it?



i just tried making them all == and now i am getting an error at some point...

Share this post


Link to post
Share on other sites
quote:

oh by the way could the fact that i used = instead of == have something to do with it?



== means "is equal to"
= means "assign a value to"

so what you are doing in the line

if (hMainDC = NULL)

is assign the value of NULL to the hMainDC. When ever you make an assignment, it will always return true. This means that not only will your MesageError() function be called, but the call to SetPixel(...) using that value will be wrong.

Try this. Revert all of your changes with the ''='' operator. then in that line chnage it to ''=='' (without apostrophes). If you are still getting an error, assign a breakpoint to the line right after you get the DC, and run the code. when the compiler stops, add a watch to see what the value of hMainDC is. If it is 0, then you aren''t acuiring(sp?)the DC correctly.


Share this post


Link to post
Share on other sites
actually
if(someVar=NULL)
dosomething();

is like doing:

someVar=NULL;
if(NULL)
doSomething();

you MUST use == in all if statments if you are comparing things. whta error do you get? you have to be clear and not use elipses for effect of trailing off.

you cant just grab the hdc and never release it unless you set your window up that way (see the docs). otherwise you could screw things up. also you should use while() around peekmessage() so that all messages get processed.

once more so you get it:
if (hMainDC = NULL)
MessageError();

is like saying

hMainDC = NULL
if (NULL)
MessageError();

instead you MUST do:
if (hMainDC == NULL)
MessageError();

i seriously think you dont want help. you are not explaining the error you are getting. if you dont want help keep responding the way you are.

Share this post


Link to post
Share on other sites
quote:

i seriously think you dont want help. you are not explaining the error you are getting. if you dont want help keep responding the way you are.


Well actually i do want help i was in a hurry to go somewhere and i didn''t get back til late. I do realize the difference between the = and == operators i just often forget while i am coding them. ;-) I tried to say that in one of my earlier posts. The error handler i made in like 2 seconds is just designed to tell me if hMainDC is NULL, it is not intended to change anything. i fixed that problem anyway, and my DC is still invalid. And also i do release the dc at the end and i do have a loop with PeekMessage, then Translate and Dispatch. The code i posted was more focused on why i cant get a valid dc.

here is my situation. after window creation i call
hMainDC = GetDC(hMainWnd);
then i try to draw with that dc
then i release it at the end.
in my main loop, hMainDC is NULL, after it has been initialized a few functions earlier. I have also tried getting the DC in WM_CREATE but it has no different effect.
Hope you can more clearly see my problem. thanks

Share this post


Link to post
Share on other sites
I''ve also tried Begin and End paint and everything compiles but SetPixel returns NULL! is there some reason i can draw in my Message handler but not my main loop? in WM_PAINT it works just fine with the same code i tried to use in the loop. But WM_PAINT messages are not consistent with my timing, obviously. calling InvalidateRect to generate them is clearly not the way to go.

Share this post


Link to post
Share on other sites
Sheesh. Go read the docs for SetPixel. It returns the previous pixel color, or -1 if the API failed. Since it''s returning 0, that means the pixel was black before you changed it to something else.

If you don''t need to know the previous pixel color when you set a pixel, use SetPixelV. It''s faster and will return non-zero if it succeeds, and zero if it fails.

Share this post


Link to post
Share on other sites
quote:
Original post by don
Sheesh. Go read the docs for SetPixel. It returns the previous pixel color, or -1 if the API failed. Since it''s returning 0, that means the pixel was black before you changed it to something else.




no matter what the return value- it''s not plotting the pixel...thanks for the tip though. i''ll try to post my code im in the middle of something right now so ill have to do it later

Share this post


Link to post
Share on other sites
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
DWORD nStartTime;
CreateMainWindow("Basic Game Structure (Empty)", &DefMainWindowProc, hInstance, 400, 300);
ShowMainWindow(nCmdShow);


// Main Loop
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;

TranslateMessage(&msg);
DispatchMessage(&msg);
}
nStartTime = GetTickCount();

COLORREF thecolor = RGB(255,255,255);
SetPixelV(hMainDC, 10,10,thecolor);


while ((GetTickCount() - nStartTime) < FRAMETIME);

}

ReleaseDC(hMainWnd, hMainDC);

return msg.wParam;
}

HWND CreateMainWindow(
char szAppName[],
WNDPROC lpfnWndProc,
HINSTANCE hInstance,
int sizeX, int sizeY)
{
RECT wndRect;
WNDCLASSEX wndClass;

wndClass.cbSize = sizeof(WNDCLASSEX);
wndClass.style = CS_OWNDC;
wndClass.lpfnWndProc = lpfnWndProc;
wndClass.cbClsExtra = 0;
wndClass.cbWndExtra = 0;
wndClass.hInstance = hInstance;
wndClass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
wndClass.hCursor = LoadCursor(NULL,IDC_ARROW);
wndClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
wndClass.lpszMenuName = "NULL";
wndClass.lpszClassName = szAppName;
wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if (RegisterClassEx(&wndClass) == 0)
{
return NULL;
}
hMainWnd = CreateWindowEx(NULL,
szAppName,
szAppName,
WS_BJSTYLE | WS_VISIBLE,
CW_USEDEFAULT,
CW_USEDEFAULT,
sizeX, sizeY,
NULL,
NULL,
hInstance,
NULL);
wndRect.left = 0;
wndRect.top = 0;
wndRect.bottom = sizeY + 1;
wndRect.right = sizeX + 1;
InvalidateRect(hMainWnd, &wndRect, false);
hMainDC = NULL;

return hMainWnd;
}

LRESULT CALLBACK DefMainWindowProc(
HWND hWnd,
UINT uMsgId,
WPARAM wParam,
LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDC;
switch (uMsgId)
{
case WM_CREATE:
hMainDC = GetDC(hMainWnd);
return 0;
case WM_PAINT:
hMainDC = BeginPaint(hMainWnd, &paintStruct);

EndPaint(hMainWnd, &paintStruct);
return 0;

case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_QUIT:

return 0;
default:
return DefWindowProc(hWnd, uMsgId, wParam, lParam);
}
}

hope everything makes sense i left out a function or two but the core should all be there.

Share this post


Link to post
Share on other sites
Ouch. Your handling of DCs is very bad. For your application I recommend drawing the pixel in WM_PAINT, or if you want it how it is now then get the DC right before you need it, set the pixel, then release the DC.

COLORREF thecolor = RGB(255,0,0);

hMainDC = GetDC(hwnd_to_your_main_window);
SetPixelV(hMainDC, 10,10,thecolor);
ReleaseDC(hwnd_to_your_main_window, hMainDC);



I will not make a list of links... I will not make a list of links... I will not make a list of links...
Invader''s Realm

Share this post


Link to post
Share on other sites
The WM_CREATE message is sent to your WndProc *before* CreateWindowEx returns.

In the code you posted you''ve set hMainDC to NULL after CreateWindowEx returns, thereby clobbering the value you loaded into the variable previously in response to WM_CREATE.

Share this post


Link to post
Share on other sites
Hey through some careful stepping i figured it out- my problem wasn''t with the DC is was with hMainWnd! hMainWnd was a very different variable in the main cpp file as opposed to the window creation cpp file where it was supposed to be initialized. I''m going to read up on static and extern because i think that may have solved the problem. thanks for all your help and direction. i guess the moral is i should have looked at the problem more openly. i was thinking the whole time the problem was my DC because it was in fact given a value, it was just a useless one.

Share this post


Link to post
Share on other sites
no i think the moral of the story is to understand the code you copy and write it yourself instead of copying and pasting code without understanding everything. i mean you dont have problems like you speak of when you deal with code you write yourslef and you plan things out. dont be hasty to code and actually plan things out. be VERY careful with globals and name them for what they are. dont misuse them.

again you are dealing with GetDC() incorrectly. you GetDC() at the start of the game loop, draw, then ReleaseDC() at the end of your game loop.

you can do things the way you are, but its incorrect and could cause problems later on that are unexpected (ie WM_PAINTS not eggting sent, etc).

Share this post


Link to post
Share on other sites
quote:
Original post by a person
no i think the moral of the story is to understand the code you copy and write it yourself instead of copying and pasting code without understanding everything.


i''ve been taking the copy and paste approach since i was like 10 and i never could figure this stuff out so i decided to try it one last time, and i really tried to understand what i was doing and type every line according to my knowledge of the structs and fucntions..and at first it just screwed me over. i think i learned alot more by just making a mistake and not being able to find it than i would have if i had typed it perfectly. i understand everything better because i had to go through it all. thanks for your help though because i got everything working that i wanted.

Share this post


Link to post
Share on other sites