實現牛牛截圖控件的初衷,是想在學習的同時,實現一個具有當前主流截圖功能的插件,方便集成進不一樣的應用系統中,節省開發時間。瀏覽器
一直以來,都對目前各主流即時通信軟件的截圖效果比較喜歡,前段時間專門花時間進行了一些研究,實現了本身的一個截圖控件,我給它取名叫「牛牛截圖」;此控件可無償使用,開放了調用的接口,有興趣的朋友能夠試一下,具體的調用方法及使用示例見下文。函數
1. 本控件實現的基本功能及特色以下工具
1). 支持窗口區域的自動識別學習
2). 支持矩形、圓形、箭頭、文字的繪製以及撤銷測試
3). 可另存爲png、jpg、bmp等格式ui
4). 支持鼠標所在區域的圖像放大功能,以便精準定位spa
5). 窗口大小、鼠標座標顯示以及光標處的顏色拾取操作系統
6). 採用C++語言開發的Win32動態庫,大小爲260KB.net
7). 支持XP、WIN七、WIN8及WIN200三、WIN2008等操做系統;插件
8). 此控件提供標準的接口,方便集成進其餘軟件中;
例如能夠與瀏覽器控件整合,實現Web頁面截圖的功能,也能夠與其餘如即時通信等其餘任何系統中
先看看使用效果:
2. 控件使用方法
1). 在測試程序中點擊啓動截圖[在集成此控件後,能夠自行經過熱鍵進行啓動],按下鼠標左鍵並拖動,以肯定須要截圖的範圍,也能夠直接在自動識別到的窗口上點擊一下鼠標左鍵,肯定截圖範圍;此時能夠經過放大的區域來精肯定位截圖區域。
2). 肯定截圖範圍後,工具欄將會顯示出來,選中指定的繪製類型[繪製類型、大小、顏色],能夠進行二次繪製塗鴉。
3). 能夠經過點擊撤銷按鈕來取消上一筆所繪製的形狀。
4). 在截圖的過程當中,能夠按ESC鍵或者點擊鼠標右鍵來取消截圖。
5). 按下回車鍵或者在截圖區域內雙擊鼠標左鍵,能夠完成截圖[也能夠點擊工具欄上的「完成」按鈕]。
6). 點擊「保存」按鈕,能夠將所截區域保存至圖片文件。
3. 控件接口的使用方法
能夠在程序中使用LoadLibrary的方式加載此控件,進行初始化後,直接調用啓動截圖的函數便可:
typedef int (*FnStartScreenCapture)(const char* szAuth, const char* szDefaultSavePath, void* pCallBack, unsigned long hWndNotice, unsigned int noticeMsg); FnStartScreenCapture m_StartScreenCapture = NULL; typedef int (*FnInitScreenCapture)(unsigned long trackerColor, unsigned long editBorderColor, int nTransparent, int flag); FnInitScreenCapture m_InitCapture = NULL; //加載截圖控件 m_hModule = LoadLibrary("NiuniuCapture.dll"); m_StartScreenCapture = (FnStartScreenCapture)GetProcAddress(m_hModule, "StartScreenCapture"); m_InitCapture = (FnInitScreenCapture)GetProcAddress(m_hModule, "InitScreenCapture"); m_InitCapture(RGB(255, 0, 0), RGB(0, 174, 255), 180, 0); m_StartScreenCapture("niuniu", "", NULL, (unsigned long)m_hWnd, WM_USER + 1111);
具體能夠參考調用Capturedemo_source.rar [下載地址見本文末尾],接口的具體描述以下:
1). 初始化接口
int InitScreenCapture(unsigned long trackerColor, unsigned long editBorderColor, int nTransparent, int flag);
此接口函數用於初始化界面的顯示效果,若是不調用,則以默認值處理。
參數說明:
參數名 |
參數類型 |
參數說明 |
備註 |
trackerColor |
COLORREF |
用於設置橡皮筋框的顏色以及自動識別窗口的邊框色 |
若是不調用此函數,則此框顏色默認爲: RGB(0, 174, 255); |
editBorderColor |
COLORREF |
用於設置文本輸入框的邊框顏色 |
若是不調用此函數,則此框顏色默認爲: RGB(255, 0, 0); |
nTransparent |
int |
用於指定工具欄窗口的透明度(0-255) |
若是不調用此函數,則透明度默認爲200 |
flag |
int |
暫未使用 |
|
2). 啓動截圖接口:
int StartScreenCapture(const char* szAuth, const char* szDefaultSavePath, void* pCallBack, unsigned long hWndNotice, unsigned int noticeMsg);
參數說明:
參數名 |
參數類型 |
參數說明 |
備註 |
szAuth |
字符串 |
用於調用控件時的受權 |
目前固定傳入」niuniu」便可 |
szDefaultSavePath |
字符串 |
用於指定在截圖完成時自動保存的文件路徑 |
如:c:\\test.jpg,若是此字符串爲空,則完成時將只寫入剪貼板 |
pCallBack |
Void* |
用於指定在截圖完成時自動回調的函數 |
用於通知調用程序截圖完成 |
hWndNotice |
UINT |
用於指定截圖完成時發送通知的窗口句柄及發送的消息 |
用於通知調用程序截圖完成,截圖完成時,控件將會發送消息: ::PostMessage(hWndNotice, noticeMsg, 1, 1); |
noticeMsg |
UINT |
4. 控件的主要技術點簡介
本控件採用C++語言,經過Win32程序進行實現,內部使用了Duilib來作工具欄以及圖片放大區域的顯示;對於畫圖部分,主要採用了GDI+,如下對我我的認爲須要注意的技術點進行簡要描述:
4.1 橡皮筋類的繪製、大小調整以及拖動等
此橡皮筋類是從MFC的源代碼中提取的CRectTracker,進而移植到Win32環境中的,具體橡皮筋類的原理就不描述了,須要重點關注的是TrackRubberBand及Track兩函數:
1) 當鼠標按下,且橡皮筋沒有顯示的狀況下,使用TrackRubberBand,以肯定橡皮筋所包含區域
if(!gl_rectTracker.TrackRubberBand(hWnd, pt, TRUE)) { //說明鼠標沒有移動,則獲取自動識別到的窗口 if (gl_borderRt.right != 0 && gl_borderRt.right > gl_borderRt.left) { gl_rectTracker.m_rect.SetRect(gl_borderRt.left, gl_borderRt.top, gl_borderRt.right, gl_borderRt.bottom); } }
2) 當橡皮筋類已經顯示,則須要判斷此時鼠標的落點,若是在橡皮筋區域內[gl_rectTracker.HitTest(pt)的返回值 大於0],則須要調用Track,以便拖動橡皮筋調整大小或者移動它。
4.2 自動窗口區域識別
在Windows系統中,全部的窗口都是有一個層級的(ZORDER),此處採用的方法是在獲取屏幕截圖以前,保存下當前全部可見的窗口句柄以及其子窗口句柄[主要利用FindWindowEx],此處值得一提的是,須要過濾掉一些帶WS_EX_LAYERED屬性的窗口[在不過濾的狀況下,WIN8下會有問題,存在透明的窗口處於當前窗口之上],同時針對任務欄窗口不能過濾掉。
4.3 GDI+繪製矩形、圓形、箭頭、文字
1). 繪製箭頭的代碼相似以下:
void DrawArraw(Graphics& graphics, CPoint pt1, CPoint pt2, Color color ) { Point pt[3] = { Point(3, -5), Point(-3, -5), Point(0, 0)}; GraphicsPath strokePath; strokePath.AddLines(pt, sizeof(pt)/sizeof(Point)); Pen pen(color, 1); CustomLineCap custCap(&strokePath, NULL); pen.SetCustomEndCap(&custCap); graphics.DrawLine(&pen, pt1.x, pt1.y, pt2.x, pt2.y); }
此處須要經過對所畫的直線進行平滑處理,不然線條將會很難看。
2). 繪製文字
此處有兩點須要注意,我只解決了其中的第一點:
a). 針對每一行須要單獨繪製,不然在EDIT控件中的行高要比DrawString的行高要少,致使繪製出來的文字佔用高度比在EDIT中要多,感受文字的Y座標有移位
b). 在同時有中文與英文時,繪製出來的文字的X座標是有移位的,我暫時沒有處理,估計須要一個字符一個字符的繪製來解決
4.4 可變大小、可拖動的EDIT控件
此處在效果上參考了微軟的mspaint程序的實現,經過將一個EDIT控件與橡皮筋類進行組合來實現,此處須要重點處理一下鼠標按下以及防止閃爍;還須要注意與EDIT控件組合的橡皮筋類的繪製細節
4.5 鼠標所在區域的放大鏡效果顯示
經過一個透明的PNG作背景圖 StretchBlt函數,經過光標所在點爲基點,以4倍大小放大顯示便可
5. 未解決的問題
5.1 目前沒有處理當輸入文字或者粘貼文字時,自動改變文本框的大小,此處不太清楚如何處理控件的自動變動大小
5.2 當文本框中有中文與英文混合時,繪製到截圖上後,文字的X座標會有移位
注:
控件包及調用說明、代碼見:牛牛截圖控件最終版
若是有任何意見建議,請聯繫QQ:182534287