Click here to Skip to main content
15,921,837 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
INTRODUCTION AND RELEVANT INFORMATION:

I have made an application that needs to change the look of a cursor into hand when mouse hovers above the static control, but resets it to a normal cursor otherwise.

My initial application was in full screen mode, but recently terms have changed and it must have a resizable window.

This means that my handler for WM_SETCURSOR must be rewritten to reflect newly introduced changes.

Cursors are loaded in WM_CREATE, and I have defined class cursor, like this:

C++
// cursors 
case WM_CREATE:
	hCursorHand = LoadCursor( NULL, IDC_HAND );
	hCursorArrow = LoadCursor( NULL, IDC_ARROW );
        // other stuff


In my class:
C++
WNDCLASSEX wc;
// ...
wc.hCursor = hCursorArrow;
//...


This is my old WM_CURSOR handler ( code is simplified for clarity purposes ):
C++
case WM_SETCURSOR:
   if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
       SetCursor(hCursorHand);
   else
       SetCursor(hCursorArrow);
   return TRUE;


If cursor hovers above static control, then my handler changes it to hand, else sets it to default cursor ( arrow ).

Below is the link to the picture I have sketched in Paint that displays the desired look of the cursor when it hovers above static control, it is on the client area, and when user resizes window.

http://pbrd.co/1fXQDvh[^]

If additional code snippets are required, ask and I will edit my post, but for now, they are omitted to keep the post short and concise.

I work on Windows XP, using MS Visual Studio C++ and pure Win32 API.

MY EFFORTS TO SOLVE PROBLEM:

Bellow are the code snippets that I have tried, but they all failed:

First snippet:
C++
case WM_SETCURSOR:
   if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
   {
      SetCursor(hCursorHand); 
      return TRUE; 
    }
    else
      return DefWindowProc( hWnd, msg, lParam, wParam );

Second Snippet:

C++
case WM_SETCURSOR:
   if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
   {
      SetCursor(hCursorHand); 
      return TRUE; 
    }
    break; // based on MSDN example


Third snippet:

C++
case WM_SETCURSOR:
    if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
    {
       SetCursor(hCursorHand); 
       return TRUE; 
    }
    else
       return FALSE;

These set cursor to hand no matter where it is.

If I leave my WM_SETCURSOR handler unchanged, the only problem I get is that instead of sizing arrows, I get regular arrow ( as the cursor’s look ) when I hover over the border, but window can be sized.

If I comment out my WM_SETCURSOR handler, sizing arrows and cursor arrow appear properly, but cursor doesn’t change into hand when hovers above static control ( which is logical, since there is no WM_SETCURSOR handler to change it ).

I have browsed through SO archive, looked on MSDN, CodeProject , DaniWeb, Cprogramming and CodeGuru, but had no success.

Looking through those, I have found an example where people compare low word of the lParam against hit test code.

Looking through MSDN I have found link for hit test values ( http://msdn.microsoft.com/en-us/library/windows/desktop/ms645618%28v=vs.85%29.aspx[^] ) and I have found link for cursor types (http://msdn.microsoft.com/en-us/library/windows/desktop/ms648391%28v=vs.85%29.aspx[^] ).

Currently I am reading them, because I think that I will have to load additional cursor resources, take several comparisons of hit test values, and then use those resources to set cursor look accordingly.

QUESTION:

I really would like my WM_SETCURSOR handler to look like this:

C++
case WM_SETCURSOR:
     if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
     {
        SetCursor(hCursorHand); 
        return TRUE;
     }
     else
       // reset cursors look to default

so I ask the community to instruct me on how to do this.

If this isn’t possible, then I will consider using multiple if statements to check the hit test code, and set cursor’s look accordingly.

Of course, if there is better solution for my problem, please suggest it, I will consider it as well.

Thank you.

Regards.
Posted

1 solution

This question is solved here:
http://stackoverflow.com/questions/19257237/reset-cursor-in-wm-setcursor-handler-properly[^]
Just in case link becomes invalid, here is the code for those who struggle with the same problem:
C++
case WM_SETCURSOR:
   if( (HWND)wParam == GetDlgItem( hwnd, 4000 ) ) 
   {
        SetCursor(hCursorHand);
        return TRUE;
   }
   return DefWindowProc(hwnd, msg, wParam, lParam);


However, I think that the problem is in loading cursor in my window class.
It is invalid cursor handle, since the variable isn't initialized.
After loading the cursor the standard way in my window class, and using my first code snippet, everything seems to work now.
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900