1. 程式人生 > 程式設計 >C++開發截圖小程式功能

C++開發截圖小程式功能

C++開發截圖小程式,Win32程式,可以顯示截圖區域並儲存。

上次的流星雨螢幕程式就簡單涉及到GDI繪圖了,這次簡單介紹幾個API函式,涉及到GDI的。

在這裡插入圖片描述

GetDC,獲取當前建立的視窗的裝置環境。
CreateDC,獲取當前螢幕的裝置環境。
CreateCompatibleDC,建立一個相容性的裝置環境(相當於一個虛擬的裝置環境)
BitBlt,這個函式,相當於拷貝,將一個環境的裝置內容拷貝到另一個裝置中。
CreateCompatibleBitmap,建立一塊畫布,將其放在相容性的DC裡面,這樣就可以在裡面畫圖了,當然還要放入畫筆和畫刷這些。

介紹完這些函式之後,那麼設計思路就來了:

1.首先當然還是定義並建立視窗,還有訊息迴圈。

ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;
 
 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hInstance;
 wcex.hIcon = LoadIcon(hInstance,MAKEINTRESOURCE(IDC_CAPTURESCREEN));
 wcex.hCursor = LoadCursor(NULL,IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(BLACK_BRUSH);
 wcex.lpszMenuName = NULL;
 wcex.lpszClassName = szWindowClass;
 wcex.hIconSm = LoadIcon(wcex.hInstance,MAKEINTRESOURCE(IDI_SMALL));

 return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance,int nCmdShow)
{

 hInst = hInstance; // 將例項控制代碼儲存在全域性變數中
 //建立自己的視窗
 hWnd = CreateWindow(szWindowClass,szTitle,WS_POPUP,CW_USEDEFAULT,NULL,hInstance,NULL);

 if (!hWnd)
 {
 return FALSE;
 }
 //顯示和更新視窗
 ShowWindow(hWnd,SW_MAXIMIZE);
 UpdateWindow(hWnd);

 return TRUE;
}

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,_In_opt_ HINSTANCE hPrevInstance,_In_ LPTSTR lpCmdLine,_In_ int  nCmdShow)
{
 //playsound只能播放wav格式,而mcisendstring可以播放任意格式的。
 
 //PlaySound("yixi.wav",SND_FILENAME | SND_ASYNC | SND_LOOP);
 mciSendString("open ./abc.mp3 alias bk",0);
 mciSendString("play bk repeat",0);

 UNREFERENCED_PARAMETER(hPrevInstance);
 UNREFERENCED_PARAMETER(lpCmdLine);

 // TODO: 在此放置程式碼。
 MSG msg;
 HACCEL hAccelTable;

 // 初始化全域性字串
 LoadString(hInstance,IDS_APP_TITLE,MAX_LOADSTRING);
 LoadString(hInstance,IDC_CAPTURESCREEN,szWindowClass,MAX_LOADSTRING);
 
 MyRegisterClass(hInstance); //註冊類

 // 執行應用程式初始化: 
 if (!InitInstance(hInstance,nCmdShow)) //初始化視窗
 {

 return FALSE;
 }

 hAccelTable = LoadAccelerators(hInstance,MAKEINTRESOURCE(IDC_CAPTURESCREEN));

 // 主訊息迴圈: 
 while (GetMessage(&msg,0))
 {
 if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg))
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 }
 return (int)msg.wParam;
}

2.之後獲取當前螢幕的裝置環境,

3.然後將它儲存到相容性的DC中,這就相當於將當前螢幕圖片放到一個緩衝區中。在WM_CREATE訊息裡面做這個動作。

void ScreenDisplay()
{
 HDC disDc = ::CreateDC("DISPLAY",NULL);
 g_memDC = ::CreateCompatibleDC(disDc);
 g_ScreenW = GetDeviceCaps(disDc,HORZRES);
 g_ScreenH = GetDeviceCaps(disDc,VERTRES);
 HBITMAP hbitmap = CreateCompatibleBitmap(disDc,g_ScreenW,g_ScreenH);
 SelectObject(g_memDC,hbitmap);
 BitBlt(g_memDC,g_ScreenH,disDc,SRCCOPY);
}

4.接著再將它放到我們建立的視窗中,這時就會看到整個桌面就不動了,就呈現的是一張圖片,

5.之後我們就可以在這張圖片上繪製我們想擷取的區域。

6.呈現的是靜止的圖片,如果繪製之後,需要更新,這就用到一個函式InvalidateRgn,會無效選定的區域,這樣會觸發訊息WM_PAINT,所以在這個訊息裡面將重新繪製圖形,然後顯示即可。

case WM_PAINT:
 hdc = BeginPaint(hWnd,&ps);
 // TODO: 在此新增任意繪圖程式碼...
 SelectObject(hdc,hpen);
 SelectObject(hdc,hBrush);
 BitBlt(hdc,g_memDC,SRCCOPY);
 Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);
 EndPaint(hWnd,&ps);
break;

接下來就是繪製想要區域的操作,需要用到的幾個滑鼠的訊息函式,滑鼠按下,滑鼠彈起,滑鼠移動,滑鼠雙擊。
那麼思路來了:

滑鼠按下,確定左上角的點,然後滑鼠移動繪製矩形區域,然後滑鼠彈起,確定右下角的點,這樣矩形區域繪製完成。

case WM_LBUTTONDOWN:
{
  if (!Iselect)
  {
   POINT pt;
   GetCursorPos(&pt);
   rect.left = pt.x;
   rect.top = pt.y;
   rect.right = pt.x;
   rect.bottom = pt.x;
   InvalidateRgn(hWnd,FALSE);
   Isdowmn = TRUE;
  }


}
 break;
case WM_LBUTTONUP:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd,FALSE);
  Isdowmn = FALSE;
  Iselect = TRUE;
  }
}
 break;
case WM_MOUSEMOVE:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd,FALSE);
  }
}
 break;

最後滑鼠雙擊將擷取到的圖片儲存剪下板,這樣就完成了螢幕擷取。

case WM_LBUTTONDBLCLK:
 if (Iselect == TRUE)
 {
 int iNum = MessageBox(hWnd,"截圖成功!","張一西",MB_OKCANCEL | MB_ICONINFORMATION);
 if (iNum == 1)
 {
  CopyToCliboard();
  Iselect = FALSE;
  PostQuitMessage(0);
 }
 else
 {
  Iselect = FALSE;
 }
 }
 break;
void CopyToCliboard()
{
 HDC hScreenDC = ::CreateDC("DISPLAY",0);
 HDC memDC = ::CreateCompatibleDC(hScreenDC);
 int Width = rect.right - rect.left-2;
 int Height = rect.bottom - rect.top-2;
 HBITMAP hBmap = CreateCompatibleBitmap(hScreenDC,Width,Height);
 HBITMAP hOldBmap = (HBITMAP)SelectObject(memDC,hBmap);
 BitBlt(memDC,Height,hScreenDC,rect.left+1,rect.top+1,SRCCOPY);
 HBITMAP hNewBmap = (HBITMAP)SelectObject(memDC,hOldBmap);
 if (OpenClipboard(0))      //開啟貼上板
 {
 EmptyClipboard();      //清空貼上板
 SetClipboardData(CF_BITMAP,hNewBmap); //把圖片放入貼上板
 CloseClipboard();      //關閉貼上板
 }
}

程式碼地址:http://xiazai.jb51.net/202004/yuanma/CaptureScreen_jb51.rar

總結

到此這篇關於C++開發截圖小程式的文章就介紹到這了,更多相關C++開發截圖小程式內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!