mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	 71601d7564
			
		
	
	71601d7564
	
	
	
		
			
			- Fixed lots of handle leak caused by Threading. Now uses ThreadPool instead of Thread. This change may fix IME issue that cannot input character like Japanese for instance. - Commented out some non-used part. - Removed ref keyword from ScanAndReplace().
		
			
				
	
	
		
			728 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			728 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| using System;
 | |
| using System.Collections.Generic;
 | |
| using System.Runtime.InteropServices;
 | |
| using System.Threading;
 | |
| 
 | |
| // This is a utility class / toolkit for communicating with Rainmeter and managing
 | |
| // logging, INI settings, bangs, window positioning, multiple instances, and temporary
 | |
| // data storage.
 | |
| //
 | |
| // You should not need to edit this code except to expand the toolkit support.
 | |
| //
 | |
| // Rather, most of your plugin's code should go in PluginCode.cs or additional files
 | |
| // that you create (such as new forms, classes, and controls).
 | |
| namespace InputText
 | |
| {
 | |
|     public class WindowWrapper : System.Windows.Forms.IWin32Window
 | |
|     {
 | |
|         public WindowWrapper(IntPtr handle)
 | |
|         {
 | |
|             _hwnd = handle;
 | |
|         }
 | |
| 
 | |
|         public IntPtr Handle
 | |
|         {
 | |
|             get { return _hwnd; }
 | |
|         }
 | |
| 
 | |
|         private IntPtr _hwnd;
 | |
|     }
 | |
| 
 | |
|     public class Rainmeter
 | |
|     {
 | |
|         #region Methods for getting the screen-relative location of the current skin
 | |
| 
 | |
|         public static IntPtr GetConfigWindow(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             return (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|         }
 | |
|         public static int ConfigX(string sSkin)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Left;
 | |
|         }
 | |
|         public static int ConfigX(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Left;
 | |
|         }
 | |
| 
 | |
|         public static int ConfigY(string sSkin)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Top;
 | |
|         }
 | |
|         public static int ConfigY(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Top;
 | |
|         }
 | |
| 
 | |
|         public static int ConfigWidth(string sSkin)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Right - rct.Left;
 | |
|         }
 | |
|         public static int ConfigWidth(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Right - rct.Left;
 | |
|         }
 | |
| 
 | |
|         public static int ConfigHeight(string sSkin)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Bottom - rct.Top;
 | |
|         }
 | |
|         public static int ConfigHeight(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|             RECT rct;
 | |
|             if (!GetWindowRect(hwnd, out rct))
 | |
|             {
 | |
|                 Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
 | |
|                 return 0;
 | |
|             }
 | |
|             return rct.Bottom - rct.Top;
 | |
|         }
 | |
| 
 | |
|         #region GetWindowRect() platform invoke to get the size/location of a window
 | |
| 
 | |
|         [DllImport("user32.dll")]
 | |
|         [return: MarshalAs(UnmanagedType.Bool)]
 | |
|         private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
 | |
| 
 | |
|         #endregion
 | |
|         #region GetParent() platform invoke to get the handle of a parent window
 | |
| 
 | |
