Solved

Drawing program - refreshing objects without redrawing the ENTIRE screen

Posted on 2000-03-04
15
197 Views
Last Modified: 2010-04-02
My questions are in the 2nd comment below this question:

Consider the following code:

#include <windows.h>
#include "resource.h"
#include "ObjectsDrawn.h"
#define ID_TIMER 1

int xCoordStart,
      yCoordStart,
      xCoordEnd,
      yCoordEnd,
      CollectionIndex;

bool FirstClick;

ObjectsDrawn Collection[100];



LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName[] = TEXT ("MenuDemo") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = szAppName ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
          MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("Menu Demonstration"),
                          WS_OVERLAPPEDWINDOW,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          CW_USEDEFAULT, CW_USEDEFAULT,
                          NULL, NULL, hInstance, NULL) ;
     
     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
          TranslateMessage (&msg) ;
          DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static int idColor [5] = { WHITE_BRUSH,  LTGRAY_BRUSH, GRAY_BRUSH,
                                DKGRAY_BRUSH, BLACK_BRUSH } ;
     static int iSelection = IDM_BKGND_WHITE ;
     HMENU      hMenu ;
     HDC hdc;
     switch (message)
     {
     case WM_COMMAND:
          hMenu = GetMenu (hwnd) ;
         
          switch (LOWORD (wParam))
          {
          case IDM_APP_EXIT:
               SendMessage (hwnd, WM_CLOSE, 0, 0) ;
               return 0 ;
             
          }
          break ;

              case WM_CREATE:
                    FirstClick = false;
                    CollectionIndex = 0;

              case WM_LBUTTONDOWN:
                    if (!FirstClick)
                    {
                          xCoordStart = LOWORD(lParam);
                          yCoordStart = HIWORD(lParam);                  
                          Collection[CollectionIndex].SetLineStart(xCoordStart,yCoordStart);
                          hdc = GetDC(hwnd);
                          MoveToEx(hdc,xCoordStart,yCoordStart,NULL);
                          ReleaseDC(hwnd, hdc);
                          FirstClick = true;
                    }
                    else if (FirstClick)
                    {                     
                          //InvalidateRect(hwnd,NULL,TRUE);                        
                          xCoordEnd = LOWORD(lParam);
                          yCoordEnd = HIWORD(lParam);
                          Collection[CollectionIndex].SetLineEnd(xCoordEnd,yCoordEnd);                        
                          Collection[CollectionIndex].DrawObject(hwnd);                        
                          FirstClick = false;
                          CollectionIndex++;
                    }
                   return 0;
              case WM_MOUSEMOVE:
                    if (FirstClick)
                    {
                          int counter;
                          xCoordEnd = LOWORD(lParam);
                          yCoordEnd = HIWORD(lParam);
                          Collection[CollectionIndex].SetLineEnd(xCoordEnd,yCoordEnd);
                          Collection[CollectionIndex].DrawObject(hwnd);                        
                          Sleep(100);
                          InvalidateRect(hwnd,NULL,TRUE);                        
                          for(counter = 0; counter < CollectionIndex; counter++)
                                Collection[counter].DrawObject(hwnd);
                    }
                    else if (!FirstClick)
                    {
                          int counter;
                                                    InvalidateRect(hwnd,NULL,TRUE);                        
                          for(counter = 0; counter < CollectionIndex; counter++)
                                Collection[counter].DrawObject(hwnd);
                    }

      case WM_DESTROY:
          PostQuitMessage (0) ;
          return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
0
Comment
Question by:knowlton
  • 10
  • 5
15 Comments
 
LVL 5

Author Comment

by:knowlton
ID: 2583126
Here is the code for ObjectsDrawn.cpp:

#include "ObjectsDrawn.h"

ObjectsDrawn::ObjectsDrawn()
{
      type = 1;
      
}      

void ObjectsDrawn::SetType(int temptype)
{
      type = temptype;
      
}      

int ObjectsDrawn::GetType()
{
      return type;
}      


void ObjectsDrawn::SetLineStart(int tempX,int tempY)
{
      xCoordStart = tempX;
      yCoordStart = tempY;
}      

void ObjectsDrawn::SetLineEnd(int tempX, int tempY)
{
      xCoordEnd = tempX;
      yCoordEnd = tempY;
}

int ObjectsDrawn::GetLineXStart()
{
  return xCoordStart;
}      

int ObjectsDrawn::GetLineYStart()
{
  return yCoordStart;
}      

int ObjectsDrawn::GetLineXEnd()
{
  return xCoordEnd;
}      

int ObjectsDrawn::GetLineYEnd()
{
  return yCoordEnd;
}      

void ObjectsDrawn::DrawLine(HWND &hwnd)
{
      HDC hdc;
      hdc = GetDC(hwnd);
      MoveToEx(hdc, xCoordEnd, yCoordEnd, NULL);
      LineTo(hdc, xCoordStart, yCoordStart);
      ReleaseDC(hwnd, hdc);
}      

void ObjectsDrawn::DrawObject(HWND &hwnd)
{
      if(type == 1)
            DrawLine(hwnd);
}

0
 
LVL 5

Author Comment

by:knowlton
ID: 2583132
Now my questions:

This is how I want the program to function:

1)  Program starts.
2)  User left clicks somewhere in the client area, setting the starting endpoint of the line.
3)  As the user moves the mouse around on the screen, the LINE "rubber-bands" to each new mouse location, showing the user where the line will be drawn to if the mouse is clicked a second time.
4)  When the user clicks a second time, the line is drawn permanently and the information is stored in an array of "Objects".
5)  More lines can be drawn and the old line will still be preserved.

I hope this gives you an idea of what I am trying to do.

Now, as I have run the program, I can tell that the line information for each object is being preserved and all of the lines I have drawn previously are being stored and reproduced on demand during this for loop:

for(counter = 0; counter < CollectionIndex; counter++)
  Collection[counter].DrawObject(hwnd);

But I am refreshing the ENTIRE screen each time I draw.  I want a more elegant solution to all of this but I don't know what to do.

I have thought about passing in an OBJECT COLOR each time I draw the lines on the screen.  I could pass in the COLOR white to "erase" lines and the color black to drawn the lines, but this also seems like a hack for a better way.

I would appreciate any help someone could give me.

0
 
LVL 5

Expert Comment

by:Wyn
ID: 2583283
Add a "if" condition to lines in WM_MOUSEMOVE:
like:
if(firsttime){  
InvalidateRect(hwnd,NULL,TRUE);
firsttime=false;
}

0
 
LVL 5

Expert Comment

by:Wyn
ID: 2583290
But better.You need do all the drawing into a mem DC and bitblt() into your window'DC.This will prevent the refreshing.
Regards
W.Yinan
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583298
Wyn:

I am rejecting your answer because I want to leave the question open to other comments.  I am sorry I should have explained that I just wanted comments for the time-being.

I understand what you mean about bitblt and the memDC, although I haven't actually tried this in Win32 I have done this type of thing in Delphi.  And yes, it does work quite well.

My one concern is how can I acheive the "rubberband" effect while I am drawing moving the mouse around prior to the second mouse-click?

Thanks!

Tom
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583303
Can I still show the line "rubber-banding" while using the memDC and bitblt techniques?

0
 
LVL 5

Accepted Solution

by:
Wyn earned 100 total points
ID: 2583339
change the code around DrawObject,for example:
HDC memdc;
RECT rect;
HBITMAP  bitmap;
  case WM_MOUSEMOVE:
  if (FirstClick)
  {
memdc=CreateCompatibleDC(0);
GetWindowRect(hwnd,&rect) ;
bitmap=CreateCompatibleBitmap(memdc,rect.rigth-rect.left,rect.bottom-rect.top);
HBITMAP oldbitmap=SelectObject(memdc,bitmap);
  for(counter = 0; counter < CollectionIndex; counter++)
  Collection[counter].DrawObject(memdc);
BltBit(....);
DeleteObject(SelectObjet(memdc,oldbitmap));
DeleteDC(memdc);
}
//.........


You should rewrite the DrawLine function,pass the memdc into it:
void ObjectsDrawn::DrawLine(HDC hdc)
{
MoveToEx(hdc, xCoordEnd, yCoordEnd, NULL);
LineTo(hdc, xCoordStart, yCoordStart);
}

Regards
W.Yinan
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 5

Expert Comment

by:Wyn
ID: 2583342
How about this?
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583357
I will try your suggestions.

This may take me a few hours.  I am still learning this stuff.

Tom
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583691
Wyn:

I appreciate your help, BUT I still don't get it.

What I need to do is draw and erase the line rapidly until the use clicks the left mouse button again.

I have made some changes to my code in an effort to use the memDc and BitBlit:

Here is my code as it stands now:

/*-----------------------------------------
   MENUDEMO.C -- Menu Demonstration
                 (c) Charles Petzold, 1998
  -----------------------------------------*/

#include <windows.h>
#include "resource.h"
#include "ObjectsDrawn.h"

int xCoordStart,
      yCoordStart,
      xCoordEnd,
      yCoordEnd,
      CollectionIndex,
      object_type;

const int INVALID = 0;
const int LINE = 1;
const int SQUARE = 2;
const int ELLIPSE = 3;

bool FirstClick;

ObjectsDrawn Collection[100];


LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;

TCHAR szAppName[] = TEXT ("MenuDemo") ;

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    PSTR szCmdLine, int iCmdShow)
{
     HWND     hwnd ;
     MSG      msg ;
     WNDCLASS wndclass ;
     
     wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
     wndclass.lpfnWndProc   = WndProc ;
     wndclass.cbClsExtra    = 0 ;
     wndclass.cbWndExtra    = 0 ;
     wndclass.hInstance     = hInstance ;
     wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
     wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
     wndclass.lpszMenuName  = szAppName ;
     wndclass.lpszClassName = szAppName ;
     
     if (!RegisterClass (&wndclass))
     {
            MessageBox (NULL, TEXT ("This program requires Windows NT!"),
                                    szAppName, MB_ICONERROR) ;
            return 0 ;
     }
     
     hwnd = CreateWindow (szAppName, TEXT ("Menu Demonstration"),
                                    WS_OVERLAPPEDWINDOW,
                                    CW_USEDEFAULT, CW_USEDEFAULT,
                                    CW_USEDEFAULT, CW_USEDEFAULT,
                                    NULL, NULL, hInstance, NULL) ;

       if (hwnd == NULL)
             {
                  MessageBox(NULL, TEXT("Not enough memory to create bitmap!"),
                        szAppName, MB_ICONERROR);
                  return 0;
             }

     ShowWindow (hwnd, iCmdShow) ;
     UpdateWindow (hwnd) ;
     
     while (GetMessage (&msg, NULL, 0, 0))
     {
            TranslateMessage (&msg) ;
            DispatchMessage (&msg) ;
     }
     return msg.wParam ;
}


void GetLargestDisplayMode (int * pcxBitmap, int * pcyBitmap)
{
     DEVMODE devmode ;
     int     iModeNum = 0 ;

     * pcxBitmap = * pcyBitmap = 0 ;

     ZeroMemory (&devmode, sizeof (DEVMODE)) ;
     devmode.dmSize = sizeof (DEVMODE) ;
     
     while (EnumDisplaySettings (NULL, iModeNum++, &devmode))
     {
          * pcxBitmap = max (* pcxBitmap, (int) devmode.dmPelsWidth) ;
          * pcyBitmap = max (* pcyBitmap, (int) devmode.dmPelsHeight) ;
     }
}


LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
     static BOOL      fLeftButtonDown, fRightButtonDown;
       static HBITMAP      hBitmap;
       static HDC            hdcMem;
       static int            cxBitmap, cyBitmap, cxClient, cyClient, xMouse, yMouse;
       HMENU                  hMenu ;
     HDC                  hdc;
       PAINTSTRUCT ps;

     switch (message)
     {
            case WM_COMMAND:
                  hMenu = GetMenu (hwnd) ;
                  switch (LOWORD (wParam))
                        {
                              case IDM_CLEAR:
                                    return 0 ;              
                              case IDM_APP_EXIT:
                                    SendMessage (hwnd, WM_CLOSE, 0, 0) ;
                                    return 0 ;
                              case IDM_EDIT_DRAWLINE:
                                    int iFlag;
                                    iFlag = GetMenuState(hMenu,IDM_EDIT_DRAWLINE,MF_BYCOMMAND);
                                    if(iFlag == 0)
                                          {
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWLINE,MF_CHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWCIRCLE,MF_UNCHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWRECT,MF_UNCHECKED);
                                                object_type = LINE;
                                          }
                                    return 0;
                              case IDM_EDIT_DRAWCIRCLE:
                                    iFlag = GetMenuState(hMenu,IDM_EDIT_DRAWCIRCLE,MF_BYCOMMAND);
                                    if(iFlag == 0)
                                          {
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWCIRCLE,MF_CHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWLINE,MF_UNCHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWRECT,MF_UNCHECKED);
                                                object_type = LINE;
                                          }
                                    return 0;
                              case IDM_EDIT_DRAWRECT:
                                    iFlag = GetMenuState(hMenu,IDM_EDIT_DRAWRECT,MF_BYCOMMAND);
                                    if(iFlag == 0)
                                          {
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWRECT,MF_CHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWLINE,MF_UNCHECKED);
                                                CheckMenuItem(hMenu,IDM_EDIT_DRAWCIRCLE,MF_UNCHECKED);
                                                object_type = SQUARE;
                                          }
                                    return 0;

                              case IDM_APP_HELP:
                                    MessageBox (hwnd, TEXT ("Help not yet implemented!"),
                                          szAppName, MB_ICONEXCLAMATION | MB_OK) ;
                                    return 0 ;
               
                              case IDM_APP_ABOUT:
                                    MessageBox (hwnd, TEXT ("Menu Demonstration Program\n")
                                          TEXT ("(c) Charles Petzold, 1998"),
                                          szAppName, MB_ICONINFORMATION | MB_OK) ;
                                    return 0 ;
                        }
                  break ;

                  case WM_CREATE:
                        object_type = LINE;
                        GetLargestDisplayMode (&cxBitmap, &cyBitmap);
                        hdc = GetDC(hwnd);
                        hBitmap = CreateCompatibleBitmap(hdc, cxBitmap, cyBitmap);
                        hdcMem = CreateCompatibleDC(hdc);
                        ReleaseDC(hwnd, hdc);

                        if (!hBitmap)
                              {
                              DeleteDC(hdcMem);
                              return - 1;
                              }
                        SelectObject(hdcMem, hBitmap);
                        PatBlt(hdcMem, 0, 0, cxBitmap, cyBitmap, WHITENESS);
                        return 0;

                  case WM_SIZE:
                        cxClient = LOWORD(lParam);
                        cyClient = HIWORD(lParam);
                        return 0;


                  case WM_LBUTTONDOWN:
                        if(!fRightButtonDown)
                              SetCapture(hwnd);
                        if(!Collection[CollectionIndex].GetFirstCoordsStatus())
                              {
                                    xMouse = LOWORD (lParam);
                                    yMouse = HIWORD (lParam);
                                    Collection[CollectionIndex].SetLineStart(xMouse,yMouse);
                                    Collection[CollectionIndex].SetFirstCoordsStatus(true);
                                    MoveToEx(hdc,xMouse,yMouse,NULL);
                                    MoveToEx(hdcMem,xMouse,yMouse,NULL);                                    
                              }
                        else
                              {
                                    xMouse = LOWORD (lParam);
                                    yMouse = HIWORD (lParam);
                                    MoveToEx(hdc,xMouse,yMouse,NULL);
                                    MoveToEx(hdcMem,xMouse,yMouse,NULL);                                    
                                    Collection[CollectionIndex].SetLineEnd(xMouse,yMouse);
                                    Collection[CollectionIndex].SetFirstCoordsStatus(false);
                                    Collection[CollectionIndex].DrawObject(hwnd);
                                    CollectionIndex++;
                              }

                        return 0;

                  case WM_LBUTTONUP:
                        if (fLeftButtonDown)
                              SetCapture(NULL);
                        fLeftButtonDown = FALSE;
                        return 0;

                  case WM_RBUTTONDOWN:
                        if (!fLeftButtonDown)
                              SetCapture(hwnd);
                        xMouse = LOWORD(lParam);
                        yMouse = HIWORD(lParam);
                        fRightButtonDown = TRUE;
                        return 0;

                  case WM_RBUTTONUP:
                        if(fRightButtonDown)
                              SetCapture(NULL);
                        fRightButtonDown = FALSE;
                        return 0;

                  case WM_MOUSEMOVE:
                        if(Collection[CollectionIndex].GetFirstCoordsStatus())
                              {
                                    hdc = GetDC(hwnd);
                                    SelectObject(hdc,GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN));
                                    SelectObject(hdcMem,GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN));
                                    xMouse = (short) LOWORD(lParam);
                                    yMouse = (short) HIWORD(lParam);
                                    Collection[CollectionIndex].SetLineEnd(xMouse,yMouse);
                                    Collection[CollectionIndex].DrawObject(hwnd);
                                    ReleaseDC(hwnd, hdc);
                              }
                        if(!fLeftButtonDown && !fRightButtonDown)
                              return 0;
                        
                        return 0;

                  case WM_PAINT:
                        hdc = BeginPaint(hwnd, &ps);
                        int result;
                        //PatBlt(hdc, 0, 0, cxBitmap, cyBitmap, WHITENESS);
                        BitBlt(hdc, 0, 0, cxClient, cyClient, hdcMem, 0,0, SRCCOPY);
                        EndPaint(hwnd, &ps);
                        return 0;

                  case WM_DESTROY:
                        DeleteDC(hdcMem);
                        DeleteObject(hBitmap);
                        PostQuitMessage (0) ;
                        return 0 ;
     }
     return DefWindowProc (hwnd, message, wParam, lParam) ;
}
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583697
Wyn:

Here is my new ObjectsDrawn class:

#include "ObjectsDrawn.h"

ObjectsDrawn::ObjectsDrawn()
{
      type = 1;
      
}      

void ObjectsDrawn::SetType(int temptype)
{
      type = temptype;
      StartCoordsSet = false;
      
}      

int ObjectsDrawn::GetType()
{
      return type;
}      

bool ObjectsDrawn::GetFirstCoordsStatus()
{
      return StartCoordsSet;
}      

void ObjectsDrawn::SetFirstCoordsStatus(bool tempstatus)
{
      StartCoordsSet = tempstatus;
}      

void ObjectsDrawn::SetLineStart(int tempX,int tempY)
{
      xCoordStart = tempX;
      yCoordStart = tempY;
}      

void ObjectsDrawn::SetLineEnd(int tempX, int tempY)
{
      xCoordEnd = tempX;
      yCoordEnd = tempY;
}

int ObjectsDrawn::GetLineXStart()
{
  return xCoordStart;
}      

int ObjectsDrawn::GetLineYStart()
{
  return yCoordStart;
}      

int ObjectsDrawn::GetLineXEnd()
{
  return xCoordEnd;
}      

int ObjectsDrawn::GetLineYEnd()
{
  return yCoordEnd;
}      

void ObjectsDrawn::DrawLine(HWND &hwnd)
{
      HDC hdc;
      hdc = GetDC(hwnd);
      MoveToEx(hdc, xCoordEnd, yCoordEnd, NULL);
      LineTo(hdc, xCoordStart, yCoordStart);
      ReleaseDC(hwnd, hdc);
}      

void ObjectsDrawn::DrawObject(HWND &hwnd)
{
      if(type == 1)
            DrawLine(hwnd);
}
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583708
Okay.

