Click here to Skip to main content
15,886,788 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
I have a rectangle which is drawn in the WM_PAINT message. Now I want to simulate this rectangular portion like a button. When I bring the mouse cursor into the rectangular area its background color should be changed and when i bring the cursor out of it it should be in its original color.

How can I catch this mouse-over event using Win32 API ? I suspect many mouse messages must be used to overcome this. However i am succesful in catching the mouse-in effect as follows:

C++
//The rectangle is just a structure with 4-values(x1, y1, x2, y2).
case WM_MOUSEMOVE:
   int x = LOWORD(lParam);
   int y = HIWORD(lParam);

   if(X_and_Y_are_inside_the_rectangle)
   {
      //get_a_dc
      //paint_the_rectangle_with_another_color
      //release_dc
   }
   else
   {
      //if i uncomment the following line even the mouse-in effect 
      //won't work
      
      //InvalidateRect(hwnd, NULL, TRUE);
   }
return 0;

case WM_PAINT:
    //get_a_dc
    //paint_the_rectangle_with_original_color
    //release_dc
    return 0;


Question in Brief:
How can I catch the mouse-in and mouse-out events of a particular rectangular area in Win32 API ?

The Only problem is with catching these 2 king of messages and not with anything else like the GDI library.
Posted

C++
#define INSIDE_RECT   1
#define OUTSIDE_RECT -1

static int iHoverRect;

case WM_CREATE:
    iHoverRect = OUTSIDE_RECT;
    return 0;

case WM_MOUSEMOVE:
    int x = LOWORD(lParam);
    int y = HIWORD(lParam);

    if(iHoverRect == OUTSIDE_RECT)
    {
        if(is_points_in_rect)
        {
            iHoverRect = INSIDE_RECT;
            //mouse-in event here
        }
    }
    else
    {
        if(!is_points_in_rect)
        {
            iHoverRect = OUTSIDE_RECT;
            //mouse-out event here
        }
    }

    return 0;
 
Share this answer
 
You should draw only inside WM_PAINT message handler. For instance (pseudo-code):

C
case WM_MOUSEMOVE:
   int x = LOWORD(lParam);
   int y = HIWORD(lParam);

   if(X_and_Y_are_inside_the_rectangle)
   {
     if ( colorRect != colorInside)
     {
        colorRect = colorInside;
        InvalidateRect
        UpdateWindow
     }
   }
   else
   {
     if ( colorRect != colorOutside)
     {
        colorRect = colorOutside;
        InvalidateRect
        UpdateWindow
     }
   }
return 0;

case WM_PAINT:
    get_a_dc
    paint the rectangle with colorRect
    release_dc
    return 0;
 
Share this answer
 
Comments
Codexzy 25-Dec-13 3:26am    
Thank You. Actually I thought about this method and this works correctly. However I found a more optimized solution. Please see my answer below !
CPallini 25-Dec-13 4:48am    
It looks pretty the same. Am I missing something?
Codexzy 28-Dec-13 23:44pm    
Yes both are pretty much the same, but there is a slight difference. If I am to hit-test more than one rectangle, you'll see that my method is a little more efficient.

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