C#實(shí)現(xiàn)QQ截圖功能及相關(guān)問題
對(duì)于QQ截圖,肯定是早就有認(rèn)識(shí)了,只是一直沒有去認(rèn)真觀察這個(gè)操作的具體實(shí)現(xiàn)步驟。所以這里將自己的記憶中的步驟簡(jiǎn)單的寫一下:
習(xí)慣性用QQ或者TIM的人,一般是使用Ctrl+Alt+A 快捷鍵(熱鍵)快速實(shí)現(xiàn)截圖。
- Ctrl+Alt+A 進(jìn)入截圖模式
- 鼠標(biāo)左鍵點(diǎn)擊
- 鼠標(biāo)拖動(dòng)對(duì)截圖去進(jìn)行選取
- 鼠標(biāo)左鍵彈起
- 雙擊截圖區(qū)域 保存圖片到剪貼板
- 鼠標(biāo)右鍵點(diǎn)擊
- 退出截圖模式
因?yàn)榭紤]到截圖模式的時(shí)候 一般只能顯示一個(gè)窗體 所以就考慮使用單例模式 在ScreenBody窗體中實(shí)現(xiàn)以下代碼
1:創(chuàng)建單例
private static ScreenBody screenBody=null;
2:私有化構(gòu)造函數(shù)
private ScreenBody() { InitializeComponent(); }
3:創(chuàng)建靜態(tài)方法
private static ScreenBody GetSingle() { if(screenBody==null) { screenBody=new ScreenBody(); } return screenBody; }
進(jìn)一步討論一下在Main窗體中的調(diào)用 Main中添加了一個(gè)button 命名為btnCutter
private void btnCutter_Click(object sender,EventArgs e) { //新建一個(gè)和屏幕大小相同的圖片img 也可以用BitMap image img=new Bitmap(Screen.AllScreens[0].Bounds.Width,Screen.AllScreens[0].Bounds.Height); //創(chuàng)建一個(gè)畫板 讓我們可以在畫板上畫圖 大小和屏幕大小一樣大 Graphics g=Graphics.FromImage(img); //將屏幕圖片拷貝到空白圖片img g.CopyFromScreen(new Point(0,0),new Point(0,0),Screen.AllScreens[0].Bounds.Size); //創(chuàng)建截圖窗體 ScreenBody body=ScreenBody.GetSingle(); //指示窗體的背景圖片為屏幕圖片 body.BackGroundImage=img; body.ShowDialog(); }
對(duì)于窗體ScreenBody
聲明全局變量
private bool CatchStart;//判斷鼠標(biāo)是否按下 private bool CatchFinished;//判斷矩形是否繪制完成 private Point DownPoint;//鼠標(biāo)按下的點(diǎn) private Image baseMap;//最基本的圖片 private Rectangle CatchRectangle;
必須要實(shí)現(xiàn)的那幾個(gè)事件
鼠標(biāo)按下MouseDown
private void ScreenBody_MouseDown(object sender, MouseEventArgs e) { //鼠標(biāo)左鍵按下就是開始畫圖,也就是截圖 if (e.Button == MouseButtons.Left) { if (CatchStart == false) { CatchStart = true; //保存此時(shí)的坐標(biāo) DownPoint = new Point(e.X, e.Y); } } }
鼠標(biāo)移動(dòng) MouseMove
private void ScreenBody_MouseMove(object sender, MouseEventArgs e) { //確保截圖開始 if (CatchStart) { //新建一個(gè)圖片,讓它與屏幕圖片相同 Bitmap copyBmp = (Bitmap)baseMap.Clone(); //鼠標(biāo)按下時(shí)的坐標(biāo) Point newPoint = new Point(DownPoint.X, DownPoint.Y); //新建畫板和畫筆 Graphics g = Graphics.FromImage(copyBmp); Pen p = new Pen(Color.Azure, 1);//畫筆的顏色為azure 寬度為1 //獲取矩形的長(zhǎng)度 int width = Math.Abs(e.X - DownPoint.Y); int height = Math.Abs(e.Y - DownPoint.Y); if (e.X < DownPoint.X) { newPoint.X = e.X; } if (e.Y < DownPoint.Y) { newPoint.Y = e.Y; } CatchRectangle = new Rectangle(newPoint, new Size(width, height)); g.DrawRectangle(p, CatchRectangle); //釋放目前的畫板 g.Dispose(); p.Dispose(); //從當(dāng)前窗體創(chuàng)建新的畫板 Graphics g1 = this.CreateGraphics(); //將剛剛所畫的圖片畫到截圖窗體上去 //為什么不直接在當(dāng)前窗體畫圖呢??? //如果直接解決將矩形畫在窗體上,會(huì)造成圖片抖動(dòng)而且有多個(gè)矩形 //這樣實(shí)現(xiàn)也屬于二次緩沖技術(shù) g1.DrawImage(copyBmp, new Point(0, 0)); g1.Dispose(); //釋放拷貝圖片 防止內(nèi)存被大量的消耗 copyBmp.Dispose(); }
鼠標(biāo)彈起 Mouseup
/// <summary> /// 鼠標(biāo)左鍵彈起事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ScreenBody_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { //如果截圖已經(jīng)開始,鼠標(biāo)左鍵彈起設(shè)置截圖完成 if (CatchStart) { CatchStart = false; CatchFinished = true; } } }
鼠標(biāo)雙擊
private void ScreenBody_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button==MouseButtons.Left&&CatchFinished) { //新建一個(gè)矩形大小相同的空白圖片 Bitmap CatcheBmp = new Bitmap(CatchRectangle.Width, CatchRectangle.Height); Graphics g = Graphics.FromImage(CatcheBmp); ; //把basemap中指定的部分按照指定大小畫到空白圖片上 //CatchRectangle指定的baseMap中指定的部分 //第二個(gè)參數(shù)指定繪制到空白圖片的位置和大小 //畫完后CatchedBmp不再是空白圖片,而是具有與截取的圖片一樣的內(nèi)容 g.DrawImage(baseMap, new Rectangle(0, 0, CatchRectangle.Width, CatchRectangle.Height)); //將圖片保存到剪切板中 Clipboard.SetImage(CatcheBmp); g.Dispose(); CatchFinished = false; this.BackgroundImage = baseMap; CatcheBmp.Dispose(); this.DialogResult = DialogResult.OK; this.Close(); } }
鼠標(biāo)右鍵 退出截圖
/// <summary> /// 鼠標(biāo)右鍵點(diǎn)擊結(jié)束截圖 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void ScreenBody_MouseClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { this.DialogResult = DialogResult.OK; this.Close(); } }
最復(fù)雜的熱鍵注冊(cè) 自己也是去網(wǎng)上看的 Main窗體中
聲明枚舉
[FlagsAttribute] public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 }
然后在類中編輯一下代碼
//在C#中引用命名空間System.Runtime.InteropServices;來加載非托管類user32.dll /* * RegisterHotKey函數(shù)原型及說明: * BOOL RegisterHotKey( * HWND hWnd, // window to receive hot-key notification * int id, // identifier of hot key * UINT fsModifiers, // key-modifier flags * UINT vk // virtual-key code); * 參數(shù) id為你自己定義的一個(gè)ID值 * 對(duì)一個(gè)線程來講其值必需在0x0000 - 0xBFFF范圍之內(nèi),十進(jìn)制為0~49151 * 對(duì)DLL來講其值必需在0xC000 - 0xFFFF 范圍之內(nèi),十進(jìn)制為49152~65535 * 在同一進(jìn)程內(nèi)該值必須唯一參數(shù) fsModifiers指明與熱鍵聯(lián)合使用按鍵 * 可取值為:MOD_ALT MOD_CONTROL MOD_WIN MOD_SHIFT參數(shù),或數(shù)字0為無,1為Alt,2為Control,4為Shift,8為Windows * vk指明熱鍵的虛擬鍵碼 */ [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函數(shù) public static extern bool RegisterHotKey( IntPtr hWnd, // handle to window int id, // hot key identifier uint fsModifiers, // key-modifier options Keys vk // virtual-key code ); [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函數(shù) public static extern bool UnregisterHotKey( IntPtr hWnd, // handle to window int id // hot key identifier );
再接著
private void Form1_Load(object sender, EventArgs e) { uint ctrlHotKey = (uint)(KeyModifiers.Alt | KeyModifiers.Ctrl); // 注冊(cè)熱鍵為Alt+Ctrl+C, "100"為唯一標(biāo)識(shí)熱鍵 RegisterHotKey(Handle, 100, ctrlHotKey, Keys.A); } //熱鍵按下執(zhí)行的方法 private void GlobalKeyProcess() { this.WindowState = FormWindowState.Minimized; //窗口最小化需要一定的時(shí)間 使用線程 Thread.Sleep(200); btnCutter.PerformClick(); } protected override void WndProc(ref Message m) { //如果m.Msg的值為0x0312那么表示用戶按下了熱鍵 const int WM_HOTKEY = 0x0312; switch (m.Msg) { case WM_HOTKEY: if (m.WParam.ToString()=="100") { GlobalKeyProcess(); } break; default: break; } base.WndProc(ref m); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { // 卸載熱鍵 UnregisterHotKey(Handle, 100); }
熱鍵的功能就能實(shí)現(xiàn)。但是我遇到了很多問題 首先是basemap 沒有初始化值
這些問題 還有待解決?。?!
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持我們。
上一篇:NancyFx框架檢測(cè)任務(wù)管理器詳解
欄 目:C#教程
下一篇:C# 獲取硬件參數(shù)的實(shí)現(xiàn)方法
本文標(biāo)題:C#實(shí)現(xiàn)QQ截圖功能及相關(guān)問題
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/5434.html
您可能感興趣的文章
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新聞效果的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已安裝軟件變化的方法
- 01-10C#實(shí)現(xiàn)多線程下載文件的方法
- 01-10C#實(shí)現(xiàn)Winform中打開網(wǎng)頁(yè)頁(yè)面的方法
- 01-10C#實(shí)現(xiàn)遠(yuǎn)程關(guān)閉計(jì)算機(jī)或重啟計(jì)算機(jī)的方法
- 01-10C#自定義簽名章實(shí)現(xiàn)方法
- 01-10C#文件斷點(diǎn)續(xù)傳實(shí)現(xiàn)方法
- 01-10winform實(shí)現(xiàn)創(chuàng)建最前端窗體的方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery