在做一个画图程序,有铅笔和直线两种工具,
我的消息处理函数如下:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
int wmId, wmEvent;
static bool tool=true;
static int x=0,y=0;//定义了两个静态变量,存坐标。
static int x1=0,y1=0;
PAINTSTRUCT ps;
HDC hdc;
TCHAR szHello[MAX_LOADSTRING];
LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
HPEN hPen;
static int proc=0;//当不画的时候为0,鼠标点下后变为一,需要将当前画笔移动到鼠
          //标位置,为2的时候开始画。 TCHAR str[50];

switch (message) 
{
case WM_COMMAND:
wmId    = LOWORD(wParam); 
wmEvent = HIWORD(wParam); 
// Parse the menu selections:
switch (wmId)
{
case IDM_ABOUT:
   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
   break;
case IDM_EXIT:
   DestroyWindow(hWnd);
   break;
case IDM_PENCIL:
   tool=true;//选择了铅笔工具,tool变成true
    proc=0;
   break;
case IDM_LINE:
   tool=false;//选择了直线工具,tool变成false
   proc=0;
   break;
default:
   return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
hPen = CreatePen(PS_SOLID,1,RGB(0,0,0));
SelectObject(hdc,hPen);
if(tool==true)//如果是铅笔执行以下
{
if(proc==1)
{
MoveToEx(hdc,x,y,NULL);
}
if(proc==2)
{
MoveToEx(hdc,x1,y1,NULL);
}
LineTo(hdc,x,y);
x1=x;
y1=y;
}
if(tool==false)//如果是直线,执行以下
{

if(proc==1)
{
MoveToEx(hdc,x,y,NULL);//错误在这里,每次画直线,画笔的起始坐标都是(0,0),好像这句没执行。
}
if(proc==2)
{

LineTo(hdc,x,y);
}
}
EndPaint(hWnd, &ps);
break;
case WM_MOUSEMOVE:
if(wParam == MK_LBUTTON)
{
x = LOWORD(lParam);
y = HIWORD(lParam);
if ( tool == true )
{
proc=2;
InvalidateRect(hWnd,NULL,false);

}
else
{
proc=2;
InvalidateRect(hWnd,NULL,true);

}
}
break;
case WM_LBUTTONUP:
x = LOWORD(lParam);
y = HIWORD(lParam);
if(tool==true)
{
proc=1;
}
if(tool==false)
{ proc=2;
InvalidateRect(hWnd,NULL,false);
proc=1;
}
break;
case WM_LBUTTONDOWN:
x = LOWORD(lParam);
y = HIWORD(lParam);
proc=1;//鼠标点下的时候,将proc设为1
InvalidateRect(hWnd,NULL,false);

break;
case WM_DESTROY:
PostQuitMessage(0);
break; default:
return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}//错误就是画直线时的,画笔总在(0,0)移不到鼠标位置,不知道怎么了 ,大家看看。

解决方案 »

  1.   

    为什么不在case WM_LBUTTONDOWN里面MoveToEx,反而要多此一举地InvalidateRect呢
      

  2.   

    是没执行吧,我看你的代码没搞清楚,逻辑比较混乱,比如:
                                      if(tool==true)//如果是铅笔执行以下  
                                       {  
                                                   if(proc==1)  
                                                   {  
                                                               MoveToEx(hdc,x,y,NULL);  
                                                   }  
                                                   if(proc==2)  
                                                   {  
                                                               MoveToEx(hdc,x1,y1,NULL);  
                                                   }  
                                                   LineTo(hdc,x,y);  
                                                   x1=x;  
                                                   y1=y;  
                                       }  
    但是后面tool为ture的时候,proc只能为1。而proc为1的时候MoveToEx和LineTo参数是一样的。建议最好先把逻辑关系理清楚。
      

  3.   

    分析一下你的思路:
    首先你选择画线工具:case IDM_LINE:
       tool=false;//选择了直线工具,tool变成false
       proc=0;
       break;然后你在客户区按下鼠标左键:
    x = LOWORD(lParam);
    y = HIWORD(lParam);
    proc=1;//鼠标点下的时候,将proc设为1
    InvalidateRect(hWnd,NULL,false);

    break;接着你移动鼠标:
    if(wParam == MK_LBUTTON)
    {
    x = LOWORD(lParam);
    y = HIWORD(lParam);
    if ( tool == true )
    {
    proc=2;
    InvalidateRect(hWnd,NULL,false);

    }
    else
    {
    proc=2;  // 执行这一步
    InvalidateRect(hWnd,NULL,true);

    }
    }InvalidateRect函数激发WM_PAINT消息:
    case WM_PAINT:
    hdc = BeginPaint(hWnd, &ps);
    hPen = CreatePen(PS_SOLID,1,RGB(0,0,0));
    SelectObject(hdc,hPen);
    if(tool==false)//如果是直线,执行以下
    {

    if(proc==1)
    {
    MoveToEx(hdc,x,y,NULL);//错误在这里,每次画直线,画笔的起始坐标都是(0,0),好像这句没执行。
    }
       if(proc==2) // 你看到没有,上一步proc已经等于2,所以只能执行这一步,
    {

    LineTo(hdc,x,y);
    }
    }
    EndPaint(hWnd, &ps);
    break;
    根源在你这个WM_PAINT消息处理函数有问题,实际上必须执行两部(MoveTo和LineTo).你只执行了LineTo.
      

  4.   

    pomelowu(羽战士) 
    放在case WM_LBUTTONDOWN里
    也不好阿,不知道为什么
      

  5.   

    思路:
    把MoveTo放在case WM_LBUTTONDOWN;
    把LineTo放在case WM_MOUSEMOVE:
    获得起始点后InvalidateRect
      

  6.   

    错了,
    把MoveTo放在case WM_LBUTTONDOWN;
    把InvalidateRect放在case WM_MOUSEMOVE:
    把LineTo放在case WM_PAINT。