国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
暴強(qiáng)貼:從.NET平臺(tái)調(diào)用Win32 API - 水之真諦
小序
Win32 API可以直接控制Microsoft Windows的核心,因?yàn)锳PI(Application Programming Interface)本來(lái)就是微軟留給我們直接控制Windows的接口。想玩兒?jiǎn)??呵呵,太難了。
C#使用非常簡(jiǎn)單,寫(xiě)程序就像打拱豬,Sorry  -_-! ,搭積木一樣簡(jiǎn)單。想玩兒?jiǎn)??呵呵,沒(méi)辦法直接控制Windows的核心。
難道就沒(méi)有兩全其美的辦法嗎?當(dāng)然不是!要不微軟的產(chǎn)品早就沒(méi)人買(mǎi)了。其實(shí)從C#(或者說(shuō).NET平臺(tái))調(diào)用Win32 API還是非常簡(jiǎn)單滴~~~~今天偶們大家就一起來(lái)研究研究。
一.    基礎(chǔ)知識(shí)
Win32 API是C語(yǔ)言(注意,不是C++語(yǔ)言,盡管C語(yǔ)言是C++語(yǔ)言的子集)函數(shù)集。C#語(yǔ)言與C語(yǔ)言是完全不同的(除了語(yǔ)法上比較像),所以,要想用C#語(yǔ)言調(diào)用C語(yǔ)言的Win32 API,要費(fèi)上一番周折。首先我們就要準(zhǔn)備一些基礎(chǔ)知識(shí)。
1. Win32 API函數(shù)放在哪里?
Win32 API函數(shù)是Windows的核心,比如我們看到的窗體、按鈕、對(duì)話框什么的,都是依靠Win32函數(shù)“畫(huà)”在屏幕上的,由于這些控件(有時(shí)也稱組件)都用于用戶與Windows進(jìn)行交互,所以控制這些控件的Win32 API函數(shù)稱為“用戶界面”函數(shù)(User Interface Win32 API),簡(jiǎn)稱UI函數(shù);還有一些函數(shù),并不用于交互,比如管理當(dāng)前系統(tǒng)正在運(yùn)行的進(jìn)程、硬件系統(tǒng)狀態(tài)的監(jiān)視等等……這些函數(shù)只有一套,但是可以被所有的Windows程序調(diào)用(只要這個(gè)程序的權(quán)限足夠高),簡(jiǎn)而言之,API是為程序所共享的。為了達(dá)到所有程序能共享一套API的目的,Windows采用了“動(dòng)態(tài)鏈接庫(kù)”的辦法。之所以叫“動(dòng)態(tài)鏈接庫(kù)”,是因?yàn)檫@樣的函數(shù)庫(kù)的調(diào)用方式是“隨用隨取”而不是像靜態(tài)鏈接庫(kù)那樣“用不用都要帶上”。
這里不太好理解,不要緊,我們舉個(gè)小例子。我們把Windows比做一個(gè)游樂(lè)場(chǎng),而把在游樂(lè)場(chǎng)里玩兒的小孩比做一個(gè)一個(gè)程序。小孩在玩的過(guò)程中可能要喝水。我們有兩個(gè)辦法讓小家伙們想喝水的時(shí)候就有水喝:1.給每個(gè)小家伙配一個(gè)水壺,小家伙們喝了的話就喝自己帶的水;2.給游樂(lè)場(chǎng)配一個(gè)飲水機(jī),誰(shuí)渴了誰(shuí)來(lái)喝。顯然,第二個(gè)方法要好得多,這體現(xiàn)在三個(gè)地方。第一,帶著水壺,小家伙身體不靈活、玩不爽(影響程序的速度),況且這只是帶了一個(gè)水壺,要是再帶上飯盒呢?還有輪滑、頭盔、創(chuàng)可貼、紗布……AK-47 My God,如果帶全了就趕上美國(guó)大兵了。所以游樂(lè)園里還是有個(gè)公用“倉(cāng)庫(kù)”要來(lái)的方便,讓大家隨用隨?。▌?dòng)態(tài)鏈接)。第二,小家伙們帶了那么多東西,占了游樂(lè)場(chǎng)很多地方,讓游樂(lè)場(chǎng)擁擠不堪,別的小朋友就進(jìn)不來(lái)了(程序體積大,影響程序和系統(tǒng)的性能)。第三,如果某件物品升級(jí)了,比如水壺從一升的改為二升的,那么每個(gè)小家伙就必須go home去換新的(重新編譯程序,由編譯器把新的靜態(tài)庫(kù)鏈接進(jìn)程序主體里),而第二種情況里,只要游樂(lè)場(chǎng)把自己倉(cāng)庫(kù)里的水壺?fù)Q個(gè)型號(hào),那么所有小家伙就都在同一時(shí)間擁有了大容量的水壺。(悟空!我就一會(huì)兒不在,你怎么就亂丟東西?!打到小朋友多不好~~~~~)
悟空已經(jīng)急了,我就不再嘰嘰歪歪了……呃……Win32 API函數(shù)是放在Windows系統(tǒng)的核心庫(kù)文件中的,這些庫(kù)在硬盤(pán)里的存儲(chǔ)形式是.dll文件。我們常用到的dll文件是user32.dll和kernel32.dll兩個(gè)文件,還有其它一些dll文件也非常重要,大家要在實(shí)踐中多積累經(jīng)驗(yàn)。
我們知道Win32 API函數(shù)是放在dll文件中了,但新問(wèn)題又來(lái)了——我們?cè)趺凑{(diào)用它們呢?這些dll文件是用C語(yǔ)言寫(xiě)的,源代碼經(jīng)C語(yǔ)言編譯器編譯之后,會(huì)以二進(jìn)制可執(zhí)行代碼形式存放在這些dll文件中,就好像蘋(píng)果被打碎機(jī)打成果醬后裝在罐子里一樣——你再也分不清哪個(gè)是你GF給你的,哪個(gè)是你老媽給你的一樣。為了能讓程序使用這些函數(shù),微軟在發(fā)布每個(gè)新的操作系統(tǒng)的時(shí)候,也會(huì)放出這個(gè)系統(tǒng)的SDK,目前最新的是Win2003 SP1 SDK,據(jù)說(shuō)Vista的馬上就要放出來(lái),而且已經(jīng)把UI的API從核心庫(kù)中分離出去以提高系統(tǒng)的穩(wěn)定性了。SDK里有一些C語(yǔ)言的頭文件(.h文件),這些文件里描述了核心dll文件里都有哪些Win32 API函數(shù),在寫(xiě)程序的時(shí)候,把這些.h文件用#include"....."指令包含進(jìn)你的程序里,你就可以使用這些Win32 API了。至于程序是怎樣鏈接的,超出了本文的范圍——也超出了本人的知識(shí)范圍:D
至此,如果你是C語(yǔ)言高手,已經(jīng)可以使用Windows SDK去調(diào)教Windows了!不過(guò),今天我們討論的是C#語(yǔ)言調(diào)用Win32 API的問(wèn)題。我們現(xiàn)在已經(jīng)知道API函數(shù)放在dll動(dòng)態(tài)鏈接庫(kù)文件里,也知道C語(yǔ)言怎么調(diào)用它們了,那么C#語(yǔ)言怎么辦呢?C#語(yǔ)言是不能使用C語(yǔ)言的.h文件的。C#語(yǔ)言也使用dll動(dòng)態(tài)鏈接庫(kù),不過(guò)這些dll都是.NET版本的,具有“自描述性”,也就是自己肚子里都有哪些函數(shù)都已經(jīng)寫(xiě)在自己的metadata里了,不用再附加一個(gè).h文件來(lái)說(shuō)明。現(xiàn)在,我們已經(jīng)找到了問(wèn)題的關(guān)鍵點(diǎn):如何用.NET平臺(tái)上的C#語(yǔ)言來(lái)調(diào)用Win32平臺(tái)上的dll文件。答案非常簡(jiǎn)單:使用DllImport特性。
二.  小試牛刀
下面,就讓我們寫(xiě)一個(gè)小程序,試一試如何用C#語(yǔ)言和DllImport特性來(lái)調(diào)用Win32 API。
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
static int Main()
{
MessageBox(0, "Hello Win32 API", "水之真諦", 4);
Console.ReadLine();
return 0;
}
}
新建一個(gè)C#的控制臺(tái)程序,把VS自動(dòng)生成的代碼清空,把上面的代碼Copy過(guò)去就可以編譯執(zhí)行了。讓我們剖析一下這個(gè)程序:
1. 要使用DllImport這個(gè)特性(特性也是一種類),必須使用這一句using System.Runtime.InteropServices;
,導(dǎo)入“運(yùn)行時(shí)->交互服務(wù)”。喔~~~~運(yùn)行時(shí)的交互服務(wù)不就是“動(dòng)態(tài)鏈接”嗎?感謝Microsoft!
2. 然后我們就可以制造一個(gè)DllImport類的實(shí)例,并把這個(gè)實(shí)例綁定在我們要使用的函數(shù)上了。“特性類”這種類非常怪——制造類實(shí)例的時(shí)候不使用MyClass mc = new MyClass();這種形式,而是使用[特性類(參數(shù)列表)]這種形式;特性類不能獨(dú)立存在,一定要用作修飾其它目標(biāo)上(本例是修飾后面的一個(gè)函數(shù)),不同的特性可以用來(lái)修飾類、函數(shù)、變量等等;特性類實(shí)例在被編譯的時(shí)候也不產(chǎn)生可執(zhí)行代碼,而是被放進(jìn)metadata里以備檢索。總之,你記住特性類很怪就是了,想了解更多就查查MSDN,懶得查就先這么記——不懂慣性定律不影響你學(xué)騎自行車。[DllImport("User32.dll")]是說(shuō)我們要使用的Win32 API函數(shù)在User32.dll這個(gè)文件里。問(wèn)題又來(lái)了:我怎么知道那么多API函數(shù)都在哪個(gè)dll文件里呢?這個(gè)你可以在MSDN里查到,位置是Root->Win32 and COM Development->Development Guides->Windows API->Windows API->Windows API Reference->Functions by Category。打開(kāi)這頁(yè),你會(huì)看到有很多API的分類,API全在這里了。打開(kāi)一個(gè)分類,比如Dialog Box,在Functions段,你會(huì)看到很多具體的函數(shù),其中就有上面用到的MessageBox函數(shù),點(diǎn)擊進(jìn)入。你將打開(kāi)MessageBox的詳細(xì)解釋和具體用法。它的名字、返回值、參數(shù)類型盡收眼底、一覽無(wú)余!而且很練英文哦~~~~在這一頁(yè)的底部,你可以看到一個(gè)小表格,里面有一項(xiàng)“Minimum DLL Version   user32.dll”就是說(shuō)這個(gè)函數(shù)在user32.dll里。
3. 接下來(lái)就是我們的函數(shù)了。在C#里調(diào)用Win32函數(shù)有這么幾個(gè)要點(diǎn)。第一:名字要與Win32 API的完全一樣。第二:函數(shù)除了要有相應(yīng)的DllImport類修飾外,還要聲明成public static extern類型的。第三:也是最變態(tài)的一點(diǎn),函數(shù)的返回值和參數(shù)類型要與Win32 API完全一致!這可難煞我們這群初學(xué)者——Win32的數(shù)據(jù)類型比較搞怪,比如什么LPSTR、什么HINSTANCE都是些蝦米東東呢?給大家一個(gè)小參考,我的Blog里有《Windows數(shù)據(jù)類型探幽——千回百轉(zhuǎn)你是誰(shuí)?》系列拙文,可以查一下。另外在此,我從MSDN里摘出一張表來(lái),是常用Win32數(shù)據(jù)類型與.NET平臺(tái)數(shù)據(jù)類型的對(duì)應(yīng)表:
Non-Pointer Data Types
Win32 TypesSpecificationCLR Type
char, INT8, SBYTE, CHAR8-bit signed integerSystem.SByte
short, short int, INT16, SHORT16-bit signed integerSystem.Int16
int, long, long int, INT32, LONG32, BOOL, INT 32-bit signed integerSystem.Int32
__int64, INT64, LONGLONG64-bit signed integerSystem.Int64
unsigned char, UINT8, UCHAR, BYTE8-bit unsigned integerSystem.Byte
unsigned short, UINT16, USHORT, WORD, ATOM, WCHAR, __wchar_t16-bit unsigned integerSystem.UInt16
unsigned, unsigned int, UINT32, ULONG32, DWORD32, ULONG, DWORD, UINT32-bit unsigned integerSystem.UInt32
unsigned __int64, UINT64, DWORDLONG, ULONGLONG64-bit unsigned integerSystem.UInt64
float, FLOATSingle-precision floating pointSystem.Single
double, long double, DOUBLEDouble-precision floating pointSystem.Double
In Win32 this type is an integer with a specially assigned meaning; in contrast, the CLR provides a specific type devoted to this meaning.
有了這些東西,我們就能把一個(gè)Win32 API函數(shù)轉(zhuǎn)成C#函數(shù)了。還拿MessageBox函數(shù)為例(看剛才給出的函數(shù)表),它的Win32原形如下:
int MessageBox(  HWND hWnd,   LPCTSTR lpText,    LPCTSTR lpCaption,  UINT uType );
函數(shù)名:MessageBox將保持不變。
返回值:int 將保持不變(無(wú)論是Win32還是C#,int都是32位整數(shù))
參數(shù)表:H開(kāi)頭意味著是Handle,一般情況下Handld都是指針類型,Win32平臺(tái)的指針類型是用32位來(lái)存儲(chǔ)的,所以在C#里正好對(duì)應(yīng)一個(gè)int整型。不過(guò),既然是指針,就沒(méi)有什么正負(fù)之分,32位都應(yīng)該用來(lái)保存數(shù)值——這樣一來(lái),用uint(無(wú)符號(hào)32位整型)來(lái)對(duì)應(yīng)Win32的H類型更合理。不過(guò)提醒大家一點(diǎn),int是受C#和.NET CLR雙重支持的,而uint只受C#支持而不受.NET CLR支持,所以,本例還是老老實(shí)實(shí)地使用了int型。(肚子餓了……再堅(jiān)持堅(jiān)持……)
至于LPCTSTR是Long Pointer to Constant String的縮寫(xiě),說(shuō)白了就是——字符串。所以,用C#里的string類型就對(duì)了。
修飾符:要求有相應(yīng)的DllImport和public static extern
經(jīng)過(guò)上面一番折騰,Win32的MessageBox函數(shù)就包裝成C#可以調(diào)用的函數(shù)了:
[DllImport("User32.dll")]
public static extern int MessageBox(int h, string m, string c, int type);
好人做到底,我把四個(gè)參數(shù)的用處也說(shuō)一下:
第一個(gè):彈出的MessageBox的父窗口是誰(shuí)。本例中沒(méi)有,所以是0,也就是“空指針”。
第二個(gè):MessageBox的內(nèi)容。本例中是“Hello Win32 API”。
第三個(gè):MessageBox的標(biāo)題。本例中用的是本人Blog的名字——水之真諦——請(qǐng)大家不要忘記。
第四個(gè):MessageBox上的按鈕是什么,如果是0,那就只有一個(gè)OK,MessageBox太短了,你將看不全“水之真諦”四個(gè)字,于是偶改成了4,這樣就有兩個(gè)按鈕了。這些在MSDN的函數(shù)用法里都有。不過(guò),我還是非常推薦您閱讀一下本人的另一篇拙作《一個(gè)Win32程序的進(jìn)化》 。
至此,一個(gè)麻雀雖小、五毒俱全~~~Sorry  -_-! 五臟俱全的C#調(diào)用Win32 API的程序就分析完了。原理并不難吧!應(yīng)屆生拿去蒙HR足夠了!真正見(jiàn)功底的地方是你使用MSDN、SDK、.NET Framework類庫(kù)VC/VC#的熟練程度。相信我——MSDN+SDK+VC/C#絕對(duì)足夠把Windows收拾得服服帖帖了:D
三. 真的有必要嗎?
嘿嘿嘿嘿……看我的表情,我在壞壞地笑哦!你們都上當(dāng)啦!操作Windows的底層不一定都要調(diào)用Win32 API滴~~~~(哪兒來(lái)的磚頭?。。。?div style="height:15px;">
我想說(shuō)的是:.NET Framework是對(duì)Win32 API的良好封裝,大部分Win32 API函數(shù)都已經(jīng)封裝在了.NET Framework類庫(kù)的各個(gè)類里了。如果說(shuō)Win32 API函數(shù)是散落在地上的珍珠的話,那么.NET Framework就是把這些珍珠按種類分放到了各個(gè)抽屜里——讓我想起我媽來(lái)了——我的書(shū)放得滿地滿床的時(shí)候我總是能找到,她一收拾我就再也找不到了,郁悶。唉……沒(méi)辦法,我們還是仔細(xì)把.NET Framework類庫(kù)好好翻翻吧,會(huì)有很多驚喜哦!
最后,用一個(gè)例子結(jié)束我們的文章吧!
例子是這樣滴~~~~~
那是在很久很久以前,我給一個(gè)公司寫(xiě)程序用來(lái)控制用戶登錄,在登錄之前,用戶不能把鼠標(biāo)移出登錄窗體,因?yàn)橐刂剖髽?biāo),所以我首先想起了調(diào)用Win32 API中與Cursor相關(guān)的函數(shù)來(lái)——于是不管三七二十一、花了九牛二虎之力調(diào)用了Win32 API中的ClipCursor()這個(gè)函數(shù),效果還不錯(cuò)。
結(jié)果前兩天翻.NET Framework類庫(kù)的時(shí)候,發(fā)現(xiàn)System.Windows.Forms.Cursor類的Clip屬性就是專門(mén)做這個(gè)用的!差點(diǎn)沒(méi)把鼻子氣歪了……請(qǐng)大家自己動(dòng)手創(chuàng)建一個(gè)C#的Windows程序,把下面的核心代碼貼到主窗體的雙擊事件里,試一試。做這個(gè)例子的目的就是要告訴大家:1.對(duì)類庫(kù)的了解程序直接決定了你編程的效率和質(zhì)量——用類庫(kù)里的組件比我們“從輪子造起”要快得多、安全得多。2.不到萬(wàn)不得已,不要去直接調(diào)Win32 API函數(shù)——那是不安全的。
private void Form1_DoubleClick(object sender, EventArgs e)
{
Rectangle r = new Rectangle(this.Left, this.Top, this.Width, this.Height);
System.Windows.Forms.Cursor.Clip = r;
}
最后,大家一定非常想知道,.NET Framework都為我們封裝好了哪些Win32 API,OK,MSDN里有一篇文章,專門(mén)列出了這些。文章的名字是《Microsoft Win32 to Microsoft .NET Framework API Map》請(qǐng)感興趣的朋友自己閱讀。
四.  感恩
新年快到了,這篇文章也做為一份小小的禮物,一是博大家一樂(lè),二是讓我們永遠(yuǎn)銘記這幸福的時(shí)刻。
送給對(duì)我有著知遇之恩的陸經(jīng)理;
送給劉瑩Lead感謝在工作中給予的指導(dǎo)和支持;
送給我的Team伙伴樂(lè)蓮、王勇(Worksoft),沒(méi)有你們的幫助,我是不可能開(kāi)始工作的!
送給我宿舍的兄弟張雄,沒(méi)有你,我可能要睡在城鐵站了。
送給段瑋和陳寧,感謝你們組織的活動(dòng)和培訓(xùn)。
送給陳曦、陳建、王勇、常勇、舜賢、挺挺、對(duì)面的女孩李芳,還有本組的JJMM,還有小朱……與你們共事是我最大的快樂(lè)!
文章寫(xiě)完鳥(niǎo)~~~~傾城MM大概也把飯做好鳥(niǎo)~~~~回家鳥(niǎo)~~~~
版權(quán)聲明:本文章受知識(shí)產(chǎn)權(quán)法保護(hù),如果閣下想轉(zhuǎn)載,在轉(zhuǎn)載的時(shí)候煩勞閣下連同在下的姓名一起轉(zhuǎn)載,并向bladey@tom.com發(fā)一個(gè)Mail,我很想知道我的文章都去哪里了.謝謝.
看貼要回貼,不回貼,小心我用彈弓打你家玻璃?。?!
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=557351
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
C#調(diào)用windows API的一些方法
C# 互操作性入門(mén)系列(二):使用平臺(tái)調(diào)用調(diào)用Win32 函數(shù)
請(qǐng)問(wèn)C#高手: [DllImport("kernel32.dll")]是什么意思??
C#也談dll注入
C# Control的Invoke和BeginInvoke及其實(shí)現(xiàn)機(jī)制
C# 調(diào)用 Google Earth Com API開(kāi)發(fā)(二)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服