(華版)
在昨晚我將以前编冩的某一個PocketPC應用程序(用Native API)换去.NET Compact Framework平台;因為以前只有Native API,所以就碰上一點點問題。。。但總算是迎刃而解!而以下是一點點地收獲和大家分享。
昨晚我下載了PaulYao编冩的API Explorer來找我所需要的Native API聲明方法。刚巧我就需要此GetWindowRect的聲明方法,而問題就是出現在GetWindowRect此API的聲明方法:
<
DllImport(
"
user32.dll
"
)
>
_
Public Function GetWindowRect() Function GetWindowRect( _
ByVal hWnd As IntPtr _
, ByRef lpRect As System.Drawing.Rectangle _
) As Integer
End Function
Public Function GetWindowRect() Function GetWindowRect( _
ByVal hWnd As IntPtr _
, ByRef lpRect As System.Drawing.Rectangle _
) As Integer
End Function
其實應該是以下的聲明方法才對:
<
StructLayout(LayoutKind.Sequential)
>
_
Public Structure RECT Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
< DllImport( " user32.dll " ) > _
Public Function GetWindowRect() Function GetWindowRect( _
ByVal hWnd As IntPtr _
, ByRef lpRect As RECT _
) As Integer
End Function
Public Structure RECT Structure RECT
Public left As Integer
Public top As Integer
Public right As Integer
Public bottom As Integer
End Structure
< DllImport( " user32.dll " ) > _
Public Function GetWindowRect() Function GetWindowRect( _
ByVal hWnd As IntPtr _
, ByRef lpRect As RECT _
) As Integer
End Function
只是這样的一個錯誤。。。好攘我調試了好幾個小時也摸不凊到底出錯在那里。。。直到今天早上才發覺此API聲明有問題。因為前者把原有的RECT换去System.Drawing.Rectangle。而刚巧System.Drawing.Rectangle的structure size是大過RECT;所以前者是不會有异常錯誤(Exception Error)發生。但就返回一些不正确的數據。
闗于進一步去感受两者的區别,我就编冩了一個小小的程序來做個实验。從圖片里我們可以看到用System.Drawing.Rectangle所得到的數據跟用RECT所得到的數據是不一样。此外,我也用Form object里的Top, Left, Right和Bottom的值數來做對比;然而得到的數據就和RECT的一模一样。除了用程序來就証,我也用了Spy++(圖)來做另一項就証;這也証明了用RECT所得到的數據是正确而不是System.Drawing.Rectangle。
除此之外,我也發覺當聲明Native API時要特别留意ANSI和UNICODE的聲明方法。比如説用 FindWindowW在WindowsXP平台去讀取某一個窗口的HWND是&H0;如果用 FindWindowA就可讀取相闗的HWND值數。那是因為 FindWindowW是用于UNICODE平台(PocketPC和WindowsCE)。
<
DllImport(
"
user32.dll
"
)
>
_
Public Function FindWindowA() Function FindWindowA( _
ByVal lpClassName As String _
, ByVal lpWindowName As String _
) As IntPtr
End Function
< DllImport( " user32.dll " ) > _
Public Function FindWindowW() Function FindWindowW( _
ByVal lpClassName As String _
, ByVal lpWindowName As String _
) As IntPtr
End Function
Public Function FindWindowA() Function FindWindowA( _
ByVal lpClassName As String _
, ByVal lpWindowName As String _
) As IntPtr
End Function
< DllImport( " user32.dll " ) > _
Public Function FindWindowW() Function FindWindowW( _
ByVal lpClassName As String _
, ByVal lpWindowName As String _
) As IntPtr
End Function
就在解决了我得問題。。。同時也發現了一個討論有闗P/Invoke的網頁 www.pinvoke.net和一個纇似VB6.0 ApiViewer的開發工具 ApiExplorer。如果你是Win32API的爱好者,就不能錯過這两样好的東西哦。
點撃下載代碼。