科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件感悟VB细水长流话API(四-2)

感悟VB细水长流话API(四-2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

在前一话中我们初次接触到了坐标的问题,那么当 VB在使用API时应该如何正确使用坐标系呢?这看起来似乎没什么特别的,不过事实并非如此。

作者:张鸿 来源:soft6 2008年5月14日

关键字: API 感悟 VB vb.net Windows

  • 评论
  • 分享微博
  • 分享邮件

感悟VB细水长流话API(四-2)

第五话 坐标系

  在前一话中我们初次接触到了坐标的问题,那么当 VB在使用API时应该如何正确使用坐标系呢?这看起来似乎没什么特别的,不过事实并非如此。

  VB中的坐标系统比较丰富,有Twip、Point、Pixel、 Character、Inch、Millimeter、Centimeter和User。很复杂吧?在这里我要说的是Twip和Pixel,至于剩下的,由于和本文所说的应用无多大关系,请参考MSDN或相关书籍。

  VB中最常用的是Twip的坐标系统,按照微软的说法, Twip是一种与屏幕无关的测量单位,就是说,当我们使用Twip作为单位时,(在打印时)不需要担心屏幕的分辨率。看起来是挺方便的测量单位,但是在API应用中,它却显得有点多余,因为在API中使用的坐标系统是Pixel。Pixel是以像素为单位的测量单位,像素是构成屏幕的最小元素,因此它也是常用的一种测量单位。

  下面让我们来看看如何在API中应用这两个常用的坐标系统。我把上一话的示例扩展了一下,将要用到一个新的 API:ScreenToClient。

Private Declare Function ScreenToClient Lib "user32" (ByVal hwnd As Long, lpPoint As POINTAPI) As Long

  ScreenToClient的作用是把屏幕中的坐标转换为客户区的坐标(关于什么是客户区,请参考前面的文章)。hwnd是客户区对象的句柄,而lpPoint则是已经存放着屏幕坐标的 POINTAPI类型,执行该函数后,lpPoint的内容将被转换为客户区坐标值。

参考图1,它显示了当Form1的坐标系(ScaleMode)设置为Twip时:

1.鼠标在屏幕中的坐标

2.鼠标在Form1中的坐标(即由VB计算出来的客户坐标)

3.把鼠标的屏幕坐标转换为Form1的客户坐标

4.把以Pixel为单位的客户坐标转换为以Twip为单位的客户坐标

看看我是如何计算这4对坐标值的:

Private Sub Form_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)

Dim tC As POINTAPI

GetCursorPos tC

Label1 = "1. Cursor Position: " & tC.X & Space(5) & tC.Y ''注意这里是在屏幕中的坐标

Label2 = "2. Cursor on Form Coordinate: " & X & Space(5) & Y

ScreenToClient Me.hwnd, tC
Label3 = "3. ScreenToClient: " & tC.X & Space(5) & tC.Y ''这里把屏幕中的坐标转换为在 Form1 中的坐标
Label4 = "4. Coordinate after transform: " & tC.X * Screen.TwipsPerPixelX & Space(5) & tC.Y * Screen.TwipsPerPixelY
End Sub

  然后对比图2,和上面同样的代码,把Form1的ScaleMode设置为 Pixel 时计算出来的坐标值。
  在图1中,Form1的ScaleMode是Twip,当把鼠标的屏幕坐标转换为客户坐标时,我们发现它和Form1本身提供的X、Y值不同(2和3不同),这是因为此时VB程序给我们的坐标值是以Twip为单位的。所以这里我提供了一个方法来把以像素为单位的客户坐标转换为以Twip为单位,即把水平和竖直方向的坐标值分别乘以Screen.TwipsPerPixelX和Screen.TwipsPerPixelY(所以2和4相同)。

  Screen.TwipsPerPixelX和Screen.TwipsPerPixelY是由VB本身提供的,它们的作用是得到屏幕中在水平和竖直方向上每个像素各等于多少个Twip。你也可以使用另一个VB提供的方法:ScaleX()和ScaleY(),它们可以帮你把某一坐标系的值转换成另一坐标系的值。然而,作为一种习惯,我还是建议选择第一种方法,它显得直观一些,并且许多时候当看到这样一段代码时,我们可以马上就理解它的作用。

  再看图2,Form1的ScaleMode是Pixel,因此Form1本身提供的X、Y和我们用API计算出来的值是相同的(2和3相同),而不是图1中和被转换为Twip的4相同。

  看了上面的示例,我想你应该知道如何在API中使用 Twip和Pixel了。另外我还想补充一句,在一般应用中,我们使用得最多的还是Twip,原因之一是VB默认是使用它的,之二是用它来控制长度比用Pixel更准确,特别是在涉及到打印时——1 Point等于1/72英寸,1 Twip等于1/20 Point即1/1440英寸,每厘米有567 Twips; 而Pixel却因屏幕显示范围的不同而改变,这必将使得难以掌握打印长度。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章