Server/MainForm.cs
author sl
Fri, 15 Aug 2014 10:20:01 +0200
changeset 30 c375286d1a1c
parent 29 c4e03315035c
child 31 f19b04646b6a
permissions -rw-r--r--
Still trying to setup WCF for us to work nicely.
Now using multi threading and reliable session.
Implementing thread safe functions where needed.
Enforcing session mode.
Fixing bug in marquee label as we forgot to reset current position when text is changed.
sl@0
     1
´╗┐using System;
sl@0
     2
using System.Collections.Generic;
sl@0
     3
using System.ComponentModel;
sl@0
     4
using System.Data;
sl@0
     5
using System.Drawing;
sl@0
     6
using System.Linq;
sl@0
     7
using System.Text;
sl@0
     8
using System.Threading.Tasks;
sl@0
     9
using System.Windows.Forms;
sl@14
    10
using System.IO;
sl@0
    11
using CodeProject.Dialog;
sl@14
    12
using System.Drawing.Imaging;
sl@17
    13
using System.ServiceModel;
sl@25
    14
using System.Threading;
sl@25
    15
//
sl@22
    16
using SharpDisplayInterface;
sl@25
    17
using SharpDisplayClient;
sl@14
    18
sl@0
    19
sl@0
    20
namespace SharpDisplayManager
sl@0
    21
{
sl@0
    22
    public partial class MainForm : Form
sl@0
    23
    {
sl@2
    24
        DateTime LastTickTime;
sl@3
    25
        Display iDisplay;
sl@14
    26
        System.Drawing.Bitmap iBmp;
sl@14
    27
        bool iCreateBitmap; //Workaround render to bitmap issues when minimized
sl@17
    28
        ServiceHost iServiceHost;
sl@21
    29
        /// <summary>
sl@21
    30
        /// Our collection of clients
sl@21
    31
        /// </summary>
sl@21
    32
        public Dictionary<string, IDisplayServiceCallback> iClients;
sl@29
    33
        public bool iClosing;
sl@2
    34
sl@0
    35
        public MainForm()
sl@0
    36
        {
sl@2
    37
            LastTickTime = DateTime.Now;
sl@3
    38
            iDisplay = new Display();
sl@21
    39
            iClients = new Dictionary<string, IDisplayServiceCallback>();
sl@2
    40
sl@0
    41
            InitializeComponent();
sl@7
    42
            UpdateStatus();
sl@13
    43
sl@8
    44
            //Load settings
sl@8
    45
            marqueeLabelTop.Font = Properties.Settings.Default.DisplayFont;
sl@8
    46
            marqueeLabelBottom.Font = Properties.Settings.Default.DisplayFont;
sl@9
    47
            checkBoxShowBorders.Checked = Properties.Settings.Default.DisplayShowBorders;
sl@13
    48
            checkBoxConnectOnStartup.Checked = Properties.Settings.Default.DisplayConnectOnStartup;
sl@16
    49
            checkBoxReverseScreen.Checked = Properties.Settings.Default.DisplayReverseScreen;
sl@13
    50
            //
sl@13
    51
            tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@14
    52
            //We have a bug when drawing minimized and reusing our bitmap
sl@14
    53
            iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
    54
            iCreateBitmap = false;
sl@0
    55
        }
sl@0
    56
sl@13
    57
        private void MainForm_Load(object sender, EventArgs e)
sl@13
    58
        {
sl@17
    59
            StartServer();
sl@17
    60
sl@13
    61
            if (Properties.Settings.Default.DisplayConnectOnStartup)
sl@13
    62
            {
sl@13
    63
                iDisplay.Open();
sl@13
    64
                UpdateStatus();
sl@13
    65
            }
sl@13
    66
        }
sl@13
    67
sl@13
    68
sl@0
    69
        private void buttonFont_Click(object sender, EventArgs e)
sl@0
    70
        {
sl@0
    71
            //fontDialog.ShowColor = true;
sl@0
    72
            //fontDialog.ShowApply = true;
sl@0
    73
            fontDialog.ShowEffects = true;
sl@11
    74
            fontDialog.Font = marqueeLabelTop.Font;
sl@28
    75
sl@28
    76
            fontDialog.FixedPitchOnly = checkBoxFixedPitchFontOnly.Checked;
sl@28
    77
sl@0
    78
            //fontDialog.ShowHelp = true;
sl@0
    79
sl@0
    80
            //fontDlg.MaxSize = 40;
sl@0
    81
            //fontDlg.MinSize = 22;
sl@0
    82
sl@0
    83
            //fontDialog.Parent = this;
sl@0
    84
            //fontDialog.StartPosition = FormStartPosition.CenterParent;
sl@0
    85
sl@0
    86
            //DlgBox.ShowDialog(fontDialog);
sl@0
    87
sl@0
    88
            //if (fontDialog.ShowDialog(this) != DialogResult.Cancel)
sl@0
    89
            if (DlgBox.ShowDialog(fontDialog) != DialogResult.Cancel)
sl@0
    90
            {
sl@0
    91
sl@4
    92
                //MsgBox.Show("MessageBox MsgBox", "MsgBox caption");
sl@0
    93
sl@0
    94
                //MessageBox.Show("Ok");
sl@4
    95
                marqueeLabelTop.Font = fontDialog.Font;
sl@4
    96
                marqueeLabelBottom.Font = fontDialog.Font;
sl@8
    97
                Properties.Settings.Default.DisplayFont = fontDialog.Font;
sl@8
    98
                Properties.Settings.Default.Save();
sl@0
    99
                //label1.Font = fontDlg.Font;
sl@0
   100
                //textBox1.BackColor = fontDlg.Color;
sl@0
   101
                //label1.ForeColor = fontDlg.Color;
sl@0
   102
            }
sl@0
   103
        }
sl@0
   104
sl@0
   105
        private void buttonCapture_Click(object sender, EventArgs e)
sl@0
   106
        {
sl@0
   107
            System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height);
sl@0
   108
            tableLayoutPanel.DrawToBitmap(bmp, tableLayoutPanel.ClientRectangle);
sl@14
   109
            //Bitmap bmpToSave = new Bitmap(bmp);
sl@14
   110
            bmp.Save("D:\\capture.png");
sl@14
   111
sl@17
   112
            marqueeLabelTop.Text = "Sweet";
sl@17
   113
sl@14
   114
            /*
sl@14
   115
            string outputFileName = "d:\\capture.png";
sl@14
   116
            using (MemoryStream memory = new MemoryStream())
sl@14
   117
            {
sl@14
   118
                using (FileStream fs = new FileStream(outputFileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
sl@14
   119
                {
sl@14
   120
                    bmp.Save(memory, System.Drawing.Imaging.ImageFormat.Png);
sl@14
   121
                    byte[] bytes = memory.ToArray();
sl@14
   122
                    fs.Write(bytes, 0, bytes.Length);
sl@14
   123
                }
sl@14
   124
            }
sl@14
   125
             */
sl@14
   126
sl@0
   127
        }
sl@2
   128
sl@12
   129
        private void CheckForRequestResults()
sl@12
   130
        {
sl@12
   131
            if (iDisplay.IsRequestPending())
sl@12
   132
            {
sl@12
   133
                switch (iDisplay.AttemptRequestCompletion())
sl@12
   134
                {
sl@12
   135
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestPowerSupplyStatus:
sl@12
   136
                        if (iDisplay.PowerSupplyStatus())
sl@12
   137
                        {
sl@12
   138
                            toolStripStatusLabelPower.Text = "ON";
sl@12
   139
                        }
sl@12
   140
                        else
sl@12
   141
                        {
sl@12
   142
                            toolStripStatusLabelPower.Text = "OFF";
sl@12
   143
                        }
sl@12
   144
                        //Issue next request then
sl@12
   145
                        iDisplay.RequestDeviceId();
sl@12
   146
                        break;
sl@12
   147
sl@12
   148
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestDeviceId:
sl@12
   149
                        toolStripStatusLabelConnect.Text += " - " + iDisplay.DeviceId();
sl@12
   150
                        //Issue next request then
sl@12
   151
                        iDisplay.RequestFirmwareRevision();
sl@12
   152
                        break;
sl@12
   153
sl@12
   154
                    case Display.TMiniDisplayRequest.EMiniDisplayRequestFirmwareRevision:
sl@12
   155
                        toolStripStatusLabelConnect.Text += " v" + iDisplay.FirmwareRevision();
sl@12
   156
                        //No more request to issue
sl@12
   157
                        break;
sl@12
   158
                }
sl@12
   159
            }
sl@12
   160
        }
sl@12
   161
sl@16
   162
sl@16
   163
        public delegate int CoordinateTranslationDelegate(System.Drawing.Bitmap aBmp, int aInt);
sl@16
   164
sl@16
   165
sl@16
   166
        public static int ScreenReversedX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   167
        {
sl@16
   168
            return aBmp.Width - aX - 1;
sl@16
   169
        }
sl@16
   170
sl@16
   171
        public int ScreenReversedY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   172
        {
sl@16
   173
            return iBmp.Height - aY - 1;
sl@16
   174
        }
sl@16
   175
sl@16
   176
        public int ScreenX(System.Drawing.Bitmap aBmp, int aX)
sl@16
   177
        {
sl@16
   178
            return aX;
sl@16
   179
        }
sl@16
   180
sl@16
   181
        public int ScreenY(System.Drawing.Bitmap aBmp, int aY)
sl@16
   182
        {
sl@16
   183
            return aY;
sl@16
   184
        }
sl@16
   185
sl@16
   186
sl@16
   187
        //This is our timer tick responsible to perform our render
sl@2
   188
        private void timer_Tick(object sender, EventArgs e)
sl@14
   189
        {
sl@2
   190
            //Update our animations
sl@2
   191
            DateTime NewTickTime = DateTime.Now;
sl@2
   192
sl@2
   193
            marqueeLabelTop.UpdateAnimation(LastTickTime, NewTickTime);
sl@2
   194
            marqueeLabelBottom.UpdateAnimation(LastTickTime, NewTickTime);
sl@2
   195
sl@4
   196
            //Update our display
sl@4
   197
            if (iDisplay.IsOpen())
sl@4
   198
            {
sl@12
   199
                CheckForRequestResults();
sl@12
   200
sl@22
   201
                //Draw to bitmap
sl@14
   202
                if (iCreateBitmap)
sl@14
   203
                {
sl@14
   204
                    iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   205
                }
sl@14
   206
                tableLayoutPanel.DrawToBitmap(iBmp, tableLayoutPanel.ClientRectangle);
sl@14
   207
                //iBmp.Save("D:\\capture.png");
sl@16
   208
sl@16
   209
                //Select proper coordinate translation functions
sl@16
   210
                //We used delegate/function pointer to support reverse screen without doing an extra test on each pixels
sl@16
   211
                CoordinateTranslationDelegate screenX;
sl@16
   212
                CoordinateTranslationDelegate screenY;
sl@16
   213
sl@16
   214
                if (Properties.Settings.Default.DisplayReverseScreen)
sl@16
   215
                {
sl@16
   216
                    screenX = ScreenReversedX;
sl@16
   217
                    screenY = ScreenReversedY;
sl@16
   218
                }
sl@16
   219
                else
sl@16
   220
                {
sl@16
   221
                    screenX = ScreenX;
sl@16
   222
                    screenY = ScreenY;
sl@16
   223
                }
sl@22
   224
sl@7
   225
                //Send it to our display
sl@14
   226
                for (int i = 0; i < iBmp.Width; i++)
sl@4
   227
                {
sl@14
   228
                    for (int j = 0; j < iBmp.Height; j++)
sl@4
   229
                    {
sl@4
   230
                        unchecked
sl@4
   231
                        {
sl@14
   232
                            uint color = (uint)iBmp.GetPixel(i, j).ToArgb();
sl@14
   233
                            //For some reason when the app is minimized in the task bar only the alpha of our color is set.
sl@14
   234
                            //Thus that strange test for rendering to work both when the app is in the task bar and when it isn't.
sl@16
   235
                            iDisplay.SetPixel(screenX(iBmp, i), screenY(iBmp, j), Convert.ToInt32(!(color != 0xFF000000)));
sl@4
   236
                        }
sl@4
   237
                    }
sl@4
   238
                }
sl@4
   239
sl@4
   240
                iDisplay.SwapBuffers();
sl@4
   241
sl@4
   242
            }
sl@8
   243
sl@8
   244
            //Compute instant FPS
sl@8
   245
            toolStripStatusLabelFps.Text = (1.0/NewTickTime.Subtract(LastTickTime).TotalSeconds).ToString("F0") + " FPS";
sl@8
   246
sl@8
   247
            LastTickTime = NewTickTime;
sl@8
   248
sl@2
   249
        }
sl@3
   250
sl@3
   251
        private void buttonOpen_Click(object sender, EventArgs e)
sl@3
   252
        {
sl@3
   253
            if (iDisplay.Open())
sl@3
   254
            {
sl@7
   255
                UpdateStatus();
sl@12
   256
                iDisplay.RequestPowerSupplyStatus();
sl@3
   257
            }
sl@7
   258
            else
sl@7
   259
            {
sl@7
   260
                UpdateStatus();
sl@7
   261
                toolStripStatusLabelConnect.Text = "Connection error";
sl@7
   262
            }
sl@7
   263
sl@3
   264
        }
sl@3
   265
sl@3
   266
        private void buttonClose_Click(object sender, EventArgs e)
sl@3
   267
        {
sl@3
   268
            iDisplay.Close();
sl@9
   269
            UpdateStatus();
sl@3
   270
        }
sl@3
   271
sl@3
   272
        private void buttonClear_Click(object sender, EventArgs e)
sl@3
   273
        {
sl@3
   274
            iDisplay.Clear();
sl@3
   275
            iDisplay.SwapBuffers();
sl@3
   276
        }
sl@3
   277
sl@3
   278
        private void buttonFill_Click(object sender, EventArgs e)
sl@3
   279
        {
sl@3
   280
            iDisplay.Fill();
sl@3
   281
            iDisplay.SwapBuffers();
sl@3
   282
        }
sl@3
   283
sl@3
   284
        private void trackBarBrightness_Scroll(object sender, EventArgs e)
sl@3
   285
        {
sl@9
   286
            Properties.Settings.Default.DisplayBrightness = trackBarBrightness.Value;
sl@9
   287
            Properties.Settings.Default.Save();
sl@3
   288
            iDisplay.SetBrightness(trackBarBrightness.Value);
sl@9
   289
sl@3
   290
        }
sl@7
   291
sl@7
   292
        private void UpdateStatus()
sl@7
   293
        {
sl@7
   294
            if (iDisplay.IsOpen())
sl@7
   295
            {
sl@7
   296
                buttonFill.Enabled = true;
sl@7
   297
                buttonClear.Enabled = true;
sl@7
   298
                buttonOpen.Enabled = false;
sl@7
   299
                buttonClose.Enabled = true;
sl@7
   300
                trackBarBrightness.Enabled = true;
sl@7
   301
                trackBarBrightness.Minimum = iDisplay.MinBrightness();
sl@11
   302
                trackBarBrightness.Maximum = iDisplay.MaxBrightness();
sl@9
   303
                trackBarBrightness.Value = Properties.Settings.Default.DisplayBrightness;
sl@9
   304
                trackBarBrightness.LargeChange = Math.Max(1,(iDisplay.MaxBrightness() - iDisplay.MinBrightness())/5);
sl@9
   305
                trackBarBrightness.SmallChange = 1;
sl@9
   306
                iDisplay.SetBrightness(Properties.Settings.Default.DisplayBrightness);
sl@9
   307
sl@10
   308
                toolStripStatusLabelConnect.Text = "Connected - " + iDisplay.Vendor() + " - " + iDisplay.Product();
sl@10
   309
                //+ " - " + iDisplay.SerialNumber();
sl@7
   310
            }
sl@7
   311
            else
sl@7
   312
            {
sl@7
   313
                buttonFill.Enabled = false;
sl@7
   314
                buttonClear.Enabled = false;
sl@7
   315
                buttonOpen.Enabled = true;
sl@7
   316
                buttonClose.Enabled = false;
sl@7
   317
                trackBarBrightness.Enabled = false;
sl@9
   318
                toolStripStatusLabelConnect.Text = "Disconnected";
sl@7
   319
            }
sl@7
   320
        }
sl@9
   321
sl@13
   322
sl@13
   323
sl@9
   324
        private void checkBoxShowBorders_CheckedChanged(object sender, EventArgs e)
sl@9
   325
        {
sl@16
   326
            //Save our show borders setting
sl@13
   327
            tableLayoutPanel.CellBorderStyle = (checkBoxShowBorders.Checked ? TableLayoutPanelCellBorderStyle.Single : TableLayoutPanelCellBorderStyle.None);
sl@9
   328
            Properties.Settings.Default.DisplayShowBorders = checkBoxShowBorders.Checked;
sl@9
   329
            Properties.Settings.Default.Save();
sl@9
   330
        }
sl@13
   331
sl@13
   332
        private void checkBoxConnectOnStartup_CheckedChanged(object sender, EventArgs e)
sl@13
   333
        {
sl@16
   334
            //Save our connect on startup setting
sl@13
   335
            Properties.Settings.Default.DisplayConnectOnStartup = checkBoxConnectOnStartup.Checked;
sl@13
   336
            Properties.Settings.Default.Save();
sl@13
   337
        }
sl@13
   338
sl@16
   339
        private void checkBoxReverseScreen_CheckedChanged(object sender, EventArgs e)
sl@16
   340
        {
sl@16
   341
            //Save our reverse screen setting
sl@16
   342
            Properties.Settings.Default.DisplayReverseScreen = checkBoxReverseScreen.Checked;
sl@16
   343
            Properties.Settings.Default.Save();
sl@16
   344
        }
sl@16
   345
sl@14
   346
        private void MainForm_Resize(object sender, EventArgs e)
sl@14
   347
        {
sl@14
   348
            if (WindowState == FormWindowState.Minimized)
sl@14
   349
            {
sl@14
   350
                // Do some stuff
sl@14
   351
                //iBmp = new System.Drawing.Bitmap(tableLayoutPanel.Width, tableLayoutPanel.Height, PixelFormat.Format32bppArgb);
sl@14
   352
                iCreateBitmap = true;
sl@14
   353
            }
sl@14
   354
        }
sl@14
   355
sl@17
   356
        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
sl@17
   357
        {
sl@17
   358
            StopServer();
sl@17
   359
        }
sl@17
   360
sl@17
   361
        public void StartServer()
sl@17
   362
        {
sl@17
   363
            iServiceHost = new ServiceHost
sl@17
   364
                (
sl@17
   365
                    typeof(DisplayServer),
sl@20
   366
                    new Uri[] { new Uri("net.tcp://localhost:8001/") }
sl@17
   367
                );
sl@17
   368
sl@30
   369
            iServiceHost.AddServiceEndpoint(typeof(IDisplayService), new NetTcpBinding(SecurityMode.None,true), "DisplayService");
sl@17
   370
            iServiceHost.Open();
sl@17
   371
        }
sl@17
   372
sl@17
   373
        public void StopServer()
sl@17
   374
        {
sl@17
   375
            //Tell connected client first? Is that possible?
sl@29
   376
sl@29
   377
            if (iClients.Count>0)
sl@29
   378
            {
sl@29
   379
                //Tell our clients
sl@29
   380
                BroadcastCloseEvent();
sl@29
   381
            }
sl@29
   382
sl@29
   383
            //iServiceHost.Close();
sl@29
   384
sl@17
   385
        }
sl@17
   386
sl@21
   387
        public void BroadcastCloseEvent()
sl@21
   388
        {
sl@21
   389
            var inactiveClients = new List<string>();
sl@21
   390
            foreach (var client in iClients)
sl@21
   391
            {
sl@21
   392
                //if (client.Key != eventData.ClientName)
sl@21
   393
                {
sl@21
   394
                    try
sl@21
   395
                    {
sl@21
   396
                        client.Value.OnServerClosing(/*eventData*/);
sl@21
   397
                    }
sl@21
   398
                    catch (Exception ex)
sl@21
   399
                    {
sl@21
   400
                        inactiveClients.Add(client.Key);
sl@21
   401
                    }
sl@21
   402
                }
sl@21
   403
            }
sl@21
   404
sl@21
   405
            if (inactiveClients.Count > 0)
sl@21
   406
            {
sl@21
   407
                foreach (var client in inactiveClients)
sl@21
   408
                {
sl@21
   409
                    iClients.Remove(client);
sl@30
   410
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(client, false)[0]);
sl@21
   411
                }
sl@21
   412
            }
sl@21
   413
        }
