用P/Invoke訪問native API的問題 - RECT不等于System.Drawing.Rectangle。

(華版)

在昨晚我將以前编冩的某一個PocketPC應用程序(用Native API)换去.NET Compact Framework平台;因為以前只有Native API,所以就碰上一點點問題。。。但總算是迎刃而解!而以下是一點點地收獲和大家分享。

昨晚我下載了PaulYao编冩的API Explorer來找我所需要的Native API聲明方法。刚巧我就需要此GetWindowRect的聲明方法,而問題就是出現在GetWindowRect此API的聲明方法:
 


   o_paulyao.jpg

None.gif < DllImport( " user32.dll " ) >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Function GetWindowRect() Function GetWindowRect( _
InBlock.gif   
ByVal hWnd As IntPtr _
InBlock.gif   , 
ByRef lpRect As System.Drawing.Rectangle _
InBlock.gif   ) 
As Integer
ExpandedBlockEnd.gif
End Function

其實應該是以下的聲明方法才對:

None.gif < StructLayout(LayoutKind.Sequential) >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Structure RECT Structure RECT
InBlock.gif   
Public left As Integer
InBlock.gif   
Public top As Integer
InBlock.gif   
Public right As Integer
InBlock.gif   
Public bottom As Integer
ExpandedBlockEnd.gif
End Structure

None.gif
None.gif
< DllImport( " user32.dll " ) >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Function GetWindowRect() Function GetWindowRect( _
InBlock.gif   
ByVal hWnd As IntPtr _
InBlock.gif   , 
ByRef lpRect As RECT _
InBlock.gif   ) 
As Integer
ExpandedBlockEnd.gif
End Function

只是這样的一個錯誤。。。好攘我調試了好幾個小時也摸不凊到底出錯在那里。。。直到今天早上才發覺此API聲明有問題。因為前者把原有的RECT换去System.Drawing.Rectangle。而刚巧System.Drawing.Rectangle的structure size是大過RECT;所以前者是不會有异常錯誤(Exception Error)發生。但就返回一些不正确的數據。

   o_pinvoke.jpg

闗于進一步去感受两者的區别,我就编冩了一個小小的程序來做個实验。從圖片里我們可以看到用System.Drawing.Rectangle所得到的數據跟用RECT所得到的數據是不一样。此外,我也用Form object里的Top, Left, Right和Bottom的值數來做對比;然而得到的數據就和RECT的一模一样。除了用程序來就証,我也用了Spy++(圖)來做另一項就証;這也証明了用RECT所得到的數據是正确而不是System.Drawing.Rectangle。

   o_spyresult.jpg

除此之外,我也發覺當聲明Native API時要特别留意ANSI和UNICODE的聲明方法。比如説用 FindWindowW在WindowsXP平台去讀取某一個窗口的HWND是&H0;如果用 FindWindowA就可讀取相闗的HWND值數。那是因為 FindWindowW是用于UNICODE平台(PocketPC和WindowsCE)。

None.gif < DllImport( " user32.dll " ) >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Function FindWindowA() Function FindWindowA( _
InBlock.gif   
ByVal lpClassName As String _
InBlock.gif   , 
ByVal lpWindowName As String _
InBlock.gif   ) 
As IntPtr
ExpandedBlockEnd.gif
End Function

None.gif
None.gif
< DllImport( " user32.dll " ) >  _
ExpandedBlockStart.gifContractedBlock.gif
Public   Function FindWindowW() Function FindWindowW( _
InBlock.gif   
ByVal lpClassName As String _
InBlock.gif   , 
ByVal lpWindowName As String _
InBlock.gif   ) 
As IntPtr
ExpandedBlockEnd.gif
End Function

就在解决了我得問題。。。同時也發現了一個討論有闗P/Invoke的網頁 www.pinvoke.net和一個纇似VB6.0 ApiViewer的開發工具 ApiExplorer。如果你是Win32API的爱好者,就不能錯過這两样好的東西哦。

點撃下載代碼

转载于:https://www.cnblogs.com/hackzai/archive/2005/03/15/119195.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值