LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

C#高仿騰訊QQ截圖程序

admin
2016年12月23日 23:46 本文熱度 6303

最近把以前制作的截圖程序重新寫了一下 動了一個大手術(shù) 高質(zhì)量仿照的TX的截圖程序

源碼下載1(2012-12-09)

http://download.csdn.net/detail/crystal_lz/4863320

源碼下載2(2012-12-15)

http://download.csdn.NET/download/crystal_lz/4889763

新改版見:http://blog.csdn.Net/crystal_lz/article/details/9200859

- -!、發(fā)現(xiàn)bug 在文章后面更改

先看幾個效果圖

貌似圖被和諧了

拖動過程中顯示當(dāng)前鼠標(biāo)下一小塊的圖像信息 尺寸、顏色信息的  注意 這里顏色是用的ARGB 本來截圖的話RGB就夠了 可是我把那個做成了控件 不僅截圖可用 其他地方也可用作圖像的選取 具體看代碼就知道了


貌似圖片被和諧了

并且我還加了一個可以截圖的同時把鼠標(biāo)也捕獲下來 現(xiàn)在看到的是我自己的截圖程序 那個工具條啥的 是從TX的截圖程序上面拔下來的


貌似圖片被和諧了

上面是幾個工具條上的工具的三種粗細(xì)型號的展示 看到的藍(lán)色的粗的刷筆 本來想的不應(yīng)該是這個效果的 應(yīng)該是顏色填充均勻的那種 但是仔細(xì)一想代碼中用的是DrawLine(P,PointLast,PointCurrent);這種方式來畫的自由線條 如果是一個像素的沒什么問題 粗點(diǎn)的就是上面看到的那種效果 也就是由許多小線段拼接出來的自由線條而每個線段兩端都是方的所以線段與線段之間的接縫處 可能就有問題 反正就那個意思 你懂得  不過再仔細(xì)一想雖然不是想要的效果但卻意外的出現(xiàn)了 蠟筆的效果 果斷也就不改了這樣也不錯



同樣的具有自動捕獲窗體邊框的功能


圖片貌似被和諧了

使用也非常簡單 這個截圖的功能寫到了一個dll中 引用名稱空間 然后FrmCapture 就是截圖的了給了他幾個屬性 也就是上面看到的

同時在拖動過程中可以通過鍵盤 wasd 四個鍵來控制鼠標(biāo)精確移動

操作方式也和TX的一樣

右鍵鼠標(biāo) 如果有選擇的區(qū)域則取消選擇的區(qū)域   沒有則退出截圖

雙擊將選擇的區(qū)域復(fù)制到剪切板


不過話說回來 平時聊天的時候 或許常用到截圖 但是除了聊天外就很少用到截圖了

大多數(shù)時候彈出 alt + ctrl + a 都不是為了截圖 而是為了框選一下某一個區(qū)域的大小 或者 在屏幕上去選擇一個點(diǎn)的顏色信息(所以我搞了 w a s d 四個鍵來精確移動)

所以顯示坐標(biāo)、尺寸、還有顏色信息的那些功能做得比較全

工具欄上面的 工具 我也就是象征性的做了一下 前面幾個都還成 字體哪里就有點(diǎn)水了 TX的可以選擇字號 而我還是只有三種選擇主要是為了 和前面的公用那個調(diào)色和選擇大小的那一個控件 這樣就不用再搞新的東西了(我懷疑工具條上面的一些東西 對于大多數(shù)其他人來說 估計用都沒有用過)

==========================分割線=======================

在上面的 源碼下載2 中把自己修改的自己用的放了上來 和源碼1相比 修復(fù)了已知的雙擊的那個bug - -!、、坑爹的發(fā)現(xiàn) 寫到這里腦子又想起一個bug 就是 如果截圖好了彈出保存對話框后 然后右鍵會取消截圖 然后再右鍵截圖關(guān)閉 關(guān)閉了倒好沒啥 可是 彈出保存對話框后取消截圖保存的時候就異常了  不過一般情況下貌似只要正常操作是不會出現(xiàn)這個問題了  算了一會兒還是把解決辦法搞到下面 這里就說說我改了后的源碼 (對了 在彈出保存對話框的時候默認(rèn)是 保存bmp格式 如果不習(xí)慣把對話框索引改一下就行了)

