在C#中聲明API函數(shù)
如果你已經(jīng)了解了Visual Basic或者Delphi等語(yǔ)言是如何來(lái)實(shí)現(xiàn)對(duì)屏幕圖象捕獲的。那么對(duì)于C#來(lái)說就簡(jiǎn)單多了,是如何實(shí)現(xiàn)這種功能的?本文就來(lái)探討一下這個(gè)問題。
一.程序設(shè)計(jì)開發(fā)及運(yùn)行環(huán)境:
1)微軟視窗2000服務(wù)器版
2).Net FrameWork SDK Beta 2
二.程序設(shè)計(jì)的關(guān)鍵步驟以及具體的實(shí)現(xiàn)方法:
1)首先要?jiǎng)?chuàng)建一個(gè)和當(dāng)前屏幕大小相同的Bitmap對(duì)象:
要實(shí)現(xiàn)此操作,首先就要現(xiàn)獲得當(dāng)前顯示器的DC,然后根據(jù)此DC來(lái)創(chuàng)建Graphic對(duì)象,再由此Graphic對(duì)象產(chǎn)生此位圖對(duì)象。這樣產(chǎn)生的位圖對(duì)象才是和當(dāng)前屏幕大小相一致的。由于要獲得顯示器的DC,利用.Net的類庫(kù)是無(wú)法實(shí)現(xiàn)的,這需要調(diào)用一個(gè)Windows的 API函數(shù)。我們知道視窗所有API都封裝在"Kernel"、"User "和"GDI"三個(gè)庫(kù)中文件中:其中"Kernel",他的庫(kù)名為 "KERNEL32.DLL"。"User "這個(gè)類庫(kù)在Win32中名叫 "USER32.DLL"。 它主要管理全部的用戶接口。譬如:窗口、菜單 、對(duì)話框、圖標(biāo)等等。"GDI"(圖象設(shè)備接口),它在Win32中的庫(kù)名為:"GDI32.dll",要獲得顯示器的DC,所調(diào)用的API函數(shù) --CreateDC ( ),就被封裝在此類庫(kù)中。而要在C#中聲明API函數(shù)需要使用.Net FrameWork SDK中的名字空間"System.Runtime.InteropServices",此名字空間提供了一系列的類來(lái)訪問COM對(duì)象,和調(diào)用本地的API函數(shù)。下面是在C#中聲明API函數(shù):
- [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
- private static extern IntPtr CreateDC (
- string lpszDriver , // 驅(qū)動(dòng)名稱
- string lpszDevice , // 設(shè)備名稱
- string lpszOutput , // 無(wú)用,可以設(shè)定位"NULL"
- IntPtr lpInitData // 任意的打印機(jī)數(shù)據(jù)
- ) ;
在C#中聲明API函數(shù),就可以創(chuàng)建和顯示器大小一致的位圖對(duì)象,具體實(shí)現(xiàn)語(yǔ)句如下:
- IntPtr dc1 = CreateDC ( "DISPLAY" , null , null , ( IntPtr ) null ) ;
- //創(chuàng)建顯示器的DC
- Graphics g1 = Graphics.FromHdc ( dc1 ) ;
- //由一個(gè)指定設(shè)備的句柄創(chuàng)建一個(gè)新的Graphics對(duì)象
- MyImage = new Bitmap ( Screen.PrimaryScreen.Bounds.Width ,
Screen.PrimaryScreen.Bounds.Height , g1 ) ;- //根據(jù)屏幕大小創(chuàng)建一個(gè)與之相同大小的Bitmap對(duì)象
2)根據(jù)此位圖創(chuàng)建一個(gè)和其一樣的Graphic對(duì)象:
通過下面代碼就可以實(shí)現(xiàn)此功能:
- Graphics g2 = Graphics.FromImage ( MyImage ) ;
3)獲得當(dāng)前屏幕和位圖的句柄:
獲得此二個(gè)對(duì)象的句柄是為了下一步實(shí)現(xiàn)對(duì)當(dāng)前屏幕圖象的捕獲,程序中實(shí)現(xiàn)的具體捕獲的方法是把當(dāng)前屏幕捕獲到已經(jīng)創(chuàng)建的位圖對(duì)象中。具體實(shí)現(xiàn)代碼如下:
- //獲得屏幕的句柄
- IntPtr dc3 = g1.GetHdc ( ) ;
- //獲得位圖的句柄
- IntPtr dc2 = g2.GetHdc ( ) ;
- //把當(dāng)前屏幕捕獲到位圖對(duì)象中
4)捕獲當(dāng)前屏幕:
我們是通過當(dāng)前屏幕保存到創(chuàng)建的位圖對(duì)象中來(lái)實(shí)現(xiàn)的,具體的實(shí)現(xiàn)過程中是通過Windows的一個(gè)API函數(shù)--Bitblt。我想大多數(shù)程序員對(duì)此API函數(shù)一定不陌生,因?yàn)樵赪indows的圖象編程中,會(huì)在很多地方使用到此函數(shù)。這個(gè)API函數(shù)和上面介紹的那個(gè)API函數(shù)一樣,也是被封裝在"GDI32.dll"中的,下面是在C#中聲明API函數(shù):
- [ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]
- private static extern bool BitBlt (
- IntPtr hdcDest , // 目標(biāo)設(shè)備的句柄
- int nXDest , // 目標(biāo)對(duì)象的左上角的X坐標(biāo)
- int nYDest , // 目標(biāo)對(duì)象的左上角的X坐標(biāo)
- int nWidth , // 目標(biāo)對(duì)象的矩形的寬度
- int nHeight , // 目標(biāo)對(duì)象的矩形的長(zhǎng)度
- IntPtr hdcSrc , // 源設(shè)備的句柄
- int nXSrc , // 源對(duì)象的左上角的X坐標(biāo)
- int nYSrc , // 源對(duì)象的左上角的X坐標(biāo)
- System.Int32 dwRop // 光柵的操作值
- ) ;
5)把當(dāng)前屏幕保存到硬盤,并釋放句柄:
- g1.ReleaseHdc ( dc3 ) ;
- //釋放屏幕句柄
- g2.ReleaseHdc ( dc2 ) ;
- //釋放位圖句柄
- MyImage.Save ( "c:\\MyJpeg.jpg" , ImageFormat.Jpeg ) ;
我們可以根據(jù)自己的要求把當(dāng)前屏幕以不同的文件格式來(lái)保存,在本文中介紹的程序是以"jpg"文件來(lái)保存的,你可以通過修改"Save"方法的第二個(gè)參數(shù)來(lái)改變保存到硬盤的文件類型,譬如,如果第二個(gè)參數(shù)為"ImageFormat.Gif",那么你保存到硬盤的文件就為"GIF"文件了。對(duì)于其他文件格式可以參考.Net FrameWork SDK,里面有詳細(xì)的介紹。
【編輯推薦】