有意思的程序——抓取屏幕

本文由BlueCoder編寫   轉載請說明出處:

http://blog.csdn.net/crocodile__/article/details/9769767

我的郵箱:[email protected]    歡迎大家和我交流編程心得

我的微博:BlueCoder_黎小華    歡迎光臨^_^




Win32學了一段時間了,跟着楊老師的腳步,準備學習MFC,因此最近幾天在複習C++,於是發現有將近一週沒寫博文了……

 

今天來寫一個較爲簡單、但是比較有意思的東西

 

不知大家在理髮店理髮的時候注意到一個奇觀沒:

理髮店一般都有兩面對立的鏡子,你仔細一看會發現,兩面鏡子裏面的成像逐漸縮小,並且居中排列,很有意思

 

盜夢空間中也有一個類似的場景,我截了一個圖:

 

 

 

 

yes,今天就來做一個這樣的效果,只不過是抓的屏幕

好吧,先來看看程序運行效果,來對比一下:

 

 

 

 

 

 

下面進入主題,剖析實現細節,主要分兩大步:

(1)要對屏幕"工作",在Win32中必須獲取屏幕的hdc。有兩種主要的方式:

1)GetDC(HWND), 傳遞參數NULL——GetDC(NULL)

2)CreateDC(TEXT("DISPLAY"),  NULL, NULL, NULL);

(2)貼圖

獲取環境hdc後,在hdc中會保存屏幕的狀態——相當於屏幕的截圖,只是用bmp保存的

今天貼圖用一個更好的函數StretchBlt,它有一個很好的功能——可以按比例縮放bmp位圖,然後顯示:

BOOL StretchBlt(
  HDC hdcDest,      // handle to destination DC
  int nXOriginDest, // x-coord of destination upper-left corner
  int nYOriginDest, // y-coord of destination upper-left corner
  int nWidthDest,   // width of destination rectangle
  int nHeightDest,  // height of destination rectangle
  HDC hdcSrc,       // handle to source DC
  int nXOriginSrc,  // x-coord of source upper-left corner
  int nYOriginSrc,  // y-coord of source upper-left corner
  int nWidthSrc,    // width of source rectangle
  int nHeightSrc,   // height of source rectangle
  DWORD dwRop       // raster operation code
);

使用方法和BitBlt很類似,應該不用贅述了……

 

 

具體核心實現代碼如下:

int	cxScreen, cyScreen;//全局變量——屏幕的長寬,用於窗口居中和縮放顯示bmp

 

hdcCli = BeginPaint(hwnd, &ps);

hdcScr = GetDC(NULL);

 

//循環3次

i = 0;
while(i<3)
{
 //按比例顯示桌面截圖
 StretchBlt(hdcCli, 0, 0, cxClient, cyClient, hdcScr, 0, 0, cxScreen, cyScreen, SRCCOPY);
 i++;
}


DeleteDC(hdcScr);
EndPaint(hwnd, &ps);


 

 

 

這種方式很簡單,當然我肯定不會簡單用一下這個函數就了事了,這個沒什麼大不了的,下面我在介紹一種使用GDI映射模式+BitBlt來貼bmp位圖,實現效果和上面說的完全一樣

 

BitBlt函數沒有縮放功能,我就用映射模式來實現縮放功能,縮放的具體實現代碼如下:

hdcCli = BeginPaint(hwnd, &ps);

hdcScr = GetDC(NULL);

SetMapMode(hdcCli, MM_ANISOTROPIC);//設定x、y方向異性模式,就是說x、y方向可以不同
SetWindowExtEx(hdcCli, cxScreen, cyScreen, NULL);//設定窗口範圍
SetViewportExtEx(hdcCli, cxClient, cyClient, NULL);//設定視口範圍
//這樣就能將cxScreen * cyScreen的大小縮放爲cxClient * cyClient的大小,就是將屏幕大小縮小爲客戶區大小
//循環3次
i = 0;
while(i<3)
{
	//由於已經在內存中縮放了屏幕bmp位圖,這裏就可直接貼圖
	BitBlt(hdcCli, 0, 0, cxScreen, cyScreen, hdcScr, 0, 0, SRCCOPY);//直接顯示
	i++;
}


DeleteDC(hdcScr);
EndPaint(hwnd, &ps);

 

這兩種方式實現的效果完全一樣,多一種方式,多一種思路,這樣才能提高能力……

 

源代碼下載
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章