一些雜七雜八的C#語法
今天,剛剛接到一個需求,邏輯上而言可以說是沒難度,但是,這個語法上,由於我c#太菜了,之前為了應對一個客戶端軟體現學的,一段時間不用之後,是真的記不住啊。
領導的意思是,這次寫的是一個後臺程式,按個快捷鍵,採集某裝置資料,然後將結果1寫入在游標所在位置,將游標換到下一個單元格,結果2寫入游標新的位置。
採集資料和寫入資料不能互相影響,言外之意也就是哪怕裝置半天不響應,你該列印也得打印出來,大不了結果為null嘛。
最坑的是那裝置好像就一臺,所以我的程式碼得先和裝置“解耦”,先幹寫,測試不了。
說到底這東西充其量算個小工具,邏輯上雖然沒啥難度,但是語法是真不會,搜尋引擎成了最後的歸宿。這一次也算是吸取上回的經驗,雖然需求說的挺明確,但肯定遠不止於此。
我預計按照大佬的一貫作風,這個小玩意至少還得有自動掃描可用com口,開機自啟動,應該沒啥別的了。
然後,我很疑惑的問了一句,既然這個程式不需要提供介面,那為啥還要求是winform專案呢?大佬表示exe檔案對使用者比較友好。本來想用java來著,那行吧。
開機自啟動和最小化至托盤的程式碼全是從網上扒下來的,註冊系統熱鍵的程式碼也是網上扒下來的,serialport的使用方法也是參照網上的程式碼。
吸取了上次採集溫溼度裝置的經驗,兩次查詢命令之間目前設為100毫秒的間隔,不知道裝置能不能反應的過來,最後寫了半天,感覺程式碼裡就沒幾行是自己寫的,上網找到的資料多為一些“古董級別”的文章。
最終有一種自己在破案的感覺,體驗感極差,寫到這裡對java的懷念之情油然而生。為了避免下次再遇到相同的尷尬場景,我決定將程式碼簡單整理一下(以下程式碼均轉載自網路
// 獲得應用程式路徑 string strAssName = Application.StartupPath + @"\" + Application.ProductName + @".exe"; // 獲得應用程式名稱 string strShortFileName = Application.ProductName; // 開啟登錄檔基項"HKEY_LOCAL_MACHINE" RegistryKey rgkRun = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true); if (rgkRun == null) { // 若不存在,建立登錄檔基項"HKEY_LOCAL_MACHINE" rgkRun = Registry.LocalMachine.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"); //MessageBox.Show("新增開機啟動成功"); } // 設定指定的登錄檔項的指定名稱/值對。如果指定的項不存在,則建立該項。 rgkRun.SetValue(strShortFileName, strAssName); //MessageBox.Show("新增開機啟動成功");
寫上就好使,咱也不懂,咱也不敢問。
然後,是註冊熱鍵的程式碼:
class HotKey { // 如果函式執行成功,返回值不為0。 // 如果函式執行失敗,返回值為0。要得到擴充套件錯誤資訊,呼叫GetLastError。 [DllImport("user32.dll", SetLastError = true)] public static extern bool RegisterHotKey( IntPtr hWnd, // 要定義熱鍵的視窗的控制代碼 int id, // 定義熱鍵ID(不能與其它ID重複) KeyModifiers fsModifiers, // 標識熱鍵是否在按Alt、Ctrl、Shift、Windows等鍵時才會生效 Keys vk // 定義熱鍵的內容 ); [DllImport("user32.dll", SetLastError = true)] public static extern bool UnregisterHotKey( IntPtr hWnd, // 要取消熱鍵的視窗的控制代碼 int id // 要取消熱鍵的ID ); // 定義了輔助鍵的名稱(將數字轉變為字元以便於記憶,也可去除此列舉而直接使用數值) [Flags()] public enum KeyModifiers { None = 0, Alt = 1, Ctrl = 2, Shift = 4, WindowsKey = 8 } }
上面這個類是關鍵的部分,不知道哪個大佬封裝的,感謝你。
// 註冊熱鍵Ctrl+B,Id號為101。HotKey.KeyModifiers.Ctrl也可以直接使用數字2來表示。 HotKey.RegisterHotKey(Handle, 101, HotKey.KeyModifiers.Ctrl, Keys.B);
這條語法是註冊熱鍵。
最終還需要給一個按快捷鍵後會觸發的程式碼:
protected override void WndProc(ref Message m) { const int WM_HOTKEY = 0x0312;//如果m.Msg的值為0x0312那麼表示使用者按下了熱鍵 // 按快捷鍵 switch (m.Msg) { case WM_HOTKEY: switch (m.WParam.ToInt32()) { case 101: // 按下的是Ctrl+B // 此處填寫快捷鍵響應程式碼 break; } break; } base.WndProc(ref m); }
重寫窗體的這個方法。
縮小至托盤的程式碼:
this.Hide(); //隱藏工作列區圖示 this.ShowInTaskbar = false; //圖示顯示在托盤區 notifyIcon1.Visible = true;
有一點要注意的是必須要給notifyIcon(如果你是用它實現的話,有沒有其他的實現方法我就不清楚了),必須要給它設定圖示,否則在最小化後是看不到的。
如果你還需要加一個右鍵退出程式之類的這種東西,那就會用到contextMenuStrip,這兩者需要建立關聯,怎麼操作自行搜尋一下吧,然後contextMenuStrip中新增一個按鈕或者叫選單,最後給個點選事件即可。
if (MessageBox.Show("是否確認退出程式?", "退出", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { // 關閉所有的執行緒 this.Dispose(); this.Close(); }
事件中可以寫入這段程式碼,也是我從網上扒下來又稍稍改了一小下的。
還有將文字寫入游標所在位置:
private void WriteInfo() { SendKeys.Send("結果1"); SendKeys.Send("{TAB}"); SendKeys.Send("結果2"); }
開始在網上找了一些程式碼,大多看的我頭疼,然後突然發現了一個人說可以將資料放入剪下板,再用程式模擬ctrl+v,粘上去就行了。我試了一下,真的可以,但是緊接著發現連續兩次操作不同的資料的話,會將第二個資料貼上兩次。
這就有點難受了,為了能用上簡單的方法,我開始自行探索,突然發現如果用SendKeys.Send方法傳送字母的話,最終效果類似於使用者打字,輸入法會彈出來。那如果傳送字串呢?試了一下,直接列印至游標所在位置了。
這個方法還可以用來模擬其他的快捷鍵,具體的可以自行搜尋它的用法,很好找。
希望這篇文章能夠幫助到一些同病相憐的人,如果有啥疑問建議自行搜尋,實在不行可以評論區討論一下,作者大概率給不出答案,作者c#學的菜。