混淆了两个MFC GDI功能

Raz*_*t4x 5 mfc gdi coordinate-systems visual-c++

祝大家美好的一天 这是我在这里的第一篇文章.我正在阅读"使用MFC编程Windows - J Prosise(MS Press)"
在第二章中,我遇到了2个GDI函数,这些函数让我很困惑,我引用了文本:

很容易让SetViewportOrg和SetWindowOrg混淆,但它们之间的区别实际上非常清楚.使用SetViewportOrg将视口原点更改为(x,y)告诉Windows将逻辑点(0,0)映射到设备点(x,y).使用SetWindowOrg将窗口原点更改为(x,y)基本上相反,告诉Windows将逻辑点(x,y)映射到设备点(0,0) - 显示表面的左上角.在MM_TEXT映射模式中,两个函数之间唯一真正的区别是x和y的符号.在其他映射模式中,除此之外还有更多因为SetViewportOrg处理设备坐标和SetWindowOrg处理逻辑坐标

我真的很困惑,就像我们将视点原点改为说(50,50)然后使用dc.ellipse(0,0,50,50)它将从设备点(50,50)开始原点,但如果我们将窗口原点更改为(50,50),这意味着现在逻辑点(50,50)将被映射到(0,0),如果这样,则椭圆不会在客户区域之外上部地区?什么映射模式是MM_LOWENGLISH或其他什么?情况怎么会改变呢?如果有人能对这件事有所了解,我真的很感激

Jer*_*fin 6

这是一个相当复杂的问题,主要是因为你有两个完全独立的坐标集来处理,并且(只是为了让事情变得有趣)Windows使用的大致与世界其他地方使用的术语相反.

简短的回答就是根本不用SetWindowOrg.我很确定我在实际代码中从来没有很好地使用它.

SetViewportOrg是有用的,而且它比说明书听起来更简单 - 你只是选择你想要的原点.例如,您可能希望绘图从窗口的左下角开始.你可以这样做:

CRect rect;
GetClientRect(&rect);

pDC->SetViewportOrg(0, rect.Height());
Run Code Online (Sandbox Code Playgroud)

OTOH,如果你想能够绘制负数和正数,你可能希望x = 0在窗口的左侧,但是y = 0在窗口的顶部和底部之间的中间.你会这样做:

// get rect as above.
pDC->SetViewportOrg(0, rect.Height()/2);
Run Code Online (Sandbox Code Playgroud)

如果你想让窗口的中心成为你的(0,0),你可以使用:

// again, get rect like above
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);
Run Code Online (Sandbox Code Playgroud)

请注意,其中任何一个的主要用途是将映射模式设置为MM_ISOTROPIC或MM_ANISOTROPIC - 您可以在这些位置完全自行设置坐标.使用其他模式[MM_TEXT或MM_(LO | HI)(ENGLISH | METRIC)],它会自动为您设置原点.