截圖功能實現(四)自動框選原理
阿新 • • 發佈:2019-02-20
觀察其他截圖工具比如QQ 當滑鼠在某個視窗是會自動把某個視窗高亮顯示,這個功能其實還是很有用的它可以加快截圖時間,可以更快的完成截圖,於是乎我也尋思著如何去實現這個功能,網上翻來翻去好幾天都沒什麼進展,有一天無意間發現一個截圖的Demo有這個功能,因此研究了一下,發現其實原理還是挺簡單的,興奮之餘也拿出來和大家探討下。這個功能分為2部分(下面程式碼是從哪個demo裡找的具體誰寫的我也不知道,先宣告下載這裡 CSDN下載裡有,具體哪個我也忘記有需要的自己下來看看)
第一部分:列舉視窗
桌面上有個Z-order的概念,因此我們需要遍歷整個Z次序的所有視窗,用一個迴圈遍歷,如下虛擬碼
這樣做還是不夠的因為我們現在只是儲存了所有對話方塊,但是對話方塊裡還有控制元件,控制元件中也還有控制元件,那麼要怎麼列舉所有可見的cwnd呢?HWND hWndDesktop = GetDesktopWindow(); HWND hWnd = NULL; do { hWnd = FindWindowEx(hWndDesktop, hWnd, NULL, NULL); if ( IsWindow(hWnd) && IsWindowVisible(hWnd) ) { //儲存所有有效視窗 //dosomething獲取視窗控制代碼,矩形大小等 m_listWindows.push_back(info);//把這些資訊儲存到一個list中 } } while(hWnd != NULL);
上面我們把所有的對話方塊已經儲存到了list中了那麼下面我們從list中取控制元件虛擬碼:
OK這樣當前桌面所有控制元件資訊都已經獲取來了那麼void EnumWindowsCtrl() { iterator iter = m_listWindows.begin(); while (iter != m_listWindows.end() ) { EnumAllCtrl(*iter); ++iter; } } void EnumAllCtrl(Info& win) { HWND parent = win.m_hwnd; HWND child = GetWindow(parent, GW_CHILD); while (child) { if ( IsWindow(child) && IsWindowVisible(child) ) { Info info; info.m_hwnd = child; GetWindowRect(info.m_hwnd, &(info.m_rect) );//列舉這個對話方塊中第一個控制元件裡所有控制元件 win.m_childlist.push_back(info); } child = GetWindow(child, GW_HWNDNEXT); } iterator iter = win.m_childlist.begin(); while ( iter != win.m_childlist.end() )//遞迴另一個控制元件的所有控制元件 { EnumAllCtrl(*iter); ++iter; } }
第二部分就是點在矩形內改如何判斷位置(屬於哪個控制元件)
我們已經把所有的資訊儲存到list了
那麼當一個點過來,我們把點取來給list判斷,注意這裡要判斷這個點在list中最高那層控制元件裡,比如點在一個對話方塊裡的一個控制元件上我們就要把這個控制元件的矩形區域取出來
所以要遍歷m_childlist 到最後。
這部分程式碼比較多我就不貼了
這個時候我們區域已經知道了,那麼實現高亮,就和第二章那裡是一樣拿過來就OK了