mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
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
|
|
}
|
|
}
|