diff --git a/Plugins/PluginInputText/AssemblyInfo.cs b/Plugins/PluginInputText/AssemblyInfo.cs
index 094bfd12..8c05e710 100644
--- a/Plugins/PluginInputText/AssemblyInfo.cs
+++ b/Plugins/PluginInputText/AssemblyInfo.cs
@@ -2,6 +2,6 @@
using System.Runtime.CompilerServices;
[assembly: AssemblyCopyright("© 2010 - Peter Souza IV")]
-[assembly: AssemblyVersion("1.6.0.0")]
+[assembly: AssemblyVersion("1.7.0.0")]
[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)]
[assembly: AssemblyProduct("Rainmeter")]
diff --git a/Plugins/PluginInputText/InputBox.cs b/Plugins/PluginInputText/InputBox.cs
index ba4006aa..d7967808 100644
--- a/Plugins/PluginInputText/InputBox.cs
+++ b/Plugins/PluginInputText/InputBox.cs
@@ -1,4 +1,22 @@
-using System;
+/*
+ Copyright (C) 2013 Rainmeter Team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+using System;
using System.Drawing;
using System.Windows.Forms;
@@ -6,14 +24,17 @@ namespace InputText
{
public partial class InputBox : Form
{
- public Rainmeter.Settings.InstanceSettings Instance = null;
+ private SkinWindow parent = null;
- #region Default form initializer
- public InputBox()
+ private bool _FocusDismiss = true;
+ private string _TextValue = string.Empty;
+
+ public InputBox(SkinWindow parent)
{
+ this.parent = parent;
+
InitializeComponent();
}
- #endregion
// This event will make sure we have focus when the inputbox is shown ot the user.
// it will only cause focus if the window itself has focus (i.e. doesn't steal).
@@ -26,6 +47,14 @@ namespace InputText
this.txtInput.Focus();
}
+ private void InputBox_Load(object sender, EventArgs e)
+ {
+ this.Activate();
+ this.BringToFront();
+ this.Activate();
+ this.BringToFront();
+ }
+
// All exceptions are swallowed for the sake of this example. Since the majority
// (if not all) of these are rather simple in nature, debugging without errors
// should be fairly simple anyway.
@@ -39,16 +68,13 @@ namespace InputText
// }
// catch (Exception ex)
// {
- // Rainmeter.Log(Rainmeter.LogLevel.Warning, "InputText :: exception :: " + ex.GetType().ToString() + ": " + ex.Message);
+ // API.Log(API.LogType.Warning, "InputText :: exception :: " + ex.GetType().ToString() + ": " + ex.Message);
// }
- #region TextInput -- returns the inputted text
- public string TextInput
+ #region TextValue -- returns the inputted text
+ public string TextValue
{
- get
- {
- return this.txtInput.Text.Trim();
- }
+ get { return this._TextValue; }
}
#endregion
#region ChangeFontFace(string) -- changes the text's font name
@@ -170,10 +196,10 @@ namespace InputText
this.TopMost = true;
}
#endregion
- #region MakePassword() -- causes the textbox to be password style
- public void MakePassword()
+ #region MakePassword(bool) -- causes the textbox to be password style
+ public void MakePassword(bool bPass)
{
- this.txtInput.PasswordChar = '*';
+ this.txtInput.PasswordChar = bPass ? '*' : '\0';
}
#endregion
#region ChangeFontStringStyle() -- changes the font's bold/italic styles
@@ -216,7 +242,7 @@ namespace InputText
}
#endregion
#region ChangeX(string) -- changes the X (horizontal) position of the input textbox, relative to its parent skin
- public void ChangeX(Rainmeter.Settings.InstanceSettings Instance, string sX)
+ public void ChangeX(string sX)
{
try
{
@@ -227,13 +253,13 @@ namespace InputText
// Notice that we need the position of the parent window for offset location.
//
// The Rainmeter class does this for us
- this.Location = new System.Drawing.Point(Rainmeter.ConfigX(Rainmeter.SkinName(Instance)) + int.Parse(sX), this.Location.Y);
+ this.Location = new System.Drawing.Point(this.parent.X + int.Parse(sX), this.Location.Y);
}
catch { }
}
#endregion
#region ChangeY(string) -- changes the Y (vertical) position of the input textbox, relative to its parent skin
- public void ChangeY(Rainmeter.Settings.InstanceSettings Instance, string sY)
+ public void ChangeY(string sY)
{
try
{
@@ -244,7 +270,7 @@ namespace InputText
// Notice that we need the position of the parent window for offset location.
//
// The Rainmeter class does this for us
- this.Location = new System.Drawing.Point(this.Location.X, Rainmeter.ConfigY(Rainmeter.SkinName(Instance)) + int.Parse(sY));
+ this.Location = new System.Drawing.Point(this.Location.X, this.parent.Y + int.Parse(sY));
}
catch { }
}
@@ -256,15 +282,47 @@ namespace InputText
}
#endregion
#region MakeFocusDismiss(bool) -- dismisses the input textbox if it loses cursor/window focus
-
- private bool _FocusDismiss = true;
- public DialogResult drBackup = DialogResult.None;
- public string sTextValue = string.Empty;
-
public void MakeFocusDismiss(bool bDismissing)
{
this._FocusDismiss = bDismissing;
}
+ #endregion
+
+ #region ShowInputBox() -- shows text input textbox
+
+ private DialogResult drBackup = DialogResult.None;
+
+ public bool ShowInputBox()
+ {
+ if (this._FocusDismiss)
+ {
+ this.Show(this.parent);
+
+ while (this.DialogResult == DialogResult.None &&
+ this.drBackup == DialogResult.None)
+ {
+ Application.DoEvents();
+ System.Threading.Thread.Sleep(44);
+ }
+ }
+ else
+ {
+ this.ShowDialog(this.parent);
+ }
+
+ if (this.drBackup != DialogResult.None)
+ {
+ if (this.drBackup != DialogResult.OK)
+ return false;
+ }
+ else if (this.DialogResult != DialogResult.None)
+ {
+ if (this.DialogResult != DialogResult.OK)
+ return false;
+ }
+
+ return true;
+ }
private void txtInput_Leave(object sender, EventArgs e)
{
@@ -295,8 +353,8 @@ namespace InputText
private void btnOK_Click(object sender, EventArgs e)
{
- _FocusDismiss = false;
- this.sTextValue = this.txtInput.Text.Trim();
+ this._FocusDismiss = false;
+ this._TextValue = this.txtInput.Text.Trim();
this.drBackup = DialogResult.OK;
this.DialogResult = DialogResult.OK;
this.Close();
@@ -304,20 +362,12 @@ namespace InputText
private void btnCancel_Click(object sender, EventArgs e)
{
- _FocusDismiss = false;
+ this._FocusDismiss = false;
this.drBackup = DialogResult.Cancel;
this.DialogResult = DialogResult.Cancel;
this.Close();
}
#endregion
-
- private void InputBox_Load(object sender, EventArgs e)
- {
- this.Activate();
- this.BringToFront();
- this.Activate();
- this.BringToFront();
- }
}
}
diff --git a/Plugins/PluginInputText/Main.cs b/Plugins/PluginInputText/Main.cs
index 131181b5..81629e57 100644
--- a/Plugins/PluginInputText/Main.cs
+++ b/Plugins/PluginInputText/Main.cs
@@ -1,173 +1,148 @@
-using System;
+/*
+ Copyright (C) 2013 Rainmeter Team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
using Rainmeter;
namespace InputText
{
- public class Main
+ internal partial class Measure
{
- ///
- /// Your name (author) and the version of the plugin go here. The code will
- /// automatically format the values and send them back when a call to GetAuthor()
- /// or GetVersion() is made.
- ///
- /// Optionally, you may also provide an e-mail address and additional comments
- ///
- private static Rainmeter.Settings Plugin = new Rainmeter.Settings
- (
- // Author name
- "Peter Souza IV",
+ private Rainmeter.API rm;
- // Version
- 1.06,
+ private string LastInput = string.Empty;
+ private bool IsExecuteBangRunning = false;
- // E-mail
- "psouza4@gmail.com",
+ private object locker = new object();
- // Comments (try to keep it under 50 characters)
- "Please visit the forums for support."
- );
-
- #region GetAuthor() and GetVersion() exports -- no need to modify
-
- [DllExport]
- public static UInt32 GetPluginVersion()
+ internal Measure(Rainmeter.API rm)
{
- return Rainmeter.Version(Plugin.Version);
+ this.rm = rm;
}
- [DllExport]
- public unsafe static char* GetPluginAuthor()
+ internal void Reload(Rainmeter.API rm, ref double maxValue)
{
- if (!string.IsNullOrEmpty(Plugin.Email) && !string.IsNullOrEmpty(Plugin.Comments))
- return Rainmeter.String(Plugin.Author + " (" + Plugin.Email + "): " + Plugin.Comments);
- if (!string.IsNullOrEmpty(Plugin.Email))
- return Rainmeter.String(Plugin.Author + " (" + Plugin.Email + ")");
- if (!string.IsNullOrEmpty(Plugin.Comments))
- return Rainmeter.String(Plugin.Author + ": " + Plugin.Comments);
- return Rainmeter.String(Plugin.Author);
+ // Do nothing here.
}
- #endregion
-
- #region Initialize() and Finalize() -- you may add to these functions if necessary
-
- [DllExport]
- public unsafe static UInt32 Initialize(IntPtr instance, char* iniFile, char* section, UInt32 id)
+ internal double Update()
{
- Plugin.AddInstance(iniFile, section, id); // required: do not remove
-
- ////////////////////////////////////////////////////////////////
- //
- // You may add code here, if necessary
- //
-
- ////////////////////////////////////////////////////////////////
- return 0;
+ return 0.0;
}
- [DllExport]
- public static void Finalize(IntPtr instance, UInt32 id)
+ internal string GetString()
{
- Plugin.RemoveInstance(id); // required: do not remove
-
- ////////////////////////////////////////////////////////////////
- //
- // You may add code here, if necessary
- //
-
- ////////////////////////////////////////////////////////////////
- return;
- }
- #endregion
-
- #region Update(), Update2(), and GetString() exports -- please read notes
-
- // *** WARNING / NOTES ***
- //
- // Do not add to this code: change your code in PluginCode.cs instead
- //
- // However, due to the way Rainmeter works, you will probably want to
- // comment-out either 'Update' or 'Update2' if your plugin will be returning
- // numeric values.
- //
- // Rainmeter will look for 'Update' for positive integers. If you want to
- // allow negative numbers or floating-point numbers, use 'Update2' instead.
- //
- // You *MUST* comment-out whichever function you don't want to use for this
- // to work.
- //
- // If you don't care, such as a plugin that either doesn't return data or
- // only returns string/text data, then you can leave them both here (it won't
- // hurt anything).
- //
- // *** WARNING / NOTES ***
-
-
- ///
- /// Rainmeter's request for numeric data from the plugin. This version can only
- /// return positive integers ranging from 0 to 4,294,967,296. Comment this member
- /// out and use 'Update2' if you want to return negative or floating-point values.
- ///
- /// The unique instance ID of this request.
- /// Current value for this meter.
- [DllExport]
- public static UInt32 Update(UInt32 id)
- {
- // Do not modify this member (although you can comment it out). Instead, update
- // your code in 'PluginCode.cs'.
- return new YourPlugin().Update(Plugin, id);
+ lock (this.locker)
+ {
+ return this.LastInput;
+ }
}
- ///
- /// Rainmeter's request for numeric data from the plugin. This version can return
- /// positive or negative floating-point numbers (32-bit precision). Comment this
- /// member out and use 'Update' if you want to only return positive integers.
- ///
- /// The unique instance ID of this request.
- /// Current value for this meter.
- //[DllExport]
- //public static double Update2(UInt32 id)
- //{
- // // Do not modify this member (although you can comment it out). Instead, update
- // // your code in 'PluginCode.cs'.
- // return new YourPlugin().Update2(Plugin, id);
- //}
-
- ///
- /// Rainmeter's request for text data from the plugin.
- ///
- /// The unique instance ID of this request.
- /// Unused still as of Dec 2nd, 2010.
- ///
- [DllExport]
- public unsafe static char* GetString(UInt32 id, UInt32 flags)
+ internal void ExecuteBang(string args)
{
- // Do not modify this member. Instead, update your code in 'PluginCode.cs'.
- return Rainmeter.String(new YourPlugin().GetString(Plugin, id));
+ bool go = false;
+
+ lock (this.locker)
+ {
+ if (!this.IsExecuteBangRunning)
+ {
+ this.IsExecuteBangRunning = true;
+ go = true;
+ }
+ }
+
+ if (go)
+ {
+ ThreadPool.QueueUserWorkItem(ExecuteBangThread, args);
+ }
}
- #endregion
-
- #region ExecuteBang() export -- no need to modify (change code in PluginCode.cs)
-
- [DllExport]
- public static unsafe void ExecuteBang(char* args, UInt32 id)
+ private void ExecuteBangThread(object state)
{
- new YourPlugin().ExecuteBang(Plugin, id, new string(args));
- return;
- }
+ string command = (string)state;
- #endregion
+ try
+ {
+ ExecuteCommands(command);
+ }
+ catch (Exception ex)
+ {
+ API.Log(API.LogType.Error, "C# plugin in ExecuteBang(), " + ex.GetType().ToString() + ": " + ex.Message);
+ }
+
+ lock (this.locker)
+ {
+ this.IsExecuteBangRunning = false;
+ }
+ }
}
- ///
- /// Dummy attribute to mark method as exported for DllExporter.exe.
- ///
- [AttributeUsage(AttributeTargets.Method)]
- public class DllExport : Attribute
+ #region Plugin
+
+ public static class Plugin
{
- public DllExport()
+ internal static Dictionary Measures = new Dictionary();
+
+ [DllExport]
+ public unsafe static void Initialize(void** data, void* rm)
{
+ uint id = (uint)((void*)*data);
+ Measures.Add(id, new Measure(new Rainmeter.API((IntPtr)rm)));
+ }
+
+ [DllExport]
+ public unsafe static void Finalize(void* data)
+ {
+ uint id = (uint)data;
+ Measures.Remove(id);
+ }
+
+ [DllExport]
+ public unsafe static void Reload(void* data, void* rm, double* maxValue)
+ {
+ uint id = (uint)data;
+ Measures[id].Reload(new Rainmeter.API((IntPtr)rm), ref *maxValue);
+ }
+
+ [DllExport]
+ public unsafe static double Update(void* data)
+ {
+ uint id = (uint)data;
+ return Measures[id].Update();
+ }
+
+ [DllExport]
+ public unsafe static char* GetString(void* data)
+ {
+ uint id = (uint)data;
+ fixed (char* s = Measures[id].GetString()) return s;
+ }
+
+ [DllExport]
+ public unsafe static void ExecuteBang(void* data, char* args)
+ {
+ uint id = (uint)data;
+ Measures[id].ExecuteBang(new string(args));
}
}
+
+ #endregion
}
diff --git a/Plugins/PluginInputText/PluginCode.cs b/Plugins/PluginInputText/PluginCode.cs
index 2cdfc4fc..1c8f6574 100644
--- a/Plugins/PluginInputText/PluginCode.cs
+++ b/Plugins/PluginInputText/PluginCode.cs
@@ -1,63 +1,68 @@
-using System;
+/*
+ Copyright (C) 2013 Rainmeter Team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+using System;
using System.Collections.Generic;
+using Rainmeter;
// The bulk of your plugin's code belongs in this file.
namespace InputText
{
- class PluginCode
+ internal partial class Measure
{
- // 'Update', 'Update2', and 'GetString' all return data back to Rainmeter, depending on
- // if the Rainmeter measure wants a numeric value or a string/text data.
- //
- // The 'Instance' member contains all of the data necessary to read the INI file
- // passed to your plugin when this instance was first initialized. Remember: your plugin
- // may be initialized multiple times. For example, a plugin that reads the free space
- // of a hard drive may be called multiple times -- once for each installed hard drive.
-
- public UInt32 Update(Rainmeter.Settings.InstanceSettings Instance)
+ private void ExecuteCommands(string Command)
{
- return 0;
- }
+ Command = Command.Trim();
- //public double Update2(Rainmeter.Settings.InstanceSettings Instance)
- //{
- // return 0.0;
- //}
+ // Get default options
+ Dictionary Options = new Dictionary();
+ ReadOption("DefaultValue", Options);
+ ReadOption("X", Options);
+ ReadOption("Y", Options);
+ ReadOption("W", Options);
+ ReadOption("H", Options);
+ ReadOption("StringStyle", Options);
+ ReadOption("StringAlign", Options);
+ ReadOption("FocusDismiss", Options);
+ ReadOption("FontColor", Options);
+ ReadOption("FontFace", Options);
+ ReadOption("FontSize", Options);
+ ReadOption("SolidColor", Options);
+ ReadOption("Password", Options);
+ ReadOption("TopMost", Options);
- public string GetString(Rainmeter.Settings.InstanceSettings Instance)
- {
- // This plugin is unique as it is one of the first to not be used to display data
- // back in Rainmeter, but to request user input and use that input during batch
- // operations (and other purposes).
- //
- // However, Rainmeter requires that data be sent back, so we'll return temporary data
- // In this case, the data is whatever the user last entered into an input textbox.
- return Instance.GetTempValue("LastInput", string.Empty).ToString();
- }
-
-
- // 'ExecuteBang' is a way of Rainmeter telling your plugin to do something *right now*.
- // What it wants to do can be defined by the 'Command' parameter.
- public void ExecuteBang(Rainmeter.Settings.InstanceSettings Instance, string Command)
- {
#region Handle a single parameter
// If our parameter list only contains a single word, then open a textbox immediately
// and set a value. This mode does not do any batching.
- if (!Command.Trim().Contains(" "))
+ if (!Command.Contains(" "))
{
// Assume that the parameter is the name of the variable
- string sVariableName = Command.Trim();
// Ask for input
- string sInput = GetUserInput(Instance);
+ string sInput = GetUserInput(Options);
// If the user cancelled out of the inputbox (ESC key, etc.), then abort
if (sInput == null)
return;
// Ask Rainmeter to set the variable using a bang (http://rainmeter.net/RainCMS/?q=Bangs)
- Rainmeter.Bang("!RainmeterSetVariable " + sVariableName + " \"" + sInput.Replace("\"", "\\\"") + "\"");
+ API.Execute(rm.GetSkin(), "!SetVariable " + Command + " \"" + sInput + "\"");
// Note that the skin needs DynamicVariables=1 in the measure's settings or the above
// code will have no effect.
@@ -68,7 +73,7 @@ namespace InputText
#region Handle multiple parameters
// Our parameter list contains at least two words, so split them up
- string[] sParts = Command.Trim().Split(new string[] { " " }, StringSplitOptions.None);
+ string[] sParts = Command.Split(new string[] { " " }, StringSplitOptions.None);
// If the first parameter is 'ExecuteBatch' (not case sensitive)...
if (sParts[0].Trim().ToUpper() == "EXECUTEBATCH")
@@ -126,18 +131,25 @@ namespace InputText
#region Parse commands in range
// Parse each command in the range, aborting if any line returns 'false' or
// the requested command line does not exist in the config for that measure.
+ List commands = new List();
+
for (int i = iMin; i <= iMax; i++)
{
// Read this command's line
- string sCurrentLine = Instance.INI_Value("Command" + i.ToString());
+ string sCurrentLine = rm.ReadString("Command" + i.ToString(), "", false);
// If empty/non-existent, abort
if (string.IsNullOrEmpty(sCurrentLine))
break;
+ commands.Add(sCurrentLine);
+ }
+
+ foreach (string sCurrentLine in commands)
+ {
// Execute the line, but if there's a problem (error or they cancel the
// input textbox), then abort
- if (!ExecuteLine(Instance, sCurrentLine))
+ if (!ExecuteLine(sCurrentLine, Options))
break;
// Continue to the next line, if there is any
@@ -147,7 +159,7 @@ namespace InputText
}
// Unhandled command, log the message but otherwise do nothing
- Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Received command \"" + sParts[0].Trim() + "\", left unhandled");
+ API.Log(API.LogType.Debug, "InputText: Received command \"" + sParts[0].Trim() + "\", left unhandled");
#endregion
@@ -157,7 +169,7 @@ namespace InputText
#region This is all code custom to this plugin
#region Parse the current command line
- private bool ExecuteLine(Rainmeter.Settings.InstanceSettings Instance, string sLine)
+ private bool ExecuteLine(string sLine, Dictionary Options)
{
// If this line contains a $UserInput$ token, then we need to do some extra
// parsing
@@ -186,17 +198,17 @@ namespace InputText
sLine = ScanAndReplace(sLine, "FocusDismiss", Overrides);
sLine = ScanAndReplace(sLine, "FontColor", Overrides);
sLine = ScanAndReplace(sLine, "FontFace", Overrides);
+ sLine = ScanAndReplace(sLine, "FontSize", Overrides);
sLine = ScanAndReplace(sLine, "SolidColor", Overrides);
sLine = ScanAndReplace(sLine, "Password", Overrides);
- sLine = ScanAndReplace(sLine, "FontSize", Overrides);
sLine = ScanAndReplace(sLine, "TopMost", Overrides);
#endregion
// Get user input
- string sInput = GetUserInput(Instance, Overrides);
+ string sInput = GetUserInput(Options, Overrides);
if (sInput == null)
{
- // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Aborted, user cancelled text box");
+ // API.Log(API.LogType.Debug, "InputText: Aborted, user cancelled text box");
return false;
}
@@ -206,168 +218,116 @@ namespace InputText
catch (Exception ex)
{
// If there was an error doing any of the above, log it for debugging purposes.
- Rainmeter.Log(Rainmeter.LogLevel.Warning, "InputText: Exception " + ex.GetType().ToString() + ": " + ex.Message);
+ API.Log(API.LogType.Warning, "InputText: Exception " + ex.GetType().ToString() + ": " + ex.Message);
return false;
}
}
// Execute the bang. This will either be the original line from CommandX= (sLine variable) or
// an adjusted line based on special parsing above.
- // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Executing bang: " + sLine);
- Rainmeter.Bang(sLine);
+ // API.Log(API.LogType.Debug, "InputText: Executing bang: " + sLine);
+ API.Execute(rm.GetSkin(), sLine);
return true;
}
#endregion
#region GetUserInput() -- creates an input textbox and handles all INI and override settings
- private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance)
+ delegate void ChangeSettingFromString(string value);
+ delegate void ChangeInputBoxSetting(string option, ChangeSettingFromString method);
+
+ private string GetUserInput(Dictionary Options)
{
// No INI overrides provided, so create an empty list
- return GetUserInput(Instance, new Dictionary());
+ return GetUserInput(Options, new Dictionary());
}
- private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance, Dictionary sOverrides)
+ private string GetUserInput(Dictionary Options, Dictionary Overrides)
{
+ SkinWindow skin = new SkinWindow(rm);
+
// Create the form. 'InputBox' is a .NET form with a textbox and two button controls on it.
- InputBox input = new InputBox();
- input.Instance = Instance;
- input.ChangeX(Instance, "0");
- input.ChangeY(Instance, "0");
+ InputBox input = new InputBox(skin);
+ input.ChangeX("0");
+ input.ChangeY("0");
// Change the styles of the InputBox form based on overrides or INI values
#region Style and preference tweaks (INI and override settings)
- if (sOverrides.ContainsKey("FontFace"))
- input.ChangeFontFace(sOverrides["FontFace"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("FontFace")))
- input.ChangeFontFace(Instance.INI_Value("FontFace"));
-
- if (sOverrides.ContainsKey("FontSize"))
- input.ChangeFontSize(sOverrides["FontSize"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("FontSize")))
- input.ChangeFontSize(Instance.INI_Value("FontSize"));
-
- if (sOverrides.ContainsKey("W"))
- input.ChangeW(sOverrides["W"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("W")))
- input.ChangeW(Instance.INI_Value("W"));
-
- if (sOverrides.ContainsKey("H"))
- input.ChangeH(sOverrides["H"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("H")))
- input.ChangeH(Instance.INI_Value("H"));
-
- if (sOverrides.ContainsKey("X"))
- input.ChangeX(Instance, sOverrides["X"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("X")))
- input.ChangeX(Instance, Instance.INI_Value("X"));
-
- if (sOverrides.ContainsKey("Y"))
- input.ChangeY(Instance, sOverrides["Y"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("Y")))
- input.ChangeY(Instance, Instance.INI_Value("Y"));
-
- if (sOverrides.ContainsKey("StringStyle"))
- input.ChangeFontStringStyle(sOverrides["StringStyle"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("StringStyle")))
- input.ChangeFontStringStyle(Instance.INI_Value("StringStyle"));
-
- if (sOverrides.ContainsKey("StringAlign"))
- input.ChangeStringAlign(sOverrides["StringAlign"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("StringAlign")))
- input.ChangeStringAlign(Instance.INI_Value("StringAlign"));
-
- bool bFocusDismiss = true;
- if (sOverrides.ContainsKey("FocusDismiss"))
+ ChangeInputBoxSetting changeSetting = (opt, change) =>
{
- input.MakeFocusDismiss(sOverrides["FocusDismiss"] == "1");
- bFocusDismiss = sOverrides["FocusDismiss"] == "1";
- }
- else
+ if (Overrides.ContainsKey(opt))
+ change(Overrides[opt]);
+ else if (Options.ContainsKey(opt))
+ change(Options[opt]);
+ };
+
+ changeSetting("FontFace", input.ChangeFontFace);
+ changeSetting("FontSize", input.ChangeFontSize);
+
+ changeSetting("W", input.ChangeW);
+ changeSetting("H", input.ChangeH);
+ changeSetting("X", input.ChangeX);
+ changeSetting("Y", input.ChangeY);
+
+ changeSetting("StringStyle", input.ChangeFontStringStyle);
+ changeSetting("StringAlign", input.ChangeStringAlign);
+
+ changeSetting("FontColor", input.ChangeFontColor);
+ changeSetting("SolidColor", input.ChangeBackColor);
+
+ if (Overrides.ContainsKey("FocusDismiss"))
+ input.MakeFocusDismiss(Overrides["FocusDismiss"] == "1");
+ else if (Options.ContainsKey("FocusDismiss"))
+ input.MakeFocusDismiss(Options["FocusDismiss"].Trim() == "1");
+
+ if (Overrides.ContainsKey("Password"))
+ input.MakePassword(Overrides["Password"] == "1");
+ else if (Options.ContainsKey("Password"))
+ input.MakePassword(Options["Password"].Trim() == "1");
+
+ string topmost = null;
+ if (Overrides.ContainsKey("TopMost"))
+ topmost = Overrides["TopMost"];
+ else if (Options.ContainsKey("TopMost"))
+ topmost = Options["TopMost"].Trim();
+ switch (topmost)
{
- input.MakeFocusDismiss(!(Instance.INI_Value("FocusDismiss").Trim().ToUpper() != "1"));
- bFocusDismiss = !(Instance.INI_Value("FocusDismiss").Trim().ToUpper() != "1");
- }
-
- if (sOverrides.ContainsKey("FontColor"))
- input.ChangeFontColor(sOverrides["FontColor"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("FontColor")))
- input.ChangeFontColor(Instance.INI_Value("FontColor"));
-
- if (sOverrides.ContainsKey("SolidColor"))
- input.ChangeBackColor(sOverrides["SolidColor"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("SolidColor")))
- input.ChangeBackColor(Instance.INI_Value("SolidColor"));
-
- if (sOverrides.ContainsKey("Passwords"))
- {
- if (sOverrides["DefaultValue"] == "1")
- input.MakePassword();
- }
- else if (Instance.INI_Value("Password").Trim().ToUpper() == "1")
- input.MakePassword();
-
- bool bAutoTopMost = true;
- if (sOverrides.ContainsKey("TopMost"))
- {
- if (sOverrides["TopMost"] == "1")
- {
+ case "1":
input.MakeTopmost();
- bAutoTopMost = false;
- }
- else if (sOverrides["TopMost"] == "0")
- bAutoTopMost = false;
+ break;
+ case "0":
+ break;
+ default: // AUTO
+ if (skin.IsTopmost)
+ input.MakeTopmost();
+ break;
}
- else if (Instance.INI_Value("TopMost").Trim().ToUpper() == "1")
- {
- input.MakeTopmost();
- bAutoTopMost = false;
- }
- else if (Instance.INI_Value("TopMost").Trim().ToUpper() != "AUTO")
- if (!string.IsNullOrEmpty(Instance.INI_Value("TopMost").Trim()))
- bAutoTopMost = false;
- if (bAutoTopMost)
- if (Rainmeter.ParentIsTopmost(Instance))
- input.MakeTopmost();
- if (sOverrides.ContainsKey("DefaultValue"))
- input.DefaultValue(sOverrides["DefaultValue"]);
- else if (!string.IsNullOrEmpty(Instance.INI_Value("DefaultValue")))
- input.DefaultValue(Instance.INI_Value("DefaultValue").Trim());
+ changeSetting("DefaultValue", input.DefaultValue);
#endregion
- if (bFocusDismiss)
- {
- input.Show(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
+ if (!input.ShowInputBox())
+ return null;
- for (; ; )
- {
- if (input.DialogResult != System.Windows.Forms.DialogResult.None || input.drBackup != System.Windows.Forms.DialogResult.None)
- break;
- System.Windows.Forms.Application.DoEvents();
- System.Threading.Thread.Sleep(44);
- }
- }
- else
+ lock (this.locker)
{
- input.ShowDialog(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
+ this.LastInput = input.TextValue;
}
-
- if (input.drBackup != System.Windows.Forms.DialogResult.None)
- {
- if (input.drBackup != System.Windows.Forms.DialogResult.OK)
- return null;
- }
- else if (input.DialogResult != System.Windows.Forms.DialogResult.None)
- {
- if (input.DialogResult != System.Windows.Forms.DialogResult.OK)
- return null;
- }
-
- Instance.SetTempValue("LastInput", input.sTextValue);
- return input.sTextValue;
+ return input.TextValue;
}
#endregion
+
+ #region ReadOption() -- reads given option's value from Rainmeter
+ private void ReadOption(string optionName, Dictionary Options)
+ {
+ string value = rm.ReadString(optionName, "");
+ if (!string.IsNullOrEmpty(value))
+ {
+ Options.Add(optionName, value);
+ }
+ }
+ #endregion
+
#region Replace() -- case-insensitive string replacement
private static string Replace(string sIn, string sFind, string sReplace)
{
@@ -458,7 +418,7 @@ namespace InputText
if (FindTag(sLine, sTagName))
{
string sTagData = TagData(sLine, sTagName);
- // Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Overriding " + sTagName + " with " + sTagData);
+ // API.Log(API.LogType.Debug, "InputText: Overriding " + sTagName + " with " + sTagData);
if (sTagData.StartsWith("\""))
Overrides.Add(sTagName, sTagData.Substring(1, sTagData.Length - 2));
else
diff --git a/Plugins/PluginInputText/PluginInputText.csproj b/Plugins/PluginInputText/PluginInputText.csproj
index f12a35cf..a7efe612 100644
--- a/Plugins/PluginInputText/PluginInputText.csproj
+++ b/Plugins/PluginInputText/PluginInputText.csproj
@@ -94,6 +94,7 @@
InputBox.cs
+
diff --git a/Plugins/PluginInputText/Rainmeter.cs b/Plugins/PluginInputText/Rainmeter.cs
index 6c6be2fc..24d55474 100644
--- a/Plugins/PluginInputText/Rainmeter.cs
+++ b/Plugins/PluginInputText/Rainmeter.cs
@@ -1,11 +1,27 @@
-using System;
-using System.Collections.Generic;
+/*
+ Copyright (C) 2013 Rainmeter Team
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+using System;
using System.Runtime.InteropServices;
-using System.Threading;
+using Rainmeter;
// This is a utility class / toolkit for communicating with Rainmeter and managing
-// logging, INI settings, bangs, window positioning, multiple instances, and temporary
-// data storage.
+// window positioning.
//
// You should not need to edit this code except to expand the toolkit support.
//
@@ -13,119 +29,78 @@ using System.Threading;
// that you create (such as new forms, classes, and controls).
namespace InputText
{
- public class WindowWrapper : System.Windows.Forms.IWin32Window
+ public class SkinWindow : System.Windows.Forms.IWin32Window
{
- public WindowWrapper(IntPtr handle)
+ private string _SkinName;
+ private IntPtr _Handle;
+
+ private int _X = 0;
+ private int _Y = 0;
+ private int _W = 0;
+ private int _H = 0;
+
+ private bool _IsTopmost = false;
+
+ public SkinWindow(Rainmeter.API rm)
{
- _hwnd = handle;
+ UpdateStatus(rm);
}
+ #region Methods for getting the screen-relative location of the current skin
+
public IntPtr Handle
{
- get { return _hwnd; }
+ get { return this._Handle; }
}
- 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)
+ public int X
{
- 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;
+ get { return this._X; }
}
- public static int ConfigY(string sSkin)
+ public int Y
{
- 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;
+ get { return this._Y; }
}
- public static int ConfigWidth(string sSkin)
+ public int Width
{
- 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;
+ get { return this._W; }
}
- public static int ConfigHeight(string sSkin)
+ public int Height
{
- 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;
+ get { return this._H; }
}
- public static int ConfigHeight(Rainmeter.Settings.InstanceSettings Instance)
+
+ public bool IsTopmost
{
- IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
- RECT rct;
- if (!GetWindowRect(hwnd, out rct))
+ get { return this._IsTopmost; }
+ }
+
+ public void UpdateStatus(Rainmeter.API rm = null)
+ {
+ if (rm != null)
{
- 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;
+ this._SkinName = rm.GetSkinName();
+ this._Handle = rm.GetSkinWindow();
}
- return rct.Bottom - rct.Top;
+
+ RECT rct;
+ if (GetWindowRect(this._Handle, out rct))
+ {
+ this._X = rct.Left;
+ this._Y = rct.Top;
+ this._W = rct.Right - rct.Left;
+ this._H = rct.Bottom - rct.Top;
+ }
+ else
+ {
+ API.Log(API.LogType.Error,
+ "Rainmeter told us the HWND for window '" + this._SkinName + "' is " + this._Handle.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
+ }
+
+ this._IsTopmost = ((GetWindowLong(this._Handle, GWL_EXSTYLE) & WS_EX_TOPMOST) > 0);
}
#region GetWindowRect() platform invoke to get the size/location of a window
@@ -134,12 +109,6 @@ namespace InputText
[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
{
@@ -149,578 +118,15 @@ namespace InputText
public int Bottom; // y position of lower-right corner
}
#endregion
- #region SendMessage -- SendMessage (this variant is only for WM_COPYSTRUCT messages)
+ #region GetWindowLong() -- platform invoke to check a window's Z-order (Topmost=Auto)
- [DllImport("user32.dll", CharSet = CharSet.Auto)]
- private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
+ [DllImport("user32.dll")]
+ private static extern int GetWindowLong(IntPtr hwnd, int nIndex);
- [StructLayout(LayoutKind.Sequential)]
- struct COPYDATASTRUCT
- {
- public UInt32 dwData;
- public int cbData;
- public IntPtr lpData;
- }
+ private const int GWL_EXSTYLE = -20;
+ private const int WS_EX_TOPMOST = 8;
#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 Instances = new Dictionary();
- public List KeyValues = new List();
-
- 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 TempData = new Dictionary();
-
- 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
}