关于用win32编写绘图程序的一个有关问题

关于用win32编写绘图程序的一个问题
小白第一次接触WIN32编程,遇到了很多问题
在用鼠标绘制点,直线和椭圆的过程中,总是出现我点击的位置和实际的位置不同的情况。
我是利用Getcursorpos函数获取鼠标点下和弹起的坐标,传给p1和p2两个POINT类型的点。
然后就用Lineto ,movetoex等等这些函数进行实现绘制,但是死活起点和终点和我鼠标点击的位置不一样,不知道为什么,请教一下大神们,附上相关的代码,就拿绘直线当例子吧。

long FAR PASCAL ccc_win_proc(HWND hwnd, UINT message, UINT wParam, LONG lParam)
{  
   static int menuId=0;
   PAINTSTRUCT ps;
   HDC mainwin_hdc;
   int wmId, wmEvent;
   switch (message)
   { 

    //鼠标落下
    case WM_LBUTTONDOWN:
{
GetCursorPos(&p1);
break;
}

//鼠标抬起
case WM_LBUTTONUP:
{
GetCursorPos(&p2);
break;
}

    case WM_CREATE:
  SetTimer(hwnd,1,1000,NULL);
  break;
  
case WM_TIMER:
      InvalidateRect(hwnd,NULL,TRUE);
  break;

case WM_COMMAND:
wmId    = LOWORD(wParam);
wmEvent = HIWORD(wParam);

switch (wmId)
{
case ID_40001:
menuId=ID_40001;
InvalidateRect(hwnd,NULL,TRUE);
break;

  /*************************在此处进行过修该***************************/ 

case ID_40012:
menuId=ID_40012;
InvalidateRect(hwnd,NULL,TRUE);
break;

case ID_40003:
menuId=ID_40003;
InvalidateRect(hwnd,NULL,TRUE);
break;

case ID_40009:
menuId=ID_40009;
InvalidateRect(hwnd,NULL,TRUE);
break;

case ID_40010:
menuId=ID_40010;
InvalidateRect(hwnd,NULL,TRUE);
break;

//绘图实现
case ID_40014:
menuId=ID_40014;
InvalidateRect(hwnd,NULL,TRUE);
break;

case ID_40015:
menuId=ID_40015;
InvalidateRect(hwnd,NULL,TRUE);
break;

case ID_40016:
menuId=ID_40016;
InvalidateRect(hwnd,NULL,TRUE);
break;
/*************************在此处进行过修该***************************/

case ID_40011:
DestroyWindow(hwnd);
break;
}
break;

case WM_PAINT:

        mainwin_hdc = BeginPaint(hwnd, &ps);
        switch (menuId)
        {                 
   case ID_40001:
   cwin.open(hwnd, mainwin_hdc);
   mclock(); // 绘制时钟
   break;
   case ID_40012:
       cwin.open(hwnd, mainwin_hdc);
   DrawPixels(hwnd,mainwin_hdc);
   break;  //绘制若干点
   case ID_40003:
       cwin.open(hwnd, mainwin_hdc);
   DrawTriangle(hwnd,mainwin_hdc);
   break;  //绘制三角形
   case ID_40009:
   cwin.open(hwnd, mainwin_hdc);
   DrawArc(hwnd,mainwin_hdc);
   break;  //绘制对称曲线
   case ID_40010:
   cwin.open(hwnd, mainwin_hdc);
   DrawCos(hwnd,mainwin_hdc);
   break;  //绘制余弦曲线


//绘图实现
   case ID_40014:
   cwin.open(hwnd, mainwin_hdc);
   Draw_Some_Point(hwnd,mainwin_hdc);
   break;  //绘制点
   case ID_40015:
   cwin.open(hwnd, mainwin_hdc);
   Draw_A_Line(hwnd,mainwin_hdc);
   break;  //绘制线
case ID_40016:
   cwin.open(hwnd, mainwin_hdc);
   Draw_A_Circle(hwnd,mainwin_hdc);
   break;  //绘制椭圆
        }
EndPaint(hwnd, &ps);
        break;

case WM_DESTROY:
        KillTimer(hwnd,1); 
PostQuitMessage(0);
break;

default:
return DefWindowProc(hwnd, message, wParam, lParam);
   }
   return 0;
}
void Draw_A_Line(HWND hwnd,HDC hdc)
{
// 获得客户区域
RECT r;
GetClientRect(hwnd, &r);

// 设置映像模式
    SetMapMode(hdc, MM_ISOTROPIC);

// 设置窗口坐标范围
SetWindowExtEx(hdc, 1000, 1000, NULL);

// 设置视口坐标范围
SetViewportExtEx(hdc, r.right, r.bottom, NULL);

// 绘制直线
MoveToEx( hdc, p1.x, p1.y, NULL);
LineTo( hdc, p2.x , p2.y );
}

------解决思路----------------------
鼠标点击事件得到的坐标是以左上角窗口为原点的, 你需要装换成对应窗口的坐标
//鼠标在picture control按下的处理
void CtestDlg::MouseLButtonDown(MSG * pMsg)
{
//得到picture控件rect。 
CRect rect; 
::GetClientRect(this->GetDlgItem(Picture1)->GetSafeHwnd(), &rect); 

m_StartPoint = pMsg->pt; 
//然后把当前鼠标坐标转为相对于rect的坐标。 
::ScreenToClient(this->GetDlgItem(Picture1)->GetSafeHwnd(), &m_StartPoint); 

m_StartPoint.x  = m_StartPoint.x < 0 ? 0 : m_StartPoint.x; 
m_StartPoint.y  = m_StartPoint.x < 0 ? 0 : m_StartPoint.y;
char arr[100];
sprintf(arr, "point.x = %d, point.y = %d", m_StartPoint.x, m_StartPoint.y);
setLogText(arr);

//计算出图片的实际位置
m_RoiPoint.startx = ((float)m_StartPoint.x / (float)rect.right) * m_img->width;
m_RoiPoint.starty = ((float)m_StartPoint.y / (float)rect.bottom) * m_img->height;
}

//鼠标在picture control弹起的处理
void CtestDlg::MouseLButtonUp(MSG * pMsg)
{
//得到picture控件rect。 
CRect rect; 
::GetClientRect(this->GetDlgItem(Picture1)->GetSafeHwnd(), &rect); 

m_EndPoint = pMsg->pt;
//然后把当前鼠标坐标转为相对于rect的坐标。 
::ScreenToClient(this->GetDlgItem(Picture1)->GetSafeHwnd(), &m_EndPoint);
m_EndPoint.x  = m_EndPoint.x < 0 ? 0 : m_EndPoint.x; 
m_EndPoint.y  = m_EndPoint.x < 0 ? 0 : m_EndPoint.y;

char arr[100];
sprintf(arr, "point.x = %d, point.y = %d", m_EndPoint.x, m_EndPoint.y);
setLogText(arr);

//计算出图片的实际位置
m_RoiPoint.endx = ((float)m_EndPoint.x / (float)rect.right *  m_img->width) ;
m_RoiPoint.endy = ((float)m_EndPoint.y / (float)rect.bottom * m_img->height);

//如果是自下而上拖动的窗口,则交换两个坐标
if(m_RoiPoint.endx < m_RoiPoint.startx)
{
float temp = 0;
temp = m_RoiPoint.endx;
m_RoiPoint.endx = m_RoiPoint.startx;
m_RoiPoint.startx = temp;
temp = m_RoiPoint.endy;
m_RoiPoint.endy = m_RoiPoint.starty;
m_RoiPoint.starty = temp;
}
}