Jump to content

  • Log In with Google      Sign In   
  • Create Account


Why does CreateWindowW fail?


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
28 replies to this topic

#21 Amr0   Members   -  Reputation: 1030

Like
0Likes
Like

Posted 20 October 2012 - 10:12 AM

Probably irrelevant, but you are passing messages to DefWindowProc() only if they are not in the switch statement, and returning 0 for all messages in the switch statement. This requires that you check that 0 is the expected return value for each and every message you handle in the switch statement. Instead, forget about "default:", and have the function return the value returned from DefWindowProc(), and explicitly return 0 or whatever is appropriate for messages which you process and which you don't want DefWindowProc() to process. So you get this:

switch( Msg )
{
case WM_PAINT:
{
  PAINTSTRUCT ps;
  HDC hdc = BeginPaint(&ps);
  this->OnPaint( hdc );
  EndPaint(&ps);
}
return 0; // We've already handled it and we don't want to pass it to DefWindowProc().

case WM_SIZE:
// Here lies code which we want to execute whenever the window is resized,
// but we still want DefWindowProc() to handle the message, so we break.
this->OnSize();
break;
}

return DefWindowProc();

Of course, you could still replace your "break;" statements with a "return DefWindowProc(...);" statement, but that seems counter-intuitive to me.

There is an somewhat old article which discusses coupling a C++ object with a native window handle (HWND) here. It's one of the better ways to do it. The finished code is in what he calls the AngelCode Tool Box, and the files most relevant to this discussion are acWindow.h and acWindow.cpp which you can find here.

Notice that WM_NCDESTROY is guaranteed to be the last message that a window will receive from the system, WM_NCCREATE is not the first message it will receive. I think the first message received by a window's message processor is WM_NCCALCSIZE, but I don't think it says so in the docs, so it can change, so good code will not depend on that piece of information. The article I linked above talks about how to do it by setting a hook procedure that gets called whenever a window is created, creating the window (and consequently the hook procedure that will do the coupling), then removing the hook procedure.

Good luck.

Sponsor:

#22 ATC   Members   -  Reputation: 551

Like
0Likes
Like

Posted 20 October 2012 - 11:49 AM

Thanks Arm0. I did already get my Window class working though, but this is good information and thanks for the links!

My problem now is explained on the last post of page 1... SetWindowTextW/A will not work... they don't do anything. And it's driving me crazy! :P
_______________________________________________________________________________
CEO & Lead Developer at ATCWARE™
"Project X-1"; a 100% managed, platform-agnostic game & simulation engine


Please visit our new forums and help us test them and break the ice!
___________________________________________________________________________________

#23 Amr0   Members   -  Reputation: 1030

Like
0Likes
Like

Posted 20 October 2012 - 12:25 PM

SetWindowText will fail if:
* The supplied window handle is invalid. Maybe you're passing the wrong handle somehow. Check which window you are passing by retrieving the window text and displaying it in, say, the debug output window (see OutputDebugString()).
* The WM_SETTEXT message is not being passed to DefWindowProc(), which will do what is necessary to change the window's text.

#24 ATC   Members   -  Reputation: 551

Like
0Likes
Like

Posted 20 October 2012 - 12:33 PM

@ Arm0: No, my handle is valid. I will re-describe the problem:

Does anyone know why SetWindowText W/A does not work? No matter what I do or what variation of parameters and such I try nothing happens...

HWND hWnd;

//! All of these get same, valid HWND handle
hWnd = GetActiveWindow();
hWnd = FindWindow( null, WINDOW_TITLE );
hWnd = FindWindow( WND_CLASS_NAME, null );
hWnd = FindWindow( WND_CLASS_NAME, WINDOW_TITLE );
hWnd = pWindow->hWnd; // << made public for testing
SetWindowTextW( hWnd, L"TESTING 123" ); // nothing happens...
SetWindowTextA( hWnd, "TESTING 123" ); // nothing happens...


I've confirmed my HWND handle is valid. Using it I can call other Win32 functions and easily move around or resize the window or do any number of other things. And as I show above, I've tested my Window class internal HWND against GetActiveWindow and FindWindow to make sure I've got the right handle and yes, they return an identical handle. So the the HWND IS valid.
Calling the SetWindowText function returns a value of true/1 for success, and the Window recieves the WM_SETTEXT message which I can intercept and update my Window's "title" field, like so:

[source lang="cpp"] case WM_SETTEXT: this->title = wstring( reinterpret_cast<WCHAR_STR>(lParam) ); break;[/source]


