Jump to content
  • Advertisement
Sign in to follow this  
Irlan Robson

Win32 Window Creation

This topic is 1504 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

I'm creating an Win32 Window to serve as the primary surface to make DirectX and OpenGL calls. The problem is that is more intuitive to create the window first, initialize the API and load graphics resources (Shaders, Textures, Vertex Streams), and after that start with the simulation loop, but I don't know that if there is some internal problem - maybe with the Windows platform - in this create-load-show interval. Another thing is that I'm using the main thread to bufferize keyboard events. Eg.:

/*
* Initialize and Win32 Window to be showed later.
*/

BOOL CWindow::Init(const std::wstring& _sTitle, unsigned int _ui32Width, unsigned int _ui32Height, bool /*_bFullscreen*/) {
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_OWNDC;
	wcex.lpfnWndProc = CWindow::WndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = ::GetModuleHandle(NULL);
	wcex.hIcon = NULL;
	wcex.hCursor = ::LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = _sTitle.c_str();
	wcex.hIconSm = ::LoadIcon(NULL, IDI_APPLICATION);

	if ( !::RegisterClassEx(&wcex) ) { return false; }

	m_hWnd = ::CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, wcex.lpszClassName, wcex.lpszClassName,
		WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 
		CW_USEDEFAULT, CW_USEDEFAULT, _ui32Width, _ui32Height, 
		NULL, NULL, wcex.hInstance, reinterpret_cast<LPVOID>(this) );

	return m_hWnd ? true : false;
}

Looks more intuitive than the create-show-load approach, but I don't know if I'm going to lose window events in the interval of the above implementation so after the initialization I can call:

 

int CWindow::Run() {
::SetThreadPriority(::GetCurrentThread(), THREAD_PRIORITY_HIGHEST);


MSG msg = { 0 };
while (m_bIsOpen) {
::WaitMessage();
while (::PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE)) {
::DispatchMessage(&msg);
}
}
return static_cast<int>(msg.wParam);
}

 

At the highest level:

m_wWindow.Init(...);
CGraphics::InitApi( m_wWindow.Hwnd() );
m_wWindow.Show(...);
m_wWindow.Run();
Edited by Irlan

Share this post


Link to post
Share on other sites
Advertisement
FWIW there is literally no good reason I can think of to use raw Win32 rather than something like SDL2. It'll save you a lot of pain, also let you be more portable, and is used increasingly frequently in the AAA space. Some of the framework libraries are GL-only but SDL2 can easily be used with D3D for sure (as come some of the others).

Share this post


Link to post
Share on other sites

FWIW there is literally no good reason I can think of to use raw Win32 rather than something like SDL2. It'll save you a lot of pain, also let you be more portable, and is used increasingly frequently in the AAA space. Some of the framework libraries are GL-only but SDL2 can easily be used with D3D for sure (as come some of the others).

The reason that I don't use these kind of libraries is that I want to have full control of what I am doing at the lower level possible for me. I've posted this specific problem but everything else is working fine - OpenGL and DirectX support, etc. From what I've read from the Microsoft Win32 Documentation, it says nothing related the problem I am having.

Share this post


Link to post
Share on other sites
To be honest. I don't know, but what I do recommend is rather choosing a different way of doing this. I recommend trying out and consider using the Delphi Programming Languages which is the best language to create Windows applications out there.

Share this post


Link to post
Share on other sites

To be honest. I don't know, but what I do recommend is rather choosing a different way of doing this. I recommend trying out and consider using the Delphi Programming Languages which is the best language to create Windows applications out there.

I disagree. What you have said is totally off-topic. The standard language - not the obrigatory one - to create applications - in my case an Game Engine - that use OpenGL or DirectX as the main Graphics Library API is the C++ Language if the platform you're targeting is Windows.

Edited by Irlan

Share this post


Link to post
Share on other sites

I'm not sure if you're saying there is a problem, or if you're asking if there might be a problem.

 

It sounds like you are worried that you could possibly be lose some events between "m_wWindow.Init(...);" and "m_wWindow.Run();".

Aren't the events buffered up and stored for you until you process them? How long does 'InitApi()' take to run? Are you doing alot of heavy resource loading, or are you delaying your resource loading until after Run() begins?

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites

I'm not sure if you're saying there is a problem, or if you're asking if there might be a problem.

 

It sounds like you are worried that you could possibly be lose some events between "m_wWindow.Init(...);" and "m_wWindow.Run();".

Aren't the events buffered up and stored for you until you process them? How long does 'InitApi()' take to run? Are you doing alot of heavy resource loading, or are you delaying your resource loading until after Run() begins?

Yeah, Mouse and Keyboard events for instance just get added to the Win32 Queue if I have an window that is currently on focus. Since I'm not showing the window in this interval this is not a problem. The same applies to WM_PAINT messages because I'm rendering from an different thread and just after the window is created and showed that I make an draw call.

 

I am using this approach and I have no problem, but I know that the internal Win32 Message Queue is a mystery unrevealed. Also I'm not having any syncronization issues with DirectX and OpenGL. I know that the correct way of doing this is to initialize the Graphics Library API after the WM_CREATE message, but for the sake of clarity Is better use what I've posted. Another reason is that sometimes there is an delay between the created window and the image to be displayed, so the window gets displayed while loading API resources. In my current setup immediatly my objects gets displayed on the screen without having an delay! smile.png

Edited by Irlan

Share this post


Link to post
Share on other sites
Each application has its own event queue. Events are not removed from it unless you remove them yourself (Yes, I'm intentionally ignoring the dusty corners of the API and hooks that change this).

They'll be waiting in your queue while you do whatever it is you need to to setup.

However, please note that not pumping your message queue for a length of time will cause Windows to assume you've frozen and grey the window out, put "not responding" in the title, and may ask the user if they want to terminate. So you should probably be processing your messages while you do whatever lengthy task you're doing on startup.

Share this post


Link to post
Share on other sites

Each application has its own event queue. Events are not removed from it unless you remove them yourself (Yes, I'm intentionally ignoring the dusty corners of the API and hooks that change this).

They'll be waiting in your queue while you do whatever it is you need to to setup.

However, please note that not pumping your message queue for a length of time will cause Windows to assume you've frozen and grey the window out, put "not responding" in the title, and may ask the user if they want to terminate. So you should probably be processing your messages while you do whatever lengthy task you're doing on startup.

I know. I've spend quite a lot of time with the Win32 API, but I don't know every possible type of WM_X message. The  Win32 Window Initialization and the Win32 Message Pump are single threaded. Now I'm going to assume the following pseudo-code:

 

The standard way:

 

CreateWindow() ->

ShowWindow() ->

InitializeGraphicsAPI() ->

LoadGraphicsResources() /*The window will be showed while I'm loading the resources. */ ->

StartSimulationLoop()

 

What I really need:

 

CreateWindow() -> 

InitializeGraphicsAPI() -> 

LoadGraphicsResources() ->

ShowWindow() /*Alright, I can see my rendered image immediately after the window gets showed.*/ -> 

StartGameSimulation()

Share this post


Link to post
Share on other sites


What I really need:

CreateWindow() ->
InitializeGraphicsAPI() ->
LoadGraphicsResources() ->
ShowWindow() /*Alright, I can see my rendered image immediately after the window gets showed.*/ ->
StartGameSimulation()

 

I'm not sure if this answers your concern:

 

In CreateWindow(), after the window is created, call:

ShowWindow( hWnd, SW_HIDE );

 

Your ShowWindow() is then:

ShowWindow( hWnd, SW_SHOW );

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!