mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
InputText.dll: Updated to new API
This commit is contained in:
parent
7186f0988a
commit
5eafccdba7
@ -2,6 +2,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
[assembly: AssemblyCopyright("© 2010 - Peter Souza IV")]
|
[assembly: AssemblyCopyright("© 2010 - Peter Souza IV")]
|
||||||
[assembly: AssemblyVersion("1.6.0.0")]
|
[assembly: AssemblyVersion("1.7.0.0")]
|
||||||
[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)]
|
[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)]
|
||||||
[assembly: AssemblyProduct("Rainmeter")]
|
[assembly: AssemblyProduct("Rainmeter")]
|
||||||
|
@ -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.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
@ -6,14 +24,17 @@ namespace InputText
|
|||||||
{
|
{
|
||||||
public partial class InputBox : Form
|
public partial class InputBox : Form
|
||||||
{
|
{
|
||||||
public Rainmeter.Settings.InstanceSettings Instance = null;
|
private SkinWindow parent = null;
|
||||||
|
|
||||||
#region Default form initializer
|
private bool _FocusDismiss = true;
|
||||||
public InputBox()
|
private string _TextValue = string.Empty;
|
||||||
|
|
||||||
|
public InputBox(SkinWindow parent)
|
||||||
{
|
{
|
||||||
|
this.parent = parent;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
// This event will make sure we have focus when the inputbox is shown ot the user.
|
// 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).
|
// 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();
|
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
|
// 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
|
// (if not all) of these are rather simple in nature, debugging without errors
|
||||||
// should be fairly simple anyway.
|
// should be fairly simple anyway.
|
||||||
@ -39,16 +68,13 @@ namespace InputText
|
|||||||
// }
|
// }
|
||||||
// catch (Exception ex)
|
// 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
|
#region TextValue -- returns the inputted text
|
||||||
public string TextInput
|
public string TextValue
|
||||||
{
|
{
|
||||||
get
|
get { return this._TextValue; }
|
||||||
{
|
|
||||||
return this.txtInput.Text.Trim();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region ChangeFontFace(string) -- changes the text's font name
|
#region ChangeFontFace(string) -- changes the text's font name
|
||||||
@ -170,10 +196,10 @@ namespace InputText
|
|||||||
this.TopMost = true;
|
this.TopMost = true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region MakePassword() -- causes the textbox to be password style
|
#region MakePassword(bool) -- causes the textbox to be password style
|
||||||
public void MakePassword()
|
public void MakePassword(bool bPass)
|
||||||
{
|
{
|
||||||
this.txtInput.PasswordChar = '*';
|
this.txtInput.PasswordChar = bPass ? '*' : '\0';
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region ChangeFontStringStyle() -- changes the font's bold/italic styles
|
#region ChangeFontStringStyle() -- changes the font's bold/italic styles
|
||||||
@ -216,7 +242,7 @@ namespace InputText
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region ChangeX(string) -- changes the X (horizontal) position of the input textbox, relative to its parent skin
|
#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
|
try
|
||||||
{
|
{
|
||||||
@ -227,13 +253,13 @@ namespace InputText
|
|||||||
// Notice that we need the position of the parent window for offset location.
|
// Notice that we need the position of the parent window for offset location.
|
||||||
//
|
//
|
||||||
// The Rainmeter class does this for us
|
// 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 { }
|
catch { }
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region ChangeY(string) -- changes the Y (vertical) position of the input textbox, relative to its parent skin
|
#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
|
try
|
||||||
{
|
{
|
||||||
@ -244,7 +270,7 @@ namespace InputText
|
|||||||
// Notice that we need the position of the parent window for offset location.
|
// Notice that we need the position of the parent window for offset location.
|
||||||
//
|
//
|
||||||
// The Rainmeter class does this for us
|
// 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 { }
|
catch { }
|
||||||
}
|
}
|
||||||
@ -256,15 +282,47 @@ namespace InputText
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region MakeFocusDismiss(bool) -- dismisses the input textbox if it loses cursor/window focus
|
#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)
|
public void MakeFocusDismiss(bool bDismissing)
|
||||||
{
|
{
|
||||||
this._FocusDismiss = 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)
|
private void txtInput_Leave(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
@ -295,8 +353,8 @@ namespace InputText
|
|||||||
|
|
||||||
private void btnOK_Click(object sender, EventArgs e)
|
private void btnOK_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_FocusDismiss = false;
|
this._FocusDismiss = false;
|
||||||
this.sTextValue = this.txtInput.Text.Trim();
|
this._TextValue = this.txtInput.Text.Trim();
|
||||||
this.drBackup = DialogResult.OK;
|
this.drBackup = DialogResult.OK;
|
||||||
this.DialogResult = DialogResult.OK;
|
this.DialogResult = DialogResult.OK;
|
||||||
this.Close();
|
this.Close();
|
||||||
@ -304,20 +362,12 @@ namespace InputText
|
|||||||
|
|
||||||
private void btnCancel_Click(object sender, EventArgs e)
|
private void btnCancel_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
_FocusDismiss = false;
|
this._FocusDismiss = false;
|
||||||
this.drBackup = DialogResult.Cancel;
|
this.drBackup = DialogResult.Cancel;
|
||||||
this.DialogResult = DialogResult.Cancel;
|
this.DialogResult = DialogResult.Cancel;
|
||||||
this.Close();
|
this.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private void InputBox_Load(object sender, EventArgs e)
|
|
||||||
{
|
|
||||||
this.Activate();
|
|
||||||
this.BringToFront();
|
|
||||||
this.Activate();
|
|
||||||
this.BringToFront();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
using Rainmeter;
|
||||||
|
|
||||||
namespace InputText
|
namespace InputText
|
||||||
{
|
{
|
||||||
public class Main
|
internal partial class Measure
|
||||||
{
|
{
|
||||||
/// <summary>
|
private Rainmeter.API rm;
|
||||||
/// 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
|
|
||||||
/// </summary>
|
|
||||||
private static Rainmeter.Settings Plugin = new Rainmeter.Settings
|
|
||||||
(
|
|
||||||
// Author name
|
|
||||||
"Peter Souza IV",
|
|
||||||
|
|
||||||
// Version
|
private string LastInput = string.Empty;
|
||||||
1.06,
|
private bool IsExecuteBangRunning = false;
|
||||||
|
|
||||||
// E-mail
|
private object locker = new object();
|
||||||
"psouza4@gmail.com",
|
|
||||||
|
|
||||||
// Comments (try to keep it under 50 characters)
|
internal Measure(Rainmeter.API rm)
|
||||||
"Please visit the forums for support."
|
|
||||||
);
|
|
||||||
|
|
||||||
#region GetAuthor() and GetVersion() exports -- no need to modify
|
|
||||||
|
|
||||||
[DllExport]
|
|
||||||
public static UInt32 GetPluginVersion()
|
|
||||||
{
|
{
|
||||||
return Rainmeter.Version(Plugin.Version);
|
this.rm = rm;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllExport]
|
internal void Reload(Rainmeter.API rm, ref double maxValue)
|
||||||
public unsafe static char* GetPluginAuthor()
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(Plugin.Email) && !string.IsNullOrEmpty(Plugin.Comments))
|
// Do nothing here.
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
internal double Update()
|
||||||
|
|
||||||
#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)
|
|
||||||
{
|
{
|
||||||
Plugin.AddInstance(iniFile, section, id); // required: do not remove
|
return 0.0;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// You may add code here, if necessary
|
|
||||||
//
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DllExport]
|
internal string GetString()
|
||||||
public static void Finalize(IntPtr instance, UInt32 id)
|
|
||||||
{
|
{
|
||||||
Plugin.RemoveInstance(id); // required: do not remove
|
lock (this.locker)
|
||||||
|
{
|
||||||
////////////////////////////////////////////////////////////////
|
return this.LastInput;
|
||||||
//
|
}
|
||||||
// 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 ***
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The unique instance ID of this request.</param>
|
|
||||||
/// <returns>Current value for this meter.</returns>
|
|
||||||
[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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
internal void ExecuteBang(string args)
|
||||||
/// 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.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The unique instance ID of this request.</param>
|
|
||||||
/// <returns>Current value for this meter.</returns>
|
|
||||||
//[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);
|
|
||||||
//}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Rainmeter's request for text data from the plugin.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id">The unique instance ID of this request.</param>
|
|
||||||
/// <param name="flags">Unused still as of Dec 2nd, 2010.</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[DllExport]
|
|
||||||
public unsafe static char* GetString(UInt32 id, UInt32 flags)
|
|
||||||
{
|
{
|
||||||
// Do not modify this member. Instead, update your code in 'PluginCode.cs'.
|
bool go = false;
|
||||||
return Rainmeter.String(new YourPlugin().GetString(Plugin, id));
|
|
||||||
|
lock (this.locker)
|
||||||
|
{
|
||||||
|
if (!this.IsExecuteBangRunning)
|
||||||
|
{
|
||||||
|
this.IsExecuteBangRunning = true;
|
||||||
|
go = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (go)
|
||||||
|
{
|
||||||
|
ThreadPool.QueueUserWorkItem(ExecuteBangThread, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
private void ExecuteBangThread(object state)
|
||||||
|
|
||||||
#region ExecuteBang() export -- no need to modify (change code in PluginCode.cs)
|
|
||||||
|
|
||||||
[DllExport]
|
|
||||||
public static unsafe void ExecuteBang(char* args, UInt32 id)
|
|
||||||
{
|
{
|
||||||
new YourPlugin().ExecuteBang(Plugin, id, new string(args));
|
string command = (string)state;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#region Plugin
|
||||||
/// Dummy attribute to mark method as exported for DllExporter.exe.
|
|
||||||
/// </summary>
|
public static class Plugin
|
||||||
[AttributeUsage(AttributeTargets.Method)]
|
|
||||||
public class DllExport : Attribute
|
|
||||||
{
|
{
|
||||||
public DllExport()
|
internal static Dictionary<uint, Measure> Measures = new Dictionary<uint, Measure>();
|
||||||
|
|
||||||
|
[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
|
||||||
}
|
}
|
||||||
|
@ -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 System.Collections.Generic;
|
||||||
|
using Rainmeter;
|
||||||
|
|
||||||
// The bulk of your plugin's code belongs in this file.
|
// The bulk of your plugin's code belongs in this file.
|
||||||
namespace InputText
|
namespace InputText
|
||||||
{
|
{
|
||||||
class PluginCode
|
internal partial class Measure
|
||||||
{
|
{
|
||||||
// 'Update', 'Update2', and 'GetString' all return data back to Rainmeter, depending on
|
private void ExecuteCommands(string Command)
|
||||||
// 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)
|
|
||||||
{
|
{
|
||||||
return 0;
|
Command = Command.Trim();
|
||||||
}
|
|
||||||
|
|
||||||
//public double Update2(Rainmeter.Settings.InstanceSettings Instance)
|
// Get default options
|
||||||
//{
|
Dictionary<string, string> Options = new Dictionary<string, string>();
|
||||||
// return 0.0;
|
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
|
#region Handle a single parameter
|
||||||
|
|
||||||
// If our parameter list only contains a single word, then open a textbox immediately
|
// 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.
|
// 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
|
// Assume that the parameter is the name of the variable
|
||||||
string sVariableName = Command.Trim();
|
|
||||||
|
|
||||||
// Ask for input
|
// 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 the user cancelled out of the inputbox (ESC key, etc.), then abort
|
||||||
if (sInput == null)
|
if (sInput == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Ask Rainmeter to set the variable using a bang (http://rainmeter.net/RainCMS/?q=Bangs)
|
// 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
|
// Note that the skin needs DynamicVariables=1 in the measure's settings or the above
|
||||||
// code will have no effect.
|
// code will have no effect.
|
||||||
@ -68,7 +73,7 @@ namespace InputText
|
|||||||
#region Handle multiple parameters
|
#region Handle multiple parameters
|
||||||
|
|
||||||
// Our parameter list contains at least two words, so split them up
|
// 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 the first parameter is 'ExecuteBatch' (not case sensitive)...
|
||||||
if (sParts[0].Trim().ToUpper() == "EXECUTEBATCH")
|
if (sParts[0].Trim().ToUpper() == "EXECUTEBATCH")
|
||||||
@ -126,18 +131,25 @@ namespace InputText
|
|||||||
#region Parse commands in range
|
#region Parse commands in range
|
||||||
// Parse each command in the range, aborting if any line returns 'false' or
|
// 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.
|
// the requested command line does not exist in the config for that measure.
|
||||||
|
List<string> commands = new List<string>();
|
||||||
|
|
||||||
for (int i = iMin; i <= iMax; i++)
|
for (int i = iMin; i <= iMax; i++)
|
||||||
{
|
{
|
||||||
// Read this command's line
|
// 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 empty/non-existent, abort
|
||||||
if (string.IsNullOrEmpty(sCurrentLine))
|
if (string.IsNullOrEmpty(sCurrentLine))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
commands.Add(sCurrentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (string sCurrentLine in commands)
|
||||||
|
{
|
||||||
// Execute the line, but if there's a problem (error or they cancel the
|
// Execute the line, but if there's a problem (error or they cancel the
|
||||||
// input textbox), then abort
|
// input textbox), then abort
|
||||||
if (!ExecuteLine(Instance, sCurrentLine))
|
if (!ExecuteLine(sCurrentLine, Options))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Continue to the next line, if there is any
|
// Continue to the next line, if there is any
|
||||||
@ -147,7 +159,7 @@ namespace InputText
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unhandled command, log the message but otherwise do nothing
|
// 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
|
#endregion
|
||||||
|
|
||||||
@ -157,7 +169,7 @@ namespace InputText
|
|||||||
#region This is all code custom to this plugin
|
#region This is all code custom to this plugin
|
||||||
|
|
||||||
#region Parse the current command line
|
#region Parse the current command line
|
||||||
private bool ExecuteLine(Rainmeter.Settings.InstanceSettings Instance, string sLine)
|
private bool ExecuteLine(string sLine, Dictionary<string, string> Options)
|
||||||
{
|
{
|
||||||
// If this line contains a $UserInput$ token, then we need to do some extra
|
// If this line contains a $UserInput$ token, then we need to do some extra
|
||||||
// parsing
|
// parsing
|
||||||
@ -186,17 +198,17 @@ namespace InputText
|
|||||||
sLine = ScanAndReplace(sLine, "FocusDismiss", Overrides);
|
sLine = ScanAndReplace(sLine, "FocusDismiss", Overrides);
|
||||||
sLine = ScanAndReplace(sLine, "FontColor", Overrides);
|
sLine = ScanAndReplace(sLine, "FontColor", Overrides);
|
||||||
sLine = ScanAndReplace(sLine, "FontFace", Overrides);
|
sLine = ScanAndReplace(sLine, "FontFace", Overrides);
|
||||||
|
sLine = ScanAndReplace(sLine, "FontSize", Overrides);
|
||||||
sLine = ScanAndReplace(sLine, "SolidColor", Overrides);
|
sLine = ScanAndReplace(sLine, "SolidColor", Overrides);
|
||||||
sLine = ScanAndReplace(sLine, "Password", Overrides);
|
sLine = ScanAndReplace(sLine, "Password", Overrides);
|
||||||
sLine = ScanAndReplace(sLine, "FontSize", Overrides);
|
|
||||||
sLine = ScanAndReplace(sLine, "TopMost", Overrides);
|
sLine = ScanAndReplace(sLine, "TopMost", Overrides);
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Get user input
|
// Get user input
|
||||||
string sInput = GetUserInput(Instance, Overrides);
|
string sInput = GetUserInput(Options, Overrides);
|
||||||
if (sInput == null)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,168 +218,116 @@ namespace InputText
|
|||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// If there was an error doing any of the above, log it for debugging purposes.
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the bang. This will either be the original line from CommandX= (sLine variable) or
|
// Execute the bang. This will either be the original line from CommandX= (sLine variable) or
|
||||||
// an adjusted line based on special parsing above.
|
// an adjusted line based on special parsing above.
|
||||||
// Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Executing bang: " + sLine);
|
// API.Log(API.LogType.Debug, "InputText: Executing bang: " + sLine);
|
||||||
Rainmeter.Bang(sLine);
|
API.Execute(rm.GetSkin(), sLine);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
#region GetUserInput() -- creates an input textbox and handles all INI and override settings
|
#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<string, string> Options)
|
||||||
{
|
{
|
||||||
// No INI overrides provided, so create an empty list
|
// No INI overrides provided, so create an empty list
|
||||||
return GetUserInput(Instance, new Dictionary<string,string>());
|
return GetUserInput(Options, new Dictionary<string, string>());
|
||||||
}
|
}
|
||||||
private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance, Dictionary<string,string> sOverrides)
|
private string GetUserInput(Dictionary<string, string> Options, Dictionary<string, string> Overrides)
|
||||||
{
|
{
|
||||||
|
SkinWindow skin = new SkinWindow(rm);
|
||||||
|
|
||||||
// Create the form. 'InputBox' is a .NET form with a textbox and two button controls on it.
|
// Create the form. 'InputBox' is a .NET form with a textbox and two button controls on it.
|
||||||
InputBox input = new InputBox();
|
InputBox input = new InputBox(skin);
|
||||||
input.Instance = Instance;
|
input.ChangeX("0");
|
||||||
input.ChangeX(Instance, "0");
|
input.ChangeY("0");
|
||||||
input.ChangeY(Instance, "0");
|
|
||||||
|
|
||||||
// Change the styles of the InputBox form based on overrides or INI values
|
// Change the styles of the InputBox form based on overrides or INI values
|
||||||
#region Style and preference tweaks (INI and override settings)
|
#region Style and preference tweaks (INI and override settings)
|
||||||
|
|
||||||
if (sOverrides.ContainsKey("FontFace"))
|
ChangeInputBoxSetting changeSetting = (opt, change) =>
|
||||||
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"))
|
|
||||||
{
|
{
|
||||||
input.MakeFocusDismiss(sOverrides["FocusDismiss"] == "1");
|
if (Overrides.ContainsKey(opt))
|
||||||
bFocusDismiss = sOverrides["FocusDismiss"] == "1";
|
change(Overrides[opt]);
|
||||||
}
|
else if (Options.ContainsKey(opt))
|
||||||
else
|
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"));
|
case "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")
|
|
||||||
{
|
|
||||||
input.MakeTopmost();
|
input.MakeTopmost();
|
||||||
bAutoTopMost = false;
|
break;
|
||||||
}
|
case "0":
|
||||||
else if (sOverrides["TopMost"] == "0")
|
break;
|
||||||
bAutoTopMost = false;
|
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"))
|
changeSetting("DefaultValue", input.DefaultValue);
|
||||||
input.DefaultValue(sOverrides["DefaultValue"]);
|
|
||||||
else if (!string.IsNullOrEmpty(Instance.INI_Value("DefaultValue")))
|
|
||||||
input.DefaultValue(Instance.INI_Value("DefaultValue").Trim());
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
if (bFocusDismiss)
|
if (!input.ShowInputBox())
|
||||||
{
|
return null;
|
||||||
input.Show(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
|
|
||||||
|
|
||||||
for (; ; )
|
lock (this.locker)
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
input.ShowDialog(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
|
this.LastInput = input.TextValue;
|
||||||
}
|
}
|
||||||
|
return 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;
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ReadOption() -- reads given option's value from Rainmeter
|
||||||
|
private void ReadOption(string optionName, Dictionary<string, string> Options)
|
||||||
|
{
|
||||||
|
string value = rm.ReadString(optionName, "");
|
||||||
|
if (!string.IsNullOrEmpty(value))
|
||||||
|
{
|
||||||
|
Options.Add(optionName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Replace() -- case-insensitive string replacement
|
#region Replace() -- case-insensitive string replacement
|
||||||
private static string Replace(string sIn, string sFind, string sReplace)
|
private static string Replace(string sIn, string sFind, string sReplace)
|
||||||
{
|
{
|
||||||
@ -458,7 +418,7 @@ namespace InputText
|
|||||||
if (FindTag(sLine, sTagName))
|
if (FindTag(sLine, sTagName))
|
||||||
{
|
{
|
||||||
string sTagData = TagData(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("\""))
|
if (sTagData.StartsWith("\""))
|
||||||
Overrides.Add(sTagName, sTagData.Substring(1, sTagData.Length - 2));
|
Overrides.Add(sTagName, sTagData.Substring(1, sTagData.Length - 2));
|
||||||
else
|
else
|
||||||
|
@ -94,6 +94,7 @@
|
|||||||
<DependentUpon>InputBox.cs</DependentUpon>
|
<DependentUpon>InputBox.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="$(SolutionDir)Version.cs" />
|
<Compile Include="$(SolutionDir)Version.cs" />
|
||||||
|
<Compile Include="$(SolutionDir)Plugins\API\RainmeterAPI.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="InputBox.resx">
|
<EmbeddedResource Include="InputBox.resx">
|
||||||
|
@ -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.Runtime.InteropServices;
|
||||||
using System.Threading;
|
using Rainmeter;
|
||||||
|
|
||||||
// This is a utility class / toolkit for communicating with Rainmeter and managing
|
// This is a utility class / toolkit for communicating with Rainmeter and managing
|
||||||
// logging, INI settings, bangs, window positioning, multiple instances, and temporary
|
// window positioning.
|
||||||
// data storage.
|
|
||||||
//
|
//
|
||||||
// You should not need to edit this code except to expand the toolkit support.
|
// 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).
|
// that you create (such as new forms, classes, and controls).
|
||||||
namespace InputText
|
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
|
public IntPtr Handle
|
||||||
{
|
{
|
||||||
get { return _hwnd; }
|
get { return this._Handle; }
|
||||||
}
|
}
|
||||||
|
|
||||||
private IntPtr _hwnd;
|
public int X
|
||||||
}
|
|
||||||
|
|
||||||
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))));
|
get { return this._X; }
|
||||||
}
|
|
||||||
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)
|
public int Y
|
||||||
{
|
{
|
||||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
get { return this._Y; }
|
||||||
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)
|
public int Width
|
||||||
{
|
{
|
||||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
get { return this._W; }
|
||||||
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)
|
public int Height
|
||||||
{
|
{
|
||||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
get { return this._H; }
|
||||||
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)
|
|
||||||
|
public bool IsTopmost
|
||||||
{
|
{
|
||||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
get { return this._IsTopmost; }
|
||||||
RECT rct;
|
}
|
||||||
if (!GetWindowRect(hwnd, out rct))
|
|
||||||
|
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");
|
this._SkinName = rm.GetSkinName();
|
||||||
return 0;
|
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
|
#region GetWindowRect() platform invoke to get the size/location of a window
|
||||||
@ -134,12 +109,6 @@ namespace InputText
|
|||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
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)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
public struct RECT
|
public struct RECT
|
||||||
{
|
{
|
||||||
@ -149,578 +118,15 @@ namespace InputText
|
|||||||
public int Bottom; // y position of lower-right corner
|
public int Bottom; // y position of lower-right corner
|
||||||
}
|
}
|
||||||
#endregion
|
#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)]
|
[DllImport("user32.dll")]
|
||||||
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
|
private static extern int GetWindowLong(IntPtr hwnd, int nIndex);
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
private const int GWL_EXSTYLE = -20;
|
||||||
struct COPYDATASTRUCT
|
private const int WS_EX_TOPMOST = 8;
|
||||||
{
|
|
||||||
public UInt32 dwData;
|
|
||||||
public int cbData;
|
|
||||||
public IntPtr lpData;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#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
|
#endregion
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user