1. 程式人生 > >MFC通過控制代碼後臺獲取截圖(僅僅支援directx)

MFC通過控制代碼後臺獲取截圖(僅僅支援directx)

作為一個癢癢鼠玩家,由於太多重複性操作,所以決定寫個小指令碼,但是又不會按鍵精靈,索性用的MFC,目前發現對opengl渲染方式截圖的話只會返回一個白麵,所以桌面版涼涼,只能安卓模擬器能用得到了。控制代碼查詢的話,可以用如下語句:

HWND pWnd = ::FindWindowW(NULL, _T("陰陽師 - MuMu模擬器"));

在工作管理員裡面可以找到控制代碼名字,通過獲取到的截圖和定好的圖片比對然後做出判斷並向視窗傳送按鍵或者滑鼠點選訊息,魂十完全可以讓人肝敗嚇瘋。

        HDC hDC = ::GetWindowDC(hWnd);
	ASSERT(hDC);
	HDC hMemDC = ::CreateCompatibleDC(hDC);
	ASSERT(hMemDC);
	RECT rc;
	::GetWindowRect(hWnd, &rc);
	BITMAP bitmap = { 0 };
	HBITMAP hBitmap = ::CreateCompatibleBitmap(hDC, rc.right - rc.left, rc.bottom - rc.top);
	ASSERT(hBitmap);
	HBITMAP hOldBmp = (HBITMAP)::SelectObject(hMemDC, hBitmap);

	//::BitBlt(hMemDC,0,0,rc.right-rc.left,rc.bottom-rc.top,hDC,0,0,SRCCOPY);//也可以用BitBlt獲取截圖
	::PrintWindow(hWnd, hMemDC, 0);//獲取截圖
	
	::GetObject(hBitmap, sizeof(BITMAP), &bitmap);//賦值給bitmap

	/*將bitmap格式圖片轉換為IplImage,便於處理*/
	int depth = (bitmap.bmBitsPixel == 1) ? IPL_DEPTH_1U : IPL_DEPTH_8U;
	int nChannels = (bitmap.bmBitsPixel == 1) ? 1 : bitmap.bmBitsPixel / 8;
	IplImage* img = cvCreateImage(cvSize(bitmap.bmWidth, bitmap.bmHeight), depth, nChannels);
	BYTE *pBuffer = new BYTE[bitmap.bmHeight*bitmap.bmWidth*nChannels];
	GetBitmapBits(hBitmap, bitmap.bmHeight*bitmap.bmWidth*nChannels, pBuffer);
	memcpy(img->imageData, pBuffer, bitmap.bmHeight*bitmap.bmWidth*nChannels);
	delete []pBuffer;                
	IplImage *dst = cvCreateImage(cvGetSize(img), img->depth, 3);//為了便於opencv操作,故而轉此格式
	cvCvtColor(img, dst, CV_BGRA2BGR);
	cvReleaseImage(&img);
        //imwrite(".//mat.jpg", Mat(dst));//將獲取的截圖儲存到當前目錄下
	::SelectObject(hMemDC, hOldBmp);//一定記得釋放,資源,否則容易記憶體洩露....
	::DeleteObject(hBitmap);
	::DeleteObject(hMemDC);
	::ReleaseDC(hWnd, hDC);
        return Mat(dst);

原始碼連結:https://download.csdn.net/download/u011809553/10442092

有一定不同,注意可能管理員許可權執行才能截圖。