• Как принять массив hex и вывести в textbox?

    @dark_Kelvin
    Событие DataReceived возникает в момент опроса порта (которое вероятно происходит каждый тик), если в буфере есть данные. Данные же в буфер пишутся асинхронно (по мере поступления).
    Поэтому, когда возникает событие DataReceived, в буфер могут ещё не успеть записаться все байты, для решения этой проблемы я делал так:
    Класс "ComPort" http://pastie.org/10814442
    private void ComPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                byte[] inBuf = new byte[256];
                int rxCount = _comPort.Read(ref inBuf, 2); //Максимальное время между байтами одной посылки 
                if (rxCount < 5) return; //Не наше
    
    //Обрабатываем массив inBuf 
            } 
    
    private ComPort _comPort = new ComPort();
    private void LoadPortSettings() //Повесить на загрузку формы
            {
                _comPort.DataReceived += ComPort_DataReceived;
    
                cmbPort.Items.Clear();
                cmbPort.Items.AddRange(_comPort.PortNames());
                cmbBaudRate.Items.Clear();
                cmbBaudRate.Items.AddRange(_comPort.BaudRates());
    
                cmbPort.SelectedItem = Properties.Settings.Default.Port;
                cmbBaudRate.SelectedItem = Properties.Settings.Default.BaudRate;
            }
    
    private void UpdatePortSettings() //Повесить на изменение комбобоксов cmbPort и cmbBaudRate
            {
                int cpi = cmbPort.SelectedIndex;
                int bri = cmbBaudRate.SelectedIndex;
                if (cpi >= 0 && bri >= 0)
                {
                    string port = cmbPort.Items[cpi].ToString();
                    string baudRate = cmbBaudRate.Items[bri].ToString();
                    if (!string.IsNullOrWhiteSpace(port) && !string.IsNullOrWhiteSpace(baudRate) 
                        && _comPort.isPortChange(port,baudRate))
                    {
                        _comPort.Open(port, baudRate);
                    }
                }
            }
    Ответ написан
    Комментировать
  • Как реализовать глобальный KeyPress в C#?

    @dark_Kelvin
    Если нужны горячие клавиши, то используйте RegisterHotKey / UnregisterHotKey
    Если надо отлавливать события KeyDown KeyPress KeyUp, то используйте SetWindowsHookEx с параметром WH_KEYBOARD_LL / UnhookWindowsHookEx
    private bool hooked = false;
    		private IntPtr hHook;
    		private HookProc managedDelegate = InternalCallback;
    		
    		public event KeyEventHandler KeyDown;
            public event KeyEventHandler KeyUp;
    		public event KeyPressEventHandler KeyPress;
    
    		public void StartHook()
            {
                IntPtr delegt = Marshal.GetFunctionPointerForDelegate(managedDelegate);
    			hHook = SetWindowsHookEx(HookType.WH_KEYBOARD_LL, delegt, getMainModuleHandle(), 0);
    			if (hHook == IntPtr.Zero) throw new Win32Exception(Marshal.GetLastWin32Error());
    		}
    		
    		public virtual void Unhook()
            {
    			if (!UnhookWindowsHookEx(hHook)) throw new Win32Exception(Marshal.GetLastWin32Error());
    		}
    		
    		protected int InternalCallback(int code, IntPtr wParam, IntPtr lParam)
            {
                if (code >= 0)
                {
                    bool handled = false;
                    KeyboardHookStruct keyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));
    				
    				if (KeyDown != null && ((int)wParam == WM_KEYDOWN || (int)wParam == WM_SYSKEYDOWN))
    				{
    					Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
    					KeyEventArgs e = new KeyEventArgs(keyData);
    					KeyDown.Invoke(null, e);
    					handled = e.Handled;
    				}
    				
    				if (KeyPress != null && (int)wParam == WM_KEYDOWN)
    				{
    					//Перекодирование сканкодов в Ascii
    				}
    				
    				if (KeyUp != null && ((int)wParam == WM_KEYUP || (int)wParam == WM_SYSKEYUP))
    				{
    					Keys keyData = (Keys)keyboardHookStruct.VirtualKeyCode;
    					KeyEventArgs e = new KeyEventArgs(keyData);
    					KeyUp.Invoke(null, e);
    					handled = handled || e.Handled;
    				}
    				
                    if (handled) return 1;
                }
                return CallNextHookEx(hHook, code, wParam, lParam);
            }
    		
    		
    		
    		private IntPtr getMainModuleHandle()
            {
                IntPtr hMod;
                using (Process process = Process.GetCurrentProcess())
                using (ProcessModule module = process.MainModule)
                {
                    hMod = GetModuleHandle(module.ModuleName);
                }
                return hMod;
            }
    
            [DllImport("user32.dll", SetLastError = true)]
            private static extern IntPtr SetWindowsHookEx(HookType hook, IntPtr callback,
                IntPtr hMod, uint dwThreadId);
    
            [DllImport("user32.dll", SetLastError = true)]
            internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
    
            [DllImport("user32.dll")]
            internal static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam,
                IntPtr lParam);
    
            [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern IntPtr GetModuleHandle(string lpModuleName);
    
            private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
    		
    		 private const int
             WM_KEYDOWN = 0x100,
             WM_KEYUP = 0x101,
             WM_SYSKEYDOWN = 0x104,
             WM_SYSKEYUP = 0x105;
    		
            [StructLayout(LayoutKind.Sequential)]
            private struct KeyboardHookStruct
            {
                /// <summary>
                /// Specifies a virtual-key code. The code must be a value in the range 1 to 254. 
                /// </summary>
                public int VirtualKeyCode;
                /// <summary>
                /// Specifies a hardware scan code for the key. 
                /// </summary>
                public int ScanCode;
                /// <summary>
                /// Specifies the extended-key flag, event-injected flag, context code, and transition-state flag.
                /// </summary>
                public int Flags;
                /// <summary>
                /// Specifies the Time stamp for this message.
                /// </summary>
                public int Time;
                /// <summary>
                /// Specifies extra information associated with the message. 
                /// </summary>
                public int ExtraInfo;
            }
    
    		
    		
    	internal enum HookType : int
        {
            ///
            WH_JOURNALRECORD = 0,
            ///
            WH_JOURNALPLAYBACK = 1,
            ///
            WH_KEYBOARD = 2,
            ///
            WH_GETMESSAGE = 3,
            ///
            WH_CALLWNDPROC = 4,
            ///
            WH_CBT = 5,
            ///
            WH_SYSMSGFILTER = 6,
            ///
            WH_MOUSE = 7,
            ///
            WH_HARDWARE = 8,
            ///
            WH_DEBUG = 9,
            ///
            WH_SHELL = 10,
            ///
            WH_FOREGROUNDIDLE = 11,
            ///
            WH_CALLWNDPROCRET = 12,
            ///
            WH_KEYBOARD_LL = 13,
            ///
            WH_MOUSE_LL = 14
        }
    Ответ написан
    3 комментария