sl@21
   414
sl@25
   415
        private void buttonStartClient_Click(object sender, EventArgs e)
sl@25
   416
        {
sl@25
   417
            Thread clientThread = new Thread(SharpDisplayClient.Program.Main);
sl@25
   418
            clientThread.Start();
sl@25
   419
        }
sl@25
   420
sl@27
   421
        private void buttonSuspend_Click(object sender, EventArgs e)
sl@27
   422
        {
sl@27
   423
            timer.Enabled = !timer.Enabled;
sl@27
   424
            if (!timer.Enabled)
sl@27
   425
            {
sl@27
   426
                buttonSuspend.Text = "Suspend";
sl@27
   427
            }
sl@27
   428
            else
sl@27
   429
            {
sl@27
   430
                buttonSuspend.Text = "Pause";
sl@27
   431
            }
sl@27
   432
        }
sl@27
   433
sl@29
   434
        private void buttonCloseClients_Click(object sender, EventArgs e)
sl@29
   435
        {
sl@29
   436
            BroadcastCloseEvent();
sl@29
   437
        }
sl@29
   438
sl@30
   439
        private void treeViewClients_AfterSelect(object sender, TreeViewEventArgs e)
sl@30
   440
        {
sl@21
   441
sl@30
   442
        }
sl@30
   443
sl@30
   444
        public delegate void AddClientDelegate(string aSessionId, IDisplayServiceCallback aCallback);
sl@30
   445
        public delegate void RemoveClientDelegate(string aSessionId);
sl@30
   446
        public delegate void SetTextDelegate(int aLineIndex, string aText);
sl@30
   447
        public delegate void SetTextsDelegate(System.Collections.Generic.IList<string> aTexts);
sl@30
   448
sl@30
   449
       
sl@30
   450
        /// <summary>
sl@30
   451
        /// 
sl@30
   452
        /// </summary>
sl@30
   453
        /// <param name="aSessionId"></param>
sl@30
   454
        /// <param name="aCallback"></param>
sl@30
   455
        public void AddClientThreadSafe(string aSessionId, IDisplayServiceCallback aCallback)
sl@30
   456
        {
sl@30
   457
            if (this.treeViewClients.InvokeRequired)
sl@30
   458
            {
sl@30
   459
                //Not in the proper thread, invoke ourselves
sl@30
   460
                AddClientDelegate d = new AddClientDelegate(AddClientThreadSafe);
sl@30
   461
                this.Invoke(d, new object[] { aSessionId, aCallback });
sl@30
   462
            }
sl@30
   463
            else
sl@30
   464
            {
sl@30
   465
                //We are in the proper thread
sl@30
   466
                //Add this session to our collection of clients
sl@30
   467
                Program.iMainForm.iClients.Add(aSessionId, aCallback);
sl@30
   468
                //Add this session to our UI
sl@30
   469
                Program.iMainForm.treeViewClients.Nodes.Add(aSessionId, aSessionId);
sl@30
   470
            }
sl@30
   471
        }
sl@30
   472
sl@30
   473
        /// <summary>
sl@30
   474
        /// 
sl@30
   475
        /// </summary>
sl@30
   476
        /// <param name="aSessionId"></param>
sl@30
   477
        public void RemoveClientThreadSafe(string aSessionId)
sl@30
   478
        {
sl@30
   479
            if (this.treeViewClients.InvokeRequired)
sl@30
   480
            {
sl@30
   481
                //Not in the proper thread, invoke ourselves
sl@30
   482
                RemoveClientDelegate d = new RemoveClientDelegate(RemoveClientThreadSafe);
sl@30
   483
                this.Invoke(d, new object[] { aSessionId });
sl@30
   484
            }
sl@30
   485
            else
sl@30
   486
            {
sl@30
   487
                //We are in the proper thread
sl@30
   488
                            //Remove this session from both client collection and UI tree view
sl@30
   489
                if (Program.iMainForm.iClients.Keys.Contains(aSessionId))
sl@30
   490
                {
sl@30
   491
                    Program.iMainForm.iClients.Remove(aSessionId);
sl@30
   492
                    Program.iMainForm.treeViewClients.Nodes.Remove(Program.iMainForm.treeViewClients.Nodes.Find(aSessionId, false)[0]);
sl@30
   493
                }                
sl@30
   494
            }
sl@30
   495
        }
sl@30
   496
sl@30
   497
        /// <summary>
sl@30
   498
        /// 
sl@30
   499
        /// </summary>
sl@30
   500
        /// <param name="aLineIndex"></param>
sl@30
   501
        /// <param name="aText"></param>
sl@30
   502
        public void SetTextThreadSafe(int aLineIndex, string aText)
sl@30
   503
        {
sl@30
   504
            if (this.treeViewClients.InvokeRequired)
sl@30
   505
            {
sl@30
   506
                //Not in the proper thread, invoke ourselves
sl@30
   507
                SetTextDelegate d = new SetTextDelegate(SetTextThreadSafe);
sl@30
   508
                this.Invoke(d, new object[] { aLineIndex, aText });
sl@30
   509
            }
sl@30
   510
            else
sl@30
   511
            {
sl@30
   512
                //We are in the proper thread
sl@30
   513
                //Only support two lines for now
sl@30
   514
                if (aLineIndex == 0)
sl@30
   515
                {
sl@30
   516
                    Program.iMainForm.marqueeLabelTop.Text = aText;
sl@30
   517
                }
sl@30
   518
                else if (aLineIndex == 1)
sl@30
   519
                {
sl@30
   520
                    Program.iMainForm.marqueeLabelBottom.Text = aText;
sl@30
   521
                }
sl@30
   522
            }
sl@30
   523
        }
sl@30
   524
sl@30
   525
        /// <summary>
sl@30
   526
        /// 
sl@30
   527
        /// </summary>
sl@30
   528
        /// <param name="aTexts"></param>
sl@30
   529
        public void SetTextsThreadSafe(System.Collections.Generic.IList<string> aTexts)
sl@30
   530
        {
sl@30
   531
            if (this.treeViewClients.InvokeRequired)
sl@30
   532
            {
sl@30
   533
                //Not in the proper thread, invoke ourselves
sl@30
   534
                SetTextsDelegate d = new SetTextsDelegate(SetTextsThreadSafe);
sl@30
   535
                this.Invoke(d, new object[] { aTexts });
sl@30
   536
            }
sl@30
   537
            else
sl@30
   538
            {
sl@30
   539
                //We are in the proper thread
sl@30
   540
                //Only support two lines for now
sl@30
   541
                for (int i = 0; i < aTexts.Count; i++)
sl@30
   542
                {
sl@30
   543
                    if (i == 0)
sl@30
   544
                    {
sl@30
   545
                        Program.iMainForm.marqueeLabelTop.Text = aTexts[i];
sl@30
   546
                    }
sl@30
   547
                    else if (i == 1)
sl@30
   548
                    {
sl@30
   549
                        Program.iMainForm.marqueeLabelBottom.Text = aTexts[i];
sl@30
   550
                    }
sl@30
   551
                }
sl@30
   552
            }
sl@30
   553
sl@30
   554
        }
sl@17
   555
sl@0
   556
    }
sl@0
   557
}