程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> VC++基於Dx完成的截圖法式示例代碼

VC++基於Dx完成的截圖法式示例代碼

編輯:關於C++

VC++基於Dx完成的截圖法式示例代碼。本站提示廣大學習愛好者:(VC++基於Dx完成的截圖法式示例代碼)文章只能為提供參考,不一定能成為您想要的結果。以下是VC++基於Dx完成的截圖法式示例代碼正文


本文所述的法式示例為VC++圖像殊效的截圖示例,須要DirectX 3.0以上版,代碼中的GetScreen函數是本截圖法式的症結。運轉這個法式可用Esc鍵停止。代碼中須要ddutil.h與ddutil.cpp文件,請自行下載添加。關於InitDDraw()函數,功效是初始化DirectDraw情況,創立換頁鏈(主頁面,一個後台緩沖區),和創立一個准時器。

詳細的功效代碼以下:

#include <windows.h>
#include <windowsx.h>
#include <stdio.h>
#include <ddraw.h>
#include <math.h>
#include "ddutil.h"
#define TITLE "截圖示例" //窗口題目
#define CLASSNAME "GetScreen" //窗口類名
#define COLORS 16
HINSTANCE hInst; //運用法式實例句柄
HWND hWndMain; //主窗口句柄
LPDIRECTDRAW      lpDD;      // DirectDraw對象
LPDIRECTDRAWSURFACE   lpDDSPrimary;  // 主頁面
LPDIRECTDRAWSURFACE   lpDDSBack;   // 後台緩沖區
LPDIRECTDRAWSURFACE   lpDDSPic1;   // 離屏頁面1
LPDIRECTDRAWPALETTE   lpDDPal;    // 調色板
BOOL          bActive;    // 運用法式能否活潑?
HBITMAP hbm;
RECT rect;
//函數聲明
void FreeObjects( void );
BOOL InitDDraw(void);
BOOL InitSurfaces(void);
void UpdateFrame(void);
void MakeRect(RECT *rect, long left, long top, long right, long bottom);
///////////////////////////////////////////////
// 截圖函數,是本法式的症結
// 函數名:GetScreen
// 參數:指向屏幕矩形的指針
// 返值:Bitmap裝備
//////////////////////////////////////////////
HANDLE GetScreen(LPRECT lpRect)
{
 //界說屏幕的DC和內存DC
 HDC hScrDC,hMemDC;
 //界說Bitmap裝備
 HANDLE hBitmap,hOldBitmap;
 //界說屏幕坐標變量
 unsigned int nX,nY,nX2,nY2;
 unsigned int nWidth,nHeight;
 //界說屏幕分辨率變量
 unsigned int xScrn,yScrn;
 //確保屏幕矩形不為空
 if(IsRectEmpty(lpRect))
 return NULL;
 //創立屏幕的DC
 hScrDC=CreateDC("DISPLAY",NULL,NULL,NULL);
 //創立的內存DC
 hMemDC=CreateCompatibleDC(hScrDC);
 //將屏幕矩形坐標付給坐標變量
 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;
 //取得屏幕寬度與長度
 nWidth=nX2-nX;
 nHeight=nY2-nY;
 //取得屏幕圖象並付給一個Bitmap裝備
 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);
 //消除裝備
 DeleteDC(hScrDC);
 DeleteDC(hMemDC);
 return hBitmap;
}
//*******************************************************************
//函數:FreeObject
//功效:釋放一切DirectDraw對象
//*******************************************************************
void FreeObjects( void )
{
 //釋放hbm位圖對象
  DeleteObject(hbm);

  if( lpDD != NULL )//釋放DirectDraw對象
  {
    if( lpDDSPrimary != NULL )//釋放主頁面
    {
      lpDDSPrimary->Release();
      lpDDSPrimary = NULL;
    }
    if( lpDDSPic1 != NULL )//釋放離屏頁面1
    {
      lpDDSPic1->Release();
      lpDDSPic1 = NULL;
    }
    if( lpDDPal != NULL )//釋放調色板
    {
      lpDDPal->Release();
      lpDDPal = NULL;
    }
    lpDD->Release();
    lpDD = NULL;
  }
} 
//*******************************************************************
//函數:RestoreAll
//功效:頁面喪失後,恢復頁面內存
//*******************************************************************
HRESULT RestoreAll( void )
{
  HRESULT   ddrval;
 //恢復主頁面,這也將恢復換頁鏈中的一切頁面
  ddrval = lpDDSPrimary->Restore();
 //恢復離屏頁面
  ddrval = lpDDSPic1->Restore();
 //從新繪制頁面圖像
 InitSurfaces();
  return ddrval;
}
//*******************************************************************
//函數:WindowProc
//功效:主窗口的新聞處置進程
//*******************************************************************
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://運用法式激活新聞
    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;
  }
 //挪用缺省的進程處置進程
  return DefWindowProc(hWnd, message, wParam, lParam);
}
//******************************************************************
//函數:InitWindow()
//功效:創立主窗口。
//******************************************************************
BOOL InitWindow( HINSTANCE hInstance, int nCmdShow )
{
  WNDCLASS wc; //窗口類構造
 //填充窗口類構造
  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;
 //注冊窗口類
  RegisterClass( &wc );
 //創立主窗口
  hWndMain= CreateWindowEx(
 0,
 CLASSNAME, //窗口的類稱號,必需與下面的wc.lpszClassName分歧
 TITLE, //窗口的題目名
 WS_POPUP,
 0,
 0,
 GetSystemMetrics( SM_CXSCREEN ),
 GetSystemMetrics( SM_CYSCREEN ),
 NULL,
 NULL,
 hInstance,
 NULL );
  if( !hWndMain ) 
 return FALSE;
 //顯示並更新窗口
  ShowWindow( hWndMain, nCmdShow );
 return TRUE;
}

