⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 感悟visualbasic(4).txt

📁 学习(编程技巧_编程知识_程序代码),是学习编程不可多得的学习精验
💻 TXT
字号:
感悟VisualBasic(4)
 

--------------------------------------------------------------------------------
 
张鸿 时间:2003-11-28 10:04:29 
   
经过前几期的连载,我们学到了几个有用的API,也许有的读者会希望我尽快介绍更多的API,不过有许多简单的API的用法是相似甚至相同的,所以为了让读者学到真正有用的知识,在连载的初期,我讲的API将是比较简单而又涉及到相关基础知识的。至于那些用法极相似甚至相同的,我会在适当的时候再介绍它们,只是详细程度和侧重点不同而已。这点希望引起读者的注意。
第四话 使用自定义类型
我在前面已经提到过自定义类型,这次我用一个简单的API来说明一个自定义类型在API中的使用。
VB中规定了自定义类型的变量传递给函数或子程序时必须按引用来传递(关于按引用传递与按值传递,将在以后的文章中做详细介绍),因此下面这个API的声明,你会发现和前面所介绍的几个有少许不同。
Public Declare Function GetCursorPos Lib "user32"Alias "GetCursorPos"(lpPoint As POINTAPI)As Long
相比上一话中的一个API:
Public Declare Function GetSystemDirectory Lib"kernel32"Alias "GetSystemDirectoryA"(ByVal lpBufferAs String,ByVal nSize As Long)As Long可发现参数前面少了个ByVal 。如果不加ByVal,或者把ByVal 换成ByRef,就是按引用传递。POINTAPI 不是VB 的标准数据类型,它是一个自定义类型。从API 浏览器中我们得到它的定义原形是这样的:
Public Type POINTAPI
        x As Long
        y As Long
End Type
这里应该引起注意的是,你应该把POINTAPI 的定义写在使用它的函数声明之前,否则VB 会认为你的类型未定义。你也不可以把 x As Long 和 y As Long 的位置对调,如果对调了,在这个API 中最多只会使原本 x 的值变成 y 的值,y 的值变成 x 的值,但在更复杂的自定义类型中,结果就不可预知了。
这个API 的作用是得到鼠标指针在屏幕中的坐标(以像素为单位)。你可以在自己的程序中试验它,比如:
Dim tCursor As POINTAPI
GetCursorPos tCursor
Debug.Print tCursor.x,tCursor.y
将从调试窗口打印鼠标指针的当前坐标。
第五话 坐标系
在前一话中我们初次接触到了坐标的问题,那么当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 为单位,即把水平和竖直方向的坐标值分别乘以S c r e e n.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更准确,特别是在涉及到打印时——1Point等于1/72英寸,1Twip等于1/20Point即1/1440英寸,每厘米有567Twips;而Pixel却因屏幕显示范围的不同而改变,这必将使得难以掌握打印长度。
程序在Windows98/2000+VB6下调试通过。工程文件下载地址是:http://www.cfan.net.cn/qikan/cxg/0204gwv.zip。
 
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -