Jump to content
  • Advertisement
Sign in to follow this  
golopart

win32: cursor not updating in client area

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

Okay, I have a simple app, built with the basic essentials to open up a window with the WS_OVERLAPPEDWINDOW attribute. When you drag the the cursor from outside the window over the border and into the client area of the window, it picks up whatever cursor pertains to that part that you crossed (for a side border it's the "adjust, double-pointed arrow thing"), and keeps that cursor picture when the cursor arrives in the client area. What needs to be done to change the cursor when entering the client area? Am I not catching a certain window message and updating? I don't want to post my code, b/c it's embarassingly messy, but here's what matters: I'm using PeekMessage with PM_REMOVE, I'm calling TranslateMessage then DispatchMessage (which probably are irrelevant to the problem). The window is created with CreateWindowEx, without using the Exstyle parameter, just the old style parameter with WS_OVERLAPPEDWINDOW. And I'm using RegisterClassEx to register the window class. I'm calling ShowWindow and SetFocus, and like loading a cursor or not doesn't matter, calling ShowCursor after SetFocus doesn't seem to matter. Then the Message Loop begins. In WndProc i'm only catching WM_PAINT and WM_DESTROY. And in WM_PAINT I'm calling BeginPaint and EndPaint with the hwnd sent to the WindowProc. [Edited by - golopart on January 7, 2005 8:31:56 PM]

Share this post


Link to post
Share on other sites
Advertisement
The only thing i can think of is WM_SIZE or WM_PAINT that could be causing this. When creating the window class (WNDCLASS) set the style parameter to
CS_HREDRAW | CS_VREDRAW
and OR it with whatever you have there. BeginPaint and EndPaint should be fine as they should validate the whole region again, make sure you return 0 after performing the draw.

If that isn't it i can dig through some of my old windowing code

HTH

EDIT: are you ever getting the paint message?

Share this post


Link to post
Share on other sites
Thanks for your apt replies.

[x] checked all constants (made sure they're correct)
[x] CS_VREDRAW | CS_HREDRAW
[x] returning 0 after each message, except for DefWindowProc (where it returns whatever it decides)
[x] getting paint messages (b/c when paint code is taken out, the window is drawn), but I'll check real quick and make sure...

Share this post


Link to post
Share on other sites
Here's a link to the exe: ddapp1.exe
I'll get the code ready to show so you can look at it. The problem doesn't occur when you drag the cursor fast enough over the border, but I guess if you're moving slow enough for whatever to capture the mouse at a point on the border, then it will happen. You may not want to keep this running unattended because it uses 95% cpu time. (And turns my laptop into a heater [smile])

edit: hold on, that exe has the message box pop up on WM_PAINT message, let me post it without that...

Share this post


Link to post
Share on other sites
I have a hunch, though it may be incorrect, that you aren't setting the cursor in the WinMain() function. Check for a line similar to this:

//cursor
wcx.hCursor=LoadCursor(NULL,IDC_ARROW);


For reference, wcx is type WINDOWCLASSEX.

-Greven

Share this post


Link to post
Share on other sites
This probably doesn't compile; it's just pseudo C:

#include <windows.h>

int Handle_messages(void);
int CALLBACK Wnd_proc(UINT u_msg, HWND hwnd, WPARAM w_param, LPARAM l_param);

// globals
HWND g_hwnd;
char* g_class_name = "DDAPP1\0";
char* g_window_title = "Direct Draw Application 1\0";
PAINTSTRUCT g_paint_struct;
MSG g_msg;
WNDCLASSEX g_wnd_class = {
sizeof(WNDCLASSEX),
CS_HREDRAW | CS_VREDRAW,
(LPFNWNDPROC)Wnd_proc,
0, 0, 0, 0, 0, 0, 0,
g_class_name,
0
};

// this prototype wouldn't make a win32 app in MSVC, I don't think...
int Win_main(void) {
g_wnd_class.hInstance = GetModuleHandle(NULL);
g_wnd_class.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
RegisterClassEx(&g_wnd_class);
g_hwnd = CreateWindowEx(
0, // dwExStyle
g_class_name,
g_window_title,
WS_OVERLAPPEDWINDOW,
0, 0, // x, y
800, 600, // width, height
0, 0, // cbsExtra... blah blah
g_wnd_class.h_instance,
NULL // uneeded: ptr to window-creation data
);
ShowWindow(g_hwnd, SW_SHOWDEFAULT);
SetFocus(TRUE);
int ret;
Message_loop:
ret = Handle_messages();
if (ret != 0) {
goto Message_loop;
}
ExitProcess(0);
}

int Handle_messages(void) {
// if hWnd param of PeekMessage isn't 0, annoying bug occurs (!!!)
if (PeekMessage(&g_msg, NULL, 0, 0, PM_REMOVE) != 0) {
// we got a message, check for quit
if (g_msg.message == WM_QUIT) {
// PostQuitMessage not really needed for my app
PostQuitMessage(g_msg.w_param);
return 0;
}
// else process message
TranslateMessage(&g_msg);
DispatchMessage(&g_msg);
}
return 1; // return non-zero value to continue
}

/* The below code in assembly tries best to emulate a switch(u_msg) { case...
* statement, so that breaks end in exiting the statement, but in assembly they
* are jumps out of it. The calling of DefWindowProc as shown by simple
* examples off MSDN is also emulated.
*/

int CALLBACK Wnd_proc(UINT u_msg, HWND hwnd, WPARAM w_param, LPARAM l_param) {
if (u_msg == WM_PAINT) {
goto WM_paint;
}
// essentially else-if
if (u_msg == WM_KEYDOWN) {
goto WM_key_down;
}
if (u_msg == WM_DESTROY) {
goto WM_destroy;
}
// default case: return whatever it does
return DefWindowProc(u_msg, hwnd, w_param, l_param);

WM_paint:
BeginPaint(&g_paint_struct);
EndPaint(&g_paint_struct);
goto Break;
WM_key_down:
if (w_param != VK_ESCAPE) {
goto Break;
}
PostQuitMessage(0);
goto Break;
WM_destroy:
PostQuitMessage(0);
goto Break;
Break:
return 0;
}

// That's it.





Share this post


Link to post
Share on other sites
Quote:
Original post by Evil_Greven
I have a hunch, though it may be incorrect, that you aren't setting the cursor in the WinMain() function. Check for a line similar to this:

//cursor
wcx.hCursor=LoadCursor(NULL,IDC_ARROW);


For reference, wcx is type WINDOWCLASSEX.

-Greven

This isn't required I don't think for you app to have a default cursor. Despite that, I did try this and I'll try again to make sure :)

Edit: Despite what I just stated, I found this in the Win32 API docs:
Quote:

hCursor

Identifies the class cursor. This member must be a handle of a cursor resource. If this member is NULL, an application must explicitly set the cursor shape whenever the mouse moves into the application's window.

So maybe that's it. I'll try "setting the cursor shape" or loading one from teh beginning (again).

Share this post


Link to post
Share on other sites
Quote:
Original post by Evil_Greven
I have a hunch, though it may be incorrect, that you aren't setting the cursor in the WinMain() function. Check for a line similar to this:

//cursor
wcx.hCursor=LoadCursor(NULL,IDC_ARROW);


For reference, wcx is type WINDOWCLASSEX.

-Greven

That fixed it!

push dword IDC_ARROW
push dword 0
call [LoadCursor]
mov [g_wnd_class(h_cursor)], eax

The problem when I was doing that was that I was passing in the instance of the application that I just created, which is what the API reference says to do... I had the same sort of problem with PeekMessage. I was passing in the main window handle, when it only works AFAIK now if you pass in NULL!!!! It took me two days of rearranging nonpertinant pieces of code to find what it was!!! GRRR. Die win32 die!!! Thanks for the help.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!