Now what my program does is this:

I left click with my mouse.  This sets the START coordiates of the line.

As I move my mouse around the screen AFTER this first mouse click, a line is continuously REDRAWN from the START to the new mouse location.

When I click the mouse a second time, the final line is drawn and the entire process is reset.  The only PROBLEM is ALL of the previous lines are still there on the screen!  I want those extra lines to disappear as I move the mouse around until finally I left click again and the final (and ONLY) line is then drawn on the screen.

Can you explain your BitBlit code in more detail.  Explain each line to me, please:


YOU WROTE PREVIOUSLY:

change the code around DrawObject,for example:
HDC memdc;
RECT rect;
HBITMAP  bitmap;
  case WM_MOUSEMOVE:
  if (FirstClick)
  {
memdc=CreateCompatibleDC(0);
GetWindowRect(hwnd,&rect) ;
bitmap=CreateCompatibleBitmap(memdc,rect.rigth-rect.left,rect.bottom-rect.top);
HBITMAP oldbitmap=SelectObject(memdc,bitmap);
  for(counter = 0; counter < CollectionIndex; counter++)
  Collection[counter].DrawObject(memdc);
BltBit(....);
DeleteObject(SelectObjet(memdc,oldbitmap));
DeleteDC(memdc);
}
//.........


You should rewrite the DrawLine function,pass the memdc into it:
void ObjectsDrawn::DrawLine(HDC hdc)
{
MoveToEx(hdc, xCoordEnd, yCoordEnd, NULL);
LineTo(hdc, xCoordStart, yCoordStart);
}

============
How does this code allow me to "rubberband" the line around the screen as i move the mouse?  Do you understand what I mean by rubberbanding?

Thanks for your help!  I think with a little more explanation I can get this!

Tom
0
 
LVL 5

Author Comment

by:knowlton
ID: 2583738
Wyn:

I think I finally figured it out!

Here is my current WM_MOUSEMOVE:

case WM_MOUSEMOVE:
                        if(Collection[CollectionIndex].GetFirstCoordsStatus())
                              {
                                    int counter;
                                    hdc = GetDC(hwnd);
                                    SelectObject(hdc,GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN));
                                    SelectObject(hdcMem,GetStockObject(fLeftButtonDown ? BLACK_PEN : WHITE_PEN));
                                    xMouse = (short) LOWORD(lParam);
                                    yMouse = (short) HIWORD(lParam);
                                    Collection[CollectionIndex].SetLineEnd(xMouse,yMouse);
                                    PatBlt(hdc, 0, 0, cxBitmap, cyBitmap, WHITENESS);
                                    for(counter = 0; counter < CollectionIndex; counter++)
                                          Collection[counter].DrawObject(hwnd);
                                    Collection[CollectionIndex].DrawObject(hwnd);
                                    ReleaseDC(hwnd, hdc);
                              }
                        if(!fLeftButtonDown && !fRightButtonDown)
                              return 0;
                        
                        return 0;


There is a tiny bit of flicker, but the line rubber bands now!  

Thanks for your help.  You get the points!

0
 
LVL 5

Expert Comment

by:Wyn
ID: 2584274
Why you give me the points?
Is my comments helpful?
However,thank you.
Best Regards
W.Yinan

Btw:what's rubberband exactly meaning?
(You told me and ,then,I can rehash the my code and try to explain it to you)

Thank for the pts ,i blush to get:)
0
 
LVL 5

Author Comment

by:knowlton
ID: 2585056
Rubberbanding is like when you take a rubberband and stretch it between your fingers.  You can make it bigger or smaller but the basic object is still a rubberband.

When drawing a rectangle in a drawing program, rubberbanding refers to clicking with the mouse at a location, then dragging the mouse around the screen.  The rectangle grows bigger as you move the cursor away from the origin point, and smaller as you approach it, but the rectangle does not get permanently drawn until you click the mouse again.  Make sense?

Don't worry about the points.  You actually were quite helpful with your bitblt idea.  
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now