VC++基于Dx實(shí)現(xiàn)的截圖程序示例代碼
本文所述的程序示例為VC++圖象特效的截圖示例,需要DirectX 3.0以上版,代碼中的GetScreen函數(shù)是本截圖程序的關(guān)鍵。運(yùn)行這個(gè)程序可用Esc鍵結(jié)束。代碼中需要ddutil.h與ddutil.cpp文件,請(qǐng)自行下載添加。關(guān)于InitDDraw()函數(shù),功能是初始化DirectDraw環(huán)境,創(chuàng)建換頁(yè)鏈(主頁(yè)面,一個(gè)后臺(tái)緩沖區(qū)),以及創(chuàng)建一個(gè)定時(shí)器。
具體的功能代碼如下:
#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#include <math.h>
#include "ddutil.h"
#define TITLE "截圖示例" //窗口標(biāo)題
#define CLASSNAME "GetScreen" //窗口類名
#define COLORS 16
HINSTANCE hInst; //應(yīng)用程序?qū)嵗浔?
HWND hWndMain; //主窗口句柄
LPDIRECTDRAW lpDD; // DirectDraw對(duì)象
LPDIRECTDRAWSURFACE lpDDSPrimary; // 主頁(yè)面
LPDIRECTDRAWSURFACE lpDDSBack; // 后臺(tái)緩沖區(qū)
LPDIRECTDRAWSURFACE lpDDSPic1; // 離屏頁(yè)面1
LPDIRECTDRAWPALETTE lpDDPal; // 調(diào)色板
BOOL bActive; // 應(yīng)用程序是否活躍?
HBITMAP hbm;
RECT rect;
//函數(shù)聲明
void FreeObjects( void );
BOOL InitDDraw(void);
BOOL InitSurfaces(void);
void UpdateFrame(void);
void MakeRect(RECT *rect, long left, long top, long right, long bottom);
///////////////////////////////////////////////
// 截圖函數(shù),是本程序的關(guān)鍵
// 函數(shù)名:GetScreen
// 參數(shù):指向屏幕矩形的指針
// 返值:Bitmap設(shè)備
//////////////////////////////////////////////
HANDLE GetScreen(LPRECT lpRect)
{
//定義屏幕的DC和內(nèi)存DC
HDC hScrDC,hMemDC;
//定義Bitmap設(shè)備
HANDLE hBitmap,hOldBitmap;
//定義屏幕坐標(biāo)變量
unsigned int nX,nY,nX2,nY2;
unsigned int nWidth,nHeight;
//定義屏幕分辯率變量
unsigned int xScrn,yScrn;
//確保屏幕矩形不為空
if(IsRectEmpty(lpRect))
return NULL;
//創(chuàng)建屏幕的DC
hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
//創(chuàng)建的內(nèi)存DC
hMemDC=CreateCompatibleDC(hScrDC);
//將屏幕矩形坐標(biāo)付給坐標(biāo)變量
nX=lpRect->left;
nY=lpRect->top ;
nX2=lpRect->right ;
nY2=lpRect->bottom ;
//獲得屏幕分辯率
xScrn=GetDeviceCaps(hScrDC,HORZRES);
yScrn=GetDeviceCaps(hScrDC,VERTRES);
if(nX<0)
nX=0;
if(nY<0)
nY=0;
if(nX2>xScrn)
nX2=xScrn;
if(nY2>yScrn)
nY2=yScrn;
//獲得屏幕寬度與長(zhǎng)度
nWidth=nX2-nX;
nHeight=nY2-nY;
//獲得屏幕圖像并付給一個(gè)Bitmap設(shè)備
hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight);
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap);
BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,SRCCOPY);
hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
//清除設(shè)備
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return hBitmap;
}
//*******************************************************************
//函數(shù):FreeObject
//功能:釋放所有DirectDraw對(duì)象
//*******************************************************************
void FreeObjects( void )
{
//釋放hbm位圖對(duì)象
DeleteObject(hbm);
if( lpDD != NULL )//釋放DirectDraw對(duì)象
{
if( lpDDSPrimary != NULL )//釋放主頁(yè)面
{
lpDDSPrimary->Release();
lpDDSPrimary = NULL;
}
if( lpDDSPic1 != NULL )//釋放離屏頁(yè)面1
{
lpDDSPic1->Release();
lpDDSPic1 = NULL;
}
if( lpDDPal != NULL )//釋放調(diào)色板
{
lpDDPal->Release();
lpDDPal = NULL;
}
lpDD->Release();
lpDD = NULL;
}
}
//*******************************************************************
//函數(shù):RestoreAll
//功能:頁(yè)面丟失后,恢復(fù)頁(yè)面內(nèi)存
//*******************************************************************
HRESULT RestoreAll( void )
{
HRESULT ddrval;
//恢復(fù)主頁(yè)面,這也將恢復(fù)換頁(yè)鏈中的所有頁(yè)面
ddrval = lpDDSPrimary->Restore();
//恢復(fù)離屏頁(yè)面
ddrval = lpDDSPic1->Restore();
//重新繪制頁(yè)面圖象
InitSurfaces();
return ddrval;
}
//*******************************************************************
//函數(shù):WindowProc
//功能:主窗口的消息處理過(guò)程
//*******************************************************************
LRESULT CALLBACK WinProc( HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam )
{
switch( message )
{
case WM_SETCURSOR:
SetCursor(LoadCursor( NULL, IDC_ARROW ));
return TRUE;
case WM_ACTIVATEAPP://應(yīng)用程序激活消息
bActive = wParam;
break;
case WM_KEYDOWN://擊鍵消息
switch( wParam )
{
case VK_ESCAPE:
PostMessage(hWnd, WM_CLOSE, 0, 0);
break;
}
break;
case WM_DESTROY://銷毀窗口消息
FreeObjects();
PostQuitMessage(0);
break;
}
//調(diào)用缺省的過(guò)程處理過(guò)程
return DefWindowProc(hWnd, message, wParam, lParam);
}
//******************************************************************
//函數(shù):InitWindow()
//功能:創(chuàng)建主窗口。
//******************************************************************
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
WNDCLASS wc; //窗口類結(jié)構(gòu)
//填充窗口類結(jié)構(gòu)
wc.style = 0;
wc.lpfnWndProc = WinProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon( hInstance, IDI_APPLICATION );
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//選擇黑色刷做為窗口背景
wc.lpszMenuName = NULL;
wc.lpszClassName = CLASSNAME;
//注冊(cè)窗口類
RegisterClass( &wc );
//創(chuàng)建主窗口
hWndMain= CreateWindowEx(
0,
CLASSNAME, //窗口的類名稱,必須與上面的wc.lpszClassName一致
TITLE, //窗口的標(biāo)題名
WS_POPUP,
0,
0,
GetSystemMetrics( SM_CXSCREEN ),
GetSystemMetrics( SM_CYSCREEN ),
NULL,
NULL,
hInstance,
NULL );
if( !hWndMain )
return FALSE;
//顯示并更新窗口
ShowWindow( hWndMain, nCmdShow );
return TRUE;
}
//******************************************************************
//函數(shù):InitDDraw()
//功能:初始化DirectDraw環(huán)境,創(chuàng)建換頁(yè)鏈(主頁(yè)面,一個(gè)后臺(tái)緩沖區(qū))
// 以及創(chuàng)建一個(gè)定時(shí)器。
//******************************************************************
BOOL InitDDraw(void)
{
DDSURFACEDESC ddsd;
DDSCAPS ddscaps;
HRESULT ddrval;
//創(chuàng)建DirectDraw對(duì)象
ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
if( ddrval != DD_OK )
return FALSE;
//取得全屏獨(dú)占模式
ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
if( ddrval != DD_OK )
return FALSE;
//設(shè)置顯示器顯示模式為當(dāng)前屏幕的分辯率,16位增強(qiáng)顯示模式
ddrval = lpDD->SetDisplayMode(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), COLORS);
if( ddrval != DD_OK )
return FALSE;
//填充換頁(yè)鏈結(jié)構(gòu)
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP |
DDSCAPS_COMPLEX;
//后臺(tái)緩沖區(qū)數(shù)量為2
ddsd.dwBackBufferCount = 2;
//創(chuàng)建換頁(yè)鏈,包括了主頁(yè)面及其后臺(tái)緩沖區(qū)
ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
if( ddrval != DD_OK )
return FALSE;
//獲得指向后臺(tái)緩沖區(qū)的頁(yè)面指針
ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
if( ddrval != DD_OK )
return FALSE;
//創(chuàng)建離屏頁(yè)面
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth =GetSystemMetrics(SM_CXSCREEN);
ddsd.dwHeight = GetSystemMetrics(SM_CYSCREEN);
if (lpDD->CreateSurface(&ddsd, &lpDDSPic1, NULL) != DD_OK)
return FALSE;
//調(diào)用頁(yè)面初始化函數(shù)
if( !InitSurfaces() )
return FALSE;
return TRUE;
}
//******************************************************************
//函數(shù):WinMain()
//功能:應(yīng)用程序入口
//******************************************************************
int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
hInst=hInstance;
//獲得屏幕分辯率
rect.left=rect.top=0;
rect.right=GetSystemMetrics(SM_CXSCREEN);
rect.bottom=GetSystemMetrics(SM_CYSCREEN);
//調(diào)用截屏函數(shù)
hbm=(HBITMAP)GetScreen(&rect);
//初始化主窗口
if (!InitWindow( hInstance, nCmdShow))
return FALSE;
//初始化DirectDraw環(huán)境
if (!InitDDraw())
{
MessageBox(hWndMain, "初始化DirectDraw過(guò)程中出錯(cuò)!", "Error", MB_OK);
FreeObjects();
DestroyWindow(hWndMain);
return FALSE;
}
//進(jìn)入消息循環(huán)
while(1)
{
if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
{
if(!GetMessage(&msg, NULL, 0, 0 ))
return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(bActive)
{
UpdateFrame();
}
else WaitMessage();
}
return msg.wParam;
}
//******************************************************************
//函數(shù):InitSurfaces()
//功能:初始化頁(yè)面圖象
//******************************************************************
BOOL InitSurfaces( void )
{
if (hbm == NULL)
return FALSE;
DDCopyBitmap(lpDDSPic1, hbm, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
return TRUE;
}
//更新屏幕
void UpdateFrame( void )
{
HRESULT ddrval;
//清屏后臺(tái)緩沖區(qū)
DDBLTFX ddBltFx;
ddBltFx.dwSize = sizeof(DDBLTFX);
ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
//調(diào)用灰度的實(shí)現(xiàn)函數(shù)
RECT srect, drect;
MakeRect(&srect, 0, 0, rect.right ,rect.bottom);
MakeRect(&drect, 0, 0, rect.right , rect.bottom);
//將背景圖象Blit到后臺(tái)緩沖區(qū)
lpDDSBack->Blt(&drect, lpDDSPic1, &srect, DDBLT_WAIT, NULL);
// 換頁(yè)
while( 1 )
{
ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );//調(diào)用換頁(yè)函數(shù)
if( ddrval == DD_OK )//成功則退出while循環(huán)
break;
else if( ddrval == DDERR_SURFACELOST )//如果頁(yè)面丟失,則恢復(fù)頁(yè)面,再繼續(xù)while循環(huán)
RestoreAll();
else
break;
}
}
void MakeRect(RECT *rect, long left, long top, long right, long bottom)
{
rect->left=left;
rect->top=top;
rect->right=right;
rect->bottom=bottom;
}
上一篇:VC實(shí)現(xiàn)讓關(guān)閉按鈕成灰色不可用的方法
欄 目:C語(yǔ)言
下一篇:VC++在TXT文件指定位置追加內(nèi)容的方法
本文標(biāo)題:VC++基于Dx實(shí)現(xiàn)的截圖程序示例代碼
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/3541.html
您可能感興趣的文章
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法
- 01-10C語(yǔ)言 解決不用+、-、&#215;、&#247;數(shù)字運(yùn)算符做加法
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10深入全排列算法及其實(shí)現(xiàn)方法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10用C語(yǔ)言實(shí)現(xiàn)單鏈表的各種操作(一)
- 01-10用C語(yǔ)言實(shí)現(xiàn)單鏈表的各種操作(二)


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫(xiě)分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫(xiě)函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10delphi制作wav文件的方法
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開(kāi)原生自帶讀寫(xiě)NTFS功能(圖文
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


