visual-c++ - 混淆了两个 MFC GDI 函数

标签 visual-c++ mfc gdi coordinate-systems

祝大家有美好的一天。这是我在这里的第一篇文章。 我正在阅读“使用 MFC 编程 Windows - J Prosise (MS Press)”
在第二章中,我遇到了 2 个让我非常困惑的 GDI 函数,我引用了以下文字:

SetViewportOrg 和 SetWindowOrg 很容易混淆,但是它们之间的区别实际上是很清楚的。使用 SetViewportOrg 将视口(viewport)原点更改为 (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 还是其他什么?届时情况将如何变化?请如果有人能对此事有所了解,我将不胜感激

最佳答案

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

简短的回答是不要使用 SetWindowOrg一点也不。我很确定我从来没有在实际代码中很好地使用它。
SetViewportOrg很有用,而且它确实比描述听起来更简单——你只是在挑选你想要的起源。例如,您可能希望您的绘图从窗口的左下角开始。你可以这样做:

CRect rect;
GetClientRect(&rect);

pDC->SetViewportOrg(0, rect.Height());

OTOH,如果您希望能够同时绘制负数和正数,您可能希望 x=0 位于窗口的左侧,但 y=0 位于窗口顶部和底部之间的中间。你会这样做:
// get rect as above.
pDC->SetViewportOrg(0, rect.Height()/2);

如果您希望窗口的中心是您的 (0,0),您可以使用:
// again, get rect like above
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);

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

关于visual-c++ - 混淆了两个 MFC GDI 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5685006/

相关文章:

c++ - 将指向局部变量的指针传递给另一个进程有时有效,但有时无效

c++ - 具有类型名称的矩阵总和

c++ - 如何阻止我的 MFC 应用程序在启动时调用 OnFileNew()?

c++ - "Debug Assertion"VS2008 运行时错误?

c++ - 从 ToUnicodeEx() 转换为 UTF-8

c++ - 如何修复 MSVC++(Microsoft Visual Studio)中与 "macro overloading"相关的可变参数宏相关问题?

c++ - 为什么我启用 unicode 的软件无法识别 ANSI 文件中的 'Š' 和其他字符?如何解决?

c# - .Net 等效于 ScaleHeight 和 Scalewidth

c++ - 从 OpenGL 切换到 GDI

c++ - 将文本/图像写入 HWND 的最短代码是什么