一些杂七杂八的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#学的菜。

posted @ 2020-12-04 16:56  无心大魔王  阅读(224)  评论(0编辑  收藏  举报