从TopLeft 0,0到GDI win32中的BottomLeft 0,0

时间:2011-12-21 21:34:05

标签: winapi coordinate-systems

如何将窗口中的坐标从0,0变换为从0到5左右。

我尝试了各种解决方案 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);
我甚至试过谷歌寻求解决方案,但没有优势,所以我转向互联网上经验丰富的人。

我的想法是为线性插值创建自定义控件,我可以在右上角用x,y反转坐标系,但我想要正确。目前,当我尝试绘制它时,我得到一个反向线性插值,因为我无法使坐标成为左下角。

我正在使用win32 api,我怀疑我可以跳过代码,因为屏幕坐标系在所有系统上几乎完全相同,我的意思是0,0是“总是”在屏幕上跳过如果你保持它标准的2d窗口和框架。

我真的不想要一个完整的代码示例来缓解你们的打字痛苦,但是我想要一些方向,因为我似乎无法理解在win32 api中翻转coords的简单概念。

谢谢,圣诞快乐

编辑!

我想在这个问题上添加自己的答案,因为我使用简单的数学来反转视图。

如果举个例子我得到了valuepair x,y(150,57)和另一对x,y(100,75),那么我使用了这个公式height + (-1 * y)并且我得到了一个合适的笛卡尔坐标字段: )在这个示例中,高度是未定义的变量,但在我的应用程序中,它的高度为200px。

1 个答案:

答案 0 :(得分:1)

根据SetViewportOrgEx的文档,您通常希望使用它或SetWindowOrgEx,但不能同时使用它们。也就是说,您可能希望视口原点为(0, clientrect.bottom),而不是-clientrect.bottom

使用GDI设置转换总让我发疯。我认为你最好使用GDI +。有了它,您可以创建一个矩阵,用于描述(0, clientRect.bottom)的转换,以及(1.0, -1.0)的缩放。然后你可以拨打SetWorldTransform

请参阅Using Coordinate Spaces and Transformations上的示例。有关变换的一般信息:Coordinate Spaces and Transformations

其他信息:

我没有尝试使用直接的Windows API调用,但是如果我使用Graphics类(它是GDI +的包装器)在C#中执行以下操作,那么它可以工作:

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

这会使原点位于左下角,x向右增加,y增加。如果您按照我的建议使用SetWorldTransform,则上述内容适用于您。

如果必须使用GDI,那么您将需要使用SetViewportOrgEx(0, clientRect.bottom),然后设置缩放。我不记得如何使用旧的GDI函数进行扩展。

另请注意documentation for SetViewportExtEx说:

  

设置以下映射模式时,调用SetWindowExtEx   和SetViewportExtEx函数被忽略。

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