2014年9月29日 星期一

健保雲端藥歷系統-3(WatiN、webBrowser)

改寫了一版內嵌 webBrower 的版本。由於在同一個 process 上去取得 webBrower 的控制項會有問題,所以開另外一個 thread 搭配匿名函式(Anonymous Functions)去執行 ~

public partial class Form1 : Form
{
    ...

    delegate void UpdateDataGridViewDataSourceDelegate(DataGridView dgv, DataTable dt);
    private void UpdateDataGridViewDataSource(DataGridView dgv, DataTable dt)
    {
        ...
    }

    private void btnEmbed健保雲端藥歷系統_Click(object sender, EventArgs e)
    {
        try
        {
            btnEmbed健保雲端藥歷系統.Enabled = false;

            var thread = new Thread(() =>
            {
                baseTime = DateTime.Now;

                if (WatiN.Core.Settings.AutoStartDialogWatcher)
                {
                    WatiN.Core.Settings.AutoStartDialogWatcher = false;
                }

                WatiN.Core.IE __windowIE = new WatiN.Core.IE(webBrowser1.ActiveXInstance);
                if (webBrowser1.Url == null)
                {
                    __windowIE.GoTo("https://10.253.253.245/imme0000/IMME0002S01.aspx");
                }
                else
                {
                    WatiN.Core.Button ContentPlaceHolder1_btnReSrc = __windowIE.Button("ContentPlaceHolder1_btnReSrc");
                    if (ContentPlaceHolder1_btnReSrc.Exists)
                    {
                        ContentPlaceHolder1_btnReSrc.Click();
                    }
                }

                #region busy and timeout control
                while (((SHDocVw.InternetExplorer)(__windowIE.InternetExplorer)).Busy)
                {
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(3000);

                    runTime = DateTime.Now - baseTime;
                    if (runTime > timeOut) break;
                }
                #endregion

                while (true)
                {
                    #region https://10.253.253.245/imme0000/IMME0002S01.aspx
                    if (__windowIE.Url == entryURL)
                    {
                        WatiN.Core.Span ContentPlaceHolder1_lblmsg = __windowIE.Span("ContentPlaceHolder1_lblmsg");
                        if (ContentPlaceHolder1_lblmsg.Exists)
                        {
                            MessageBox.Show(ContentPlaceHolder1_lblmsg.OuterText);
                            break;
                        }
                    }
                    #endregion

                    #region https://10.253.253.245/imme0000/IMME0002S02.aspx
                    if (__windowIE.Url == targetURL)
                    {
                        WatiN.Core.Table ContentPlaceHolder1_gvList = __windowIE.Table("ContentPlaceHolder1_gvList");
                        if (ContentPlaceHolder1_gvList.Exists)
                        {
                            DataTable dt = gvListHtml2DT(ContentPlaceHolder1_gvList);

                            if (dataGridView1.InvokeRequired)
                            {
                                dataGridView1.Invoke(new UpdateDataGridViewDataSourceDelegate(UpdateDataGridViewDataSource), new object[] { dataGridView1, dt });
                            }
                            else
                            {
                                UpdateDataGridViewDataSource(dataGridView1, dt);
                            }

                            break;
                        }

                        WatiN.Core.Span ContentPlaceHolder1_lblmsg = __windowIE.Span("ContentPlaceHolder1_lblmsg");
                        if (ContentPlaceHolder1_lblmsg.Exists && ContentPlaceHolder1_lblmsg.OuterText.Contains("查無資料"))
                        {
                            if (dataGridView1.InvokeRequired)
                            {
                                dataGridView1.Invoke(new UpdateDataGridViewDataSourceDelegate(UpdateDataGridViewDataSource), new object[] { dataGridView1, new DataTable() });
                            }
                            else
                            {
                                UpdateDataGridViewDataSource(dataGridView1, new DataTable());
                            }

                            MessageBox.Show(ContentPlaceHolder1_lblmsg.OuterText);
                            break;
                        }
                    }
                    #endregion

                    Application.DoEvents();
                    System.Threading.Thread.Sleep(1000);

                    runTime = DateTime.Now - baseTime;
                    if (runTime > timeOut) break;
                }
            });
            thread.SetApartmentState(ApartmentState.STA);
            thread.Start();
          
        }
        catch (Exception ex)
        {
            Debug.Print(ex.Message);
        }
        finally
        {
            btnEmbed健保雲端藥歷系統.Enabled = true;
        }
    }

