Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

 
Advanced search

1044490 Posts in 42327 Topics- by 34013 Members - Latest Member: azdak

September 21, 2014, 10:08:46 AM
TIGSource ForumsDeveloperTechnical (Moderators: Glaiel-Gamer, ThemsAllTook)Creating a win32 window
Pages: [1] 2
Print
Author Topic: Creating a win32 window  (Read 1566 times)
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« on: May 08, 2013, 07:47:27 AM »

Hey there.

What I would like is not an ordinary win32 window which we can get by making a new project with template set properly in MSVC++. I can't seem to find the solution Huh?

Say, I have a console application,

Code:
#include <windows>

int main(int argc, char* argv[]) {
    return 0;
}

Now, how can I create a new window handle from main function? (Bonus points for OpenGL context)

Cheers!
Logged

Nothing to do here
zacaj
Level 3
***


void main()


View Profile WWW Email
« Reply #1 on: May 08, 2013, 07:51:14 AM »

Code:
struct VideoProperties//todo multiple window support
{
uint x,y;
    uint w; ///< The width (in pixels) of the current display
    uint h; ///< The height (in pixels) of the current display
    uint bpp; ///< The Bits Per Pixel (NOT bytes) of the current display \warning IT IS NOT BYTES
    float aspect; ///< The Aspect Ratio of the current display (w/h)
    float inverseAspect; ///< Inverse of \a asoect (h/w)
bool fullscreen; ///< Signifies whether the current display is fullscreen
bool vsync; ///< Signifies whether the current display has V-Sync
#ifdef USE_WIN
HGLRC hrc; // Rendering context
HDC hdc; // Device context
HWND hwnd; // Window identifier
HINSTANCE hInstance;
#endif
} videoProperties;
int main(int argc,char **argv)
{
videoProperties.x=640;
videoProperties.y=220;
videoProperties.w=800;
videoProperties.h=600;
videoProperties.bpp=32;
videoProperties.fullscreen=0;
videoProperties.vsync=0;
videoProperties.aspect=-1;
videoProperties.inverseAspect=-1;
vec2i originalSize(videoProperties.w,videoProperties.h);
if(videoProperties.aspect==-1)
videoProperties.aspect=(float)videoProperties.w/(float)videoProperties.h;
if(videoProperties.inverseAspect==-1)
videoProperties.inverseAspect=(float)videoProperties.h/(float)videoProperties.w;

VideoProperties &vp=videoProperties;
vp.hInstance=GetModuleHandle(NULL);
WNDCLASS windowClass;
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc = (WNDPROC) WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = vp.hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
#ifdef MSVC
windowClass.lpszClassName = L"Engine";
#else
windowClass.lpszClassName = "Engine";
#endif

if (!RegisterClass(&windowClass)) {
error("Could not register WNDCLASS!",0);
return 1;
}
vp.hwnd = CreateWindowExW(WS_EX_APPWINDOW | WS_EX_WINDOWEDGE, L"Engine", L"Engine", WS_OVERLAPPEDWINDOW,
vp.x, vp.y,vp.w, vp.h, NULL, NULL, vp.hInstance, NULL);

vp.hdc=GetDC(vp.hwnd);
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
int depthBits=32;
formatTry:
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = vp.bpp; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = depthBits; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD

int nPixelFormat = ChoosePixelFormat(vp.hdc, &pfd); // Check if our PFD is valid and get a pixel format back
if (nPixelFormat == 0) // If it fails
{
if(depthBits==8)
{
error("Could not create pixel format : %ix%i\n",vp.bpp,32);
return 1;
}
warn("Could not create pixel format with %i depth bits\n",depthBits);
depthBits-=8;
goto formatTry;//OMG, a goto!
}
if(!SetPixelFormat(vp.hdc, nPixelFormat, &pfd)) // Try and set the pixel format based on our PFD
{
error("Could not set pixel format (%i bpp)\n",vp.bpp);
return 1;
}
print("Created %ix%i pixel format\n",vp.bpp,depthBits);
HGLRC OpenGLContext = wglCreateContext(vp.hdc); // Create an OpenGL 2.1 context for our device context
wglMakeCurrent(vp.hdc, OpenGLContext); // Make the OpenGL 2.1 context current and active

ShowWindow(vp.hwnd,5);
UpdateWindow(vp.hwnd);
Just torn out of my engine without testing, but hopefully should help you out
Logged

My twitter: @zacaj_

Quote from: mcc
Well let's just take a look at this "getting started" page and see--
Quote
Download and install cmake
Noooooooo
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #2 on: May 08, 2013, 12:09:30 PM »

Hmm, seems like I can't see that window. Crazy
Not sure where the error might lay.

The code:

Code:
#if defined(_WIN32)
hInstance=GetModuleHandle(NULL);
WNDCLASS windowClass;
windowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
windowClass.lpfnWndProc = (WNDPROC)WndProc;
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = hInstance;
windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
windowClass.hCursor = LoadCursor(NULL, IDC_ARROW);
windowClass.hbrBackground = NULL;
windowClass.lpszMenuName = NULL;
#ifdef MSVC
windowClass.lpszClassName = L"BlueKit";
#else
windowClass.lpszClassName = "BlueKit";
#endif

if (!RegisterClass(&windowClass)) {
MessageBox(NULL,L"Could not register WNDCLASS",L"ERROR",MB_OK);
return;
}
hwnd = CreateWindow(L"BlueKit", s2ws(title).c_str(), WS_OVERLAPPEDWINDOW, x, y, width, height, NULL, NULL, hInstance, NULL);

hdc=GetDC(hwnd);
PIXELFORMATDESCRIPTOR pfd; // Create a new PIXELFORMATDESCRIPTOR (PFD)
int depthBits=32;
formatTry:
memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR)); // Clear our  PFD
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); // Set the size of the PFD to the size of the class
pfd.dwFlags = PFD_DOUBLEBUFFER | PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW; // Enable double buffering, opengl support and drawing to a window
pfd.iPixelType = PFD_TYPE_RGBA; // Set our application to use RGBA pixels
pfd.cColorBits = 32; // Give us 32 bits of color information (the higher, the more colors)
pfd.cDepthBits = depthBits; // Give us 32 bits of depth information (the higher, the more depth levels)
pfd.iLayerType = PFD_MAIN_PLANE; // Set the layer of the PFD

