Win32 Window Issue (C++)

Started by
11 comments, last by Zoner 12 years, 10 months ago
I was wondering if anyone could help me out with a little problem I am having.

I started a new empty Windows C++ project in Visual Studio 2010. I added, what I've known to be, the basic code for getting a window up and running with a simple message loop. Already I am having an unusual issue with my window. When I launch the program my window appears but I always get the busy cursor icon. I have no control over minimizing/maximizing/moving/etc. the window. Has anyone ever seen this happen? I'm on Windows 7 if it makes any difference.

From what I can tell this looks no different than any other Windows program I have written...

One thing I tried was to use the basic Windows C++ project template instead of empty. That seemed to work well. The only thing they seemed to do different is use TranslateAccelerator, which I have never used before, instead of PeekMessage.


#include <Windows.h>

//Forward declarations
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND CreateAndRegisterWindow(const char* name);

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
HWND hWnd = CreateAndRegisterWindow("Sandbox");
if(hWnd == NULL)
{
MessageBox(NULL, "Error!", "Unable to create and register the Sandbox window", MB_ICONERROR);
return -1;
}

MSG msg = { };
while(msg.message != WM_QUIT)
{
//Process current window messages
if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
}
}

return static_cast<int>(msg.wParam);
}

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_DESTROY:
{
PostQuitMessage(0);
}
return 0;

case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);

FillRect(hdc, &ps.rcPaint, reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1));
EndPaint(hWnd, &ps);
}
return 0;
}

return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

HWND CreateAndRegisterWindow(const char* name)
{
//Register the window class.
WNDCLASS wc = { };
wc.lpfnWndProc = WindowProc;
wc.lpszClassName = name;

RegisterClass(&wc);

//Create the window
HWND hWnd = CreateWindowEx(
0,
name,
name,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL,
NULL,
NULL,
NULL);

if(hWnd == NULL)
{
return NULL;
}

ShowWindow(hWnd, SW_SHOWDEFAULT);
return hWnd;
}
Advertisement
You need to set a valid class cursor in your WNDCLASS. If you set it to NULL (which you do) Windows displays the busy cursor.


The default is usually LoadCursor( NULL, IDC_ARROW );

Fruny: Ftagn! Ia! Ia! std::time_put_byname! Mglui naflftagn std::codecvt eY'ha-nthlei!,char,mbstate_t>


You need to set a valid class cursor in your WNDCLASS. If you set it to NULL (which you do) Windows displays the busy cursor.


The default is usually LoadCursor( NULL, IDC_ARROW );


Sorry, forgot to mention, I do have that set up in my current code base. I'm away from my main computer so I had to pull from my last commit to my repository. My WNDCLASS looks more like this:


wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
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(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = name;
Looks like you're missing an UpdateWindow call to pair with that ShowWindow call...
There is nothing wrong with your code above except the mentioned window class cursor thing. I compiled it and it works fine.

What exactly do you mean "I have no control over minimizing/maximizing/moving/etc. the window."? Maybe you're running a different maybe older version of the exe than the one whose code you posted?


You need to set a valid class cursor in your WNDCLASS. If you set it to NULL (which you do) Windows displays the busy cursor.


that is not correct, from personel experiance.
it uses the default windows arrow.

Never say Never, Because Never comes too soon. - ryan20fun

Disclaimer: Each post of mine is intended as an attempt of helping and/or bringing some meaningfull insight to the topic at hand. Due to my nature, my good intentions will not always be plainly visible. I apologise in advance and assure you I mean no harm and do not intend to insult anyone.


There is nothing wrong with your code above except the mentioned window class cursor thing. I compiled it and it works fine.

What exactly do you mean "I have no control over minimizing/maximizing/moving/etc. the window."? Maybe you're running a different maybe older version of the exe than the one whose code you posted?




What I mean is that I get the busy cursor (I'm on Windows 7 so the spinning doughnut). When I attempt to grab the title bar I can not move the window. When I try to press minimize or maximize nothing happens, and when I try to press the close icon nothing happens. Same thing when I attempt to grab the edge of the window in order to resize. Now I understand I may have turned off some of those features with my window setup, but I'm pretty sure I should at minimum be able to close the window and move it around by the title bar.

Edit: The code I have posted + the update to my WNDCLASS in the other post is currently what I am building and running.

[quote name='Endurion' timestamp='1307039681' post='4818789']
You need to set a valid class cursor in your WNDCLASS. If you set it to NULL (which you do) Windows displays the busy cursor.


that is not correct, from personel experiance.
it uses the default windows arrow.
[/quote]

No it doesn't. It doesn't display the busy cursor either. It simply doesn't change it.


If the cursor member of the window class is set to NULL, and the application doesn't take charge of setting the mouse cursor itself (for example, in the window's message processor procedure in response to WM_SETCURSOR), then the operating system will not set the cursor for you. What this means is the cursor will remain the same as it was before it entered the window's client area. That's why if you move the cursor to the outer frame of the window as if you want to resize it, then bring it back inside the client area, the cursor will still look like the "sizing" cursor. Note that the default window procedure handles setting the cursor when the mouse is in the non-client area.

In fact, the default window procedure's response to WM_SETCURSOR is to set the cursor to whatever it is that is assigned to the hCursor member of the window class structure.

Are you running the EXE standalone? What happens if you attach a debugger and break execution? Where does it indicate that execution is halting, if anywhere specific?

It sounds suspiciously like your message pump is not working and/or your window procedure is not deferring to DefWindowProc() correctly; either of those two situations can lead to behaviour like what you describe, although there may well be other causes as well.

Strip your code down to a minimal example that reproduces the problem, and post it in its entirety; your code as described works fine for me on Win7 32-bit. If you're positive that there's no difference between the code you're compiling and what's posted here, and a full clean/rebuild of your EXE doesn't help, try just starting a new project from scratch. Could be that some compiler setting or option got borked and now something is screwy.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]


Are you running the EXE standalone? What happens if you attach a debugger and break execution? Where does it indicate that execution is halting, if anywhere specific?

It sounds suspiciously like your message pump is not working and/or your window procedure is not deferring to DefWindowProc() correctly; either of those two situations can lead to behaviour like what you describe, although there may well be other causes as well.

Strip your code down to a minimal example that reproduces the problem, and post it in its entirety; your code as described works fine for me on Win7 32-bit. If you're positive that there's no difference between the code you're compiling and what's posted here, and a full clean/rebuild of your EXE doesn't help, try just starting a new project from scratch. Could be that some compiler setting or option got borked and now something is screwy.


I am running the EXE through my debugger, it doesn't indicate the execution is halting in any specific place. I threw in some rendering code at one point that rendered my FPS and MSPF and those all updated and rendered properly.

The current code I am compiling is what I posted.

I guess when I get home tonight I'll trash the project and try starting from scratch again. Thanks for your help.

This topic is closed to new replies.

Advertisement