Confusion in two MFC GDI function
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
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.
精彩评论