StephaneLenclud@433: /* StephaneLenclud@433: StephaneLenclud@433: This Source Code Form is subject to the terms of the Mozilla Public StephaneLenclud@433: License, v. 2.0. If a copy of the MPL was not distributed with this StephaneLenclud@433: file, You can obtain one at http://mozilla.org/MPL/2.0/. StephaneLenclud@433: StephaneLenclud@433: Copyright (C) 2009-2012 Michael Möller StephaneLenclud@433: StephaneLenclud@433: */ StephaneLenclud@433: StephaneLenclud@433: using System; StephaneLenclud@433: using System.Collections.Generic; StephaneLenclud@433: using System.Drawing; StephaneLenclud@433: using System.Text; StephaneLenclud@433: using System.Windows.Forms; StephaneLenclud@433: using OpenHardwareMonitor.Hardware; StephaneLenclud@433: using OpenHardwareMonitor.Utilities; StephaneLenclud@433: using System.Runtime.InteropServices; StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: static class NativeMethods StephaneLenclud@433: { StephaneLenclud@433: [System.Flags] StephaneLenclud@433: public enum LoadLibraryFlags : uint StephaneLenclud@433: { StephaneLenclud@433: DONT_RESOLVE_DLL_REFERENCES = 0x00000001, StephaneLenclud@433: LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010, StephaneLenclud@433: LOAD_LIBRARY_AS_DATAFILE = 0x00000002, StephaneLenclud@433: LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040, StephaneLenclud@433: LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020, StephaneLenclud@433: LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: [DllImport("kernel32.dll", SetLastError = true)] StephaneLenclud@433: public static extern IntPtr LoadLibrary(string dllToLoad); StephaneLenclud@433: StephaneLenclud@433: [DllImport("kernel32.dll")] StephaneLenclud@433: public static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hReservedNull, LoadLibraryFlags dwFlags); StephaneLenclud@433: StephaneLenclud@433: [DllImport("kernel32.dll", SetLastError = true)] StephaneLenclud@433: public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName); StephaneLenclud@433: StephaneLenclud@433: [DllImport("kernel32.dll", SetLastError = true)] StephaneLenclud@433: public static extern bool FreeLibrary(IntPtr hModule); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@434: /** StephaneLenclud@434: Definitions taken from public Sound Graph APIs. StephaneLenclud@434: */ StephaneLenclud@434: static class SoundGraph StephaneLenclud@434: { StephaneLenclud@434: /**DSPResult StephaneLenclud@434: @brief These enumeration values represent the returned result for iMON Display API function calls.\n StephaneLenclud@434: All iMON Display API function calls return one of this result values.\n StephaneLenclud@434: For meaning of each result, refer the comment of each line below*/ StephaneLenclud@434: public enum DSPResult : uint StephaneLenclud@434: { StephaneLenclud@434: DSP_SUCCEEDED = 0, //// Function Call Succeeded Without Error StephaneLenclud@434: DSP_E_FAIL, //// Unspecified Failure StephaneLenclud@434: DSP_E_OUTOFMEMORY, //// Failed to Allocate Necessary Memory StephaneLenclud@434: DSP_E_INVALIDARG, //// One or More Arguments Are Not Valid StephaneLenclud@434: DSP_E_NOT_INITED, //// API is Not Initialized StephaneLenclud@434: DSP_E_POINTER, //// Pointer is Not Valid StephaneLenclud@434: StephaneLenclud@434: DSP_S_INITED = 0x1000, //// API is Initialized StephaneLenclud@434: DSP_S_NOT_INITED, //// API is Not Initialized StephaneLenclud@434: DSP_S_IN_PLUGIN_MODE, //// API Can Control iMON Display (Display Plug-in Mode) StephaneLenclud@434: DSP_S_NOT_IN_PLUGIN_MODE, //// API Can't Control iMON Display StephaneLenclud@434: }; StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@434: /**DSPNInitResult StephaneLenclud@434: @brief These enumeration values represent the result status for requesting Display Plug-in Mode to iMON.\n StephaneLenclud@434: iMON Display API notifies one of this result values to the caller application after requesting Display Plug-in Mode to iMON.\n StephaneLenclud@434: For more information, refer the comment of each line below*/ StephaneLenclud@434: public enum DSPNInitResult : uint StephaneLenclud@434: { StephaneLenclud@434: DSPN_SUCCEEDED = 0, //// Display Plug-in Mode is Initialized Successfully StephaneLenclud@434: DSPN_ERR_IN_USED = 0x0100, //// Display Plug-in is Already Used by Other Application StephaneLenclud@434: DSPN_ERR_HW_DISCONNECTED, //// iMON HW is Not Connected StephaneLenclud@434: DSPN_ERR_NOT_SUPPORTED_HW, //// The Connected iMON HW doesn't Support Display Plug-in StephaneLenclud@434: DSPN_ERR_PLUGIN_DISABLED, //// Display Plug-in Mode Option is Disabled StephaneLenclud@434: DSPN_ERR_IMON_NO_REPLY, //// The Latest iMON is Not Installed or iMON Not Running StephaneLenclud@434: DSPN_ERR_UNKNOWN = 0x0200, //// Unknown Failure StephaneLenclud@434: }; StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@434: /**DSPType StephaneLenclud@434: @brief These enumeration values represent display type.\n StephaneLenclud@434: Currently iMON Display API supports VFD and LCD products.*/ StephaneLenclud@434: public enum DSPType : uint StephaneLenclud@434: { StephaneLenclud@434: DSPN_DSP_NONE = 0, StephaneLenclud@434: DSPN_DSP_VFD = 0x01, //// VFD products StephaneLenclud@434: DSPN_DSP_LCD = 0x02, //// LCD products StephaneLenclud@434: }; StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@434: /**DSPNotifyCode StephaneLenclud@434: @brief These enumeration values represent the notification codes.\n StephaneLenclud@434: iMON Display API will send or post message to the caller application.\n StephaneLenclud@434: The caller application should assign the message and the winodw handle to receivce message with IMON_Display_Init fucntion.\n StephaneLenclud@434: These enumeration values are used with WPARAM parameter of the message.\n StephaneLenclud@434: For more information, see the explanation of each notification code below*/ StephaneLenclud@434: public enum DSPNotifyCode : uint StephaneLenclud@434: { StephaneLenclud@434: /**DSPNM_PLUGIN_SUCCEED StephaneLenclud@434: @brief When API succeeds to get the control for the display, API will post caller-specified message with DSPNM_PLUGIN_SUCCEED as WPARAM parameter.\n StephaneLenclud@434: LPARAM represents DSPType. This value can be 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).*/ StephaneLenclud@434: DSPNM_PLUGIN_SUCCEED = 0, StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_PLUGIN_FAILED StephaneLenclud@434: @brief When API fails to get the control for the display, API will post caller-specified message with DSPNM_PLUGIN_FAILED as WPARAM parameter.\n StephaneLenclud@434: LPARAM represents error code with DSPNResult.*/ StephaneLenclud@434: DSPNM_PLUGIN_FAILED, StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_IMON_RESTARTED StephaneLenclud@434: @brief When iMON starts, API will post caller-specified message with DSPNM_IMON_RESTARTED as WPARAM parameter.\n StephaneLenclud@434: LPARAM represents DSPType. This value can be 0 (No Display), 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).*/ StephaneLenclud@434: DSPNM_IMON_RESTARTED, StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_IMON_CLOSED StephaneLenclud@434: @brief When iMON closed, API will post caller-specified message with DSPNM_IMON_CLOSED as WPARAM parameter.\n StephaneLenclud@434: LPARAM is not used.*/ StephaneLenclud@434: DSPNM_IMON_CLOSED, StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_HW_CONNECTED StephaneLenclud@434: @brief When iMON HW newly connected, API will post caller-specified message with DSPNM_HW_CONNECTED as WPARAM parameter.\n StephaneLenclud@434: LPARAM represents DSPType. This value can be 0 (No Display), 0x01 (VFD), 0x02 (LCD) or 0x03 (VFD+LCD).*/ StephaneLenclud@434: DSPNM_HW_CONNECTED, StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_HW_DISCONNECTED StephaneLenclud@434: @brief When iMON HW disconnected, API will post caller-specified message with DSPNM_HW_DISCONNECTED as WPARAM parameter.\n StephaneLenclud@434: LPARAM is DSPNResult value, DSPN_ERR_HW_DISCONNECTED.*/ StephaneLenclud@434: DSPNM_HW_DISCONNECTED, StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@434: /**DSPNM_LCD_TEXT_SCROLL_DONE StephaneLenclud@434: @brief When iMON LCD finishes scrolling Text, API will post caller-specified message with DSPNM_LCD_TEXT_SCROLL_DONE as WPARAM parameter.\n StephaneLenclud@434: The caller application may need to know when text scroll is finished, for sending next text.\n StephaneLenclud@434: LPARAM is not used.*/ StephaneLenclud@434: DSPNM_LCD_TEXT_SCROLL_DONE = 0x1000, StephaneLenclud@434: }; StephaneLenclud@434: StephaneLenclud@434: /// Functions StephaneLenclud@434: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] StephaneLenclud@434: public delegate DSPResult IMON_Display_Uninit(); StephaneLenclud@434: StephaneLenclud@434: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] StephaneLenclud@434: public delegate DSPResult IMON_Display_Init(IntPtr hwndNoti, uint uMsgNotification); StephaneLenclud@434: StephaneLenclud@434: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] StephaneLenclud@434: public delegate DSPResult IMON_Display_IsInited(); StephaneLenclud@434: StephaneLenclud@434: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] StephaneLenclud@434: public delegate DSPResult IMON_Display_IsPluginModeEnabled(); StephaneLenclud@434: StephaneLenclud@434: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] StephaneLenclud@434: public delegate DSPResult IMON_Display_SetVfdText( StephaneLenclud@434: [MarshalAs(UnmanagedType.LPWStr)] string lpsz1stLine, StephaneLenclud@434: [MarshalAs(UnmanagedType.LPWStr)] string lpsz2ndLine); StephaneLenclud@434: StephaneLenclud@434: //IMONDSPAPI DSPResult IMON_Display_SetVfdText(LPCTSTR lpsz1stLine, LPCTSTR lpsz2ndLine); StephaneLenclud@434: StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@433: StephaneLenclud@433: namespace OpenHardwareMonitor.GUI StephaneLenclud@433: { StephaneLenclud@433: public class SoundGraphDisplay : IDisposable StephaneLenclud@433: { StephaneLenclud@433: private IComputer computer; StephaneLenclud@433: private PersistentSettings settings; StephaneLenclud@433: private UnitManager unitManager; StephaneLenclud@433: private List list = new List(); StephaneLenclud@433: //private bool mainIconEnabled = false; StephaneLenclud@433: //private NotifyIconAdv mainIcon; StephaneLenclud@433: IntPtr iSoundGraphDll; StephaneLenclud@434: SoundGraph.IMON_Display_Uninit iIMON_Display_Uninit; StephaneLenclud@434: SoundGraph.IMON_Display_Init iIMON_Display_Init; StephaneLenclud@434: SoundGraph.IMON_Display_IsInited iIMON_Display_IsInited; StephaneLenclud@434: SoundGraph.IMON_Display_IsPluginModeEnabled iIMON_Display_IsPluginModeEnabled; StephaneLenclud@434: SoundGraph.IMON_Display_SetVfdText iIMON_Display_SetVfdText; StephaneLenclud@433: StephaneLenclud@433: public SoundGraphDisplay(IComputer computer, PersistentSettings settings, StephaneLenclud@433: UnitManager unitManager) StephaneLenclud@433: { StephaneLenclud@433: this.computer = computer; StephaneLenclud@433: this.settings = settings; StephaneLenclud@433: this.unitManager = unitManager; StephaneLenclud@433: computer.HardwareAdded += new HardwareEventHandler(HardwareAdded); StephaneLenclud@433: computer.HardwareRemoved += new HardwareEventHandler(HardwareRemoved); StephaneLenclud@433: StephaneLenclud@433: //Try loading SoundGraph iMON Disaply DLL StephaneLenclud@433: iSoundGraphDll = NativeMethods.LoadLibraryEx(@"iMONDisplay.dll", IntPtr.Zero, NativeMethods.LoadLibraryFlags.LOAD_WITH_ALTERED_SEARCH_PATH); StephaneLenclud@433: int err=Marshal.GetLastWin32Error(); //If you 193 it means you need build for x86 StephaneLenclud@433: if (err == 193) StephaneLenclud@433: { StephaneLenclud@433: Console.Write(@"iMON: Cannot load x86 DLL from x64 process."); StephaneLenclud@433: } StephaneLenclud@433: else if (err != 0) StephaneLenclud@433: { StephaneLenclud@433: Console.Write(@"iMON: Error: %i - Failed to load iMONDisplay.dll", err); StephaneLenclud@433: } StephaneLenclud@433: else StephaneLenclud@433: { StephaneLenclud@433: Console.Write(@"iMON: DLL loaded."); StephaneLenclud@434: //Gather our function pointers StephaneLenclud@434: //TODO: Check returned pointers for validity StephaneLenclud@434: IntPtr functionPointer = NativeMethods.GetProcAddress(iSoundGraphDll, "IMON_Display_Uninit"); StephaneLenclud@434: iIMON_Display_Uninit = (SoundGraph.IMON_Display_Uninit)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(SoundGraph.IMON_Display_Uninit)); StephaneLenclud@434: StephaneLenclud@434: functionPointer = NativeMethods.GetProcAddress(iSoundGraphDll, "IMON_Display_Init"); StephaneLenclud@434: iIMON_Display_Init = (SoundGraph.IMON_Display_Init)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(SoundGraph.IMON_Display_Init)); StephaneLenclud@434: StephaneLenclud@434: functionPointer = NativeMethods.GetProcAddress(iSoundGraphDll, "IMON_Display_IsInited"); StephaneLenclud@434: iIMON_Display_IsInited = (SoundGraph.IMON_Display_IsInited)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(SoundGraph.IMON_Display_IsInited)); StephaneLenclud@434: StephaneLenclud@434: functionPointer = NativeMethods.GetProcAddress(iSoundGraphDll, "IMON_Display_IsPluginModeEnabled"); StephaneLenclud@434: iIMON_Display_IsPluginModeEnabled = (SoundGraph.IMON_Display_IsPluginModeEnabled)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(SoundGraph.IMON_Display_IsPluginModeEnabled)); StephaneLenclud@434: StephaneLenclud@434: functionPointer = NativeMethods.GetProcAddress(iSoundGraphDll, "IMON_Display_SetVfdText"); StephaneLenclud@434: iIMON_Display_SetVfdText = (SoundGraph.IMON_Display_SetVfdText)Marshal.GetDelegateForFunctionPointer(functionPointer, typeof(SoundGraph.IMON_Display_SetVfdText)); StephaneLenclud@434: StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void HardwareRemoved(IHardware hardware) StephaneLenclud@433: { StephaneLenclud@433: hardware.SensorAdded -= new SensorEventHandler(SensorAdded); StephaneLenclud@433: hardware.SensorRemoved -= new SensorEventHandler(SensorRemoved); StephaneLenclud@433: foreach (ISensor sensor in hardware.Sensors) StephaneLenclud@433: SensorRemoved(sensor); StephaneLenclud@433: foreach (IHardware subHardware in hardware.SubHardware) StephaneLenclud@433: HardwareRemoved(subHardware); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void HardwareAdded(IHardware hardware) StephaneLenclud@433: { StephaneLenclud@433: foreach (ISensor sensor in hardware.Sensors) StephaneLenclud@433: SensorAdded(sensor); StephaneLenclud@433: hardware.SensorAdded += new SensorEventHandler(SensorAdded); StephaneLenclud@433: hardware.SensorRemoved += new SensorEventHandler(SensorRemoved); StephaneLenclud@433: foreach (IHardware subHardware in hardware.SubHardware) StephaneLenclud@433: HardwareAdded(subHardware); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void SensorAdded(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: if (settings.GetValue(new Identifier(sensor.Identifier, StephaneLenclud@433: "tray").ToString(), false)) StephaneLenclud@433: Add(sensor, false); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void SensorRemoved(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: if (Contains(sensor)) StephaneLenclud@433: Remove(sensor, false); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Dispose() StephaneLenclud@433: { StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: icon.Dispose(); StephaneLenclud@433: StephaneLenclud@433: //Unload our DLL StephaneLenclud@433: if (iSoundGraphDll != IntPtr.Zero) StephaneLenclud@433: { StephaneLenclud@433: bool result = NativeMethods.FreeLibrary(iSoundGraphDll); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Redraw() StephaneLenclud@433: { StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: icon.Update(); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public bool Contains(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: if (icon.Sensor == sensor) StephaneLenclud@433: return true; StephaneLenclud@433: return false; StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Add(ISensor sensor, bool balloonTip) StephaneLenclud@433: { StephaneLenclud@433: if (Contains(sensor)) StephaneLenclud@433: { StephaneLenclud@433: return; StephaneLenclud@433: } StephaneLenclud@433: else StephaneLenclud@433: { StephaneLenclud@433: //SL: StephaneLenclud@433: //list.Add(new SensorFrontView(this, sensor, balloonTip, settings, unitManager)); StephaneLenclud@433: //UpdateMainIconVisibilty(); StephaneLenclud@433: //settings.SetValue(new Identifier(sensor.Identifier, "tray").ToString(), true); StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: public void Remove(ISensor sensor) StephaneLenclud@433: { StephaneLenclud@433: Remove(sensor, true); StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: private void Remove(ISensor sensor, bool deleteConfig) StephaneLenclud@433: { StephaneLenclud@433: if (deleteConfig) StephaneLenclud@433: { StephaneLenclud@433: settings.Remove( StephaneLenclud@433: new Identifier(sensor.Identifier, "tray").ToString()); StephaneLenclud@433: settings.Remove( StephaneLenclud@433: new Identifier(sensor.Identifier, "traycolor").ToString()); StephaneLenclud@433: } StephaneLenclud@433: SensorFrontView instance = null; StephaneLenclud@433: foreach (SensorFrontView icon in list) StephaneLenclud@433: if (icon.Sensor == sensor) StephaneLenclud@433: instance = icon; StephaneLenclud@433: if (instance != null) StephaneLenclud@433: { StephaneLenclud@433: list.Remove(instance); StephaneLenclud@433: UpdateMainIconVisibilty(); StephaneLenclud@433: instance.Dispose(); StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: StephaneLenclud@433: private void UpdateMainIconVisibilty() StephaneLenclud@433: { StephaneLenclud@433: /* StephaneLenclud@433: if (mainIconEnabled) StephaneLenclud@433: { StephaneLenclud@433: mainIcon.Visible = list.Count == 0; StephaneLenclud@433: } StephaneLenclud@433: else StephaneLenclud@433: { StephaneLenclud@433: mainIcon.Visible = false; StephaneLenclud@433: } StephaneLenclud@433: */ StephaneLenclud@433: } StephaneLenclud@433: StephaneLenclud@434: private void Init(IntPtr aHWND) StephaneLenclud@434: { StephaneLenclud@434: //iIMON_Display_Init StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@434: private void Uninit() StephaneLenclud@434: { StephaneLenclud@434: iIMON_Display_Uninit(); StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@434: private void SetText(string aUpperLine, string aLowerLine) StephaneLenclud@434: { StephaneLenclud@434: StephaneLenclud@434: } StephaneLenclud@434: StephaneLenclud@433: /* StephaneLenclud@433: public bool IsMainIconEnabled StephaneLenclud@433: { StephaneLenclud@433: get { return mainIconEnabled; } StephaneLenclud@433: set StephaneLenclud@433: { StephaneLenclud@433: if (mainIconEnabled != value) StephaneLenclud@433: { StephaneLenclud@433: mainIconEnabled = value; StephaneLenclud@433: UpdateMainIconVisibilty(); StephaneLenclud@433: } StephaneLenclud@433: } StephaneLenclud@433: }*/ StephaneLenclud@434: StephaneLenclud@434: StephaneLenclud@434: public bool IsDllLoaded StephaneLenclud@434: { StephaneLenclud@434: get { return iSoundGraphDll!=IntPtr.Zero; } StephaneLenclud@434: } StephaneLenclud@433: } StephaneLenclud@433: }