 |
我拜读您编写的《深入研究VB.NET》,说真的,我受益不浅,谢谢您!
我现在遇到了一个问题:
我现在想获得一个控件在屏幕上的坐标,由于我以前是用好VB的,所以我理所当然的想到了一个API函数:ClientToScreen,在这个函数中,在这个函数中,要用到一个自定义的变量:Point,由于在VB.NET中与好VB不同,所以我按照您在书上所说的那样,在声明时,作了相应的改变,即保证了该函数在声明时是完全正确的,然后就声明了函数ClientToScreen.我在模块中声明如下:
Module a
<StructLayout(LayoutKind.Sequential)> Public Structure PointAPI
Dim x As Integer
Dim y As Integer
End Structure
Public Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Integer, ByVal lPoint As PointAPI) As Integer
End Module
然后我在窗体中声明一个变量:
Dim LPOINT As PointAPI
ClientToScreen(Me.PictureBox1.Handle.ToInt32(), LPOINT)
但是,在运行时,则出现了问题:系统提示是 "没有将对象的引用传递到对象的实例"。
我想问您一下,这个问题是什么原因?怎么解决?还有没有更好的办法来获得一个控件在屏幕中的坐标? (monk9999)
|
| |
|
 |
先看一下Windows API中关于ClientToScreen的定义:
BOOL ClientToScreen(
HWND hWnd, // handle to window
LPPOINT lpPoint // screen coordinates
);
关键在第2个参数,这里的LPPOINT是POINT类型的指针,在VB中应该定义为ByRef,而不是ByVal。有关ByRef和ByVal的区别在我的书的2.4节已经有介绍,这里不再赘述。正确的定义应该如下:
Public Declare Function ClientToScreen Lib "user32" (ByVal hwnd As Integer, ByRef lPoint As PointAPI) As Integer
尽管从NullReferenceException异常的帮助中找不到这方面的提示,但一般在调用API时遇到NullReferenceException异常,首先应该考虑是否有ByRef的定义问题,这是很容易搞错的。
当然对于你的问题,其实可以不使用API。因为.NET平台的目的是替换掉Windows API,绝大多数API都有对应的.NET方法,所以在VB.NET中调用API的机会比VB6少得多。ClientToScreen可以用System.Windows.Forms.Form.PointToScreen 来代替。对于你的要求,可以使用下面的代码实现:
Dim p1, p2 As Point
p2 = Me.PictureBox1.PointToScreen(p1)
Console.WriteLine(p2.X)
Console.WriteLine(p2.Y)
此问题由李海回答。
附加关键字:编程, 源程序, programming, source code, Visual Basic, VB, 标准控件, screen, button, combo, checkbox, listbox, Windows API, win32, api, windows api, gdi32, kernel。
|
| |
|
| |
|
| |
|
|