Click here to Skip to main content
14,102,320 members
Rate this:
 
Please Sign up or sign in to vote.
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:

//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
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 2

#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;
   
Rate this: bad
 
good
Please Sign up or sign in to vote.

Solution 1

You should draw only inside WM_PAINT message handler. For instance (pseudo-code):

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;
   
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)

  Print Answers RSS
Top Experts
Last 24hrsThis month


Advertise | Privacy | Cookies | Terms of Service
Web01 | 2.8.190518.1 | Last Updated 25 Dec 2013
Copyright © CodeProject, 1999-2019
All Rights Reserved.
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100