|         [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
 | |
|         private static extern IntPtr GetParent(IntPtr hWnd);
 | |
| 
 | |
|         [StructLayout(LayoutKind.Sequential)]
 | |
|         public struct RECT
 | |
|         {
 | |
|             public int Left;        // x position of upper-left corner
 | |
|             public int Top;         // y position of upper-left corner
 | |
|             public int Right;       // x position of lower-right corner
 | |
|             public int Bottom;      // y position of lower-right corner
 | |
|         }
 | |
|         #endregion
 | |
|         #region SendMessage -- SendMessage (this variant is only for WM_COPYSTRUCT messages)
 | |
| 
 | |
|         [DllImport("user32.dll", CharSet = CharSet.Auto)]
 | |
|         private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
 | |
| 
 | |
|         [StructLayout(LayoutKind.Sequential)]
 | |
|         struct COPYDATASTRUCT
 | |
|         {
 | |
|             public UInt32 dwData;
 | |
|             public int cbData;
 | |
|             public IntPtr lpData;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|         #region FindWindowByClass -- platform invoke to find a window given a class name
 | |
| 
 | |
|         [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
 | |
|         private static extern IntPtr FindWindowByClass(string lpClassName, IntPtr ZeroOnly);
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region GetWindowInfo -- platform invoke to check a window's Z-order (Topmost=Auto)
 | |
| 
 | |
|         [DllImport("user32.dll", SetLastError = true)]
 | |
|         [return: MarshalAs(UnmanagedType.Bool)]
 | |
|         private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
 | |
| 
 | |
|         [StructLayout(LayoutKind.Sequential)]
 | |
|         private struct WINDOWINFO
 | |
|         {
 | |
|             public uint cbSize;
 | |
|             public RECT rcWindow;
 | |
|             public RECT rcClient;
 | |
|             public uint dwStyle;
 | |
|             public uint dwExStyle;
 | |
|             public uint dwWindowStatus;
 | |
|             public uint cxWindowBorders;
 | |
|             public uint cyWindowBorders;
 | |
|             public ushort atomWindowType;
 | |
|             public ushort wCreatorVersion;
 | |
| 
 | |
|             public WINDOWINFO(Boolean? filler)
 | |
|                 : this()   // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
 | |
|             {
 | |
|                 cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         // Call this function to determine if the parent skin is topmost
 | |
|         public static bool ParentIsTopmost(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
 | |
|             WINDOWINFO info = new WINDOWINFO(true);
 | |
|             GetWindowInfo(hwnd, ref info);
 | |
|             return ((info.dwExStyle & 0x00000008L) > 0);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|         #region SkinName -- gets the current skin name
 | |
| 
 | |
|         public static string SkinName(Rainmeter.Settings.InstanceSettings Instance)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 return Instance.ConfigName;
 | |
|                 /*
 | |
|                 if (Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString() == string.Empty)
 | |
|                 {
 | |
|                     string sAppDataPath = System.Environment.GetEnvironmentVariable("AppData").Trim();
 | |
|                     string sRainmeterINIText = System.IO.File.ReadAllText(sAppDataPath + "\\Rainmeter\\Rainmeter.ini");
 | |
|                     string sSkinPath = Chopper(sRainmeterINIText.Replace('\n', '\r'), "SkinPath=", "\r").Trim().TrimEnd(new char[] { '\\' });
 | |
|                     Instance.SetTempValue("_internal_SkinPath", sSkinPath);
 | |
|                 }
 | |
| 
 | |
|                 System.IO.FileInfo fi = new System.IO.FileInfo(Instance.INI_File);
 | |
|                 return fi.DirectoryName.Replace(Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString(), string.Empty).TrimEnd(new char[] { '\\' }).TrimStart(new char[] { '\\' });
 | |
|                 */
 | |
|             }
 | |
|             catch { }
 | |
| 
 | |
|             return string.Empty;
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Chopper -- string manipulation
 | |
| 
 | |
|         public static string Chopper(string sText, string sSearch, string sEnd, int offset)
 | |
|         {
 | |
|             string sIntermediate = "";
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 if ((sSearch == null) || (sSearch == string.Empty))
 | |
|                 {
 | |
|                     sIntermediate = sText.Substring(offset);
 | |
|                 }
 | |
|                 else
 | |
|                 {
 | |
|                     if (sText.Contains(sSearch) == false)
 | |
|                         return sText;
 | |
| 
 | |
|                     sIntermediate = sText.Substring(sText.IndexOf(sSearch) + sSearch.Length + offset);
 | |
|                 }
 | |
| 
 | |
|                 if ((sEnd == null) || (sEnd == string.Empty))
 | |
|                     return sIntermediate;
 | |
| 
 | |
|                 if (sIntermediate.Contains(sEnd) == false)
 | |
|                     return sIntermediate;
 | |
| 
 | |
|                 return sIntermediate.Substring(0, sIntermediate.IndexOf(sEnd));
 | |
|             }
 | |
|             catch
 | |
|             {
 | |
|                 if (sIntermediate == "")
 | |
|                     return sText;
 | |
|                 return sIntermediate;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public static string Chopper(string sText, string sSearch, string sEnd)
 | |
|         {
 | |
|             return Chopper(sText, sSearch, sEnd, 0);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Version helpers (converts "1.04" or "1, 4" to 1004, etc.)
 | |
| 
 | |
|         public static UInt32 Version(double dVersion)
 | |
|         {
 | |
|             return (UInt32)(dVersion * 1000.0);
 | |
|         }
 | |
| 
 | |
|         public static UInt32 Version(int iMajor, int iMinor)
 | |
|         {
 | |
|             return (UInt32)((iMajor * 1000) + iMinor);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Converts a C# 'string' to a C++ 'char *'
 | |
|         public static unsafe char* String(string s)
 | |
|         {
 | |
|             fixed (char* p = s) return p;
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region Export for Rainmeter's new plugin bridge
 | |
| 
 | |
|         [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
 | |
|         private extern static unsafe char* PluginBridge(char* sCommand, char* sData);
 | |
| 
 | |
|         private unsafe static string PluginBridge(string sCommand, string sData)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 return new string(PluginBridge(Rainmeter.String(sCommand), Rainmeter.String(sData)));
 | |
|             }
 | |
|             catch { }
 | |
| 
 | |
|             return string.Empty;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Read INI values using Rainmeter's 'ReadConfigString' export
 | |
| 
 | |
|         // We have to use this method rather than loading the .INI file manually because Rainmeter will
 | |
|         // replace tokens for us.  See:  http://rainmeter.net/RainCMS/?q=Settings_BuiltInVariables
 | |
|         //
 | |
|         // Please note that this is done during plugin initialization and stored in the Instance
 | |
|         // variable.  This is done automatically, so this function should not be used by plugin developers
 | |
|         // directly, therefore the methods here are 'private'.
 | |
| 
 | |
|         [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
 | |
|         private extern static unsafe char* ReadConfigString(char* sSection, char* key, char* defValue);
 | |
| 
 | |
|         // If an INI is missing, a blank string will be returned to avoid raising exceptions
 | |
|         private unsafe static string ReadConfigString(string sSection, string sKey)
 | |
|         {
 | |
|             try
 | |
|             {
 | |
|                 char* szString = ReadConfigString(Rainmeter.String(sSection), Rainmeter.String(sKey), Rainmeter.String(string.Empty));
 | |
| 
 | |
|                 if (szString != null)
 | |
|                     return new string(szString);
 | |
|             }
 | |
|             catch { }
 | |
| 
 | |
|             return string.Empty;
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Use Rainmeter's 'LSLog' export to log using its format and settings
 | |
| 
 | |
|         [DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
 | |
|         private extern static unsafe UInt16 LSLog(int nLevel, char* pszModule, char* pszMessage);
 | |
|         public enum LogLevel : int
 | |
|         {
 | |
|             Error = 1,
 | |
|             Warning = 2,
 | |
|             Notice = 3,
 | |
|             Debug = 4
 | |
|         }
 | |
| 
 | |
|         // You can call this function directly to log to Rainmeter.log
 | |
|         //
 | |
|         // Rainmeter needs to be configured to allow debug logging, of course.
 | |
| 
 | |
|         public static unsafe bool Log(LogLevel level, string sText)
 | |
|         {
 | |
|             return (Rainmeter.LSLog((int)level, Rainmeter.String("C# plugin"), Rainmeter.String(sText)) != 0);
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
| 
 | |
|         #region Send a bang to Rainmeter (prepends a '!' if necessary)
 | |
|         public static void Bang(string sBang)
 | |
|         {
 | |
|             System.Diagnostics.Process.Start(System.Windows.Forms.Application.ExecutablePath, sBang);
 | |
|         }
 | |
|         #endregion
 | |
| 
 | |
|         #region Settings are automatically created (and set at the top of 'Main.cs'), don't edit here
 | |
| 
 | |
|         // WARNING: DO NOT EDIT THIS HERE.  Change your author name, version, etc. in 'Main.cs'
 | |
|         public class Settings
 | |
|         {
 | |
|             public string Author = "(unknown)";
 | |
|             public double Version = 0.01;
 | |
|             public string Email = string.Empty;
 | |
|             public string Comments = string.Empty;
 | |
| 
 | |
|             public Settings(string _Author, double _Version)
 | |
|             {
 | |
|                 this.Author = _Author;
 | |
|                 this.Version = _Version;
 | |
|             }
 | |
|             public Settings(string _Author, double _Version, string _Email)
 | |
|             {
 | |
|                 this.Author = _Author;
 | |
|                 this.Version = _Version;
 | |
|                 this.Email = _Email;
 | |
|             }
 | |
|             public Settings(string _Author, double _Version, string _Email, string _Comments)
 | |
|             {
 | |
|                 this.Author = _Author;
 | |
|                 this.Version = _Version;
 | |
|                 this.Email = _Email;
 | |
|                 this.Comments = _Comments;
 | |
|             }
 | |
| 
 | |
|             public Dictionary<UInt32, InstanceSettings> Instances = new Dictionary<uint, InstanceSettings>();
 | |
|             public List<SectionKey> KeyValues = new List<SectionKey>();
 | |
| 
 | |
|             public struct SectionKey
 | |
|             {
 | |
|                 public UInt32 id;
 | |
|                 public string INI_File;
 | |
|                 public string Section;
 | |
|                 public string Key;
 | |
|                 public string Value;
 | |
|             }
 | |
| 
 | |
|             public unsafe void AddInstance(char* iniFile, char* section, UInt32 id)
 | |
|             {
 | |
|                 InstanceSettings new_instance = new InstanceSettings();
 | |
|                 new_instance.Initialize(this, iniFile, section, id);
 | |
|                 this.Instances.Add(id, new_instance);
 | |
| 
 | |
|                 bool bInSection = false;
 | |
|                 foreach (string line in System.IO.File.ReadAllLines(new_instance.INI_File))
 | |
|                 {
 | |
|                     if (line.Trim().StartsWith(";")) continue; // ignore comments
 | |
|                     if (line.Trim().StartsWith("[")) bInSection = false; // new section
 | |
| 
 | |
|                     // section test
 | |
|                     if (line.Trim().ToLower() == ("[" + new_instance.Section.ToLower() + "]"))
 | |
|                         bInSection = true;
 | |
| 
 | |
|                     if (!bInSection) continue; // abort this pass if not in section
 | |
|                     if (!line.Contains("=")) continue; // abort this pass if there's no INI setting here
 | |
| 
 | |
|                     string[] sLineParts = line.Trim().Split(new char[] { '=' });
 | |
| 
 | |
|                     SectionKey sk = new SectionKey();
 | |
|                     sk.id = id;
 | |
|                     sk.INI_File = new_instance.INI_File;
 | |
|                     sk.Key = sLineParts[0].Trim();
 | |
|                     sk.Section = new_instance.Section;
 | |
|                     sk.Value = ReadConfigString(new_instance.Section, sLineParts[0].Trim());
 | |
| 
 | |
|                     this.KeyValues.Add(sk);
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             public void RemoveInstance(UInt32 id)
 | |
|             {
 | |
|                 try
 | |
|                 {
 | |
|                 start_over:
 | |
|                     for (int i = 0; i < this.KeyValues.Count; i++)
 | |
|                     {
 | |
|                         if (this.KeyValues[i].id == id)
 | |
|                         {
 | |
|                             this.KeyValues.RemoveAt(i);
 | |
|                             goto start_over; // start over since the IEnumerable has been modified
 | |
|                         }
 | |
|                     }
 | |
|                     this.Instances.Remove(id);
 | |
|                 }
 | |
|                 catch { }
 | |
|             }
 | |
| 
 | |
|             public class InstanceSettings
 | |
|             {
 | |
|                 private UInt32 _ID = 0;
 | |
|                 private string _INI_File = string.Empty;
 | |
|                 private string _Section = string.Empty;
 | |
|                 private Settings PluginSettings = null;
 | |
| 
 | |
|                 private Dictionary<string, object> TempData = new Dictionary<string, object>();
 | |
| 
 | |
|                 private object locker = new object();
 | |
| 
 | |
|                 public object GetTempValue(string name, object oDefault)
 | |
|                 {
 | |
|                     lock (this.locker)
 | |
|                     {
 | |
|                         if (this.TempData.ContainsKey(name))
 | |
|                             return this.TempData[name];
 | |
|                         return oDefault;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 public void SetTempValue(string name, object o)
 | |
|                 {
 | |
|                     lock (this.locker)
 | |
|                     {
 | |
|                         if (this.TempData.ContainsKey(name))
 | |
|                             this.TempData[name] = o;
 | |
|                         else
 | |
|                             this.TempData.Add(name, o);
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 public string INI_Value(string name)
 | |
|                 {
 | |
|                     try
 | |
|                     {
 | |
|                         foreach (SectionKey sk in PluginSettings.KeyValues)
 | |
|                             if (sk.id == this.ID)
 | |
|                                 if (sk.Section == this.Section)
 | |
|                                     if (sk.Key.Trim().ToLower() == name.Trim().ToLower())
 | |
|                                         return sk.Value;
 | |
|                     }
 | |
|                     catch { }
 | |
| 
 | |
|                     return string.Empty;
 | |
|                 }
 | |
| 
 | |
|                 public unsafe void Initialize(Settings _PluginSettings, char* iniFile, char* section, UInt32 id)
 | |
|                 {
 | |
|                     this.PluginSettings = _PluginSettings;
 | |
|                     this._ID = id;
 | |
|                     this._INI_File = new string(iniFile);
 | |
|                     this._Section = new string(section);
 | |
| 
 | |
|                     this.ConfigName = Rainmeter.PluginBridge("GetConfig", this.INI_File);
 | |
|                 }
 | |
| 
 | |
|                 public string GetVariable(string sVariable)
 | |
|                 {
 | |
|                     return Rainmeter.PluginBridge("GetVariable", "\"" + this.ConfigName + "\" " + sVariable.Trim() + "");
 | |
|                 }
 | |
| 
 | |
|                 public string SetVariable(string sVariable, object oData)
 | |
|                 {
 | |
|                     return Rainmeter.PluginBridge("SetVariable", "\"" + this.ConfigName + "\" " + sVariable.Trim() + " \"" + oData.ToString().Trim() + "\"");
 | |
|                 }
 | |
| 
 | |
|                 public string ConfigName = string.Empty;
 | |
| 
 | |
|                 public UInt32 ID
 | |
|                 {
 | |
|                     get
 | |
|                     {
 | |
|                         return this._ID;
 | |
|                     }
 | |
|                     set
 | |
|                     {
 | |
|                         this._ID = value;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 public string INI_File
 | |
|                 {
 | |
|                     get
 | |
|                     {
 | |
|                         return this._INI_File;
 | |
|                     }
 | |
|                 }
 | |
| 
 | |
|                 public string Section
 | |
|                 {
 | |
|                     get
 | |
|                     {
 | |
|                         return this._Section;
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|         #endregion
 | |
|     }
 | |
| 
 | |
|     public class YourPlugin
 | |
|     {
 | |
|         #region YourPlugin class -- do not modify
 | |
| 
 | |
|         // This class is a simple launcher for your actual code in PluginCode.cs
 | |
|         //
 | |
|         // We make use of non-volatile data and threading to let your work run in another
 | |
|         // thread, making Rainmeter nice and responsive.  Checks are automatically performed
 | |
|         // so that overlapping of execution does not occur.
 | |
| 
 | |
|         // Default values of a blank string for GetUpdate() and zero for Update()/Update2()
 | |
|         // are returned.
 | |
| 
 | |
|         public UInt32 Update(Rainmeter.Settings Plugin, UInt32 id)
 | |
|         {
 | |
|             //bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_U_AlreadyRunning", false);
 | |
|             //if (!bAlreadyRunning)
 | |
|             //{
 | |
|             //    Plugin.Instances[id].SetTempValue("__RMT_U_AlreadyRunning", true);
 | |
| 
 | |
|             //    ThreadPool.QueueUserWorkItem(_instance =>
 | |
|             //    {
 | |
|             //        Rainmeter.Settings.InstanceSettings Instance = (Rainmeter.Settings.InstanceSettings)_instance;
 | |
| 
 | |
|             //        try
 | |
|             //        {
 | |
|             //            Instance.SetTempValue("__RMT_U_LastValue", new PluginCode().Update(Instance));
 | |
|             //        }
 | |
|             //        catch (Exception ex)
 | |
|             //        {
 | |
|             //            Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in Update(), " + ex.GetType().ToString() + ": " + ex.Message);
 | |
|             //        }
 | |
| 
 | |
|             //        Instance.SetTempValue("__RMT_U_AlreadyRunning", false);
 | |
|             //    }, Plugin.Instances[id]);
 | |
|             //}
 | |
| 
 | |
|             //try
 | |
|             //{
 | |
|             //    return (UInt32)Plugin.Instances[id].GetTempValue("__RMT_U_LastValue", 0);
 | |
|             //}
 | |
|             //catch
 | |
|             {
 | |
|                 return 0;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         //public double Update2(Rainmeter.Settings Plugin, UInt32 id)
 | |
|         //{
 | |
|         //    bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_U2_AlreadyRunning", false);
 | |
|         //    if (!bAlreadyRunning)
 | |
|         //    {
 | |
|         //        Plugin.Instances[id].SetTempValue("__RMT_U2_AlreadyRunning", true);
 | |
| 
 | |
|         //        ThreadPool.QueueUserWorkItem(_instance =>
 | |
|         //        {
 | |
|         //            Rainmeter.Settings.InstanceSettings Instance = (Rainmeter.Settings.InstanceSettings)_instance;
 | |
| 
 | |
|         //            try
 | |
|         //            {
 | |
|         //                Instance.SetTempValue("__RMT_U2_LastValue", new PluginCode().Update2(Instance));
 | |
|         //            }
 | |
|         //            catch (Exception ex)
 | |
|         //            {
 | |
|         //                Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in Update2(), " + ex.GetType().ToString() + ": " + ex.Message);
 | |
|         //            }
 | |
| 
 | |
|         //            Instance.SetTempValue("__RMT_U2_AlreadyRunning", false);
 | |
|         //        }, Plugin.Instances[id]);
 | |
|         //    }
 | |
| 
 | |
|         //    try
 | |
|         //    {
 | |
|         //        return (double)Plugin.Instances[id].GetTempValue("__RMT_U2_LastValue", 0.0);
 | |
|         //    }
 | |
|         //    catch
 | |
|         //    {
 | |
|         //        return 0.0;
 | |
|         //    }
 | |
|         //}
 | |
| 
 | |
|         public string GetString(Rainmeter.Settings Plugin, UInt32 id)
 | |
|         {
 | |
|             bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_GS_AlreadyRunning", false);
 | |
|             if (!bAlreadyRunning)
 | |
|             {
 | |
|                 Plugin.Instances[id].SetTempValue("__RMT_GS_AlreadyRunning", true);
 | |
| 
 | |
|                 ThreadPool.QueueUserWorkItem(_instance =>
 | |
|                 {
 | |
|                     Rainmeter.Settings.InstanceSettings Instance = (Rainmeter.Settings.InstanceSettings)_instance;
 | |
| 
 | |
|                     try
 | |
|                     {
 | |
|                         Instance.SetTempValue("__RMT_GS_LastValue", new PluginCode().GetString(Instance));
 | |
|                     }
 | |
|                     catch (Exception ex)
 | |
|                     {
 | |
|                         Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message);
 | |
|                     }
 | |
| 
 | |
|                     Instance.SetTempValue("__RMT_GS_AlreadyRunning", false);
 | |
|                 }, Plugin.Instances[id]);
 | |
|             }
 | |
| 
 | |
|             try
 | |
|             {
 | |
|                 return (string)Plugin.Instances[id].GetTempValue("__RMT_GS_LastValue", string.Empty);
 | |
|             }
 | |
|             catch
 | |
|             {
 | |
|                 return string.Empty;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         public void ExecuteBang(Rainmeter.Settings Plugin, UInt32 id, string sArguments)
 | |
|         {
 | |
|             bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_EB_AlreadyRunning", false);
 | |
|             if (!bAlreadyRunning)
 | |
|             {
 | |
|                 Plugin.Instances[id].SetTempValue("__RMT_EB_AlreadyRunning", true);
 | |
| 
 | |
|                 ThreadPool.QueueUserWorkItem(_param =>
 | |
|                 {
 | |
|                     Rainmeter.Settings.InstanceSettings Instance = (Rainmeter.Settings.InstanceSettings)((ExecuteBangParam)_param).Instance;
 | |
|                     string Command = (string)((ExecuteBangParam)_param).Command;
 | |
| 
 | |
|                     try
 | |
|                     {
 | |
|                         new PluginCode().ExecuteBang(Instance, Command);
 | |
|                     }
 | |
|                     catch (Exception ex)
 | |
|                     {
 | |
|                         Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in ExecuteBang(), " + ex.GetType().ToString() + ": " + ex.Message);
 | |
|                     }
 | |
| 
 | |
|                     Instance.SetTempValue("__RMT_EB_AlreadyRunning", false);
 | |
|                 }, new ExecuteBangParam(Plugin.Instances[id], sArguments));
 | |
|             }
 | |
|             return;
 | |
|         }
 | |
| 
 | |
|         private class ExecuteBangParam
 | |
|         {
 | |
|             public Rainmeter.Settings.InstanceSettings Instance = null;
 | |
|             public string Command = string.Empty;
 | |
| 
 | |
|             public ExecuteBangParam(Rainmeter.Settings.InstanceSettings _Instance, string _Command)
 | |
|             {
 | |
|                 this.Instance = _Instance;
 | |
|                 this.Command = _Command;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         #endregion
 | |
|     }
 | |
| }
 |