Solved

Drawing program - refreshing objects without redrawing the ENTIRE screen

Posted on 2000-03-04
15
198 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
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

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

Live: Real-Time Solutions, Start Here

Receive instant 1:1 support from technology experts, using our real-time conversation and whiteboard interface. Your first 5 minutes are always free.

Question has a verified solution.

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

Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
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.

813 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

13 Experts available now in Live!

Get 1:1 Help Now