# HG changeset patch # User StephaneLenclud # Date 1411329336 -7200 # Node ID fe4c711fd7f89a80074833f4c14e82531f748772 # Parent 9b09e2ee09680643ddb87c8225c87dd66a6c5fd1 Support for SharpDisplayManager. Switching to .NET v4.0 to allow System.ServiceModel. OxyPlot fix and recompile for .NET v4.0. FrontView fix to start-up without SoundGraphAccess.exe. diff -r 9b09e2ee0968 -r fe4c711fd7f8 External/OxyPlot.WindowsForms.dll Binary file External/OxyPlot.WindowsForms.dll has changed diff -r 9b09e2ee0968 -r fe4c711fd7f8 External/OxyPlot.dll Binary file External/OxyPlot.dll has changed diff -r 9b09e2ee0968 -r fe4c711fd7f8 External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj --- a/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Thu Apr 18 23:25:10 2013 +0200 +++ b/External/OxyPlot/OxyPlot.WindowsForms/OxyPlot.WindowsForms.csproj Sun Sep 21 21:55:36 2014 +0200 @@ -9,7 +9,7 @@ Properties OxyPlot.WindowsForms OxyPlot.WindowsForms - v2.0 + v4.0 512 diff -r 9b09e2ee0968 -r fe4c711fd7f8 External/OxyPlot/OxyPlot/OxyPlot.csproj --- a/External/OxyPlot/OxyPlot/OxyPlot.csproj Thu Apr 18 23:25:10 2013 +0200 +++ b/External/OxyPlot/OxyPlot/OxyPlot.csproj Sun Sep 21 21:55:36 2014 +0200 @@ -9,7 +9,7 @@ Properties OxyPlot OxyPlot - v2.0 + v4.0 512 @@ -93,7 +93,6 @@ - diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/MainForm.Designer.cs --- a/GUI/MainForm.Designer.cs Thu Apr 18 23:25:10 2013 +0200 +++ b/GUI/MainForm.Designer.cs Sun Sep 21 21:55:36 2014 +0200 @@ -114,6 +114,9 @@ this.frontViewMenuItem = new System.Windows.Forms.MenuItem(); this.frontViewPackedMenuItem = new System.Windows.Forms.MenuItem(); this.frontViewDisplayTimeMenuItem = new System.Windows.Forms.MenuItem(); + this.menuItemSharpDisplay = new System.Windows.Forms.MenuItem(); + this.sharpDisplayPackedMenuItem = new System.Windows.Forms.MenuItem(); + this.sharpDisplayShowTimeMenuItem = new System.Windows.Forms.MenuItem(); this.splitContainer.Panel1.SuspendLayout(); this.splitContainer.SuspendLayout(); this.SuspendLayout(); @@ -377,6 +380,7 @@ this.logSensorsMenuItem, this.loggingIntervalMenuItem, this.frontViewMenuItem, + this.menuItemSharpDisplay, this.webMenuItemSeparator, this.webMenuItem}); this.optionsMenuItem.Text = "Options"; @@ -472,15 +476,33 @@ // this.frontViewDisplayTimeMenuItem.Index = 1; this.frontViewDisplayTimeMenuItem.Text = "Display time"; + // + // menuItemSharpDisplay + // + this.menuItemSharpDisplay.Index = 11; + this.menuItemSharpDisplay.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { + this.sharpDisplayPackedMenuItem, + this.sharpDisplayShowTimeMenuItem}); + this.menuItemSharpDisplay.Text = "SharpDisplay"; + // + // sharpDisplayPackedMenuItem + // + this.sharpDisplayPackedMenuItem.Index = 0; + this.sharpDisplayPackedMenuItem.Text = "Packed"; + // + // sharpDisplayDisplayTimeMenuItem + // + this.sharpDisplayShowTimeMenuItem.Index = 1; + this.sharpDisplayShowTimeMenuItem.Text = "Display Time"; // // webMenuItemSeparator // - this.webMenuItemSeparator.Index = 11; + this.webMenuItemSeparator.Index = 12; this.webMenuItemSeparator.Text = "-"; // // webMenuItem // - this.webMenuItem.Index = 12; + this.webMenuItem.Index = 13; this.webMenuItem.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] { this.runWebServerMenuItem, this.serverPortMenuItem}); @@ -787,6 +809,9 @@ private System.Windows.Forms.MenuItem frontViewMenuItem; private System.Windows.Forms.MenuItem frontViewPackedMenuItem; private System.Windows.Forms.MenuItem frontViewDisplayTimeMenuItem; + private System.Windows.Forms.MenuItem menuItemSharpDisplay; + private System.Windows.Forms.MenuItem sharpDisplayPackedMenuItem; + private System.Windows.Forms.MenuItem sharpDisplayShowTimeMenuItem; } } diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/MainForm.cs --- a/GUI/MainForm.cs Thu Apr 18 23:25:10 2013 +0200 +++ b/GUI/MainForm.cs Sun Sep 21 21:55:36 2014 +0200 @@ -39,6 +39,7 @@ private Color[] plotColorPalette; private SystemTray systemTray; private SoundGraphDisplay soundGraphDisplay; + private SharpDisplay sharpDisplay; private bool displayTick; private StartupManager startupManager = new StartupManager(); private UpdateVisitor updateVisitor = new UpdateVisitor(); @@ -57,6 +58,8 @@ private UserOption autoStart; private UserOption frontViewPacked; //Tells whether FrontView should cycle or pack sensors private UserOption frontViewDisplayTime; //Tells whether or not FrontView should display current time + private UserOption sharpDisplayPacked; //Tells whether SharpDisplay should cycle or pack sensors + private UserOption sharpDisplayShowTime; //Tells whether or not SharpDisplay should display current time private UserOption readMainboardSensors; private UserOption readCpuSensors; @@ -131,14 +134,18 @@ treeView.Model = treeModel; this.computer = new Computer(settings); - + + //System tray systemTray = new SystemTray(computer, settings, unitManager); systemTray.HideShowCommand += hideShowClick; systemTray.ExitCommand += exitClick; + //SoundGraph Display soundGraphDisplay = new SoundGraphDisplay(computer, settings, unitManager); - - + //Sharp Display Manager + sharpDisplay = new SharpDisplay(computer, settings, unitManager); + + // int p = (int)Environment.OSVersion.Platform; if ((p == 4) || (p == 128)) { // Unix treeView.RowHeight = Math.Max(treeView.RowHeight, 18); @@ -233,6 +240,10 @@ frontViewPacked = new UserOption("frontViewPackedMenuItem", false, frontViewPackedMenuItem, settings); frontViewDisplayTime = new UserOption("frontViewDisplayTimeMenuItem", false, frontViewDisplayTimeMenuItem, settings); + sharpDisplayPacked = new UserOption("sharpDisplayPackedMenuItem", false, sharpDisplayPackedMenuItem, settings); + sharpDisplayShowTime = new UserOption("sharpDisplayShowTimeMenuItem", false, sharpDisplayShowTimeMenuItem, settings); + + readMainboardSensors = new UserOption("mainboardMenuItem", true, mainboardMenuItem, settings); readMainboardSensors.Changed += delegate(object sender, EventArgs e) { @@ -499,6 +510,14 @@ SolidBrush greenBrush = new SolidBrush(Color.FromName("mediumspringgreen")); e.BackgroundBrush = greenBrush; } + + //If displayed in SharpDisplay draw background in blue + if (sensorNode != null && settings.GetValue(new Identifier(sensorNode.Sensor.Identifier, "SharpDisplay").ToString(), false)) + { + SolidBrush aquaBrush = new SolidBrush(Color.FromName("aqua")); + e.BackgroundBrush = aquaBrush; + } + } else { e.TextColor = Color.DarkGray; @@ -571,6 +590,11 @@ */ } + if (sharpDisplay != null) + { + sharpDisplay.Redraw(sharpDisplayPacked.Value, sharpDisplayShowTime.Value); + } + if (logSensors != null && logSensors.Value && delayCount >= 4) logger.Log(); @@ -640,6 +664,7 @@ server.Quit(); systemTray.Dispose(); soundGraphDisplay.Dispose(); + sharpDisplay.Dispose(); } private void aboutMenuItem_Click(object sender, EventArgs e) { @@ -711,6 +736,18 @@ }; treeContextMenu.MenuItems.Add(item); } + { + MenuItem item = new MenuItem("Show in SharpDisplay"); + item.Checked = sharpDisplay.Contains(node.Sensor); + item.Click += delegate(object obj, EventArgs args) + { + if (item.Checked) + sharpDisplay.Remove(node.Sensor); + else + sharpDisplay.Add(node.Sensor, true); + }; + treeContextMenu.MenuItems.Add(item); + } if (gadget != null) { MenuItem item = new MenuItem("Show in Gadget"); item.Checked = gadget.Contains(node.Sensor); diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/SensorSharpDisplay.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/SensorSharpDisplay.cs Sun Sep 21 21:55:36 2014 +0200 @@ -0,0 +1,190 @@ +/* + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + Copyright (C) 2009-2012 Michael Möller + +*/ + +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.Drawing.Text; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using OpenHardwareMonitor.Hardware; +using OpenHardwareMonitor.Utilities; + +namespace OpenHardwareMonitor.GUI +{ + public class SensorSharpDisplay : IDisposable + { + + private UnitManager unitManager; + + private ISensor sensor; + private Color color; + private Color darkColor; + private Font font; + private Font smallFont; + public string iFirstLine; + public string iSecondLine; + + + public SensorSharpDisplay(SharpDisplay soundGraphDisplay, ISensor sensor, + bool balloonTip, PersistentSettings settings, UnitManager unitManager) + { + this.unitManager = unitManager; + this.sensor = sensor; + + // get the default dpi to create an icon with the correct size + float dpiX, dpiY; + using (Bitmap b = new Bitmap(1, 1, PixelFormat.Format32bppArgb)) + { + dpiX = b.HorizontalResolution; + dpiY = b.VerticalResolution; + } + + // adjust the size of the icon to current dpi (default is 16x16 at 96 dpi) + int width = (int)Math.Round(16 * dpiX / 96); + int height = (int)Math.Round(16 * dpiY / 96); + + // make sure it does never get smaller than 16x16 + width = width < 16 ? 16 : width; + height = height < 16 ? 16 : height; + + // adjust the font size to the icon size + FontFamily family = SystemFonts.MessageBoxFont.FontFamily; + float baseSize; + switch (family.Name) + { + case "Segoe UI": baseSize = 12; break; + case "Tahoma": baseSize = 11; break; + default: baseSize = 12; break; + } + + this.font = new Font(family, + baseSize * width / 16.0f, GraphicsUnit.Pixel); + this.smallFont = new Font(family, + 0.75f * baseSize * width / 16.0f, GraphicsUnit.Pixel); + + } + + public ISensor Sensor + { + get { return sensor; } + } + + public Color Color + { + get { return color; } + set + { + this.color = value; + this.darkColor = Color.FromArgb(255, + this.color.R / 3, + this.color.G / 3, + this.color.B / 3); + } + } + + public void Dispose() + { + font.Dispose(); + smallFont.Dispose(); + } + + public string GetString() + { + if (!sensor.Value.HasValue) + return "-"; + + switch (sensor.SensorType) + { + case SensorType.Voltage: + return string.Format("{0:F1}", sensor.Value); + case SensorType.Clock: + return string.Format("{0:F1}", 1e-3f * sensor.Value); + case SensorType.Load: + return string.Format("{0:F0}", sensor.Value); + case SensorType.Temperature: + if (unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) + return string.Format("{0:F0}", + UnitManager.CelsiusToFahrenheit(sensor.Value)); + else + return string.Format("{0:F0}", sensor.Value); + case SensorType.Fan: + return string.Format("{0:F1}", 1e-3f * sensor.Value); + case SensorType.Flow: + return string.Format("{0:F1}", 1e-3f * sensor.Value); + case SensorType.Control: + return string.Format("{0:F0}", sensor.Value); + case SensorType.Level: + return string.Format("{0:F0}", sensor.Value); + case SensorType.Power: + return string.Format("{0:F0}", sensor.Value); + case SensorType.Data: + return string.Format("{0:F0}", sensor.Value); + case SensorType.Factor: + return string.Format("{0:F1}", sensor.Value); + } + return "-"; + } + + + public void Update() + { + + + switch (sensor.SensorType) + { + case SensorType.Load: + case SensorType.Control: + case SensorType.Level: + //notifyIcon.Icon = CreatePercentageIcon(); + break; + default: + //notifyIcon.Icon = CreateTransparentIcon(); + break; + } + + + string format = ""; + switch (sensor.SensorType) + { + case SensorType.Voltage: format = "{0:F2}V"; break; + case SensorType.Clock: format = "{0:F0}MHz"; break; + case SensorType.Load: format = "{0:F0}%"; break; + //iMON VFD escape sequence for Celsius + case SensorType.Temperature: format = "{0:F0}°C"; break; + case SensorType.Fan: format = "{0:F0}*"; break; //RPM + case SensorType.Flow: format = "{0:F0}L/h"; break; + case SensorType.Control: format = "{0:F0}%"; break; + case SensorType.Level: format = "{0:F0}%"; break; + case SensorType.Power: format = "{0:F0}W"; break; + case SensorType.Data: format = "{0:F0}GB"; break; + case SensorType.Factor: format = "{0:F3}GB"; break; + } + string formattedValue = string.Format(format, sensor.Value); + + if (sensor.SensorType == SensorType.Temperature && + unitManager.TemperatureUnit == TemperatureUnit.Fahrenheit) + { + //iMON VFD escape sequence for Fahrenheit + format = "{0:F0}°F"; + formattedValue = string.Format(format, UnitManager.CelsiusToFahrenheit(sensor.Value)); + } + + //iFirstLine = sensor.Hardware.Name; + //iSecondLine = sensor.Name+ ":" + formattedValue; + + iFirstLine = sensor.Name; + iSecondLine = formattedValue; + + + } + } +} diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/SharpDisplay.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/SharpDisplay.cs Sun Sep 21 21:55:36 2014 +0200 @@ -0,0 +1,353 @@ +/* + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + Copyright (C) 2009-2012 Michael Möller + +*/ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Diagnostics; +using System.Windows.Forms; +using System.Windows; +using OpenHardwareMonitor.Hardware; +using OpenHardwareMonitor.Utilities; +using System.Runtime.InteropServices; +using UacHelpers; +using System.ServiceModel; +using SharpDisplay; + + +namespace OpenHardwareMonitor.GUI +{ + public class SharpDisplay : ICallback, IDisposable + { + private IComputer computer; + private PersistentSettings settings; + private UnitManager unitManager; + private List list = new List(); + private global::SharpDisplay.Client iClient; + TextField iTextFieldTop; + TextField iTextFieldBottom; + TextField[] iTextFields; + + private int iNextSensorToDisplay = 0; + private int iTickCounter = 0; + + + public SharpDisplay(IComputer computer, PersistentSettings settings, UnitManager unitManager) + { + this.computer = computer; + this.settings = settings; + this.unitManager = unitManager; + computer.HardwareAdded += new HardwareEventHandler(HardwareAdded); + computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved); + + //Connect our client + //Instance context is then managed by our client class + iClient = new global::SharpDisplay.Client(this); + // + iTextFieldTop = new TextField(0); + iTextFieldBottom = new TextField(1); + iTextFields = new TextField[] { iTextFieldTop, iTextFieldBottom }; + + } + + //From ICallback + public void OnConnected() + { + //Debug.Assert(Thread.CurrentThread.IsThreadPoolThread); + //Trace.WriteLine("Callback thread = " + Thread.CurrentThread.ManagedThreadId); + //MessageBox.Show("OnConnected()", "Client"); + } + + //From ICallback + public void OnCloseOrder() + { + iClient.Close(); + } + + + private void HardwareRemoved(IHardware hardware) + { + hardware.SensorAdded -= new SensorEventHandler(SensorAdded); + hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved); + foreach (ISensor sensor in hardware.Sensors) + SensorRemoved(sensor); + foreach (IHardware subHardware in hardware.SubHardware) + HardwareRemoved(subHardware); + } + + private void HardwareAdded(IHardware hardware) + { + foreach (ISensor sensor in hardware.Sensors) + SensorAdded(sensor); + hardware.SensorAdded += new SensorEventHandler(SensorAdded); + hardware.SensorRemoved += new SensorEventHandler(SensorRemoved); + foreach (IHardware subHardware in hardware.SubHardware) + HardwareAdded(subHardware); + } + + private void SensorAdded(ISensor sensor) + { + if (settings.GetValue(new Identifier(sensor.Identifier, + "SharpDisplay").ToString(), false)) + Add(sensor, false); + } + + private void SensorRemoved(ISensor sensor) + { + if (Contains(sensor)) + Remove(sensor, false); + } + + public void Dispose() + { + foreach (SensorSharpDisplay icon in list) + icon.Dispose(); + + Quit(); + //iServer.Stop(); + iClient.Close(); + + } + + public void Redraw(bool aPacked, bool aDisplayTime) + { + const int KNumberOfTickBeforeSwitch = 4; + const int KMaxCharacterPerLine = 16; + string packedFirstLine = ""; //We have 16 chars per line on our VFD + string packedSecondLine = ""; + int count = 0; + + string time = DateTime.Now.ToShortTimeString(); + + //Update all sensors from our front view + foreach (SensorSharpDisplay sensor in list) + { + count++; + sensor.Update(); + + if (aDisplayTime && count == 1) + { + //First slot is take by time display + count++; + packedFirstLine = time + " "; + } + + if (aPacked) + { + //Build strings for packed mode + string packedText = ""; + packedText = sensor.iFirstLine.Substring(0, 3) + ":" + sensor.iSecondLine; + if (count == 1) + { + packedFirstLine = packedText + " "; //Minimum one space to separate sensors on the same line + } + else if (count == 2) + { + //Add enough spaces to align to right hand side + while (packedFirstLine.Length + packedText.Length < KMaxCharacterPerLine) + { + packedFirstLine += " "; + } + packedFirstLine += packedText; + } + else if (count == 3) + { + packedSecondLine = packedText + " "; //Minimum one space to separate sensors on the same line + } + else if (count == 4) + { + //Add enough spaces to align to right hand side + while (packedSecondLine.Length + packedText.Length < KMaxCharacterPerLine) + { + packedSecondLine += " "; + } + packedSecondLine += packedText; + } + } + //SetText(sensor.iFirstLine, sensor.iSecondLine); + } + + //Alternate between sensors + if (list.Count > 0) + { + if (aPacked) + { + //string packedLine = ""; + iTickCounter++; + if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick + { + iTickCounter = 0; + if (iNextSensorToDisplay == 1) + { + iNextSensorToDisplay = 0; + } + else + { + iNextSensorToDisplay = 1; + } + } + + //TODO: Do something like that to cycle lines if ever we want to + //SetText(time, (iNextSensorToDisplay == 1 && packedSecondLine.Length > 0 ? packedSecondLine : packedFirstLine)); + + //Display packed sensors on our FrontView display + SetText(packedFirstLine, packedSecondLine); + } + else + { + string secondLine = list[iNextSensorToDisplay].iSecondLine; + if (aDisplayTime) + { + //Add enough spaces + while (secondLine.Length + time.Length < KMaxCharacterPerLine) + { + secondLine += " "; + } + secondLine += time; + } + //Display current sensor on our FrontView display + SetText(list[iNextSensorToDisplay].iFirstLine, secondLine); + iTickCounter++; + if (iTickCounter == KNumberOfTickBeforeSwitch) //Move to the next sensor only every so many tick + { + iTickCounter = 0; + iNextSensorToDisplay++; + } + } + } + + if (iNextSensorToDisplay == list.Count) + { + //Go back to first sensor + iNextSensorToDisplay = 0; + } + + + } + + public bool Contains(ISensor sensor) + { + foreach (SensorSharpDisplay icon in list) + if (icon.Sensor == sensor) + return true; + return false; + } + + public void Add(ISensor sensor, bool balloonTip) + { + if (Contains(sensor)) + { + return; + } + else + { + //SL: + list.Add(new SensorSharpDisplay(this, sensor, balloonTip, settings, unitManager)); + //UpdateMainIconVisibilty(); + settings.SetValue(new Identifier(sensor.Identifier, "SharpDisplay").ToString(), true); + iNextSensorToDisplay = 0; + if (list.Count == 1) + { + //Just added first sensor in FrontView, unable FrontView plug-in mode + Init(); + } + } + + } + + public void Remove(ISensor sensor) + { + Remove(sensor, true); + iNextSensorToDisplay = 0; + if (list.Count == 0) + { + //No sensor to display in FrontView, just disable FrontView plug-in mode + Uninit(); + } + + } + + private void Remove(ISensor sensor, bool deleteConfig) + { + if (deleteConfig) + { + settings.Remove( + new Identifier(sensor.Identifier, "SharpDisplay").ToString()); + } + SensorSharpDisplay instance = null; + foreach (SensorSharpDisplay icon in list) + if (icon.Sensor == sensor) + instance = icon; + if (instance != null) + { + list.Remove(instance); + //UpdateMainIconVisibilty(); + instance.Dispose(); + } + } + + + + private void UpdateMainIconVisibilty() + { + /* + if (mainIconEnabled) + { + mainIcon.Visible = list.Count == 0; + } + else + { + mainIcon.Visible = false; + } + */ + } + + public void Init() + { + //iServer.SendMessage("init:"); + } + + public void Uninit() + { + //iServer.SendMessage("uninit:"); + } + + public void SetText(string aUpperLine, string aLowerLine) + { + //iServer.SendMessage("set-vfd-text:" + aUpperLine + "\n" + aLowerLine); + iTextFieldTop.Text = aUpperLine; + iTextFieldBottom.Text = aLowerLine; + iClient.SetTexts(iTextFields); + + } + + public void Quit() + { + //iServer.SendMessage("quit:"); + } + + /* + public bool IsMainIconEnabled + { + get { return mainIconEnabled; } + set + { + if (mainIconEnabled != value) + { + mainIconEnabled = value; + UpdateMainIconVisibilty(); + } + } + }*/ + + + } +} diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/SharpDisplayClient.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GUI/SharpDisplayClient.cs Sun Sep 21 21:55:36 2014 +0200 @@ -0,0 +1,159 @@ +/* + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at http://mozilla.org/MPL/2.0/. + + Copyright (C) 2009-2012 Michael Möller + +*/ + +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Text; +using System.Diagnostics; +using System.Windows.Forms; +using System.Windows; +using OpenHardwareMonitor.Hardware; +using OpenHardwareMonitor.Utilities; +using System.Runtime.InteropServices; +using UacHelpers; +// +using System.ServiceModel; +using System.Runtime.Serialization; +using SharpDisplay; + +namespace SharpDisplay +{ + //That contract need to be in the same namespace than the original assembly + //otherwise our parameter won't make to the server. + //See: http://stackoverflow.com/questions/14956377/passing-an-object-using-datacontract-in-wcf/25455292#25455292 + [DataContract] + public class TextField + { + public TextField() + { + Index = 0; + Text = ""; + Alignment = ContentAlignment.MiddleLeft; + } + + public TextField(int aIndex, string aText = "", ContentAlignment aAlignment = ContentAlignment.MiddleLeft) + { + Index = aIndex; + Text = aText; + Alignment = aAlignment; + } + + [DataMember] + public int Index { get; set; } + + [DataMember] + public string Text { get; set; } + + [DataMember] + public ContentAlignment Alignment { get; set; } + } + + + [ServiceContract(CallbackContract = typeof(ICallback), SessionMode = SessionMode.Required)] + public interface IService + { + /// + /// Set the name of this client. + /// Name is a convenient way to recognize your client. + /// Naming you client is not mandatory. + /// In the absence of a name the session ID is often used instead. + /// + /// + [OperationContract(IsOneWay = true)] + void SetName(string aClientName); + + /// + /// Put the given text in the given field on your display. + /// Fields are often just lines of text. + /// + /// + [OperationContract(IsOneWay = true)] + void SetText(TextField aTextField); + + /// + /// Allows a client to set multiple text fields at once. + /// + /// + [OperationContract(IsOneWay = true)] + void SetTexts(System.Collections.Generic.IList aTextFields); + + /// + /// Provides the number of clients currently connected + /// + /// + [OperationContract()] + int ClientCount(); + + } + + + public interface ICallback + { + [OperationContract(IsOneWay = true)] + void OnConnected(); + + /// + /// Tell our client to close its connection. + /// Notably sent when the server is shutting down. + /// + [OperationContract(IsOneWay = true)] + void OnCloseOrder(); + } +} + + + +namespace SharpDisplay +{ + + /// + /// + /// + [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)] + public class Client : DuplexClientBase + { + public string Name { get; set; } + public string SessionId { get { return InnerChannel.SessionId; } } + + public Client(ICallback aCallback) + : base(new InstanceContext(aCallback), new NetTcpBinding(SecurityMode.None, true), new EndpointAddress("net.tcp://localhost:8001/DisplayService")) + { } + + public void SetName(string aClientName) + { + Name = aClientName; + Channel.SetName(aClientName); + } + + public void SetText(TextField aTextField) + { + Channel.SetText(aTextField); + } + + public void SetTexts(System.Collections.Generic.IList aTextFields) + { + Channel.SetTexts(aTextFields); + } + + public int ClientCount() + { + return Channel.ClientCount(); + } + + public bool IsReady() + { + return State == CommunicationState.Opened; + } + + } + + +} \ No newline at end of file diff -r 9b09e2ee0968 -r fe4c711fd7f8 GUI/SoundGraphDisplay.cs --- a/GUI/SoundGraphDisplay.cs Thu Apr 18 23:25:10 2013 +0200 +++ b/GUI/SoundGraphDisplay.cs Sun Sep 21 21:55:36 2014 +0200 @@ -53,10 +53,17 @@ Process[] processes = Process.GetProcessesByName("SoundGraphAccess"); if (!(processes.Length > 0)) { + try + { //Try to launch the sound graph process from the same folder as this executable - string exeName=System.IO.Path.GetDirectoryName(Application.ExecutablePath); + string exeName = System.IO.Path.GetDirectoryName(Application.ExecutablePath); exeName += @"\SoundGraphAccess.exe"; - Process client = UserAccountControl.CreateProcessAsStandardUser(exeName,""); + Process client = UserAccountControl.CreateProcessAsStandardUser(exeName, ""); + } + catch (Exception e) + { + Debug.WriteLine("SoundGraphAccess.exe start-up failed: " + e.ToString()); + } } //Start our SoundGraph server diff -r 9b09e2ee0968 -r fe4c711fd7f8 OpenHardwareMonitor.csproj --- a/OpenHardwareMonitor.csproj Thu Apr 18 23:25:10 2013 +0200 +++ b/OpenHardwareMonitor.csproj Sun Sep 21 21:55:36 2014 +0200 @@ -9,7 +9,7 @@ WinExe false OpenHardwareMonitor - v2.0 + v4.0 512 OpenHardwareMonitor Resources\icon.ico @@ -34,6 +34,7 @@ 1.0.0.%2a false true + true @@ -68,6 +69,8 @@ + + @@ -111,6 +114,9 @@ + + + diff -r 9b09e2ee0968 -r fe4c711fd7f8 OpenHardwareMonitorLib.csproj --- a/OpenHardwareMonitorLib.csproj Thu Apr 18 23:25:10 2013 +0200 +++ b/OpenHardwareMonitorLib.csproj Sun Sep 21 21:55:36 2014 +0200 @@ -10,7 +10,7 @@ Properties OpenHardwareMonitor OpenHardwareMonitorLib - v2.0 + v4.0 512 @@ -31,6 +31,7 @@ false false true + true diff -r 9b09e2ee0968 -r fe4c711fd7f8 UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj --- a/UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj Thu Apr 18 23:25:10 2013 +0200 +++ b/UacHelpers.CppLibrary/UacHelpers.CppLibrary.vcxproj Sun Sep 21 21:55:36 2014 +0200 @@ -19,7 +19,7 @@ - v2.0 + v4.0 UacHelpers.UserAccountControl {D043A646-FE7A-4334-B23D-E327593C1AE2} UacHelpersCppLibrary