...I've run in debug mode and the text I get on the WM_SETTEXT message matches the text I use in SetWindowText calls, demonstrating that everything about this seems to be working correctly except for one incredibly annoying fact: nothing happens and the text in the caption/title bar remains untouched! *double facepalm*
What the hell is going on here? This is serious frustrating... Posted Image

Thanks,

--ATC--

Edited by ATC, 20 October 2012 - 12:36 PM.

_______________________________________________________________________________
CEO & Lead Developer at ATCWARE™
"Project X-1"; a 100% managed, platform-agnostic game & simulation engine


Please visit our new forums and help us test them and break the ice!
___________________________________________________________________________________

#25 Amr0   Members   -  Reputation: 1030

Like
0Likes
Like

Posted 20 October 2012 - 12:46 PM

Try replacing the message processor code in your window class with
LRESULT MsgProc( UINT Msg, WPARAM wParam, LPARAM lParam ) { return DefWindowProc( this->hWnd, Msg, wParam, lParam ); }


#26 ATC   Members   -  Reputation: 551

Like
0Likes
Like

Posted 20 October 2012 - 12:51 PM

Hmmm, that did it... WTF lol...

Is it acceptable to just redefine my WndProc like so:

[source lang="cpp"]LRESULT Window::WndProc( UInt32 msg, WPARAM wParam, LPARAM lParam ) { HDC hDC; PAINTSTRUCT paintStruct; switch( msg ) { case WM_PAINT: hDC = BeginPaint( this->hWnd, &paintStruct ); EndPaint( this->hWnd, &paintStruct ); break; case WM_SIZE: this->width = (Int32)LOWORD(lParam); this->height = (Int32)HIWORD(lParam); break; case WM_SETTEXT: this->title = wstring( reinterpret_cast<WCHAR_STR>(lParam) ); break; case WM_DESTROY: PostQuitMessage( 0x00 ); break; } return DefWindowProc( this->hWnd, msg, wParam, lParam );}[/source]

???

Now my text is changing correctly, but I just want to be sure that structuring my WndProc method like this is ok and isn't going to cause any problems for my class. The original version was returning 0x00 instead of the result of DefWindowProc.

EDIT:

I assume that if I do it this way and I want to block Windows from getting a message then I can replace a break with a return.

Edited by ATC, 20 October 2012 - 12:59 PM.

_______________________________________________________________________________
CEO & Lead Developer at ATCWARE™
"Project X-1"; a 100% managed, platform-agnostic game & simulation engine


Please visit our new forums and help us test them and break the ice!
___________________________________________________________________________________

#27 Amr0   Members   -  Reputation: 1030

Like
0Likes
Like

Posted 20 October 2012 - 01:07 PM

That's what I spoke about in my first post. Always return DefWindowProc() for all messages, even the ones you process, except in the case where you know that you do NOT want DefWindowProc() to process the message, and that the value you are returning instead is meaningful to the system. DefWindowProc() does A LOT of things, and the less you interfere with it (the less messages you keep from it), the less problems you are likely to have. So yes, that structure of the message procedure is the natural one.

I assume that if I do it this way and I want to block Windows from getting a message then I can replace a break with a return.

Yep, but again, see the documentation for the message in question to know what to return.

Edited by Amr0, 20 October 2012 - 01:08 PM.


#28 ATC   Members   -  Reputation: 551

Like
0Likes
Like

Posted 20 October 2012 - 01:24 PM

That's what I spoke about in my first post. Always return DefWindowProc() for all messages, even the ones you process, except in the case where you know that you do NOT want DefWindowProc() to process the message, and that the value you are returning instead is meaningful to the system. DefWindowProc() does A LOT of things, and the less you interfere with it (the less messages you keep from it), the less problems you are likely to have. So yes, that structure of the message procedure is the natural one.

I assume that if I do it this way and I want to block Windows from getting a message then I can replace a break with a return.

Yep, but again, see the documentation for the message in question to know what to return.


Gotcha! Thanks a lot! :-)

I've got a nice general purpose Window class coming together now... now working on wiring up some events and such. When it's done I won't feel so bummed out every time I start a new Win32 or native DirectX project (from having to do all this crap over again). :P

Thanks again,

--ATC--
_______________________________________________________________________________
CEO & Lead Developer at ATCWARE™
"Project X-1"; a 100% managed, platform-agnostic game & simulation engine


Please visit our new forums and help us test them and break the ice!
___________________________________________________________________________________

#29 MarkS   Prime Members   -  Reputation: 875

Like
0Likes
Like

Posted 20 October 2012 - 07:51 PM

CRAP! I cannot believe I missed that! You don't need to process WM_CREATE or WM_PAINT or most of the other messages, but you do need to return DefWindowProc().Posted Image




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS