顯示具有 C# 標籤的文章。 顯示所有文章
顯示具有 C# 標籤的文章。 顯示所有文章

2017年5月12日 星期五

C# 在背景執行全域鍵盤事件的GlobalKeyboardHook

一般Form表單上的keyDown鍵盤事件,必須是在Form成為Focus焦點的情況下才有辦法觸發,可是如果要寫個類似autohotkey之類,可在背景執行鍵盤事件的程式的話,就沒辦法了.

根據網路上查到的資料的說法,微軟的.Net Framework裡面並沒有可在背景執行鍵盤事件的方法,必須要自己寫程式,調用User32的API,或者,直接引用別人寫好的程式.

YouTube上這個影片展示了如何可以在背景監控鍵盤按鍵,並引發事件的方式
https://youtu.be/P1syNv_Qnio

作者的部落格也展示了這段程式碼
http://tutplusplus.blogspot.tw/2010/10/ultimate-keylogger-lesson-1-global.html

需要把GlobalKeyboardHook.cs這個檔案加入到專案的項目中,可以從作者的部落格上下載,也可以從我的雲端硬碟下載這個檔案,跟作者的部落格上所下載的是一樣的
https://drive.google.com/file/d/0BwcJdYDuBNwYa0JUS1VtN2ZVY1E/view?usp=sharing

我稍微改寫成我要的樣子:

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
//
//要用的變數和物件先宣告在這裡

        GlobalKeyboardHook gHook;
        int kv;//將keyValue轉成整數用的變數
        bool ctrl, alt, shift;//按下功能鍵時就改為true



//
//在Load事件裡要先載入
        private void Form1_Load(object sender, EventArgs e)
        {

            gHook = new GlobalKeyboardHook(); //根據作者的程式碼(class)創造一個新物件

            gHook.KeyDown += new KeyEventHandler(gHook_KeyDown);// 連結KeyDown事件

            foreach (Keys key in Enum.GetValues(typeof(Keys)))
            gHook.HookedKeys.Add(key);

            gHook.hook();//開始監控
        }

//
//把按下按鍵後要觸發的事件寫在這裡
        public void gHook_KeyDown(object sender, KeyEventArgs e)
        {
            kv = (int)e.KeyValue;//把按下的按鍵號碼轉成整數存在kv中

            switch (kv)
            {
                        case 65: break;//按下A之後要怎樣怎樣
                        case 66: break;//按下B之後要怎樣怎樣
                        case 112: break;//按下F1之後要怎樣怎樣
                        case 160: shift = true;//當按下左shift的時候布林值為真
                        case 161: shift = true;//當按下右shift的時候布林值為真
                        case 162: ctrl = true;//當按下左ctrl的時候布林值為真
                        case 163: ctrl = true;//當按下右ctrl的時候布林值為真
                        case 164: alt = true;//當按下左alt的時候布林值為真
                        case 165: alt = true;//當按下右alt的時候布林值為真
            }
        }


如果想要有keyUp事件的話,就在Load事件裡面加入這一條
gHook.KeyUp += new KeyEventHandler(gHook_KeyUp);

然後下面就可以寫入想要的keyUp事件了
        public void gHook_KeyUp(object sender, KeyEventArgs e)
        {
            kv = (int)e.KeyValue;//把按下的按鍵號碼轉成整數存在kv中

            switch (kv)
            {
                        case 160: shift = false;//當放開左shift的時候布林值為假
                        case 161: shift = false;//當放開右shift的時候布林值為假
                        case 162: ctrl = false;//當放開左ctrl的時候布林值為假
                        case 163: ctrl = false;//當放開右ctrl的時候布林值為假
                        case 164: alt = false;//當放開左alt的時候布林值為假
                        case 165: alt = false;//當放開右alt的時候布林值為假
            }
        }


如果我今天想要把程式寫成[按下Ctrl + F2的時候就可以怎樣怎樣]的話,就可以在keydown事件裡面加入這一條:

case 113: if (ctrl == true) {如此如此這般這般} break;

其他依此類推

如果想知道鍵盤按鍵所對應的號碼的話,可以查表,當然,也可以自己先寫一個超簡單的小程式來把keyValue的值顯示出來,下面這個就是我花不到十分鐘做的小程式,很簡陋,請不要介意
https://drive.google.com/file/d/0BwcJdYDuBNwYeTF0N09SVngzV1k/view?usp=sharing

2017年5月4日 星期四

C# 取得dataGridView及listView所選取的那格的索引值 VS2017

相關的問題上網找,有一些答案不太正確,可能是因為版本的關係?
自己摸索後得到的答案如下:

listView只能一次選一整列,可以用預設的ItemSelectionChanged事件,讓滑鼠在上面點一下的時候,立刻知道所選取的是哪一列,該列的索引值是多少?

語法如下:
//
//這個事件是"所選取的項目改變"時就會觸發
private void listView1_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
    {
        //
        //先宣告一個整數變數來儲存索引的值
        int i;
        //
        //把索引值存入i,關鍵字是"焦點的項目",記得轉換型別
        i = Convert.ToInt32(listView1.FocusedItem.Text);
        //
        //接著來測試看看是否有成功
        label1.Text = Convert.ToString(i);
    }



dataGridView方面,一樣有類似的SelectionChanged事件,不過在listView中所有的項目都只有Item,而在dataGridView中則有分行Row和列Column,而關鍵字則變成"當前格子的地址",行跟列變成X和Y.

語法如下:
//
//一樣用事件啟動,選擇改變時就立刻改變
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
    {
        //
        //需要兩個變數來儲存行跟列
        int x, y;
        //
        //
        x = Convert.ToInt32(dataGridView1.CurrentCellAddress.X);
        y = Convert.ToInt32(dataGridView1.CurrentCellAddress.Y);
        //
        //一樣用兩個label來測試看看有沒有成功
        labelx.Text = Convert.ToString(x);
        labely.Text = Convert.ToString(y);
    }
如果測試後的結果,label上的數字會跟著我所選的格子而改變,就是成功了

2017年4月28日 星期五

C# 將控制項陣列化

如果要將表單上已經拉好位置的12個button做成陣列的話,就這麼做:

控制項類型[] 名稱 = new 控制項類型[]

然後在大括號裡面寫入每一個要加入陣列的控制項的名稱,像這樣

button[] bt = new button[] { button1, button2, button3, button4, button5, button6, button7, button8, button9, button10, button11, button12 };

由於陣列第一個索引號碼是0,所以原本的button1現在就有了另一個名稱,叫做bt[0],而button2就是bt[1],依此類推.

陣列化之後,用起來就很方便了,也可以大幅減少程式碼的篇幅

C# 自動滑鼠ATM_Lite ver0.97的程式碼

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq...