Posted
Filed under .NET/C#
몇 달만에 포스팅 인지 모르겠습니다.....
이전 포스팅에 USB 장치 인식시 자동으로 Comport를 찾아주는 소스를... (윈폼)
올려 드렸습니다..

이번 포스팅은 WPF에서 USB인식시 Comport를 찾아주는 소스 입니다.

using System;
using System.Windows;
using System.IO.Ports;
using System.Windows.Threading;
using System.Windows.Interop;
using System.Runtime.InteropServices;

namespace Wpf_Serial
{
    /// 
    /// MainWindow.xaml에 대한 상호 작용 논리
    /// 
    public partial class MainWindow : Window
    {
        decimal LineNumber = 1;

        SerialPort SP = new SerialPort();

        public MainWindow()
        {
            InitializeComponent();
        }

        IntPtr WndProc(IntPtr hWnd, int nMsg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            UInt32 WM_DEVICECHANGE = 0x0219;
            UInt32 DBT_DEVTUP_VOLUME = 0x02;
            UInt32 DBT_DEVICEARRIVAL = 0x8000;
            UInt32 DBT_DEVICEREMOVECOMPLETE = 0x8004;

            //디바이스 연결시
            if ((nMsg == WM_DEVICECHANGE) && (wParam.ToInt32() == DBT_DEVICEARRIVAL))
            {
                int devType = Marshal.ReadInt32(lParam, 4);

                if (devType == DBT_DEVTUP_VOLUME)
                {
                    GetSerialPort();
                }
            }

            //디바이스 연결 해제시...
            if((nMsg == WM_DEVICECHANGE) && (wParam.ToInt32() == DBT_DEVICEREMOVECOMPLETE))
            {
                int devType = Marshal.ReadInt32(lParam,4);
                if(devType == DBT_DEVTUP_VOLUME)
                {
                    GetSerialPort();
                }
            }

            return IntPtr.Zero;
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            WindowInteropHelper helper = new WindowInteropHelper(this);
            HwndSource source = HwndSource.FromHwnd(helper.Handle);
            source.AddHook(new HwndSourceHook(this.WndProc));

            SP.DataReceived += new SerialDataReceivedEventHandler(SP_DataReceived);
        }

        private void SP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate
            {
                string str = SP.ReadLine();
                textBox1.AppendText("[" + LineNumber++.ToString() + "] : " + str);
                textBox1.ScrollToEnd();
            }));
        }

        private void btnPortSearch_Click(object sender, RoutedEventArgs e)
        {
            GetSerialPort();
        }

        private void GetSerialPort()
        {
            lst_ComPort.Items.Clear();
            foreach (string comport in SerialPort.GetPortNames())
            {
                lst_ComPort.Items.Add(comport);
            }

            if (lst_ComPort.Items.Count <= 0)
            {
                lst_ComPort.Items.Add("찾을 수 없음");
            }
        }

        private void btnPortOpen_Click(object sender, RoutedEventArgs e)
        {
            if (SP.IsOpen)
            {

            }
            else
            {
                SP.Open();
            }
        }

        private void lst_ComPort_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            SP.PortName = lst_ComPort.SelectedItem.ToString();
        }

        private void btnPortClose_Click(object sender, RoutedEventArgs e)
        {
            if (SP.IsOpen)
            {
                SP.Close();
            }
        }
    }
}
음 WPF에서 요 코드를 사용하기 전에 WindowsBase 항목을 참조를 해주어야 했던걸로 기억이 납니다..
2012/08/20 14:44 2012/08/20 14:44