转自:http://hi.baidu.com/lincisheng/blog/item/81bb584de70c14c7d1c86ab1.html
历经艰辛,终于完成了了屏幕截图程序,代码如下:
'VB.NET中进行图象捕获 ,需要先引用一些API,以下是声明:
Private Declare Function CreateCompatibleDC Lib "GDI32" (ByVal hDC As Integer) As Integer Private Declare Function CreateCompatibleBitmap Lib "GDI32" (ByVal hDC As Integer,ByVal nWidth As Integer,ByVal nHeight As Integer) As Integer Private Declare Function SelectObject Lib "GDI32" (ByVal hDC As Integer,ByVal hObject As Integer) As Integer Private Declare Function BitBlt Lib "GDI32" (ByVal srchDC As Integer,ByVal srcX As Integer,ByVal srcY As Integer,ByVal srcW As Integer,ByVal srcH As Integer,ByVal desthDC As Integer,ByVal destX As Integer,ByVal destY As Integer,ByVal op As Integer) As Integer Private Declare Function DeleteDC Lib "GDI32" (ByVal hDC As Integer) As Integer Private Declare Function DeleteObject Lib "GDI32" (ByVal hObj As Integer) As Integer Declare Function GetDC Lib "user32" Alias "GetDC" (ByVal hwnd As Integer) As Integer Const SRCCOPY As Integer = &HCC0020 '抓屏-在Form中添加一个button Private Sub Button1_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles Button1.Click Dim hDC,hMDC As Integer Dim hBMP,hBMPOld As Integer Dim sw,sh As Integer hDC = GetDC(0) hMDC = CreateCompatibleDC(hDC) sw = Screen.PrimaryScreen.Bounds.Width sh = Screen.PrimaryScreen.Bounds.Height hBMP = CreateCompatibleBitmap(hDC,sw,sh) hBMPOld = SelectObject(hMDC,hBMP) BitBlt(hMDC,sh,hDC,SRCCOPY) hBMP = SelectObject(hMDC,hBMPOld) '如果直接将图片保存,就不要放在PictureBox中,另外,要做的好用,应该增加一个Notifyico控件,再设置一个ContextMenuStrip1控件,不明白的请在百度上HI我: PictureBox1.Image = Image.FromHbitmap(New IntPtr(hBMP)) DeleteDC(hDC) DeleteDC(hMDC) DeleteObject(hBMP) Me.Button2.Enabled = True End Sub '保存图像-在Form中添加一个button Private Sub Button2_Click(ByVal sender As System.Object,ByVal e As System.EventArgs) Handles Button2.Click '在form中增加一个OpenFileDialog1控件 Dim ofd As OpenFileDialog = Me.OpenFileDialog1 ofd.Filter = "jpg file|*.jpg|bmp file|*.bmp" Dim bmp As Bitmap = Me.PictureBox1.Image If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then bmp.Save(ofd.FileName) End If End Sub以上使用到的技术资料如下: 才疏学浅,只能粗略讲一下啦 SourceDC = CreateDC("DISPLAY",0) '以屏幕为源建立一个设备场景 DestDC = CreateCompatibleDC(SourceDC) '在内存中建立一个与刚才建立的设备场景一致的设备场景 Bhandle = CreateCompatibleBitmap(SourceDC,400,300) '显示区域设置 '在内存中建立一幅与刚建立的设备场景相兼容的位图 SelectObject DestDC,Bhandle '这句难理解一点,不乱说了,回头给你看API说明 BitBlt DestDC,100,300,SourceDC,&HCC0020 '设置抓图区域 '在两个设备场景(DestDC和SourceDC)间复制位图 Wnd = Screen.ActiveForm.hwnd OpenClipboard Wnd EmptyClipboard SetClipboardData 2,Bhandle CloseClipboard '这一段是对剪贴板的操作,我的API工具中没有相关说明 '大体意思应该是把刚才在内存中建立的位图放到剪贴板中 DeleteDC DestDC '删除一个设备场景 ReleaseDC Dhandle,SourceDC '在内存中释放掉一个设备场景 Picture1.Picture = Clipboard.GetData() '这句不用解释了吧,把剪贴板中的位图下载到Picture1中 ======================== 下面是我在API工具中查到的相关说明,但愿对你有帮助 CreateDC 【说明】 为专门设备创建设备场景 【返回值】 Long,新设备场景句柄,若出错则为零 【其它】 在绘制之前,先要为该设备场景选定一个位图。不再需要时,该设备场景可用DeleteDC函数删除。删除前,其所有对象应回复初始状态。若有设备初始设置可用DocumentProperties API函数载入DEVMODE结构。使用屏幕设备场景(DISPLAY)时要小心,因为它会干扰其他应用程序的外观 示例:靠近屏幕左上角画一个矩形 dc& = CreateDCBynum("DISPLAY",vbNullString,0) dl& = Rectangle(dc&,5,100) 【参数表】 lpDriverName --- String,用vbNullString传递null值给该参数,除非:1、用DISPLAY,是获取整个屏幕的设备场景;2、用WINSPOOL,则是访问打印驱动 lpDeviceName --- String,所用专门设备的名称。该名由打印管理器分配显示 lpOutput ------- String,用vbNullString传递null值给该参数 lpInitData ----- DEVMODE,这个结构保存初始值。用CreateDCBynum传递0(NULL)值则适用默认设置 CreateCompatibleDC 【说明】 创建一个与特定设备场景一致的内存设备场景 【返回值】 Long,新设备场景句柄,若出错则为零 【其它】 在绘制之前,先要为该设备场景选定一个位图。不再需要时,该设备场景可用DeleteDC函数删除。删除前,其所有对象应回复初始状态 【参数表】 hdc ------------ Long,设备场景句柄。新的设备场景将与它一致。也可能为0以创建一个与屏幕一致的设备场景 CreateCompatibleBitmap 【说明】 创建一幅与设备有关位图,它与指定的设备场景兼容 【返回值】 Long,执行成功返回位图句柄,零表示失败 【其它】 内存设备场景即与彩色位图兼容,也与单色位图兼容。这个函数的作用是创建一幅与当前选入hdc中的场景兼容。对一个内存场景来说,默认的位图是单色的。倘若内存设备场景有一个DIBSection选入其中,这个函数就会返回DIBSection的一个句柄。如hdc是一幅设备位图,那么结果生成的位图就肯定兼容于设备(也就是说,彩色设备生成的肯定是彩色位图) 如果nWidth和nHeight为零,返回的位图就是一个1×1的单色位图 一旦位图不再需要,一定用DeleteObject函数释放它占用的内存及资源 【参数表】 hdc ------------ Long,设备场景的句柄 nWidth --------- Long,位图宽度,以像素为单位 nHeight -------- Long,位图高度,以像素为单位 SelectObject 【说明】 每个设备场景都可能有选入其中的图形对象。其中包括位图、刷子、字体、画笔以及区域等等。一次选入设备场景的只能有一个对象。选定的对象会在设备场景的绘图操作中使用。例如,当前选定的画笔决定了在设备场景中描绘的线段颜色及样式 【返回值】 Long,与以前选入设备场景的相同hObject类型的一个对象的句柄,零表示出错。如选定的对象是一个区域(Region),结果就是下列常数之一:SIMPLEREGION, COMPLEXREGION 或 NULLREGION 对区域进行描述, GDI_ERROR 表示出错 【其它】 返回值通常用于获得选入DC的对象的原始值。绘图操作完成后,原始的对象通常选回设备场景。在清除一个设备场景前,务必注意恢复原始的对象 【参数表】 hdc ------------ Long,一个设备场景的句柄 hObject -------- Long,一个画笔、位图、刷子、字体或区域的句柄 BitBlt 【说明】 将一幅位图从一个设备场景复制到另一个。源和目标DC相互间必须兼容 【返回值】 Long,非零表示成功,零表示失败。会设置GetLastError 【其它】 在NT环境下,如在一次世界传输中要求在源设备场景中进行剪切或旋转处理,这个函数的执行会失败 如目标和源DC的映射关系要求矩形中像素的大小必须在传输过程中改变,那么这个函数会根据需要自动伸缩、旋转、折叠、或切断,以便完成最终的传输过程 【参数表】 hDestDC -------- Long,目标设备场景 x,y ------------ Long,对目标DC中目标矩形左上角位置进行描述的那个点。用目标DC的逻辑坐标表示 nWidth,nHeight - Long,欲传输图象的宽度和高度 hSrcDC --------- Long,源设备场景。如光栅运算未指定源,则应设为0 xSrc,ySrc ------ Long,对源DC中源矩形左上角位置进行描述的那个点。用源DC的逻辑坐标表示 dwRop ---------- Long,传输过程要执行的光栅运算 (插一句:&HCC0020应该是一个光栅运算的常数vbSrcCopy) DeleteDC 【说明】 删除专用设备场景或信息场景,释放所有相关窗口资源。不要将它用于GetDC函数取回的设备场景 【返回值】 Long,执行成功则为非零,失败则为零 【其它】 若有对象被选入设备场景,则在调用本函数前应将它们选出。为此,可将初始对象回选入DC,也可用SaveDC, RestoreDC函数对回复DC为其创建时的状态 在vb里使用 不要将它用于由vb hdc属性获取的设备场景句柄 【参数表】 hdc ------------ Long,将要删除的设备场景 ReleaseDC 【说明】 释放由调用GetDC或GetWindowDC函数获取的指定设备场景。它对类或私有设备场景无效(但这样的调用不会造成损害) 【返回值】 Long,执行成功为1,否则为0 【其它】 对那些用CreateDC一类的DC创建函数生成的设备场景,不要用本函数 【参数表】 hwnd ----------- Long,要释放的设备场景相关的窗口句柄 hdc ------------ Long,要释放的设备场景句柄