    private DataTable gvListHtml2DT(WatiN.Core.Table table)
    {
        ...
    }

} 

健保雲端藥歷系統-2(WatiN)

如果你不希望看到IE,那就呼叫前先設定 WatiN.Core.Settings.MakeNewIeInstanceVisible 為 false。

if (WatiN.Core.Settings.MakeNewIeInstanceVisible)
    WatiN.Core.Settings.MakeNewIeInstanceVisible = false;

健保雲端藥歷系統-1(WatiN)

衛生福利部的送的"大禮" ~ 健保雲端藥歷系統
經過各同仁一番努力之後,看來不得不將這套系統整合到自己的HIS內,所以參考了WatiN這套網頁測試工具,效果不錯但仍有些非同步的網頁的狀態判斷仍不夠好(只能拉長等待秒數,避免判斷錯誤)!

public partial class Form1 : Form
{
    private WatiN.Core.IE windowIE = null;
    private string entryURL = "https://10.253.253.245/imme0000/IMME0002S01.aspx";
    private string targetURL = "https://10.253.253.245/imme0000/IMME0002S02.aspx";
    private DateTime baseTime;
    private TimeSpan runTime;
    private TimeSpan timeOut = TimeSpan.FromSeconds(90);

    private void btnShow健保雲端藥歷系統_Click(object sender, EventArgs e)
    {
        try
        {
            StartCounting();

            baseTime = DateTime.Now;

            if (windowIE != null)
            {
                WatiN.Core.Button ContentPlaceHolder1_btnReSrc = windowIE.Button("ContentPlaceHolder1_btnReSrc");
                if (ContentPlaceHolder1_btnReSrc.Exists)
                {
                    ContentPlaceHolder1_btnReSrc.Click();
                }
            }
            else
            {
                windowIE = new WatiN.Core.IE(entryURL);
                windowIE.WaitForComplete((int)timeOut.TotalSeconds);
            }

            #region busy and timeout control
            while (((SHDocVw.InternetExplorer)(windowIE.InternetExplorer)).Busy)
            {
                Application.DoEvents();
                System.Threading.Thread.Sleep(3000);

                runTime = DateTime.Now - baseTime;
                if (runTime > timeOut) break;
            }
            #endregion

            while (true)
            {
                #region https://10.253.253.245/imme0000/IMME0002S01.aspx
                if (windowIE.Url == entryURL)
                {
                    WatiN.Core.Span ContentPlaceHolder1_lblmsg = windowIE.Span("ContentPlaceHolder1_lblmsg");
                    if (ContentPlaceHolder1_lblmsg.Exists)
                    {
                        MessageBox.Show(ContentPlaceHolder1_lblmsg.OuterText);
                        break;
                    }
                }
                #endregion

                #region https://10.253.253.245/imme0000/IMME0002S02.aspx
                if (windowIE.Url == targetURL)
                {
                    WatiN.Core.Table ContentPlaceHolder1_gvList = windowIE.Table("ContentPlaceHolder1_gvList");
                    if (ContentPlaceHolder1_gvList.Exists)
                    {
                        if (dataGridView1.DataSource != null)
                        {
                            dataGridView1.DataSource = null;
                        }
                        else
                        {
                            dataGridView1.Rows.Clear();
                        }
                        dataGridView1.Refresh();
                        dataGridView1.DataSource = gvListHtml2DT(ContentPlaceHolder1_gvList);
                        break;
                    }

                    WatiN.Core.Span ContentPlaceHolder1_lblmsg = windowIE.Span("ContentPlaceHolder1_lblmsg");
                    if (ContentPlaceHolder1_lblmsg.Exists && ContentPlaceHolder1_lblmsg.OuterText.Contains("查無資料"))
                    {
                        if (dataGridView1.DataSource != null)
                        {
                            dataGridView1.DataSource = null;
                        }
                        else
                        {
                            dataGridView1.Rows.Clear();
                        }
                        dataGridView1.Refresh();
                        MessageBox.Show(ContentPlaceHolder1_lblmsg.OuterText);
                        break;
                    }
                }
                #endregion

                Application.DoEvents();
                System.Threading.Thread.Sleep(1000);

                runTime = DateTime.Now - baseTime;
                if (runTime > timeOut) break;
            }
        }
        catch (Exception ex)
        {
            Debug.Print(ex.Message);
            if (windowIE != null)
            {
                windowIE.Dispose();
            }
        }
        finally
        {
            StopCounting();
        }
    }

