Differentiating 2 events coming under same handler

Hi
iam in little bit confusion regarding my application.In my win 32 application i have to do 2 operation
1.Left mouse click on the client area should generate a rectangle of predifined dimension around the cursor position
2.Clicking and dragging the mouse on the client area should generate ractangle with dimension equals to the dragged area(nothing but selction of client area by dragging),While doing this cursor shape should change from IDC_ARROW to IDC_CROSS
For the first operation i have to write the handler in WM_LBUTTONDOWN
For second operation I hvave to write the code in WM_LBUTTONDOWN,UP,& WM_MOUSEMOVE.How to identify the opration coming under LBUTTONDOWN,because dragging is also first need to do LBUTTONDOWN.My code has given below
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
 void DrawBoxOutline (HWND hwnd, POINT ptBeg, POINT ptEnd)
{
     HDC hdc ;
     
     hdc = GetDC (hwnd) ;
     
     SetROP2 (hdc, R2_NOT) ;
     SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
     Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;

     ReleaseDC (hwnd, hdc) ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL  fBlocking, fValidBox ;
     static POINT ptBeg, ptEnd, ptBoxBeg, ptBoxEnd,ptClient ;
     HDC          hdc ;
     PAINTSTRUCT  ps ;
     
     switch (message)
     {
     case WM_LBUTTONDOWN :

//mouse left click
          GetCursorPos(&ptClient);
          ScreenToClient(hwnd,ptClient);
          Rectangle (hdc, ptClient.x-3, ptClient.y-3, ptClient.x+3,         ptClient.y+3) ;

//dragging opration
          ptBeg.x = ptEnd.x = LOWORD (lParam) ;
          ptBeg.y = ptEnd.y = HIWORD (lParam) ;
          
          DrawBoxOutline (hwnd, ptBeg, ptEnd) ;
          
          SetCapture (hwnd) ;
          SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
          
          fBlocking = TRUE ;
          return 0 ;
          
     case WM_MOUSEMOVE :
          if (fBlocking)
          {
               SetCursor (LoadCursor (NULL, IDC_CROSS)) ;
               
               DrawBoxOutline (hwnd, ptBeg, ptEnd) ;
               
               ptEnd.x = (short) LOWORD (lParam) ;
               ptEnd.y = (short) HIWORD (lParam) ;
               
               DrawBoxOutline (hwnd, ptBeg, ptEnd) ;
          }
          return 0 ;
          
     case WM_LBUTTONUP :
          if (fBlocking)
          {
               DrawBoxOutline (hwnd, ptBeg, ptEnd) ;
               
               ptBoxBeg   = ptBeg ;
               ptBoxEnd.x = (short) LOWORD (lParam) ;
               ptBoxEnd.y = (short) HIWORD (lParam) ;
               
               ReleaseCapture () ;
               SetCursor (LoadCursor (NULL, IDC_ARROW)) ;
               
               fBlocking = FALSE ;
               fValidBox  = TRUE ;
               
               InvalidateRect (hwnd, NULL, TRUE) ;
          }
          return 0 ;
 case WM_PAINT :
          hdc = BeginPaint (hwnd, &ps) ;
          
          if (fValidBox)
          {
               SelectObject (hdc, GetStockObject (BLACK_BRUSH)) ;
               Rectangle (hdc, ptBoxBeg.x, ptBoxBeg.y,
                               ptBoxEnd.x, ptBoxEnd.y) ;
          }
          
          if (fBlocking)
          {
               SetROP2 (hdc, R2_NOT) ;
               SelectObject (hdc, GetStockObject (NULL_BRUSH)) ;
               Rectangle (hdc, ptBeg.x, ptBeg.y, ptEnd.x, ptEnd.y) ;
          }
          
          EndPaint (hwnd, &ps) ;
          return 0 ;
 case WM_DESTROY :
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}

          

          
Last edited on
i have to do 2 operation

Have
to?

What you're asking for is not really possible. At least, not in a way that won't confuse the user (e.g. use a timer to see it the up button down and button up occur within a time limit, and at more or less the same position.) Esp. as the click and drag operations position the rectangle in a different way (when you drag, you click where one corner will be, rather than the center.)

It might be better to:
1. use a double-click to create the fixed size rectangle
2. or use a right-click menu for the insertion
3. or allow the user to switch modes: single click insert vs drag modes

Also, when it comes to the the mouse left click method of adding a rectangle, I would not draw the rectangle in the WM_LBUTTONDOWN (lines 26 - 28). You should just remember the rectangle's position, and call InvalidateRect to trigger a repaint. (The code on these lines look broken anyway; no sign of GetDC() to start with.)

I assume you plan to use an array or (preferably) vector or RECTs at some point?

Andy
Last edited on
Topic archived. No new replies allowed.