关于用win32编写绘图程序的一个有关问题
关于用win32编写绘图程序的一个问题
小白第一次接触WIN32编程,遇到了很多问题
在用鼠标绘制点,直线和椭圆的过程中,总是出现我点击的位置和实际的位置不同的情况。
我是利用Getcursorpos函数获取鼠标点下和弹起的坐标,传给p1和p2两个POINT类型的点。
然后就用Lineto ,movetoex等等这些函数进行实现绘制,但是死活起点和终点和我鼠标点击的位置不一样,不知道为什么,请教一下大神们,附上相关的代码,就拿绘直线当例子吧。
------解决思路----------------------
鼠标点击事件得到的坐标是以左上角窗口为原点的, 你需要装换成对应窗口的坐标
小白第一次接触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;
}
}