淺析如何用C#.NET做螢幕截圖軟體以及註冊全域快速鍵(下)

來源:互聯網
上載者:User

續:淺析如何用C#.NET做螢幕軟體以及註冊全域快速鍵(上)

下面來說第三種方法:類比PrintScreen按鍵,訪問Clipboard來獲得螢幕,繼而執行截取操作。
1、類比PrintScreen按鍵為我們省去了很多代碼,但剛開始也給我帶來了很大的費解,假如你想通過button_click事件調用API來類比按下PrintScreen鍵,然後通過Clipboard.GetImage()去擷取剪貼簿裡面的圖片,那樣結果只有一個:失敗!也許你認為是我們在調用Clipboard.GetImage()時類比按鍵還未完成操作,然後我們在它們中間加個Thread.Sleep(0),很遺憾,結果還是一樣。我懷疑是滑鼠點擊button和類比PrintScreen按鍵兩者之間的紊亂造成的,在此就不多說廢話了,本人想到的解決方案就是使用backgroundWorker來執行按鍵處理,這樣就分離了表單線程和類比按鍵之間的紊亂問題。
C#類比鍵盤按鍵的實現:
類比鍵盤要用到user32.dll裡面的keybd_event
原型如下:

[DllImport("user32.dll")]static extern void keybd_event( byte bVk,// 虛擬索引值 byte bScan,// 硬體掃描碼 uint dwFlags,// 動作標識 UIntPtr dwExtraInfo// 與鍵盤動作關聯的輔加資訊);

其中,bVk表示虛擬索引值,其實它是一個BYTE類型值的宏,其取值範圍為1-254。有關虛擬索引值表請在MSDN上使用關鍵字“Virtual-Key Codes”尋找相關資料。bScan表示當鍵盤上某鍵被按下和放開時,鍵盤系統硬體產生的掃描碼我們可以MapVirtualKey()函數在虛擬索引值與掃描碼之間進行轉換,一般可以設定為0。dwFlags表示各種各樣的鍵盤動作,應用程式可使用如下一些預定義常數的組合設定標誌位,KEYEVENTF_EXETENDEDKEY=1:若指定該值,則掃描碼前一個值為OXEO(224)的首碼位元組。DEYEVENTF_KEYUP=2:若指定該值,該鍵將被釋放;若未指定該值,該鍵交被接下。dwExtralnfo:定義與擊鍵相關的附加的32位值。C#類比PrintScreen按鍵樣本如下,

public static void PrintScreen() {            IceApi.keybd_event( (byte)0x2c, 0, (uint)0, IntPtr.Zero );//down            IceApi.keybd_event( (byte)0x2c, 0, (uint)2, IntPtr.Zero );//up        }

 

貼一下button的處理,見~:

我們把click之後的事情都交給backgroundWorker去做,省去了很多很多麻煩問題。

接下來是開始進入真正的階段。首先New一個表單SnapForm,設定如下屬性:

this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;this.Opacity = 0.99;this.ShowIcon = false;this.ShowInTaskbar = false;this.TopMost = true;this.WindowState =System.Windows.Forms.FormWindowState.Maximized;

修改建構函式為(見):

當表單顯示時,就已經是全螢幕的了。

之後,我們可以在form上面放個PictureBox,然後在PictureBox_Paint裡面畫線和矩形。
樣本:

picBox_Paint

private void picBox_Paint( object sender, PaintEventArgs e ) {
Graphics g = e.Graphics;
if (isDrawing) {
//g.DrawRectangle( penRect, captureRect);
DrawScableRect( captureRect, g );
}
else if (!isDrawned) {
g.DrawLine( penLine, 0, currentPoint.Y, fullScreen.Width, currentPoint.Y );
g.DrawLine( penLine, currentPoint.X, 0, currentPoint.X, fullScreen.Height );
}
}

 

 

首先我們需要在滑鼠按下時記錄矩形的起點,

if (!isDrawing) {                    startPoint = e.Location;                    captureRect.Location = startPoint;                    isDrawing = true;                    return;                }

然後在MouseMove事件裡面重新整理矩形大小,最後調用this.Refresh(),強制表單重繪,調用Paint方法。
最最後是在MouseUp事件裡面檢測畫圖是否完成。這樣就停止調用this.Refresh()了。
至於畫圖形,就要用到Graphics.DrawRectangle()和Graphics.DrawLine(),可以到MSDN查詢它們的使用方法。
在MouseMove事件裡面,我們可以檢測滑鼠的當前位置,然後設定滑鼠形狀,繼而可以實現矩形的拖動以及擴大和縮小。
在此不詳贅述了。

關於儲存,我們可以加個MouseDoubleClick事件。在下面,我是直接從原始圖片截取矩形覆蓋地區的,
利用orgbmp.Clone( captureRect, screenSnap.PixelFormat )來複製我們需要的地區,這樣既保證了截取圖片的
映像品質,也避免了考慮矩形邊框問題。

MouseDoubleClick

private void SnapForm_MouseDoubleClick( object sender, MouseEventArgs e ) {
if (e.Button==MouseButtons.Left) {
Bitmap orgbmp = new Bitmap( screenSnap );
try {
Bitmap ab = orgbmp.Clone( captureRect, screenSnap.PixelFormat );
if (saveDlg.ShowDialog() == DialogResult.OK) {
ab.Save( saveDlg.FileName, imgFormat[Path.GetExtension( saveDlg.FileName )] );
MessageBox.Show( "Completed!" );
}
}
catch { }
finally { orgbmp.Dispose(); }
}
}

 

 

這樣C#就基本說完了,為了美化,我們可以在表單上面放個半透明圖層,做出類似QQ的效果。
最後說說在C#裡面如何來自訂滑鼠的樣式,以及定義全域快速鍵來實現。

1、自訂滑鼠的樣式:假如你只用C#裡面的Managed Code,自訂出的滑鼠結果顯示出來的會變成單色。
我們需要user32.dll裡面的幾個API來實現自訂彩色滑鼠樣式。

C# Signature:[DllImport("user32.dll")]static extern IntPtr LoadCursorFromFile(string lpFileName);[DllImport( "user32.dll" )]public static extern uint DestroyCursor( IntPtr cursorHandle );

這兩個都比較簡單,我們可以在form_load時載入滑鼠控制代碼,記得最後要在form_closing時釋放控制代碼資源~
this.Cursor = new Cursor( IntPtr handle )用來執行個體化滑鼠。

2、全域快速鍵或稱熱鍵,則需要調用user32裡面的另外兩個API來實現。

    [DllImport( "user32.dll", SetLastError = true )]    public static extern bool RegisterHotKey(            IntPtr hWnd, // handle to window               int id, // hot key identifier               KeyModifiers fsModifiers, // key-modifier options               System.Windows.Forms.Keys vk // virtual-key code       );    [DllImport( "user32.dll", SetLastError = true )]    public static extern bool UnregisterHotKey(        IntPtr hWnd, // handle to window           int id // hot key identifier       );    [Flags]    public enum KeyModifiers    {        None = 0,        Alt = 1,        Control = 2,        Shift = 4,        Windows = 8    }

比如註冊F3鍵為快速鍵:RegisterHotKey( this.Handle, 7890, IceApi.KeyModifiers.None, Keys.F3 );
這兩個API分別要放到Form_Load和Form_FormClosed事件裡面。
最後,我們需要截獲系統訊息來為我們定義的快速鍵執行相應操作。此時我們需要重寫WndProc

WndProc

protected override void WndProc( ref Message m ) {
switch (m.Msg) {
//hotkey pressed
case 0x0312:
if (m.WParam.ToString() == "7890") {
GlobalKeyProc( this.WindowState == FormWindowState.Minimized );
}
break;
}
base.WndProc( ref m );
}

 

 

在GlobalKeyProc()裡面處理我們需要的工作。

 

終於完成了。謝謝觀看。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.