2012年7月6日 星期五

殘念的客顯

最近接到有個需求,需要去接廠商程式丟出來的資料顯示在延伸螢幕上
我不知道D2K有沒有辦法處理延伸螢幕,但是我們的協力廠技術上不行是確定的XD
所以就有了這段
∼考慮文字檔做中介資料交換
另外利用WPF寫一支程式來將資料呈現在延伸螢幕上作為客顯
基本上這隻程式的運作就是
兩個表單
主表單開在主畫面,並檢查系統環境(監控的文字檔存不存在,顯卡是否有多個輸出,是否連接兩個以上螢幕)
由主表單開啟控制副表單。若有連接第二顆螢幕則自動將副表單開在延伸畫面中
利用FileWatcher監控文字檔,文字內容有異動利用委派的方式更新在副表單畫面中∼



--mainWindow
using System;
using System.IO;
using System.Text;
using System.Windows;
using System.Threading;
using System.Windows.Forms;
using System.Windows.Media.Imaging;
using MsgBox = System.Windows.MessageBox;

namespace CustomerDisplay
{
    ///

    /// MainWindow.xaml
    /// 主視窗
    ///

    public partial class MainWindow : Window
    {
        private string fullpath = string.Empty;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //WindowState = WindowState.Maximized;
        }

        public MainWindow()
        {
            InitializeComponent();
            fullpath = App.dirPath + App.fileName;
            updateStatus(string.Format("檢查檔案:{0}", fullpath));
            updateStatus(string.Format("Result:{0}", CheckFileExist()));
            CheckDisplayDevice();
            this.Focus();
        }

        #region 檔案檢查

        private string CheckFileExist()
        {
            if (File.Exists(fullpath)) return "OK!";
            MessageBoxResult r = MsgBox.Show(@"預設目錄中找不到指定檔案
Yes:建立它
No:重新指定檔案位置 ", "檢查檔案", MessageBoxButton.YesNo);

            if (r.Equals(MessageBoxResult.OK))
            {
                File.Create(fullpath);
                return string.Format("{0} is created", fullpath);
            }
            else if (r.Equals(MessageBoxResult.No))
            {
                return SetFilePath();
            }
            else return string.Empty;
        }
        private string SetFilePath()
        {
            string rtn = "Nothing";
            OpenFileDialog ofDialog = new OpenFileDialog();
            ofDialog.InitialDirectory = "c:\\";
            ofDialog.Filter = "*.txt|";
            ofDialog.Multiselect = false;
            ofDialog.FilterIndex = 2;
            ofDialog.RestoreDirectory = true;

            if (ofDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                fullpath = ofDialog.FileName;
                App.dirPath = fullpath.Replace(ofDialog.SafeFileName, string.Empty);
                App.fileName = ofDialog.SafeFileName;
                rtn = string.Format("重新指定檔案:{0}{1}", App.dirPath, App.fileName);
            }
            return rtn;
        }

        #endregion

        #region 按鈕事件

        private void btnStart_Click(object sender, RoutedEventArgs e)
        {
            btnClose.IsEnabled = true;
            btnFileDialog.IsEnabled = false;
            btnStart.IsEnabled = false;
            image1.Source = GetImageSource("CustomerDisplay", "Images", "group.png");
            //客顯示窗
            CustomerWindow cusWindow = new CustomerWindow();
            Screen customerScreen = Screen.AllScreens[Screen.AllScreens.Length - 1]; //指定顯示於最後一個螢幕
            cusWindow.Top = customerScreen.WorkingArea.Top;
            cusWindow.Left = customerScreen.WorkingArea.Left;
            cusWindow.Show();
            cusWindow.Owner = this;
        }
      
        private void btnClose_Click(object sender, RoutedEventArgs e)
        {
            image1.Source = GetImageSource("CustomerDisplay", "Images", "guard.png");
            btnClose.IsEnabled = false;
            btnFileDialog.IsEnabled = true;
            btnStart.IsEnabled = true;
            this.OwnedWindows[0].Close();
        }

        private void btnFileDialog_Click(object sender, RoutedEventArgs e)
        {
            updateStatus(SetFilePath());
        }

        private void btnExit_Click(object sender, RoutedEventArgs e)
        {
            if (MsgBox.Show("確定要關閉客顯程式?", "ADL", MessageBoxButton.OKCancel).Equals(MessageBoxResult.OK)) App.Current.Shutdown();
        }

        #endregion

        #region 自訂

        ///
        /// 檢查顯示裝置狀態
        ///

        private void CheckDisplayDevice()
        {
            int displayPort = DisplayAPI.DisplayDeviceList().Count;
            int displayMonitor = Screen.AllScreens.Length;
            updateStatus(string.Format("顯示裝置數:{0}", displayPort));
            if (displayPort <= 1) { updateStatus("不支援多螢幕輸出"); return; }
            updateStatus(string.Format("顯示器數:{0}", displayMonitor));
            if (displayMonitor <= 1) { updateStatus("延伸螢幕尚未連接?"); return; }
            //有延伸桌面則開啟
            //if () //檢測目前模式、非延伸則切換
            //updateStatus("裝置偵測正常,變更設定為延伸桌面模式");
            //DisplayAPI.ChangeDisplayMode(DisplayAPI.DisplayMode.ExtendedDisplay);
        }
        ///
        /// 更新顯示訊息(新上舊下)
        ///

        /// updateStatus(string.Format("{0}"));
        private void updateStatus(string msg)
        {           
            lblStatus.Content = string.Format("{0}》{1}\r\n{2}", System.DateTime.Now.ToString("hh:mm:sss"), msg, lblStatus.Content);
        }
        ///
        /// 取得圖片
        ///

        ///
        ///
        ///
        ///
        private BitmapImage GetImageSource(string appName, string imageFolder, string imageName)
        {
            var uriSource = new Uri(string.Format(@"/{0};component/{1}/{2}", appName, imageFolder, imageName), UriKind.Relative);
            return new BitmapImage(uriSource);
        }

        #endregion
    }
}
--CusWindow 
using System.IO;
using System.Text;
using System.Threading;
using System.Windows;

namespace CustomerDisplay
{
    ///
    /// CustomerWindow.xaml
    /// 客顯示窗
    ///

    public partial class CustomerWindow : Window
    {
        private FileSystemWatcher fsWatcher = new FileSystemWatcher();
        private delegate void ThreadsSynchronization(string value);

        public CustomerWindow()
        {
            InitializeComponent();
            StartFileWatch();          
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //WindowState = WindowState.Maximized;
        }

        private void Window_Unloaded(object sender, System.Windows.RoutedEventArgs e)
        {
            lblShow.Content = string.Empty;
            fsWatcher.EnableRaisingEvents = false;
        }

        #region FileWatcher & Theard

        private void StartFileWatch()
        {
            fsWatcher.Path = App.dirPath;
            fsWatcher.Filter = App.fileName;
            fsWatcher.Changed += new FileSystemEventHandler(OnChanged);
            fsWatcher.EnableRaisingEvents = true;
        }
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            var thread = new Thread(new ThreadStart(displayThread));
            thread.Start();
        }
        private void displayThread()
        {
            Dispatcher.BeginInvoke(new ThreadsSynchronization(CustomerDisplayShow), new object[] { App.dirPath + App.fileName });
        }
        private void CustomerDisplayShow(string value)
        {
            using (StreamReader sr = new StreamReader(value, Encoding.UTF8))
            {
                lblShow.Content = sr.ReadToEnd();
            }
        }
        #endregion

    }
}

--Result

--

看到、想到、說到、做到 
能夠填平大海的誓言,也比不上邁出一步的價值 
是以吾輩此生,再無任何誓言

沒有留言: