Support for SharDisplayManager.
authorsl
Sun, 21 Sep 2014 21:55:36 +0200
changeset 4031d10b3a8a235
parent 402 ded1323b61ee
child 404 7b7fad708159
Support for SharDisplayManager.
GUI/MainForm.Designer.cs
GUI/MainForm.cs
GUI/SensorSharpDisplay.cs
GUI/SharpDisplay.cs
GUI/SharpDisplayClient.cs
OpenHardwareMonitor.csproj
     1.1 --- a/GUI/MainForm.Designer.cs	Thu Apr 18 23:25:10 2013 +0200
     1.2 +++ b/GUI/MainForm.Designer.cs	Sun Sep 21 21:55:36 2014 +0200
     1.3 @@ -84,7 +84,7 @@
     1.4              this.plotWindowMenuItem = new System.Windows.Forms.MenuItem();
     1.5              this.plotBottomMenuItem = new System.Windows.Forms.MenuItem();
     1.6              this.plotRightMenuItem = new System.Windows.Forms.MenuItem();
     1.7 -            this.menuItem4 = new System.Windows.Forms.MenuItem();
     1.8 +            this.menuItemFrontView = new System.Windows.Forms.MenuItem();
     1.9              this.frontViewPackedMenuItem = new System.Windows.Forms.MenuItem();
    1.10              this.frontViewDisplayTimeMenuItem = new System.Windows.Forms.MenuItem();
    1.11              this.webMenuItemSeparator = new System.Windows.Forms.MenuItem();
    1.12 @@ -98,6 +98,9 @@
    1.13              this.timer = new System.Windows.Forms.Timer(this.components);
    1.14              this.splitContainer = new OpenHardwareMonitor.GUI.SplitContainerAdv();
    1.15              this.treeView = new Aga.Controls.Tree.TreeViewAdv();
    1.16 +            this.menuItemSharpDisplay = new System.Windows.Forms.MenuItem();
    1.17 +            this.sharpDisplayPackedMenuItem = new System.Windows.Forms.MenuItem();
    1.18 +            this.sharpDisplayShowTimeMenuItem = new System.Windows.Forms.MenuItem();
    1.19              ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
    1.20              this.splitContainer.Panel1.SuspendLayout();
    1.21              this.splitContainer.SuspendLayout();
    1.22 @@ -358,7 +361,8 @@
    1.23              this.separatorMenuItem,
    1.24              this.temperatureUnitsMenuItem,
    1.25              this.plotLocationMenuItem,
    1.26 -            this.menuItem4,
    1.27 +            this.menuItemFrontView,
    1.28 +            this.menuItemSharpDisplay,
    1.29              this.webMenuItemSeparator,
    1.30              this.webMenuItem});
    1.31              this.optionsMenuItem.Text = "Options";
    1.32 @@ -437,13 +441,13 @@
    1.33              this.plotRightMenuItem.RadioCheck = true;
    1.34              this.plotRightMenuItem.Text = "Right";
    1.35              // 
    1.36 -            // menuItem4
    1.37 +            // menuItemFrontView
    1.38              // 
    1.39 -            this.menuItem4.Index = 7;
    1.40 -            this.menuItem4.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    1.41 +            this.menuItemFrontView.Index = 7;
    1.42 +            this.menuItemFrontView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    1.43              this.frontViewPackedMenuItem,
    1.44              this.frontViewDisplayTimeMenuItem});
    1.45 -            this.menuItem4.Text = "FrontView";
    1.46 +            this.menuItemFrontView.Text = "FrontView";
    1.47              // 
    1.48              // frontViewPackedMenuItem
    1.49              // 
    1.50 @@ -455,14 +459,32 @@
    1.51              this.frontViewDisplayTimeMenuItem.Index = 1;
    1.52              this.frontViewDisplayTimeMenuItem.Text = "Display time";
    1.53              // 
    1.54 +            // menuItemSharpDisplay
    1.55 +            // 
    1.56 +            this.menuItemSharpDisplay.Index = 8;
    1.57 +            this.menuItemSharpDisplay.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    1.58 +            this.sharpDisplayPackedMenuItem,
    1.59 +            this.sharpDisplayShowTimeMenuItem});
    1.60 +            this.menuItemSharpDisplay.Text = "SharpDisplay";
    1.61 +            // 
    1.62 +            // sharpDisplayPackedMenuItem
    1.63 +            // 
    1.64 +            this.sharpDisplayPackedMenuItem.Index = 0;
    1.65 +            this.sharpDisplayPackedMenuItem.Text = "Packed";
    1.66 +            // 
    1.67 +            // sharpDisplayDisplayTimeMenuItem
    1.68 +            // 
    1.69 +            this.sharpDisplayShowTimeMenuItem.Index = 1;
    1.70 +            this.sharpDisplayShowTimeMenuItem.Text = "Display Time";
    1.71 +            // 
    1.72              // webMenuItemSeparator
    1.73              // 
    1.74 -            this.webMenuItemSeparator.Index = 8;
    1.75 +            this.webMenuItemSeparator.Index = 9;
    1.76              this.webMenuItemSeparator.Text = "-";
    1.77              // 
    1.78              // webMenuItem
    1.79              // 
    1.80 -            this.webMenuItem.Index = 9;
    1.81 +            this.webMenuItem.Index = 10;
    1.82              this.webMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
    1.83              this.runWebServerMenuItem,
    1.84              this.serverPortMenuItem});
    1.85 @@ -564,7 +586,7 @@
    1.86              // 
    1.87              this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    1.88              this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    1.89 -            this.ClientSize = new System.Drawing.Size(418, 554);
    1.90 +            this.ClientSize = new System.Drawing.Size(418, 533);
    1.91              this.Controls.Add(this.splitContainer);
    1.92              this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
    1.93              this.Menu = this.mainMenu;
    1.94 @@ -644,9 +666,12 @@
    1.95      private System.Windows.Forms.MenuItem gpuMenuItem;
    1.96      private System.Windows.Forms.MenuItem fanControllerMenuItem;
    1.97      private System.Windows.Forms.MenuItem ramMenuItem;
    1.98 -    private System.Windows.Forms.MenuItem menuItem4;
    1.99 +    private System.Windows.Forms.MenuItem menuItemFrontView;
   1.100      private System.Windows.Forms.MenuItem frontViewPackedMenuItem;
   1.101      private System.Windows.Forms.MenuItem frontViewDisplayTimeMenuItem;
   1.102 +    private System.Windows.Forms.MenuItem menuItemSharpDisplay;
   1.103 +    private System.Windows.Forms.MenuItem sharpDisplayPackedMenuItem;
   1.104 +    private System.Windows.Forms.MenuItem sharpDisplayShowTimeMenuItem;
   1.105    }
   1.106  }
   1.107  
     2.1 --- a/GUI/MainForm.cs	Thu Apr 18 23:25:10 2013 +0200
     2.2 +++ b/GUI/MainForm.cs	Sun Sep 21 21:55:36 2014 +0200
     2.3 @@ -39,6 +39,7 @@
     2.4      private Color[] plotColorPalette;
     2.5      private SystemTray systemTray;
     2.6      private SoundGraphDisplay soundGraphDisplay;
     2.7 +    private SharpDisplay sharpDisplay;
     2.8      private bool displayTick;
     2.9      private StartupManager startupManager = new StartupManager();
    2.10      private UpdateVisitor updateVisitor = new UpdateVisitor();
    2.11 @@ -57,6 +58,8 @@
    2.12      private UserOption autoStart;
    2.13      private UserOption frontViewPacked; //Tells whether FrontView should cycle or pack sensors
    2.14      private UserOption frontViewDisplayTime; //Tells whether or not FrontView should display current time
    2.15 +    private UserOption sharpDisplayPacked; //Tells whether SharpDisplay should cycle or pack sensors
    2.16 +    private UserOption sharpDisplayShowTime; //Tells whether or not SharpDisplay should display current time
    2.17  
    2.18      private UserOption readMainboardSensors;
    2.19      private UserOption readCpuSensors;
    2.20 @@ -127,14 +130,18 @@
    2.21        treeView.Model = treeModel;
    2.22  
    2.23        this.computer = new Computer(settings);
    2.24 -
    2.25 +       
    2.26 +      //System tray
    2.27        systemTray = new SystemTray(computer, settings, unitManager);
    2.28        systemTray.HideShowCommand += hideShowClick;
    2.29        systemTray.ExitCommand += exitClick;
    2.30    
    2.31 +      //SoundGraph Display
    2.32        soundGraphDisplay = new SoundGraphDisplay(computer, settings, unitManager);
    2.33 - 
    2.34 -
    2.35 +      //Sharp Display Manager
    2.36 +      sharpDisplay = new SharpDisplay(computer, settings, unitManager);
    2.37 +      
    2.38 +      //
    2.39        int p = (int)Environment.OSVersion.Platform;
    2.40        if ((p == 4) || (p == 128)) { // Unix
    2.41          treeView.RowHeight = Math.Max(treeView.RowHeight, 18); 
    2.42 @@ -227,6 +234,10 @@
    2.43        frontViewPacked = new UserOption("frontViewPackedMenuItem", false, frontViewPackedMenuItem, settings);
    2.44        frontViewDisplayTime = new UserOption("frontViewDisplayTimeMenuItem", false, frontViewDisplayTimeMenuItem, settings);
    2.45  
    2.46 +      sharpDisplayPacked = new UserOption("sharpDisplayPackedMenuItem", false, sharpDisplayPackedMenuItem, settings);
    2.47 +      sharpDisplayShowTime = new UserOption("sharpDisplayShowTimeMenuItem", false, sharpDisplayShowTimeMenuItem, settings);
    2.48 +
    2.49 +
    2.50        readMainboardSensors = new UserOption("mainboardMenuItem", true, 
    2.51          mainboardMenuItem, settings);
    2.52        readMainboardSensors.Changed += delegate(object sender, EventArgs e) {
    2.53 @@ -466,6 +477,14 @@
    2.54                SolidBrush greenBrush = new SolidBrush(Color.FromName("mediumspringgreen"));
    2.55                e.BackgroundBrush = greenBrush;
    2.56            }
    2.57 +
    2.58 +          //If displayed in SharpDisplay draw background in blue
    2.59 +          if (sensorNode != null && settings.GetValue(new Identifier(sensorNode.Sensor.Identifier, "SharpDisplay").ToString(), false))
    2.60 +          {
    2.61 +              SolidBrush aquaBrush = new SolidBrush(Color.FromName("aqua"));
    2.62 +              e.BackgroundBrush = aquaBrush;
    2.63 +          }
    2.64 +
    2.65          } else {
    2.66  
    2.67            e.TextColor = Color.DarkGray;
    2.68 @@ -539,8 +558,14 @@
    2.69                soundGraphDisplay.SetText("       -+-", "");
    2.70            }
    2.71            */
    2.72 +      }
    2.73 +
    2.74 +      if (sharpDisplay != null)
    2.75 +      {
    2.76 +          sharpDisplay.Redraw(sharpDisplayPacked.Value, sharpDisplayShowTime.Value);
    2.77        }  
    2.78  
    2.79 +
    2.80      }
    2.81  
    2.82      private void SaveConfiguration() {
    2.83 @@ -603,6 +628,7 @@
    2.84            server.Quit();
    2.85        systemTray.Dispose();
    2.86        soundGraphDisplay.Dispose();
    2.87 +      sharpDisplay.Dispose();
    2.88      }
    2.89  
    2.90      private void aboutMenuItem_Click(object sender, EventArgs e) {
    2.91 @@ -674,6 +700,18 @@
    2.92                };
    2.93                treeContextMenu.MenuItems.Add(item);
    2.94            }
    2.95 +          {
    2.96 +              MenuItem item = new MenuItem("Show in SharpDisplay");
    2.97 +              item.Checked = sharpDisplay.Contains(node.Sensor);
    2.98 +              item.Click += delegate(object obj, EventArgs args)
    2.99 +              {
   2.100 +                  if (item.Checked)
   2.101 +                      sharpDisplay.Remove(node.Sensor);
   2.102 +                  else
   2.103 +                      sharpDisplay.Add(node.Sensor, true);
   2.104 +              };
   2.105 +              treeContextMenu.MenuItems.Add(item);
   2.106 +          }
   2.107            if (gadget != null) {
   2.108              MenuItem item = new MenuItem("Show in Gadget");
   2.109              item.Checked = gadget.Contains(node.Sensor);
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/GUI/SensorSharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
     3.3 @@ -0,0 +1,190 @@
     3.4 +/*
     3.5 + 
     3.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     3.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     3.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     3.9 + 
    3.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    3.11 +	
    3.12 +*/
    3.13 +
    3.14 +using System;
    3.15 +using System.Drawing;
    3.16 +using System.Drawing.Drawing2D;
    3.17 +using System.Drawing.Imaging;
    3.18 +using System.Drawing.Text;
    3.19 +using System.Runtime.InteropServices;
    3.20 +using System.Windows.Forms;
    3.21 +using OpenHardwareMonitor.Hardware;
    3.22 +using OpenHardwareMonitor.Utilities;
    3.23 +
    3.24 +namespace OpenHardwareMonitor.GUI
    3.25 +{
    3.26 +    public class SensorSharpDisplay : IDisposable
    3.27 +    {
    3.28 +
    3.29 +        private UnitManager unitManager;
    3.30 +
    3.31 +        private ISensor sensor;
    3.32 +        private Color color;
    3.33 +        private Color darkColor;
    3.34 +        private Font font;
    3.35 +        private Font smallFont;
    3.36 +        public string iFirstLine;
    3.37 +        public string iSecondLine;
    3.38 +
    3.39 +
    3.40 +        public SensorSharpDisplay(SharpDisplay soundGraphDisplay, ISensor sensor,
    3.41 +          bool balloonTip, PersistentSettings settings, UnitManager unitManager)
    3.42 +        {
    3.43 +            this.unitManager = unitManager;
    3.44 +            this.sensor = sensor;
    3.45 +
    3.46 +            // get the default dpi to create an icon with the correct size
    3.47 +            float dpiX, dpiY;
    3.48 +            using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
    3.49 +            {
    3.50 +                dpiX = b.HorizontalResolution;
    3.51 +                dpiY = b.VerticalResolution;
    3.52 +            }
    3.53 +
    3.54 +            // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi) 
    3.55 +            int width = (int)Math.Round(16 * dpiX / 96);
    3.56 +            int height = (int)Math.Round(16 * dpiY / 96);
    3.57 +
    3.58 +            // make sure it does never get smaller than 16x16
    3.59 +            width = width < 16 ? 16 : width;
    3.60 +            height = height < 16 ? 16 : height;
    3.61 +
    3.62 +            // adjust the font size to the icon size
    3.63 +            FontFamily family = SystemFonts.MessageBoxFont.FontFamily;
    3.64 +            float baseSize;
    3.65 +            switch (family.Name)
    3.66 +            {
    3.67 +                case "Segoe UI": baseSize = 12; break;
    3.68 +                case "Tahoma": baseSize = 11; break;
    3.69 +                default: baseSize = 12; break;
    3.70 +            }
    3.71 +
    3.72 +            this.font = new Font(family,
    3.73 +              baseSize * width / 16.0f, GraphicsUnit.Pixel);
    3.74 +            this.smallFont = new Font(family,
    3.75 +              0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel);
    3.76 +
    3.77 +        }
    3.78 +
    3.79 +        public ISensor Sensor
    3.80 +        {
    3.81 +            get { return sensor; }
    3.82 +        }
    3.83 +
    3.84 +        public Color Color
    3.85 +        {
    3.86 +            get { return color; }
    3.87 +            set
    3.88 +            {
    3.89 +                this.color = value;
    3.90 +                this.darkColor = Color.FromArgb(255,
    3.91 +                  this.color.R / 3,
    3.92 +                  this.color.G / 3,
    3.93 +                  this.color.B / 3);
    3.94 +            }
    3.95 +        }
    3.96 +
    3.97 +        public void Dispose()
    3.98 +        {
    3.99 +            font.Dispose();
   3.100 +            smallFont.Dispose();
   3.101 +        }
   3.102 +
   3.103 +        public string GetString()
   3.104 +        {
   3.105 +            if (!sensor.Value.HasValue)
   3.106 +                return "-";
   3.107 +
   3.108 +            switch (sensor.SensorType)
   3.109 +            {
   3.110 +                case SensorType.Voltage:
   3.111 +                    return string.Format("{0:F1}", sensor.Value);
   3.112 +                case SensorType.Clock:
   3.113 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   3.114 +                case SensorType.Load:
   3.115 +                    return string.Format("{0:F0}", sensor.Value);
   3.116 +                case SensorType.Temperature:
   3.117 +                    if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   3.118 +                        return string.Format("{0:F0}",
   3.119 +                          UnitManager.CelsiusToFahrenheit(sensor.Value));
   3.120 +                    else
   3.121 +                        return string.Format("{0:F0}", sensor.Value);
   3.122 +                case SensorType.Fan:
   3.123 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   3.124 +                case SensorType.Flow:
   3.125 +                    return string.Format("{0:F1}", 1e-3f * sensor.Value);
   3.126 +                case SensorType.Control:
   3.127 +                    return string.Format("{0:F0}", sensor.Value);
   3.128 +                case SensorType.Level:
   3.129 +                    return string.Format("{0:F0}", sensor.Value);
   3.130 +                case SensorType.Power:
   3.131 +                    return string.Format("{0:F0}", sensor.Value);
   3.132 +                case SensorType.Data:
   3.133 +                    return string.Format("{0:F0}", sensor.Value);
   3.134 +                case SensorType.Factor:
   3.135 +                    return string.Format("{0:F1}", sensor.Value);
   3.136 +            }
   3.137 +            return "-";
   3.138 +        }
   3.139 +
   3.140 +
   3.141 +        public void Update()
   3.142 +        {
   3.143 +
   3.144 +
   3.145 +            switch (sensor.SensorType)
   3.146 +            {
   3.147 +                case SensorType.Load:
   3.148 +                case SensorType.Control:
   3.149 +                case SensorType.Level:
   3.150 +                    //notifyIcon.Icon = CreatePercentageIcon();
   3.151 +                    break;
   3.152 +                default:
   3.153 +                    //notifyIcon.Icon = CreateTransparentIcon();
   3.154 +                    break;
   3.155 +            }
   3.156 +
   3.157 +
   3.158 +            string format = "";
   3.159 +            switch (sensor.SensorType)
   3.160 +            {
   3.161 +                case SensorType.Voltage: format = "{0:F2}V"; break;
   3.162 +                case SensorType.Clock: format = "{0:F0}MHz"; break;
   3.163 +                case SensorType.Load: format = "{0:F0}%"; break;
   3.164 +                //iMON VFD escape sequence for Celsius
   3.165 +                case SensorType.Temperature: format = "{0:F0}°C"; break;
   3.166 +                case SensorType.Fan: format = "{0:F0}*"; break; //RPM
   3.167 +                case SensorType.Flow: format = "{0:F0}L/h"; break;
   3.168 +                case SensorType.Control: format = "{0:F0}%"; break;
   3.169 +                case SensorType.Level: format = "{0:F0}%"; break;
   3.170 +                case SensorType.Power: format = "{0:F0}W"; break;
   3.171 +                case SensorType.Data: format = "{0:F0}GB"; break;
   3.172 +                case SensorType.Factor: format = "{0:F3}GB"; break;
   3.173 +            }
   3.174 +            string formattedValue = string.Format(format, sensor.Value);
   3.175 +
   3.176 +            if (sensor.SensorType == SensorType.Temperature &&
   3.177 +              unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit)
   3.178 +            {
   3.179 +                //iMON VFD escape sequence for Fahrenheit
   3.180 +                format = "{0:F0}°F";
   3.181 +                formattedValue = string.Format(format, UnitManager.CelsiusToFahrenheit(sensor.Value));
   3.182 +            }
   3.183 +
   3.184 +            //iFirstLine = sensor.Hardware.Name;
   3.185 +            //iSecondLine = sensor.Name+ ":" + formattedValue;
   3.186 +
   3.187 +            iFirstLine = sensor.Name;
   3.188 +            iSecondLine = formattedValue;
   3.189 +
   3.190 +
   3.191 +        }
   3.192 +    }
   3.193 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/GUI/SharpDisplay.cs	Sun Sep 21 21:55:36 2014 +0200
     4.3 @@ -0,0 +1,353 @@
     4.4 +/*
     4.5 + 
     4.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     4.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     4.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     4.9 + 
    4.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    4.11 +	
    4.12 +*/
    4.13 +
    4.14 +using System;
    4.15 +using System.Collections.Generic;
    4.16 +using System.Drawing;
    4.17 +using System.Text;
    4.18 +using System.Diagnostics;
    4.19 +using System.Windows.Forms;
    4.20 +using System.Windows;
    4.21 +using OpenHardwareMonitor.Hardware;
    4.22 +using OpenHardwareMonitor.Utilities;
    4.23 +using System.Runtime.InteropServices;
    4.24 +using UacHelpers;
    4.25 +using System.ServiceModel;
    4.26 +using SharpDisplay;
    4.27 +
    4.28 +
    4.29 +namespace OpenHardwareMonitor.GUI
    4.30 +{
    4.31 +    public class SharpDisplay : ICallback, IDisposable
    4.32 +    {
    4.33 +        private IComputer computer;
    4.34 +        private PersistentSettings settings;
    4.35 +        private UnitManager unitManager;
    4.36 +        private List<SensorSharpDisplay> list = new List<SensorSharpDisplay>();
    4.37 +        private global::SharpDisplay.Client iClient;
    4.38 +        TextField iTextFieldTop;
    4.39 +        TextField iTextFieldBottom;
    4.40 +        TextField[] iTextFields;
    4.41 +
    4.42 +        private int iNextSensorToDisplay = 0;
    4.43 +        private int iTickCounter = 0;
    4.44 +
    4.45 +
    4.46 +        public SharpDisplay(IComputer computer, PersistentSettings settings, UnitManager unitManager)
    4.47 +        {
    4.48 +            this.computer = computer;
    4.49 +            this.settings = settings;
    4.50 +            this.unitManager = unitManager;
    4.51 +            computer.HardwareAdded += new HardwareEventHandler(HardwareAdded);
    4.52 +            computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved);
    4.53 +
    4.54 +            //Connect our client
    4.55 +            //Instance context is then managed by our client class
    4.56 +            iClient = new global::SharpDisplay.Client(this);
    4.57 +            //
    4.58 +            iTextFieldTop = new TextField(0);
    4.59 +            iTextFieldBottom = new TextField(1);
    4.60 +            iTextFields = new TextField[] { iTextFieldTop, iTextFieldBottom };
    4.61 +
    4.62 +        }
    4.63 +
    4.64 +        //From ICallback
    4.65 +        public void OnConnected()
    4.66 +        {
    4.67 +            //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread);
    4.68 +            //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId);
    4.69 +            //MessageBox.Show("OnConnected()", "Client");
    4.70 +        }
    4.71 +
    4.72 +        //From ICallback
    4.73 +        public void OnCloseOrder()
    4.74 +        {
    4.75 +            iClient.Close();
    4.76 +        }
    4.77 +
    4.78 +
    4.79 +        private void HardwareRemoved(IHardware hardware)
    4.80 +        {
    4.81 +            hardware.SensorAdded -= new SensorEventHandler(SensorAdded);
    4.82 +            hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved);
    4.83 +            foreach (ISensor sensor in hardware.Sensors)
    4.84 +                SensorRemoved(sensor);
    4.85 +            foreach (IHardware subHardware in hardware.SubHardware)
    4.86 +                HardwareRemoved(subHardware);
    4.87 +        }
    4.88 +
    4.89 +        private void HardwareAdded(IHardware hardware)
    4.90 +        {
    4.91 +            foreach (ISensor sensor in hardware.Sensors)
    4.92 +                SensorAdded(sensor);
    4.93 +            hardware.SensorAdded += new SensorEventHandler(SensorAdded);
    4.94 +            hardware.SensorRemoved += new SensorEventHandler(SensorRemoved);
    4.95 +            foreach (IHardware subHardware in hardware.SubHardware)
    4.96 +                HardwareAdded(subHardware);
    4.97 +        }
    4.98 +
    4.99 +        private void SensorAdded(ISensor sensor)
   4.100 +        {
   4.101 +            if (settings.GetValue(new Identifier(sensor.Identifier,
   4.102 +              "SharpDisplay").ToString(), false))
   4.103 +                Add(sensor, false);
   4.104 +        }
   4.105 +
   4.106 +        private void SensorRemoved(ISensor sensor)
   4.107 +        {
   4.108 +            if (Contains(sensor))
   4.109 +                Remove(sensor, false);
   4.110 +        }
   4.111 +
   4.112 +        public void Dispose()
   4.113 +        {
   4.114 +            foreach (SensorSharpDisplay icon in list)
   4.115 +                icon.Dispose();
   4.116 +
   4.117 +            Quit();            
   4.118 +            //iServer.Stop();
   4.119 +            iClient.Close();
   4.120 +
   4.121 +        }
   4.122 +
   4.123 +        public void Redraw(bool aPacked, bool aDisplayTime)
   4.124 +        {
   4.125 +            const int KNumberOfTickBeforeSwitch = 4;
   4.126 +            const int KMaxCharacterPerLine = 16;
   4.127 +            string packedFirstLine = ""; //We have 16 chars per line on our VFD
   4.128 +            string packedSecondLine = "";
   4.129 +            int count = 0;
   4.130 +
   4.131 +            string time = DateTime.Now.ToShortTimeString();
   4.132 +
   4.133 +            //Update all sensors from our front view
   4.134 +            foreach (SensorSharpDisplay sensor in list)
   4.135 +            {
   4.136 +                count++;
   4.137 +                sensor.Update();
   4.138 +
   4.139 +                if (aDisplayTime && count == 1)
   4.140 +                {
   4.141 +                    //First slot is take by time display
   4.142 +                    count++;
   4.143 +                    packedFirstLine = time + " ";
   4.144 +                }
   4.145 +
   4.146 +                if (aPacked)
   4.147 +                {
   4.148 +                    //Build strings for packed mode
   4.149 +                    string packedText = "";
   4.150 +                    packedText = sensor.iFirstLine.Substring(0, 3) + ":" + sensor.iSecondLine;
   4.151 +                    if (count == 1)
   4.152 +                    {
   4.153 +                        packedFirstLine = packedText + " "; //Minimum one space to separate sensors on the same line
   4.154 +                    }
   4.155 +                    else if (count == 2)
   4.156 +                    {
   4.157 +                        //Add enough spaces to align to right hand side
   4.158 +                        while (packedFirstLine.Length + packedText.Length < KMaxCharacterPerLine)
   4.159 +                        {
   4.160 +                            packedFirstLine += " ";
   4.161 +                        }
   4.162 +                        packedFirstLine += packedText;
   4.163 +                    }
   4.164 +                    else if (count == 3)
   4.165 +                    {
   4.166 +                        packedSecondLine = packedText + " "; //Minimum one space to separate sensors on the same line
   4.167 +                    }
   4.168 +                    else if (count == 4)
   4.169 +                    {
   4.170 +                        //Add enough spaces to align to right hand side
   4.171 +                        while (packedSecondLine.Length + packedText.Length < KMaxCharacterPerLine)
   4.172 +                        {
   4.173 +                            packedSecondLine += " ";
   4.174 +                        }
   4.175 +                        packedSecondLine += packedText;
   4.176 +                    }
   4.177 +                }
   4.178 +                //SetText(sensor.iFirstLine, sensor.iSecondLine);
   4.179 +            }
   4.180 +
   4.181 +            //Alternate between sensors 
   4.182 +            if (list.Count > 0)
   4.183 +            {
   4.184 +                if (aPacked)
   4.185 +                {
   4.186 +                    //string packedLine = "";
   4.187 +                    iTickCounter++;
   4.188 +                    if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
   4.189 +                    {
   4.190 +                        iTickCounter = 0;
   4.191 +                        if (iNextSensorToDisplay == 1)
   4.192 +                        {
   4.193 +                            iNextSensorToDisplay = 0;
   4.194 +                        }
   4.195 +                        else
   4.196 +                        {
   4.197 +                            iNextSensorToDisplay = 1;
   4.198 +                        }
   4.199 +                    }
   4.200 +
   4.201 +                    //TODO: Do something like that to cycle lines if ever we want to
   4.202 +                    //SetText(time, (iNextSensorToDisplay == 1 && packedSecondLine.Length > 0 ? packedSecondLine : packedFirstLine));
   4.203 +
   4.204 +                    //Display packed sensors on our FrontView display
   4.205 +                    SetText(packedFirstLine, packedSecondLine);
   4.206 +                }
   4.207 +                else
   4.208 +                {
   4.209 +                    string secondLine = list[iNextSensorToDisplay].iSecondLine;
   4.210 +                    if (aDisplayTime)
   4.211 +                    {
   4.212 +                        //Add enough spaces
   4.213 +                        while (secondLine.Length + time.Length < KMaxCharacterPerLine)
   4.214 +                        {
   4.215 +                            secondLine += " ";
   4.216 +                        }
   4.217 +                        secondLine += time;
   4.218 +                    }
   4.219 +                    //Display current sensor on our FrontView display
   4.220 +                    SetText(list[iNextSensorToDisplay].iFirstLine, secondLine);
   4.221 +                    iTickCounter++;
   4.222 +                    if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick
   4.223 +                    {
   4.224 +                        iTickCounter = 0;
   4.225 +                        iNextSensorToDisplay++;
   4.226 +                    }
   4.227 +                }
   4.228 +            }
   4.229 +
   4.230 +            if (iNextSensorToDisplay == list.Count)
   4.231 +            {
   4.232 +                //Go back to first sensor
   4.233 +                iNextSensorToDisplay = 0;
   4.234 +            }
   4.235 +
   4.236 +
   4.237 +        }
   4.238 +
   4.239 +        public bool Contains(ISensor sensor)
   4.240 +        {
   4.241 +            foreach (SensorSharpDisplay icon in list)
   4.242 +                if (icon.Sensor == sensor)
   4.243 +                    return true;
   4.244 +            return false;
   4.245 +        }
   4.246 +
   4.247 +        public void Add(ISensor sensor, bool balloonTip)
   4.248 +        {
   4.249 +            if (Contains(sensor))
   4.250 +            {
   4.251 +                return;
   4.252 +            }
   4.253 +            else
   4.254 +            {
   4.255 +                //SL:
   4.256 +                list.Add(new SensorSharpDisplay(this, sensor, balloonTip, settings, unitManager));
   4.257 +                //UpdateMainIconVisibilty();
   4.258 +                settings.SetValue(new Identifier(sensor.Identifier, "SharpDisplay").ToString(), true);
   4.259 +                iNextSensorToDisplay = 0;
   4.260 +                if (list.Count == 1)
   4.261 +                {
   4.262 +                    //Just added first sensor in FrontView, unable FrontView plug-in mode
   4.263 +                    Init();
   4.264 +                }
   4.265 +            }
   4.266 +
   4.267 +        }
   4.268 +
   4.269 +        public void Remove(ISensor sensor)
   4.270 +        {
   4.271 +            Remove(sensor, true);
   4.272 +            iNextSensorToDisplay = 0;
   4.273 +            if (list.Count == 0)
   4.274 +            {
   4.275 +                //No sensor to display in FrontView, just disable FrontView plug-in mode
   4.276 +                Uninit();
   4.277 +            }
   4.278 +
   4.279 +        }
   4.280 +
   4.281 +        private void Remove(ISensor sensor, bool deleteConfig)
   4.282 +        {
   4.283 +            if (deleteConfig)
   4.284 +            {
   4.285 +                settings.Remove(
   4.286 +                  new Identifier(sensor.Identifier, "SharpDisplay").ToString());
   4.287 +            }
   4.288 +            SensorSharpDisplay instance = null;
   4.289 +            foreach (SensorSharpDisplay icon in list)
   4.290 +                if (icon.Sensor == sensor)
   4.291 +                    instance = icon;
   4.292 +            if (instance != null)
   4.293 +            {
   4.294 +                list.Remove(instance);
   4.295 +                //UpdateMainIconVisibilty();
   4.296 +                instance.Dispose();
   4.297 +            }
   4.298 +        }
   4.299 +
   4.300 +
   4.301 +
   4.302 +        private void UpdateMainIconVisibilty()
   4.303 +        {
   4.304 +            /*
   4.305 +            if (mainIconEnabled)
   4.306 +            {
   4.307 +                mainIcon.Visible = list.Count == 0;
   4.308 +            }
   4.309 +            else
   4.310 +            {
   4.311 +                mainIcon.Visible = false;
   4.312 +            }
   4.313 +             */
   4.314 +        }
   4.315 +
   4.316 +        public void Init()
   4.317 +        {
   4.318 +            //iServer.SendMessage("init:");
   4.319 +        }
   4.320 +
   4.321 +        public void Uninit()
   4.322 +        {
   4.323 +            //iServer.SendMessage("uninit:");
   4.324 +        }
   4.325 +
   4.326 +        public void SetText(string aUpperLine, string aLowerLine)
   4.327 +        {
   4.328 +            //iServer.SendMessage("set-vfd-text:" + aUpperLine + "\n" + aLowerLine);
   4.329 +            iTextFieldTop.Text = aUpperLine;
   4.330 +            iTextFieldBottom.Text = aLowerLine;
   4.331 +            iClient.SetTexts(iTextFields);
   4.332 +
   4.333 +        }
   4.334 +
   4.335 +        public void Quit()
   4.336 +        {
   4.337 +            //iServer.SendMessage("quit:");
   4.338 +        }
   4.339 +
   4.340 +        /*
   4.341 +        public bool IsMainIconEnabled
   4.342 +        {
   4.343 +            get { return mainIconEnabled; }
   4.344 +            set
   4.345 +            {
   4.346 +                if (mainIconEnabled != value)
   4.347 +                {
   4.348 +                    mainIconEnabled = value;
   4.349 +                    UpdateMainIconVisibilty();
   4.350 +                }
   4.351 +            }
   4.352 +        }*/
   4.353 +
   4.354 +
   4.355 +    }
   4.356 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/GUI/SharpDisplayClient.cs	Sun Sep 21 21:55:36 2014 +0200
     5.3 @@ -0,0 +1,159 @@
     5.4 +/*
     5.5 + 
     5.6 +  This Source Code Form is subject to the terms of the Mozilla Public
     5.7 +  License, v. 2.0. If a copy of the MPL was not distributed with this
     5.8 +  file, You can obtain one at http://mozilla.org/MPL/2.0/.
     5.9 + 
    5.10 +  Copyright (C) 2009-2012 Michael Möller <mmoeller@openhardwaremonitor.org>
    5.11 +	
    5.12 +*/
    5.13 +
    5.14 +using System;
    5.15 +using System.Collections.Generic;
    5.16 +using System.Drawing;
    5.17 +using System.Text;
    5.18 +using System.Diagnostics;
    5.19 +using System.Windows.Forms;
    5.20 +using System.Windows;
    5.21 +using OpenHardwareMonitor.Hardware;
    5.22 +using OpenHardwareMonitor.Utilities;
    5.23 +using System.Runtime.InteropServices;
    5.24 +using UacHelpers;
    5.25 +//
    5.26 +using System.ServiceModel;
    5.27 +using System.Runtime.Serialization;
    5.28 +using SharpDisplay;
    5.29 +
    5.30 +namespace SharpDisplay
    5.31 +{
    5.32 +    //That contract need to be in the same namespace than the original assembly
    5.33 +    //otherwise our parameter won't make to the server.
    5.34 +    //See: http://stackoverflow.com/questions/14956377/passing-an-object-using-datacontract-in-wcf/25455292#25455292
    5.35 +    [DataContract]
    5.36 +    public class TextField
    5.37 +    {
    5.38 +        public TextField()
    5.39 +        {
    5.40 +            Index = 0;
    5.41 +            Text = "";
    5.42 +            Alignment = ContentAlignment.MiddleLeft;
    5.43 +        }
    5.44 +
    5.45 +        public TextField(int aIndex, string aText = "", ContentAlignment aAlignment = ContentAlignment.MiddleLeft)
    5.46 +        {
    5.47 +            Index = aIndex;
    5.48 +            Text = aText;
    5.49 +            Alignment = aAlignment;
    5.50 +        }
    5.51 +
    5.52 +        [DataMember]
    5.53 +        public int Index { get; set; }
    5.54 +
    5.55 +        [DataMember]
    5.56 +        public string Text { get; set; }
    5.57 +
    5.58 +        [DataMember]
    5.59 +        public ContentAlignment Alignment { get; set; }
    5.60 +    }
    5.61 +
    5.62 +
    5.63 +    [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)]
    5.64 +    public interface IService
    5.65 +    {
    5.66 +        /// <summary>
    5.67 +        /// Set the name of this client.
    5.68 +        /// Name is a convenient way to recognize your client.
    5.69 +        /// Naming you client is not mandatory.
    5.70 +        /// In the absence of a name the session ID is often used instead.
    5.71 +        /// </summary>
    5.72 +        /// <param name="aClientName"></param>
    5.73 +        [OperationContract(IsOneWay = true)]
    5.74 +        void SetName(string aClientName);
    5.75 +
    5.76 +        /// <summary>
    5.77 +        /// Put the given text in the given field on your display.
    5.78 +        /// Fields are often just lines of text.
    5.79 +        /// </summary>
    5.80 +        /// <param name="aTextFieldIndex"></param>
    5.81 +        [OperationContract(IsOneWay = true)]
    5.82 +        void SetText(TextField aTextField);
    5.83 +
    5.84 +        /// <summary>
    5.85 +        /// Allows a client to set multiple text fields at once.
    5.86 +        /// </summary>
    5.87 +        /// <param name="aTexts"></param>
    5.88 +        [OperationContract(IsOneWay = true)]
    5.89 +        void SetTexts(System.Collections.Generic.IList<TextField> aTextFields);
    5.90 +
    5.91 +        /// <summary>
    5.92 +        /// Provides the number of clients currently connected
    5.93 +        /// </summary>
    5.94 +        /// <returns></returns>
    5.95 +        [OperationContract()]
    5.96 +        int ClientCount();
    5.97 +
    5.98 +    }
    5.99 +
   5.100 +
   5.101 +    public interface ICallback
   5.102 +    {
   5.103 +        [OperationContract(IsOneWay = true)]
   5.104 +        void OnConnected();
   5.105 +
   5.106 +        /// <summary>
   5.107 +        /// Tell our client to close its connection.
   5.108 +        /// Notably sent when the server is shutting down.
   5.109 +        /// </summary>
   5.110 +        [OperationContract(IsOneWay = true)]
   5.111 +        void OnCloseOrder();
   5.112 +    }
   5.113 +}
   5.114 +
   5.115 +
   5.116 +
   5.117 +namespace SharpDisplay
   5.118 +{
   5.119 +
   5.120 +    /// <summary>
   5.121 +    ///
   5.122 +    /// </summary>
   5.123 +    [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
   5.124 +    public class Client : DuplexClientBase<IService>
   5.125 +    {
   5.126 +        public string Name { get; set; }
   5.127 +        public string SessionId { get { return InnerChannel.SessionId; } }
   5.128 +
   5.129 +        public Client(ICallback aCallback)
   5.130 +            : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService"))
   5.131 +        { }
   5.132 +
   5.133 +        public void SetName(string aClientName)
   5.134 +        {
   5.135 +            Name = aClientName;
   5.136 +            Channel.SetName(aClientName);
   5.137 +        }
   5.138 +
   5.139 +        public void SetText(TextField aTextField)
   5.140 +        {
   5.141 +            Channel.SetText(aTextField);
   5.142 +        }
   5.143 +
   5.144 +        public void SetTexts(System.Collections.Generic.IList<TextField> aTextFields)
   5.145 +        {
   5.146 +            Channel.SetTexts(aTextFields);
   5.147 +        }
   5.148 +
   5.149 +        public int ClientCount()
   5.150 +        {
   5.151 +            return Channel.ClientCount();
   5.152 +        }
   5.153 +
   5.154 +        public bool IsReady()
   5.155 +        {
   5.156 +            return State == CommunicationState.Opened;
   5.157 +        }
   5.158 +
   5.159 +    }
   5.160 +
   5.161 +
   5.162 +}
   5.163 \ No newline at end of file
     6.1 --- a/OpenHardwareMonitor.csproj	Thu Apr 18 23:25:10 2013 +0200
     6.2 +++ b/OpenHardwareMonitor.csproj	Sun Sep 21 21:55:36 2014 +0200
     6.3 @@ -81,6 +81,8 @@
     6.4      <Reference Include="System.Configuration.Install" />
     6.5      <Reference Include="System.Drawing" />
     6.6      <Reference Include="System.Management" />
     6.7 +    <Reference Include="System.Runtime.Serialization" />
     6.8 +    <Reference Include="System.ServiceModel" />
     6.9      <Reference Include="System.Windows.Forms" />
    6.10      <Reference Include="System.Xml" />
    6.11      <Reference Include="Aga.Controls, Version=1.7.0.0, Culture=neutral, PublicKeyToken=fcc90fbf924463a3">
    6.12 @@ -124,6 +126,9 @@
    6.13      <Compile Include="GUI\SensorFrontView.cs" />
    6.14      <Compile Include="GUI\SensorGadget.cs" />
    6.15      <Compile Include="GUI\SensorNotifyIcon.cs" />
    6.16 +    <Compile Include="GUI\SensorSharpDisplay.cs" />
    6.17 +    <Compile Include="GUI\SharpDisplay.cs" />
    6.18 +    <Compile Include="GUI\SharpDisplayClient.cs" />
    6.19      <Compile Include="GUI\ShowDesktop.cs" />
    6.20      <Compile Include="GUI\SoundGraphDisplay.cs" />
    6.21      <Compile Include="GUI\SoundGraphServer.cs" />