//******************************************************************
//函數:InitDDraw()
//功效:初始化DirectDraw情況,創立換頁鏈(主頁面,一個後台緩沖區)
// 和創立一個准時器。
//******************************************************************
BOOL InitDDraw(void)
{
  DDSURFACEDESC    ddsd;
  DDSCAPS       ddscaps;
  HRESULT       ddrval;
  //創立DirectDraw對象
 ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
  if( ddrval != DD_OK )
    return FALSE;
  //獲得全屏獨有形式
  ddrval = lpDD->SetCooperativeLevel( hWndMain, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
  if( ddrval != DD_OK )
    return FALSE;
  //設置顯示器顯示形式為以後屏幕的分辨率,16位加強顯示形式
  ddrval = lpDD->SetDisplayMode(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), COLORS);
  if( ddrval != DD_OK )
    return FALSE;
  //填充換頁鏈構造
  ddsd.dwSize = sizeof( ddsd );
  ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
  ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
             DDSCAPS_FLIP |
             DDSCAPS_COMPLEX;
 //後台緩沖區數目為2
  ddsd.dwBackBufferCount = 2;
 //創立換頁鏈,包含了主頁面及厥後台緩沖區
  ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
  if( ddrval != DD_OK )
    return FALSE;
  //取得指向後台緩沖區的頁面指針
 ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
  ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
  if( ddrval != DD_OK )
    return FALSE;
 //創立離屏頁面
 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;
 //挪用頁面初始化函數
 if( !InitSurfaces() )
    return FALSE;
  return TRUE;
}

//******************************************************************
//函數:WinMain()
//功效:運用法式進口
//******************************************************************
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);
 //挪用截屏函數
 hbm=(HBITMAP)GetScreen(&rect);
 //初始化主窗口
 if (!InitWindow( hInstance, nCmdShow))
  return FALSE;
 //初始化DirectDraw情況
 if (!InitDDraw())
 {
 MessageBox(hWndMain, "初始化DirectDraw進程中失足!", "Error", MB_OK);
 FreeObjects();
 DestroyWindow(hWndMain);
 return FALSE;
 }

 //進入新聞輪回
 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;
} 
//******************************************************************
//函數:InitSurfaces()
//功效:初始化頁面圖像
//******************************************************************
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;
 //清屏後台緩沖區
 DDBLTFX ddBltFx;
 ddBltFx.dwSize = sizeof(DDBLTFX);
 ddBltFx.dwFillColor = DDColorMatch(lpDDSBack, RGB(0,0,0));
 lpDDSBack->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddBltFx);
 //挪用灰度的完成函數
 RECT srect, drect;
 MakeRect(&srect, 0, 0, rect.right ,rect.bottom);
 MakeRect(&drect, 0, 0, rect.right , rect.bottom);
 //將配景圖像Blit到後台緩沖區
 lpDDSBack->Blt(&drect, lpDDSPic1, &srect, DDBLT_WAIT, NULL);
  // 換頁
  while( 1 )
  {
    ddrval = lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );//挪用換頁函數
    if( ddrval == DD_OK )//勝利則加入while輪回
      break;
    else if( ddrval == DDERR_SURFACELOST )//假如頁面喪失,則恢復頁面,再持續while輪回
      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;
}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved