Why does CreateWindowW fail?
#1 Members - Reputation: 551
Posted 19 October 2012 - 01:54 PM
gamewnd.h
[source lang="cpp"]#pragma region Description/* gamewnd.h ::* Implements a game window class for DirectX applications.** Copyright © ATCWARE 2010, All Rights Reserved.*/#pragma endregion/*----------------------------------* INCLUDE DIRECTIVES ::*----------------------------------*/#pragma once#define WIN32_LEAN_AND_MEAN#include <atc_standards.h>#include <Windows.h>#include <stdexcept>using namespace std;/*----------------------------------* PREPROCESSOR DIRECTIVES ::*----------------------------------*/#define WND_CLASS_NAME_W L"GameWndClass"#define MAX_WINDOW_WIDTH 0x1000#define MAX_WINDOW_HEIGHT 0x1000/*-----------------------------------------------------------------------------** GLOBAL VARIABLES ::*-----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------** PROTOTYPES & FORWARD DECLARATIONS ::*-----------------------------------------------------------------------------*/enum WndState{ DEFAULT = 0x00, MAXIMIZED = 0x01, MINIMIZED = 0x02,};class Window{public: virtual void Show( ); virtual void Hide( ); virtual void Close( ); static void ClientToAbsSize( Int32* const pWidth, Int32* const pHeight ); static Window* Create( Int32 width, Int32 height, wstring title, HINSTANCE hInstance ); protected: Window( ); HWND hWnd; HINSTANCE hInstance; virtual LRESULT WndProc( UInt32 msg, WPARAM wParam, LPARAM lParam );private: static LRESULT CALLBACK MsgRouter( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);};/*-----------------------------------------------------------------------------*********************************************************************************-----------------------------------------------------------------------------*/[/source]
gamewnd.cpp
[source lang="cpp"]#pragma region Description/* gamewnd.cpp ::*** Copyright © ATCWARE 2010, All Rights Reserved.*/#pragma endregion/*----------------------------------* INCLUDE DIRECTIVES ::*----------------------------------*/#include "gamewnd.h"/*----------------------------------* PREPROCESSOR DIRECTIVES ::*----------------------------------*//*-----------------------------------------------------------------------------** GLOBAL VARIABLES ::*-----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------** GameWndBase Implementation ::*-----------------------------------------------------------------------------*/Window::Window( ) { this->hInstance = 0x00; this->hWnd = 0x00;}void Window::Show( ) { ShowWindow( this->hWnd, SHOW_OPENWINDOW );}void Window::Hide( ) { ShowWindow( this->hWnd, HIDE_WINDOW );}void Window::Close( ) { CloseWindow( this->hWnd );}void Window::ClientToAbsSize( Int32* const pWidth, Int32* const pHeight ) { RECT rc = { 0, 0, *pWidth, *pHeight }; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); *pWidth = (rc.right - rc.left); *pHeight = (rc.bottom - rc.top);}Window* Window::Create( Int32 width, Int32 height, wstring title, HINSTANCE hInstance ) {#if DEBUG || PERFORM_CHECKS //! Validate arguments if( (width < 0) || (width > MAX_WINDOW_WIDTH) ) throw new invalid_argument( "Specified Window width out of range." ); if( (height < 0) || (height > MAX_WINDOW_HEIGHT) ) throw new invalid_argument( "Specified Window width out of range." ); if( !(title.data()) || (title.length() < 1) ) throw new invalid_argument( "Invalid Window title parameter." ); if( !hInstance ) throw new invalid_argument( "HINSTANCE parameter is NULL." );#endif Window* pWindow = new Window; // Create & register window class :: WNDCLASSEX wndClass = { 0 }; wndClass.cbSize = sizeof( WNDCLASSEX ); wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wndClass.lpfnWndProc = Window::MsgRouter; wndClass.hCursor = LoadCursor( null, IDC_ARROW ); wndClass.style = (CS_VREDRAW | CS_HREDRAW); wndClass.hInstance = hInstance; wndClass.lpszMenuName = null; wndClass.lpszClassName = WND_CLASS_NAME_W; if( !RegisterClassEx( &wndClass ) ) throw new runtime_error( "Window registration failed!" ); // Calculate absolute window size :: Int32 abs_width = width, abs_height = height; ClientToAbsSize( &abs_width, &abs_height ); // Create the Win32 window :: HWND hWnd = CreateWindowW( WND_CLASS_NAME_W, title.data(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, abs_width, abs_height, null, null, hInstance, static_cast<LPVOID>( pWindow ) ); // Show the game window :: if( !hWnd ) throw new runtime_error( "Window creation failed!" ); pWindow->hWnd = hWnd; pWindow->hInstance = hInstance; //! Store handles return pWindow;}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_DESTROY: PostQuitMessage( 0x00 ); break; default: return DefWindowProc( this->hWnd, msg, wParam, lParam ); } return static_cast<LRESULT>( 0x00 );}// Routes messages to Window instances:LRESULT CALLBACK Window::MsgRouter(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { Window* Wnd = (Window *)0x00; if( msg == WM_NCCREATE ) { SetWindowLongPtr( hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>( (LPCREATESTRUCT(lParam))->lpCreateParams) ); } else { Wnd = reinterpret_cast<Window *>( GetWindowLongPtr( hWnd, GWLP_USERDATA ) ); if( !Wnd ) throw new runtime_error( "No Window instance associated with HWND!" ); return Wnd->WndProc( msg, wParam, lParam ); }}/*-----------------------------------------------------------------------------*********************************************************************************-----------------------------------------------------------------------------*/[/source]
...for some reason CreateWindowW always returns null (0x00000000)! At first I thought maybe it was some invalid parameters, but I've stepped through in debug mode and cannot see anything wrong with them. I even switched some of the custom parameters to hard-coded values that I already know work in regular Win32 applications (e.g., the original version of this project) but it still fails.
For example, I just hard-coded the window title to L"MyWindow", changed the width/height params to 1024 and 768, changed the last parameter to NULL, etc... Still doesn't work, still returns a null HWND... :'(
Any idea what's going on here?
Thanks,
--ATC--
P.S. -- Just getting back into C++ to resharpen my old skills, so if you see any other coding problems or bad practices that don't have anything to do with the actual issue I welcome your corrections and suggestions...
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!
___________________________________________________________________________________
#2 Members - Reputation: 551
Posted 19 October 2012 - 02:06 PM
I just call Window::Create in my wWinMain function like so:
Window* pWindow = Window::Create( 1024, 768, L"DirectX11 Tutorial", hInstance );
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!
___________________________________________________________________________________
#4 Moderators - Reputation: 4633
Posted 19 October 2012 - 02:53 PM
Chances are that the function happens to return zero, which is the response to the NCCREATE message to abort the window creation and return a null handle.
#5 Members - Reputation: 551
Posted 19 October 2012 - 02:54 PM
1400 (0x578)
Invalid window handle.
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!
___________________________________________________________________________________
#6 Members - Reputation: 551
Posted 19 October 2012 - 03:01 PM
Ahhh, good eye... I didn't notice that. But I changed it to this:
[source lang="cpp"]// Routes messages to Window instances:LRESULT CALLBACK Window::MsgRouter(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { Window* Wnd = (Window *)0x00; if( msg == WM_NCCREATE ) { SetWindowLongPtr( hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>( (LPCREATESTRUCT(lParam))->lpCreateParams) ); return ::DefWindowProc( hWnd, msg, wParam, lParam ); } else { Wnd = reinterpret_cast<Window *>( GetWindowLongPtr( hWnd, GWLP_USERDATA ) ); if( !Wnd ) throw new runtime_error( "No Window instance associated with HWND!" ); return Wnd->WndProc( msg, wParam, lParam ); }}[/source]
...now the code does not crash but I don't get a proper window. I just get a borderless square on the screen without any control buttons/boxes or anything. Just a blank square client area it appears.
EDIT:
It appears this is happening because my window never recieves a WM_PAINT... every time WndProc is invoked it seems that msg == 0x00... ?
EDIT 2:
Or is the above happening (no WM_PAINT) because the window is occluded/minimized as I debug the application?
EDIT 3 (lol):
Yes, that's why... so the window IS getting WM_PAINT, leaving me with no idea why it's all screwed up...
BTW, this is a very odd Windows behavior if you ask me...
Edited by ATC, 19 October 2012 - 03:25 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!
___________________________________________________________________________________
#7 Members - Reputation: 570
Posted 19 October 2012 - 03:26 PM
You mean to set the hInstance of the window class to the argument from Window::Create. However, you also have a NULL hInstance member variable. If the NULL variable is being substituted for the function argument, then you'll see issues.
Try changing the variable names to remove the ambiguity or move "pWindow->hInstance = hInstance;" immediately prior to setting up wndClass.
Again, I could be wrong, but this is the only thing that jumps out at me.
#8 Moderators - Reputation: 4633
Posted 19 October 2012 - 03:48 PM
Name resolution is well defined. Function parameters have higher priority than members, so that is not a problem.I see an ambiguity, but I am not sure how compilers handle this, so I could be wrong.
You mean to set the hInstance of the window class to the argument from Window::Create. However, you also have a NULL hInstance member variable. If the NULL variable is being substituted for the function argument, then you'll see issues.
Try changing the variable names to remove the ambiguity or move "pWindow->hInstance = hInstance;" immediately prior to setting up wndClass.
Again, I could be wrong, but this is the only thing that jumps out at me.
Anyway, I have copied your code and I truly cannot see how your code flow is different from mine, yet mine works and your behaves just as you describe. I will see if I can spend some more time later and investigate some more if you haven't found a solution. My observation so far is that the window becomes OK after a while, you just need to, for example, minimize and maximize the window and it starts behaving as expected.
#10 Members - Reputation: 515
Posted 19 October 2012 - 04:07 PM
You call CreateWindow: this->hwnd == NULL
CreateWindow sends WM_NCCreate - you set the window data, this->hwnd still == NULL
CreateWindow sends the other messages it sends - you call Wnd->WndProc, you pass this->hwnd to DefWindowProc but this->hwnd is still NULL
CreateWindow finally returns, after a check only now is this->hwnd set to a valid value
Long story short, you handle who knows how many messages by passing a NULL hwnd to DefWindowProc or to Begin/EndPaint.
The easiest way to fix it is to assign this->hwnd in WM_NCCreate.
Edited by adeyblue, 19 October 2012 - 04:08 PM.
#11 Members - Reputation: 551
Posted 19 October 2012 - 04:09 PM
You're saying the same exact code works on your PC?
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!
___________________________________________________________________________________
#12 Members - Reputation: 551
Posted 19 October 2012 - 04:11 PM
You (OP) have a problem everybody seems to run into when doing this at some point.
You call CreateWindow: this->hwnd == NULL
CreateWindow sends WM_NCCreate - you set the window data, this->hwnd still == NULL
CreateWindow sends the other messages it sends - you call Wnd->WndProc, you pass this->hwnd to DefWindowProc but this->hwnd is still NULL
CreateWindow finally returns, after a check only now is this->hwnd set to a valid value
Long story short, you handle who knows how many messages by passing a NULL hwnd to DefWindowProc or to Begin/EndPaint.
The easiest way to fix it is to assign this->hwnd in WM_NCCreate.
I tried doing that too and it didn't work, I seem to remember... And then there's the issue that you can't get the Window* on the WM_NCCreate message anyway, so not sure how you could actually do this correctly...
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!
___________________________________________________________________________________
#13 Moderators - Reputation: 4633
Posted 19 October 2012 - 04:14 PM
I see how I expressed myself incorrectly. What I meant was that I compared your code with my own window code and I cannot see any difference in the basic structure of the code. When I run your code it works as you describe (in other words; doesn't work), but my own code works, so apparently there's something different that I just cannot see even when I compare the codes side by side.@ Brother Bob:
You're saying the same exact code works on your PC?
#14 Members - Reputation: 551
Posted 19 October 2012 - 04:21 PM
I see how I expressed myself incorrectly. What I meant was that I compared your code with my own window code and I cannot see any difference in the basic structure of the code. When I run your code it works as you describe (in other words; doesn't work), but my own code works, so apparently there's something different that I just cannot see even when I compare the codes side by side.
If it's not some sort of proprietary code would you mind showing me for me to examine and correct this problem?
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!
___________________________________________________________________________________
#15 Moderators - Reputation: 4633
Posted 19 October 2012 - 04:40 PM
#16 Moderators - Reputation: 4633
Posted 19 October 2012 - 05:45 PM
Joke aside, I found a difference: you set the window pointer when you receive the NCCREATE message, but I change it on the CREATE message. The NC-messages are sent before the non-NC messages to pass non-client (NC) messages to your window before the client are is set up. It could be that the window simply don't have any storage to store your pointer at that time, or that you are not allowed to store data there yet. In any case, I don't know why this makes a difference becuase you proceed to call DefWindowProc in the same order as me as far as I can see. Simply changing the pointer setup on the CREATE message instead of on the NCCREATE message seems to work just fine. You have to write your message router a bit different though.
I do it using two separate window handlers: one for the initial NC-messages and then I change handler once the CREATE message arrives.
LRESULT CALLBACK messagehandler::WndProcNC(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM lparam)
{
if(wmsg == WM_CREATE) {
LPCREATESTRUCT cs = reinterpret_cast<LPCREATESTRUCT>(lparam);
window *win = reinterpret_cast<window *>(cs->lpCreateParams);
SetWindowLongPtr(hwnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(win));
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
return WndProc(hwnd, wmsg, wparam, lparam);
} else {
return DefWindowProc(hwnd, wmsg, wparam, lparam);
}
}
LRESULT CALLBACK messagehandler::WndProc(HWND hwnd, UINT wmsg, WPARAM wparam, LPARAM lparam)
{
// handle window messages here as usual
}
The window class structure is registered with the WndProcNC function which processes NC-messages until CREATE is received. At that point, the window pointer is fetched from the create parameter and put into the window data, the window's message handler is swapped to WndProc, and finally the message is passed manually to WndProc for further processing.This method brings me to a problem with your method. If you just change it to set the window pointer on the CREATE message instead of the NCCREATE message, you will fall through the first if-statement and call you windows message handler on a null-pointer (or rather, throw the exception in that code path). You can either use my method and use separate message handlers for windows with and without pointer data (since the pointer data is set and the window handler is changed at the same time), or add some extra logic to your own method.
LRESULT CALLBACK Window::MsgRouter(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
Window* Wnd = reinterpret_cast<Window *>( GetWindowLongPtr( hWnd, GWLP_USERDATA ) );
if(Wnd == nullptr) {
if( msg == WM_CREATE ) {
SetWindowLongPtr( hWnd, GWLP_USERDATA, reinterpret_cast<LONG>( (LPCREATESTRUCT(lParam))->lpCreateParams) );
}
return DefWindowProc(hWnd, msg, wParam, lParam);
}
else
{
if( !Wnd )
throw new runtime_error( "No Window instance associated with HWND!" );
return Wnd->WndProc( msg, wParam, lParam );
}
}
The idea is the same as my method, as long as the window pointer is null, then you process messages in the if-statement; otherwise you have a window pointer and you process it in the else-statement.
Edited by Brother Bob, 19 October 2012 - 05:49 PM.
#17 Members - Reputation: 551
Posted 19 October 2012 - 07:14 PM
The first way won't even compile because of this line:
SetWindowLongPtr(hwnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(WndProc));
WndProc is member function of type Window, and no matter what I do I cannot obtain/use its address in calling SetWindowLongPtr... doesn't make sense to me...
"Error 1 error C2440: 'reinterpret_cast' : cannot convert from 'LRESULT (__cdecl Window::* )(UInt32,WPARAM,LPARAM)' to 'LONG_PTR' C:\Users\ATC\Documents\Visual Studio 2012\Projects\D3D11Tutorial01\D3D11Tutorial01\gamewnd.cpp 142 1 D3D11Tutorial01"
The second way compiles and runs but no window is created or show at all... just a loop running and I have to click Stop Debugging to exit...
Edited by ATC, 19 October 2012 - 07:29 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!
___________________________________________________________________________________
#18 Members - Reputation: 551
Posted 19 October 2012 - 07:52 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!
___________________________________________________________________________________
#19 Members - Reputation: 551
Posted 19 October 2012 - 08:19 PM
gamewnd.h ::
[source lang="cpp"]#pragma region Description/* gamewnd.h ::* Implements a game window class for DirectX applications.** Copyright © ATCWARE 2010, All Rights Reserved.*/#pragma endregion/*----------------------------------* INCLUDE DIRECTIVES ::*----------------------------------*/#pragma once#define WIN32_LEAN_AND_MEAN#include <atc_standards.h>#include <Windows.h>#include <list>#include <string>#include <stdexcept>using namespace std;/*----------------------------------* PREPROCESSOR DIRECTIVES ::*----------------------------------*/#define WND_CLASS_NAME_W L"GameWndClass"#define MAX_WINDOW_WIDTH 0x1000#define MAX_WINDOW_HEIGHT 0x1000/*-----------------------------------------------------------------------------** GLOBAL VARIABLES ::*-----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------** PROTOTYPES & FORWARD DECLARATIONS ::*-----------------------------------------------------------------------------*/enum WndState{ DEFAULT = 0x00, MAXIMIZED = 0x01, MINIMIZED = 0x02,};class Window{public: virtual void Show( ); virtual void Hide( ); virtual void Close( ); static void ClientToAbsSize( Int32* const pWidth, Int32* const pHeight ); static Window* Create( Int32 width, Int32 height, wstring title, HINSTANCE hInstance );protected: Window( ); ~Window( ); HWND hWnd; HINSTANCE hInstance; virtual LRESULT WndProc( UInt32 msg, WPARAM wParam, LPARAM lParam );private: static LRESULT CALLBACK MsgRouter( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );};/*-----------------------------------------------------------------------------*********************************************************************************-----------------------------------------------------------------------------*/[/source]
gamewnd.cpp ::
[source lang="cpp"]#pragma region Description/* gamewnd.cpp ::*** Copyright © ATCWARE 2010, All Rights Reserved.*/#pragma endregion/*----------------------------------* INCLUDE DIRECTIVES ::*----------------------------------*/#include "gamewnd.h"/*----------------------------------* PREPROCESSOR DIRECTIVES ::*----------------------------------*//*-----------------------------------------------------------------------------** GLOBAL VARIABLES ::*-----------------------------------------------------------------------------*//*-----------------------------------------------------------------------------** GameWndBase Implementation ::*-----------------------------------------------------------------------------*/Window::Window( ) { this->hInstance = 0x00; this->hWnd = 0x00;}Window::~Window( ) { this->Close();}void Window::Show( ) { ShowWindow( this->hWnd, SHOW_OPENWINDOW );}void Window::Hide( ) { ShowWindow( this->hWnd, HIDE_WINDOW );}void Window::Close( ) { CloseWindow( this->hWnd );}void Window::ClientToAbsSize( Int32* const pWidth, Int32* const pHeight ) { RECT rc = { 0, 0, *pWidth, *pHeight }; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); *pWidth = (rc.right - rc.left); *pHeight = (rc.bottom - rc.top);}Window* Window::Create( Int32 width, Int32 height, wstring title, HINSTANCE hInstance ) {#if DEBUG || PERFORM_CHECKS //! Validate arguments if( (width < 0) || (width > MAX_WINDOW_WIDTH) ) throw new invalid_argument( "Specified Window width out of range." ); if( (height < 0) || (height > MAX_WINDOW_HEIGHT) ) throw new invalid_argument( "Specified Window width out of range." ); if( !(title.data()) || (title.length() < 1) ) throw new invalid_argument( "Invalid Window title parameter." ); if( !hInstance ) throw new invalid_argument( "HINSTANCE parameter is NULL." );#endif Window* pWindow = new Window; pWindow->hInstance = hInstance; //! Store handle // Create & register window class :: WNDCLASSEX wndClass = { 0 }; wndClass.cbSize = sizeof( WNDCLASSEX ); wndClass.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wndClass.lpfnWndProc = Window::MsgRouter; wndClass.hCursor = LoadCursor( null, IDC_ARROW ); wndClass.style = (CS_VREDRAW | CS_HREDRAW); wndClass.hInstance = hInstance; wndClass.lpszMenuName = null; wndClass.lpszClassName = WND_CLASS_NAME_W; if( !RegisterClassEx( &wndClass ) ) throw new runtime_error( "Window registration failed!" ); // Calculate absolute window size :: Int32 abs_width = width, abs_height = height; ClientToAbsSize( &abs_width, &abs_height ); // Create the Win32 window :: HWND hWnd = CreateWindowW( WND_CLASS_NAME_W, title.data(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, abs_width, abs_height, null, null, hInstance, static_cast<LPVOID>( pWindow ) ); // Show the game window :: if( !hWnd ) throw new runtime_error( "Window creation failed!" ); return pWindow;}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_DESTROY: PostQuitMessage( 0x00 ); break; default: return DefWindowProc( this->hWnd, msg, wParam, lParam ); } return static_cast<LRESULT>( 0x00 );}LRESULT CALLBACK Window::MsgRouter( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam ) {#if DEBUG || PERFORM_CHECKS if( !hWnd ) throw invalid_argument( "Null window handle!" );#endif auto wnd = (Window *)null; if( Msg == WM_NCCREATE ) { // Get the Window pointer from lpCreateParams :: wnd = reinterpret_cast<Window *>( ((LPCREATESTRUCT)lParam)->lpCreateParams ); // Save our Window pointer and the valid HWND :: SetWindowLongPtr(hWnd, GWLP_USERDATA, reinterpret_cast<long>(wnd)); wnd->hWnd = hWnd; } else // Get Window pointer from our window info :: wnd = reinterpret_cast<Window *>( GetWindowLongPtrW( hWnd, GWLP_USERDATA ) ); return wnd->WndProc(Msg, wParam, lParam); //! Invoke Window::WndProc}/*-----------------------------------------------------------------------------*********************************************************************************-----------------------------------------------------------------------------*/[/source]
Enjoy! BTW, I know it says "Copyright" in the description section but that's just because my default .h, .cpp, .c, etc file templates automatically format the code files that way. So disregard the copyright notice; you're free to use this code.
Regards,
--ATC--
EDIT:
For some reason the code block feature on the forums makes anything enclosed in <> braces disappear, so it screws up C/C++ include directives and C# generics, for example. The includes for gamewnd.h are:
#include <atc_standards.h>
#include <Windows.h>
#include <list>
#include <string>
#include <stdexcept>
Edited by ATC, 19 October 2012 - 08:25 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!
___________________________________________________________________________________
#20 Members - Reputation: 551
Posted 19 October 2012 - 11:07 PM
The SetWindowTextW and SetWindowTextA functions flat out don't work... they do NOTHING... And just to make sure it wasn't a bad HWND handle at fault I tried this:
SetWindowPos( hWnd, null, 700, 700, width, height, null );
...and it worked exactly as expected! So I know my handle is good. But why won't SetWindowText work? I've used this function a million times in the past, even called in from C# with P/Invoke and it always worked. Why is it not working now? Even if I just hard-code something like:
SetWindowTextW( hWnd, L"WTF!?" );
...even that doesn't work!
Any ideas?
EDIT:
Even more odd is that my Window gets the WM_SETTEXT message if I call SetWindowText, but still, nothing happens... the text remains untouched...
Edited by ATC, 19 October 2012 - 11:08 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!
___________________________________________________________________________________