- -!、其實(shí)也沒改啥源碼出了修復(fù)bug直接新建了一個工程導(dǎo)入dll然后寫代碼

貌似圖片被和諧了

Oh God 突然發(fā)現(xiàn)窗體上面的 Other 寫錯了 坑爹啊 下載自己改吧、、、

這個是設(shè)置窗體可以自定義快捷鍵 還有是否開機(jī)自起 是否捕獲鼠標(biāo)(開始運(yùn)行不會出現(xiàn)窗體 隱藏啟動在托盤顯示)

我一直覺得那里不對勁 終于發(fā)現(xiàn)了 那個最小化按鈕還在 居然忘了 要么屏蔽最小化按鈕(this.MinimizeBox = false;)要么直接設(shè)置成toolwindow

this.FormBorderStyle = FormBorderStyle.FixedToolWindow;

貌似圖片被和諧了

注意如果要設(shè)置開機(jī)自起的話 務(wù)必確保你的程序的路徑開機(jī)后能找到 也就是要保持你程序的當(dāng)前路徑 因?yàn)殚_機(jī)自啟的時候 是獲取的程序的當(dāng)前路徑然后寫入注冊表的

反正我是把它放到我的文檔下面然后新建了一個文件夾

貌似圖片被和諧了

那個dll是截圖的模塊 exe是那個設(shè)置的窗體 那個cfg保存的是設(shè)置的信息(默認(rèn)情況下是木有滴 是要設(shè)置后生成滴)  要放哪里看個人愛好 如果你要選擇自起的話



整個思路也和前面幾篇文章中提到的一樣 只是在代碼層面上動了一個大手術(shù) 因?yàn)樵瓉韺懙闹饕峭癸@那個自動捕獲窗體的功能

[csharp] view plain copy
  1. //根據(jù)鼠標(biāo)位置找尋窗體平繪制邊框  
  2. private void FoundAndDrawWindowRect() {  
  3.     Win32.LPPOINT pt = new Win32.LPPOINT();  
  4.     pt.X = MousePosition.X; pt.Y = MousePosition.Y;  
  5.     IntPtr hWnd = Win32.ChildWindowFromPointEx(Win32.GetDesktopWindow(), pt,  
  6.         Win32.CWP_SKIPINVISIBL | Win32.CWP_SKIPDISABLED);  
  7.     if (hWnd != IntPtr.Zero) {  
  8.         IntPtr hTemp = hWnd;  
  9.         while (true) {      //循環(huán)的根據(jù)坐標(biāo)向內(nèi)部找尋子窗體 直到無法找到位置  
  10.             Win32.ScreenToClient(hTemp, out pt);  
  11.             hTemp = Win32.ChildWindowFromPointEx(hTemp, pt, Win32.CWP_All);  
  12.             if (hTemp == IntPtr.Zero || hTemp == hWnd)  
  13.                 break;  
  14.             hWnd = hTemp;  
  15.             pt.X = MousePosition.X; pt.Y = MousePosition.Y; //坐標(biāo)還原為屏幕坐標(biāo)  
  16.         }  
  17.         Win32.LPRECT rect = new Win32.LPRECT();  
  18.         Win32.GetWindowRect(hWnd, out rect);  
  19.         imageProcessBox1.SetSelectRect(  
  20.             new Rectangle(rect.Left, rect.Top,   
  21.             rect.Right - rect.Left, rect.Bottom - rect.Top));  
  22.     }  
  23. }  

同前幾篇文章一樣是通過禁用自身窗體然后通過ChildWindowFromPointEx函數(shù)來根據(jù)鼠標(biāo)位置 獲得鼠標(biāo)下面的窗體 因?yàn)樵讷@取的時候 鼠標(biāo)下面是截圖程序的一個窗體 所以在找尋窗體的時候得把自己忽略掉 而ChildWindowFromPointEx在查找過程中可以忽略禁用的窗體 所以講自己禁用就到到目的了 然后通過Hook來監(jiān)視鼠標(biāo)的行為 來恢復(fù)禁用的窗體

[csharp] view plain copy
  1. private void m_MHook_MHookEvent(object sender, MHookEventArgs e) {  
  2.       
  3.     ........  
  4.       
  5.     //鼠標(biāo)點(diǎn)下恢復(fù)窗體禁用  
  6.     if (e.MButton == ButtonStatus.LeftDown || e.MButton == ButtonStatus.RightDown) {  
  7.         this.Enabled = true;  
  8.         imageProcessBox1.IsDrawOperationDot = true;  
  9.     }  
  10.       
  11.     ........  
  12. }  

還有一點(diǎn) 就只捕獲鼠標(biāo)的時候

[csharp] view plain copy
  1. //獲取桌面圖像  
  2. private Bitmap GetScreen() {  
  3.     Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,  
  4.             Screen.PrimaryScreen.Bounds.Height);  
  5.     if (this.isCaptureCursor) {     //是否捕獲鼠標(biāo)  
  6.         //如果直接將捕獲當(dāng)?shù)氖髽?biāo)畫在bmp上 光標(biāo)不會反色 指針邊框也很濃 也就是說  
  7.         //盡管bmp上繪制了圖像 繪制鼠標(biāo)的時候還是以黑色作為鼠標(biāo)的背景 然后在將混合好的鼠標(biāo)繪制到圖像 會很別扭  
  8.         //所以 干脆直接在桌面把鼠標(biāo)繪制出來再截取桌面  
  9.         using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) {   //傳入0默認(rèn)就是桌面 Win32.GetDesktopWindow()也可以  
  10.             Win32.PCURSORINFO pci;  
  11.             pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32.PCURSORINFO));  
  12.             Win32.GetCursorInfo(out pci);  
  13.             if (pci.hCursor != IntPtr.Zero) {  
  14.                 Cursor cur = new Cursor(pci.hCursor);  
  15.                 g.CopyFromScreen(0, 0, 0, 0, bmp.Size); //在桌面繪制鼠標(biāo)前 先在桌面繪制一下當(dāng)前的桌面圖像  
  16.                 //如果不繪制當(dāng)前桌面 那么cur.Draw的時候會是用歷史桌面的快照 進(jìn)行鼠標(biāo)的混合 那么到時候混出現(xiàn)底色(測試中就是這樣的)  
  17.                 cur.Draw(g, new Rectangle((Point)((Size)MousePosition - (Size)cur.HotSpot), cur.Size));  
  18.             }  
  19.         }  
  20.     }  
  21.     //做完以上操作 才開始捕獲桌面圖像  
  22.     using (Graphics g = Graphics.FromImage(bmp)) {  
  23.         g.CopyFromScreen(0, 0, 0, 0, bmp.Size);  
  24.     }  
  25.     return bmp;  
  26. }  

我總感覺上面的方式很別扭 可是目前我也就只能通過這種方式去捕獲鼠標(biāo)了

有興趣的就自己改造吧 導(dǎo)入那個dll自己想咋改造就咋改造

=========================================================================

更改bug

如果在選區(qū)內(nèi)部雙擊 會出現(xiàn)異常

解決辦法

貌似圖片被和諧了

在FrmCapture中的  mouseDown事件中 把 m_ptOriginal = e.Location 放到if外面去 這個是記錄鼠標(biāo)點(diǎn)下時候的位置的

還有

貌似圖片被和諧了

mouseup中 加上這一句 如果與點(diǎn)下的時候的坐標(biāo)一樣啥都不做

好吧 就算上面的這樣還是有問題 是用畫刷工具的時候 就有問題了 因?yàn)楫嬎⒌膍_ptOriginal在mousemove中不停的給他賦值 

而且 邏輯還有點(diǎn)問題 鼠標(biāo)抬起只要在繪制狀態(tài)下無論如何都要 把m_isStartDraw賦值成false 和 Cursor.Clip 也要清空

那個return只是決定是否 SetLayer 將圖層繪制上去而已

所以

[csharp] view plain copy
  1. if (!m_isStartDraw) return;  
  2. Cursor.Clip = Rectangle.Empty;  
  3. m_isStartDraw = false;  
  4. if (e.Location == m_ptOriginal && !tBtn_Brush.IsSelected) return;  
  5. this.SetLayer();        //將繪制的圖形繪制到歷史圖層中  
順序這樣放置

這樣都還有問題 還是出在畫刷上 所以在下面的SetLayer()方法前面加一句 if(this.IsDisposed) return;如果窗體都關(guān)閉了就 不執(zhí)行操作 解釋看下面、、

再解釋一下為什么在選取類雙擊會出問題 因?yàn)樵谶x區(qū)內(nèi)做鼠標(biāo)的一些操作的時候 mousedown 和 up 都會根據(jù)情況執(zhí)行一些代碼

然后雙擊事件眾所周知 是兩個單擊 而單擊是 mousedown 和 mouseup的組合 所以 doubleclick 的時候會分別執(zhí)行兩次 mousedown 和 mouseup 不過雙擊這個過程中順序是這樣的

mousedown - mouseup - mousedown - doubleclick - mouseup

雙擊事件 會在最后一個mouseup之前執(zhí)行  而我卻在雙擊中把圖拷貝到剪切板 然后就關(guān)閉窗體了 所以 之后執(zhí)行的mouseup的時候 調(diào)用函數(shù)的時候 就有問題 因?yàn)橐恍┵Y源被我釋放了

順便再說一個

圖片貌似被和諧了

在FrmCapture中的InitMember里面加上上面三條

之所以這樣 是可能會出現(xiàn)在不同電腦上 運(yùn)行出來 工具條的大小什么的會有些錯位

尤其是panel1 因?yàn)閜anel1里面放的button是自定義的 而button的大小也是用戶不能控制的

我對自定義的那個button 搞23 是固定的 寬至少23 (也就是沒有文本顯示只有圖)  如果在有文本的情況下 比如最后 一個是 finish 那么button的寬自動根據(jù)文本的寬度啥的自動調(diào)整大小

所以在不同電腦上 字體啥的可能不一樣 所以 自定義的button的大小也可能不一樣 所以用上面三條代碼來控制兩個panel的大小 

在截圖后 然后點(diǎn)擊保存出現(xiàn)保存對話框的時候 還可以右鍵取消截圖選取 

(- -!、、雖然保存對話框是模態(tài)對話框 hook無法可擋..)雖然正常情況不會出現(xiàn)這個情況 不過還是說一下

解決辦法

再搞一個全局變量 m_bSave然后在 保存的那個按鈕的事件函數(shù)里面

[csharp] view plain copy
  1. private void tBtn_Save_Click(object sender, EventArgs e) {  
  2.         m_bSave = true;    //進(jìn)入的時候設(shè)置成true  
  3.         ...  
  4.         m_bSave = false;   //結(jié)束的時候設(shè)置成false  
  5. }  
然后在 m_MHook_MHookEvent 事件中的 右鍵抬起 部分

[csharp] view plain copy
  1. #region 右鍵抬起  
  2.   
  3. if (e.MButton == ButtonStatus.RightUp) {  
  4.     if (!imageProcessBox1.IsDrawed) //沒有繪制那么退出(直接this.Close右鍵將傳遞到下面)  
  5.         this.BeginInvoke(new MethodInvoker(() => this.Close()));  
  6.     if (m_bSave) return;    //如果正在保存 不執(zhí)行下面的代碼  
  7.     ......  
  8. }  
  9.  
  10. #endregion  


該文章在 2016/12/23 23:46:21 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場、車隊、財務(wù)費(fèi)用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
日本羞羞的视频在线播放 | 色婷婷综合激情中文在线 | 日韩一区二区三区中文 | 亚洲步兵在线播放 | 色偷偷8888欧美精品久久 | 亚洲伊人伊成久久人综合网 |