    private DataTable gvListHtml2DT(WatiN.Core.Table table)
    {
        DataTable dt = new DataTable();

        WatiN.Core.TableRowCollection rows = table.TableRows;
        WatiN.Core.TableRow row = rows[0];
        WatiN.Core.ElementCollection cols = row.Elements;

        StringCollection RowValues = new StringCollection();
        foreach (WatiN.Core.Element col in cols)
        {
            if (col.TagName == "TH") RowValues.Add(col.OuterText);
        }

        for (int j = 0; j < RowValues.Count; j++)
        {
            dt.Columns.Add(RowValues[j], Type.GetType("System.String"));
        }

        if (rows.Count > 1)
        {
            for (int i = 1; i < rows.Count; i++)
            {
                row = rows[i];
                cols = row.Elements;

                dt.Rows.Add();
                for (int j = 0; j < RowValues.Count; j++)
                {
                    dt.Rows[i - 1][j] = cols[j].OuterText;
                }
            }
        }

        return dt;
    }

    private void StartCounting()
    {
        ...
    }

    private void StopCounting()
    {
        ...
    }

}

2014年9月28日 星期日

診間報到系統-2(BackgroundWorker)

由於我們報到系統的USB延長線有10米長,很容易就需要重新插拔USB接頭,間接daemon的程式就很容易死掉。所以,打算改寫daemon的程式,希望能多一些錯誤控制但又不想用timer去寫程式(內心覺得有點low ~ 哈)。最後,用BackgroundWorker模擬像是daemon的運作方式 ~

public class SmartCardLite
{
    // 讀取健保卡基本資料
    public static void ManualSmartCardDetection()
    {
        ...
    }

    private static BackgroundWorker _worker;

    public static void StartAutoSmartCardDetection()
    {
        _worker = new BackgroundWorker();
        _worker.WorkerSupportsCancellation = true;
        _worker.DoWork += WaitChangeStatus;
        _worker.RunWorkerAsync();
    }

    public static void StopAutoSmartCardDetection()
    {
        _worker.CancelAsync();
        _worker.Dispose();
    }

    private static void WaitChangeStatus(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker bwAsync = sender as BackgroundWorker;

        while (!bwAsync.CancellationPending)
        {
            ManualSmartCardDetection();

            Thread.Sleep(5000);
        }
    }

}

診間報到系統-1(DoubleBuffered)

叫號時閃爍功能不夠順暢!開啟控制項的DoubleBuffered

Public Sub New()

    ' 此為 Windows Form 設計工具所需的呼叫。
    InitializeComponent()

    ' 在 InitializeComponent() 呼叫之後加入任何初始設定。
    Me.DoubleBuffered = True
    Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer, True)
    Me._PropertyInfo = Me.GetType().GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.NonPublic)
    SearchControl(Me)

End Sub

Sub SearchControl(ByVal Ctrl As System.Windows.Forms.Control)

    For Each rootCtrl As System.Windows.Forms.Control In Ctrl.Controls
        Me._PropertyInfo.SetValue(rootCtrl, True, Nothing)
        If (rootCtrl.HasChildren) Then
            SearchControl(rootCtrl)
        End If
    Next

End Sub