两个 MFC GDI 函数的混淆

发布于 2024-11-01 21:26:27 字数 685 浏览 2 评论 0原文

祝大家有美好的一天。这是我在这里发表的第一篇文章。 我正在阅读“使用 MFC 编程 Windows - J Prosise(MS Press)”
在第二章中,我遇到了两个让我很困惑的 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 还是其他?那么情况会发生怎样的变化呢?如果有人能解释一下这个问题,我将非常感激

and good day to all of you. This is my first post in here. I was reading "Programming Windows with MFC - J Prosise (MS Press)"
In second chapter I came across 2 GDI functions that really confused me, I am quoting the text:

It's easy to get SetViewportOrg and SetWindowOrg confused, but the distinction between them is actually quite clear. Changing the viewport origin to (x,y) with SetViewportOrg tells Windows to map the logical point (0,0) to the device point (x,y). Changing the window origin to (x,y) with SetWindowOrg does essentially the reverse, telling Windows to map the logical point (x,y) to the device point (0,0)—the upper left corner of the display surface. In the MM_TEXT mapping mode, the only real difference between the two functions is the signs of x and y. In other mapping modes, there's more to it than that because SetViewportOrg deals in device coordinates and SetWindowOrg deals in logical coordinates

I am really confused with this, is is like if we change viewpoint origin to say (50,50) and then use dc.ellipse (0,0,50,50) it would start from the device point (50,50) as origin, but if we changed window origin to (50,50) would that means now logical point (50,50) would be mapped to (0,0) if that so, wouldn't the ellipse be out of client's area in the upper region? And what the mapping mode was MM_LOWENGLISH or something else? How would the situation change then? Please if anyone could shed some light on the matter I'd be really grateful

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

椒妓 2024-11-08 21:26:27

这是一个相当复杂的问题,主要是因为您有两组完全独立的坐标需要处理,并且(只是为了让事情变得有趣)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)],它会自动为您设置原点。

This is a rather complex question, mostly because you have two entirely separate sets of coordinates to deal with, and (just to keep things interesting) Windows uses roughly the reverse of the terminology the rest of the world uses.

The short answer is just don't use SetWindowOrg at all. I'm pretty sure I've never had a good use for it in real code.

SetViewportOrg is useful, and it's really simpler than the description makes it sound -- you're just picking out where you want your origin to be. For example, you might want your drawing to start from the bottom, left-hand corner of the window. You'd do that with something like:

CRect rect;
GetClientRect(&rect);

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

OTOH, if you want to be able to draw both negative and positive numbers, you might want x=0 to be at the left side of the window, but y=0 to be centered halfway between the top and bottom of the window. You'd do that something like:

// get rect as above.
pDC->SetViewportOrg(0, rect.Height()/2);

If you wanted the center of the window to be your (0,0), you'd use:

// again, get rect like above
pDC->SetViewportOrg(rect.Width()/2, rect.Height()/2);

Note that the primary use of either of these is with the mapping mode set to MM_ISOTROPIC or MM_ANISOTROPIC -- these are where you get to set the coordinates completely on your own. With the other modes [MM_TEXT or MM_(LO|HI)(ENGLISH|METRIC)], it sets up an origin for you automatically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文