int nPixelFormat = ChoosePixelFormat(hdc, &pfd); // Check if our PFD is valid and get a pixel format back
if (nPixelFormat == 0) // If it fails
{
if(depthBits==8)
{
MessageBox(NULL,L"Could not create pixel format 32x32",L"ERROR",MB_OK);
return;
}
fprintf(stderr,"Could not create pixel format with %i depth bits\n",depthBits);
depthBits-=8;
goto formatTry;//OMG, a goto!
}
if(!SetPixelFormat(hdc, nPixelFormat, &pfd)) // Try and set the pixel format based on our PFD
{
MessageBox(NULL,L"Could not set pixel format (32 bpp)",L"ERROR",MB_OK);
return;
}
HGLRC OpenGLContext = wglCreateContext(hdc); // Create an OpenGL 2.1 context for our device context
wglMakeCurrent(hdc, OpenGLContext); // Make the OpenGL 2.1 context current and active
ShowWindow(hwnd,SW_SHOW);
UpdateWindow(hwnd);
#endif
Logged

Nothing to do here
zacaj
Level 3
***


void main()


View Profile WWW Email
« Reply #3 on: May 08, 2013, 12:19:23 PM »

Can I see your WndProc and main loop?  I don't see anything wrong with the code you posted (although maybe I'm just missing it too)
Logged

My twitter: @zacaj_

Quote from: mcc
Well let's just take a look at this "getting started" page and see--
Quote
Download and install cmake
Noooooooo
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #4 on: May 08, 2013, 12:23:59 PM »

Sure.

WndProc:

Code:
LRESULT CALLBACK Window::WndProc(HWND hWindow, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
Window::isRunning = false;
break;

default:
return DefWindowProc(hwnd, msg, wParam, lParam);
break;
}
return 0;
}

Main loop:

Code:
int main(int argc, char* argv[])
{
BlueKit::Window::Init(800,600,"BlueKit tests",0,BlueKit::Window::POS_CENTERED,0,0);
while(BlueKit::Window::isRunning)
{
BlueKit::Window::SwapBuffers();
}
return 0;
}
Logged

Nothing to do here
zacaj
Level 3
***


void main()


View Profile WWW Email
« Reply #5 on: May 08, 2013, 02:49:58 PM »

I assume in SwapBuffers you're calling SwapBuffers(hdc)?

Do you do this anywhere in the loop?
Code:
MSG   msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
Logged

My twitter: @zacaj_

Quote from: mcc
Well let's just take a look at this "getting started" page and see--
Quote
Download and install cmake
Noooooooo
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #6 on: May 08, 2013, 03:28:35 PM »

Quote
I assume in SwapBuffers you're calling SwapBuffers(hdc)?

Yes.

Quote
Do you do this anywhere in the loop?
[..]

Aw, forgot to add that one.

Now BlueKit::Window::SwapBuffers(); looks like this:

Code:
MSG   msg;
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
SwapBuffers(hdc);

And the above is basically my main loop right now. Yet cannot see the window for some reason.
Logged

Nothing to do here
zacaj
Level 3
***


void main()


View Profile WWW Email
« Reply #7 on: May 08, 2013, 04:01:39 PM »

I'm stumped
Logged

My twitter: @zacaj_

Quote from: mcc
Well let's just take a look at this "getting started" page and see--
Quote
Download and install cmake
Noooooooo
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW Email
« Reply #8 on: May 08, 2013, 04:31:10 PM »

If it helps, the source code to my project contains code to do all this.  I will answer questions if you like.
Logged

Franchise - The restaurant wars begin!

What would John Carmack do?
powly
Level 3
***



View Profile WWW
« Reply #9 on: May 08, 2013, 05:24:11 PM »

pfd.nVersion = 1;

Else I'd just start dropping stuff, you seem to define everything in there and most of it isn't necessary.

