Thread: Drawing a rectangle in a control

  1. #1
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310

    Drawing a rectangle in a control

    I'm trying to draw a rectangle, like in Spy++
    Code:
    case WM_MOUSEMOVE:
    		{
    			if (bSearching) {
    				POINT pMouse = {0};
    				HWND hwnd;
    				char szMouse[64];
    
    				GetCursorPos(&pMouse);
    				hwnd = WindowFromPoint(pMouse);
    				wsprintf(szMouse, "Cursor: %i x %i", pMouse.x, pMouse.y);
    				SendMessage(hStatus, SB_SETTEXT, 0, (LPARAM)szMouse);
    				if (IsWindow(hwnd)) {
    					RECT rc;
    					HDC hdc;
    					HGDIOBJ hPrevPen;
    					HGDIOBJ hPrevBrush;
    					HPEN hPen;
    
    					hdc = GetWindowDC(hwnd);
    					GetWindowRect(hwnd, &rc);
    
    					hPen = CreatePen(PS_SOLID, 2, RGB(0,0,0));
    					hPrevPen = SelectObject(hdc, hPen);
    					hPrevBrush = SelectObject (hdc, GetStockObject(HOLLOW_BRUSH));
    					Rectangle(hdc, 0, 0, rc.right-rc.left, rc.bottom-rc.top);
    					SelectObject(hdc, hPrevBrush);
    					SelectObject(hdc, hPrevPen);
    					DeleteObject(hPen);
    					ReleaseDC(hwnd, hdc);
    				}
    			}
    			return 0;
    		}
    Ok, when I point to a control, the rectangle is corretly draw...but when I left that control, the rectangle stays.... How to erase that rectangle?
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    InvalidateRect? Or maybe, draw a second rectangle of background color to "erase" it.

  3. #3
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    One possibility is to redraw the rectangle after changing the raster op code for the device context to effectively erase the first rectangle. This approach is used in msdn: How To Use Win32 API to Draw a Dragging Rectangle on Screen DC
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  4. #4
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310
    ok...I'm still lost :\

    @Ken Fitlike:

    I see the code but, still confused at how implement it
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  5. #5
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    The important part is the SetROP2 function which defines how drawing is done for the device context in question. Note that the possible raster operation codes are similar to those listed for Bitblt so if you have familiarity with that api function then it shouldn't be too obscure.

    Essentially what you do is draw the rectangle once normally and this is what shows up. When you want to erase that visible rectangle, you set the raster operation code for the same device context to the inverse xor of what you just drew (R2_NOTXORPEN code) and redraw the rectangle which effectively removes the original.

    So you'd need to introduce the SetROP2(and store its return value) call when the mouse pointer leaves the control - once to draw the inverse of the original rectangle (ie the erasing action) and once more to restore the raster operation code to its original value when you're done erasing the rectangle.
    Code:
    /*pseudocode*/
    /*erase rectangle*/
    int oldcode=SetROP2(hdc,R2_NOTXORPEN);
    /*now redraw rectangle which erases original*/
    Rectangle(hdc,original_left,original_top,original_right,original_bottom);
    /*restore device context*/
    SetROP2(hdc,oldcode);
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

  6. #6
    Registered User Joelito's Avatar
    Join Date
    Mar 2005
    Location
    Tijuana, BC, México
    Posts
    310
    ah..ok...I think I got it...now I have another issue:
    Code:
    case WM_MOUSEMOVE:
    		{
    			if (bnowDraw) {
    				HDC hdc;
    				hdc = GetDC(hWnd);
    				MoveToEx(hdc, pCursorPos.x, pCursorPos.y, NULL);
    				pCursorPos = MAKEPOINTS(lParam);
    				LineTo(hdc, pCursorPos.x, pCursorPos.y);
    				ReleaseDC(hWnd, hdc);
    			}
    			return 0;
    		}
    The line is correctly, but when I minimized the window...the line is gone...any ideas why or how can I draw it without been erase?
    * PC: Intel Core 2 DUO E6550 @ 2.33 GHz with 2 GB RAM: Archlinux-i686 with xfce4.
    * Laptop: Intel Core 2 DUO T6600 @ 2.20 GHz with 4 GB RAM: Archlinux-x86-64 with xfce4.

  7. #7
    erstwhile
    Join Date
    Jan 2002
    Posts
    2,227
    Which window? Your own or another application's? If it's your own then you should move drawing code to the WM_PAINT handler and just InvalidateRect if/as necessary. If it's another application's window then maybe you should periodically check the activation state of the current target window and redraw it as required; a timer (see SetTimer, KillTimer, WM_TIMER) may be an option here.
    CProgramming FAQ
    Caution: this person may be a carrier of the misinformation virus.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  2. Drawing rectangle in a web page
    By alphaoide in forum Tech Board
    Replies: 3
    Last Post: 02-20-2005, 07:40 PM
  3. Help With pointers in classes.
    By indigo0086 in forum C++ Programming
    Replies: 12
    Last Post: 10-10-2002, 02:03 PM
  4. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM
  5. Drawing a grid on a plain rectangle
    By kamikazeecows in forum Windows Programming
    Replies: 1
    Last Post: 04-01-2002, 06:51 PM