OMG-1
OMG-1

Reputation: 508

From TopLeft 0,0 to BottomLeft 0,0 in GDI win32

How can I change transform the coordinates in a window from 0,0 topleft to 0,0 bottomleft.

I have tried various solutions with
SetMapMode(hdc,MM_TEXT);,
SetViewportExtEx(hdc,0,-clientrect.bottom,NULL);
SetViewPortOrgEx(hdc,0,-clientrect.bottom,NULL);
SetWindowOrgEx(hdc,0,-clientrect.bottom,NULL);
SetWindowExtEx(hdc,0,-clientrect.bottom,NULL);
I have even tried google for a solution but to no prevail, so I turn to you the more experienced people on the internet.

The idea is I'm creating a custom control for linear interpolation and I could reverse the coordinate system by x,y in top right corner but I want it right. At the moment I get a reversed linear interpolation when I try to draw it as I cannot get the coords to be bottomleft.

I'm using win32 api, and I suspect I can skip the code as the screen coordinate system is almost identical on all systems, by that I mean 0,0 is "always" topleft on the screen if you are keeping it to standard 2d window and frames.

I really don't want a whole codesample to ease the typing pain for you guys, but I want some direction as it seems I cannot grasp the simple concept of flipping the coords in win32 api.

Thanks and a merry christmas

EDIT !

I would like to add my own answer to this question as I used simple math to reverse the view so to say.

If for an example I got the valuepair x,y (150,57) and another pair x,y (100,75) then I used this formulae height + (-1 * y) and voila I get a proper cartesian coordinate field :) ofcourse in this example height is undefined variable but in my application its 200px in height.

Upvotes: 1

Views: 1510

Answers (1)

Jim Mischel
Jim Mischel

Reputation: 133995

According to the documentation for SetViewportOrgEx, you generally want to use it or SetWindowOrgEx, but not both. That said, you probably want the viewport origin to be (0, clientrect.bottom), not -clientrect.bottom.

Setting transforms with GDI always made me crazy. I think you're better off using GDI+. With it, you can create a matrix that describes a translation of (0, clientRect.bottom), and a scaling of (1.0, -1.0). Then you can call SetWorldTransform.

See the example at Using Coordinate Spaces and Transformations. For general information about transforms: Coordinate Spaces and Transformations.

Additional information:

I've not tried this with direct Windows API calls, but if I do the following in C# using the Graphics class (which is a wrapper around GDI+), it works:

Graphics g = GetGraphics();  // gets a canvas to draw on
SetTranslateTransform(0, clientRect.Bottom);
SetScaleTransform(1.0f, -1.0f);

That puts the origin at the bottom left, with x increasing to the right and y increasing as you go up. If you use SetWorldTransform as I suggested, the above will work for you.

If you have to use GDI, then you'll want to use SetViewportOrgEx(0, clientRect.bottom), and then set the scaling. I don't remember how to do scaling with the old GDI functions.

Note also that the documentation for SetViewportExtEx says:

When the following mapping modes are set, calls to the SetWindowExtEx and SetViewportExtEx functions are ignored.

  • MM_HIENGLISH
  • MM_HIMETRIC
  • MM_LOENGLISH
  • MM_LOMETRIC
  • MM_TEXT
  • MM_TWIPS

Upvotes: 1

Related Questions