Also, do you set that isRunning as true somewhere?
« Last Edit: May 08, 2013, 05:30:43 PM by powly » Logged
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #10 on: May 09, 2013, 12:04:23 AM »

If it helps, the source code to my project contains code to do all this.  I will answer questions if you like.

I have read through window_main.h and window_main.c (or something similar) from under windows folder, but didn't spot any differences between what you do, and what zacaj does. (since I am using his code at the moment)

pfd.nVersion = 1;

Else I'd just start dropping stuff, you seem to define everything in there and most of it isn't necessary.

Also, do you set that isRunning as true somewhere?

Adding pfd.nVersion didn't help either. Yep, isRunning is set to true on the end of window creation. I have also put a breakpoint inside my main loop to see if it's executed, and it is.

I might just try dropping stuff as you mentioned, though, I am not sure if it can help here Droop
Logged

Nothing to do here
Xienen
Level 3
***


Greater Good Games


View Profile WWW
« Reply #11 on: May 09, 2013, 03:07:40 AM »

Just read this on the bottom of the Microsoft page for the RegisterClass function:

Quote
This function seems to rearrange the WndClass structure to a WndClassEx structure and eventually calls RegisterClassEx().


Missing to zero-out some unused structure members may lead to CreateWindowEx(), not RegisterClass(), to fail with some unexpected GetLastError() code.

Try changing to WNDCLASSEX and RegisterClassEx.  The only thing you actually need to add after you memset it is
windowclass.cbSize = sizeof(WNDCLASSEX);
Logged

kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #12 on: May 09, 2013, 03:30:16 AM »

That doesn't actually work.

Maybe I should've mentioned that window creation function is inside a static library? Because, when I copy that code and paste it into int main(..), it works. Weird?
Logged

Nothing to do here
soryy708
Level 3
***


Where is my tea?


View Profile Email
« Reply #13 on: May 09, 2013, 06:00:06 AM »

Why not use SDL?
Logged

Portfolio:
  • Cacto Loco! - 'Additional Tunes' (Composer)
  • To be continued...
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #14 on: May 09, 2013, 06:15:03 AM »

Because when I'd want to port my library to something else than decent platforms, it starts to be much of a trouble.
Logged

Nothing to do here
Xienen
Level 3
***


Greater Good Games


View Profile WWW
« Reply #15 on: May 09, 2013, 06:16:37 AM »

That doesn't actually work.

Maybe I should've mentioned that window creation function is inside a static library? Because, when I copy that code and paste it into int main(..), it works. Weird?

I've run into that issue before.  I believe it has something to do with the WinProc needing to be built in the executable rather than in a library...maybe?  I can't remember
Logged

soryy708
Level 3
***


Where is my tea?


View Profile Email
« Reply #16 on: May 09, 2013, 06:31:59 AM »

Uh... You're talking about portability but using win32? Hmm... Does not compute.
Logged

Portfolio:
  • Cacto Loco! - 'Additional Tunes' (Composer)
  • To be continued...
kamac
Level 10
*****


Notorious posts editor


View Profile Email
« Reply #17 on: May 09, 2013, 06:45:09 AM »

Uh... You're talking about portability but using win32? Hmm... Does not compute.

Please, why does there always have to be one person who enters a thread and wants to know why I don't want to use something they'd prefer?
And that happens to almost any technical thread on tigsource, but I have already made my choice, I considered alternatives like glfw, SFML, SDL and so forth, but I have picked this way for a reason.

If you want to know so badly what that reason is, then I am happy to say that I want to:
A) Get more comfortable with Win32 API
B) Be less dependant on 3rd party libraries
C) Create a framework on my own

Also,

Quote
You're talking about portability but using win32?

Yes?

Code:
#if defined(_WIN32)
//.. win32 code
#endif
#if defined(__linux)
//.. linux code
#endif
#if defined(__APPLE__)
//.. apple code
#endif

That's what I am using. Seems quite portable to me. Alternatively, I could've make separate libraries for platforms of choice, but instead I prefer to have that all in once place, so I don't end up surrounded with libraries.
Logged

Nothing to do here
Xienen
Level 3
***


Greater Good Games


View Profile WWW
« Reply #18 on: May 09, 2013, 08:42:44 AM »

If you want to know so badly what that reason is, then I am happy to say that I want to:
A) Get more comfortable with Win32 API
B) Be less dependant on 3rd party libraries
C) Create a framework on my own

...

That's what I am using. Seems quite portable to me. Alternatively, I could've make separate libraries for platforms of choice, but instead I prefer to have that all in once place, so I don't end up surrounded with libraries.

Hear hear!  If you could be so kind, soryy, just let this one go.  Some of us just prefer to build things ourselves to learn more about them even if it doesn't "make sense" to others.
Logged

Crimsontide
Level 3
***


View Profile
« Reply #19 on: May 09, 2013, 12:18:21 PM »

I've run into that issue before.  I believe it has something to do with the WinProc needing to be built in the executable rather than in a library...maybe?  I can't remember

I've been able to put the WinProc function in a library and statically link it.  Never tried with a dll and dynamic linkage though.  Perhaps the library has different compiler options that don't mesh with the main program?
Logged
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic