mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Reintegrated 2.3 branch into trunk
This commit is contained in:
7
Plugins/PluginInputText/AssemblyInfo.cs
Normal file
7
Plugins/PluginInputText/AssemblyInfo.cs
Normal file
@ -0,0 +1,7 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: AssemblyCopyright("© 2010 - Peter Souza IV")]
|
||||
[assembly: AssemblyVersion("1.4.0.0")]
|
||||
[assembly: AssemblyInformationalVersion(Rainmeter.Version.Informational)]
|
||||
[assembly: AssemblyProduct("Rainmeter")]
|
105
Plugins/PluginInputText/InputBox.Designer.cs
generated
Normal file
105
Plugins/PluginInputText/InputBox.Designer.cs
generated
Normal file
@ -0,0 +1,105 @@
|
||||
namespace InputText
|
||||
{
|
||||
partial class InputBox
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.txtInput = new System.Windows.Forms.TextBox();
|
||||
this.btnOK = new System.Windows.Forms.Button();
|
||||
this.btnCancel = new System.Windows.Forms.Button();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// txtInput
|
||||
//
|
||||
this.txtInput.BorderStyle = System.Windows.Forms.BorderStyle.None;
|
||||
this.txtInput.Location = new System.Drawing.Point(0, 0);
|
||||
this.txtInput.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.txtInput.Multiline = true;
|
||||
this.txtInput.Name = "txtInput";
|
||||
this.txtInput.Size = new System.Drawing.Size(200, 22);
|
||||
this.txtInput.TabIndex = 0;
|
||||
this.txtInput.Leave += new System.EventHandler(this.txtInput_Leave);
|
||||
//
|
||||
// btnOK
|
||||
//
|
||||
this.btnOK.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
this.btnOK.Location = new System.Drawing.Point(2, 2);
|
||||
this.btnOK.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.btnOK.Name = "btnOK";
|
||||
this.btnOK.Size = new System.Drawing.Size(2, 2);
|
||||
this.btnOK.TabIndex = 1;
|
||||
this.btnOK.TabStop = false;
|
||||
this.btnOK.Text = "OK";
|
||||
this.btnOK.UseVisualStyleBackColor = true;
|
||||
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
this.btnCancel.Location = new System.Drawing.Point(2, 2);
|
||||
this.btnCancel.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.btnCancel.Name = "btnCancel";
|
||||
this.btnCancel.Size = new System.Drawing.Size(2, 2);
|
||||
this.btnCancel.TabIndex = 2;
|
||||
this.btnCancel.TabStop = false;
|
||||
this.btnCancel.Text = "btnCancel";
|
||||
this.btnCancel.UseVisualStyleBackColor = true;
|
||||
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
|
||||
//
|
||||
// InputBox
|
||||
//
|
||||
this.AcceptButton = this.btnOK;
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
|
||||
this.AutoSize = true;
|
||||
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.CancelButton = this.btnCancel;
|
||||
this.ClientSize = new System.Drawing.Size(251, 42);
|
||||
this.Controls.Add(this.txtInput);
|
||||
this.Controls.Add(this.btnCancel);
|
||||
this.Controls.Add(this.btnOK);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.Name = "InputBox";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "InputBox";
|
||||
this.Deactivate += new System.EventHandler(this.InputBox_Deactivate);
|
||||
this.Load += new System.EventHandler(this.InputBox_Load);
|
||||
this.Shown += new System.EventHandler(this.InputBox_Shown);
|
||||
this.Leave += new System.EventHandler(this.InputBox_Leave);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox txtInput;
|
||||
private System.Windows.Forms.Button btnOK;
|
||||
private System.Windows.Forms.Button btnCancel;
|
||||
}
|
||||
}
|
323
Plugins/PluginInputText/InputBox.cs
Normal file
323
Plugins/PluginInputText/InputBox.cs
Normal file
@ -0,0 +1,323 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace InputText
|
||||
{
|
||||
public partial class InputBox : Form
|
||||
{
|
||||
public Rainmeter.Settings.InstanceSettings Instance = null;
|
||||
|
||||
#region Default form initializer
|
||||
public InputBox()
|
||||
{
|
||||
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).
|
||||
private void InputBox_Shown(object sender, EventArgs e)
|
||||
{
|
||||
this.Activate();
|
||||
this.BringToFront();
|
||||
this.Activate();
|
||||
this.BringToFront();
|
||||
this.txtInput.Focus();
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// However, if you wanted to log errors, a simple way would be to add something like
|
||||
// this:
|
||||
//
|
||||
// try
|
||||
// {
|
||||
// ... // code you are testing
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Rainmeter.Log(Rainmeter.LogLevel.Warning, "InputText :: exception :: " + ex.GetType().ToString() + ": " + ex.Message);
|
||||
// }
|
||||
|
||||
#region TextInput -- returns the inputted text
|
||||
public string TextInput
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.txtInput.Text.Trim();
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
#region ChangeFontFace(string) -- changes the text's font name
|
||||
public void ChangeFontFace(string sFont)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.txtInput.Font = new Font(sFont, this.txtInput.Font.Size);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeFontColor(string) -- changes the font's color, supports 6 and 8-digit hex or a series of 3 or 4 comma-separated numbers
|
||||
public void ChangeFontColor(string sColor)
|
||||
{
|
||||
try
|
||||
{
|
||||
sColor = sColor.Trim();
|
||||
|
||||
if (sColor.Contains(",")) // #,#,# or #,#,#,# format
|
||||
{
|
||||
string[] sParts = sColor.Trim().Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.None);
|
||||
this.txtInput.ForeColor = Color.FromArgb(int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2]));
|
||||
this.txtInput.ForeColor = Color.FromArgb(int.Parse(sParts[3]), int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sColor.Length == 6) // 6-digit hex (no alpha transparency)
|
||||
{
|
||||
uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber);
|
||||
// Since it was omitted, force full opacity (not transparent at all)
|
||||
this.txtInput.ForeColor = Color.FromArgb((int)(0xFF000000 | iColor));
|
||||
}
|
||||
else if (sColor.Length == 8) // 8-digit hex (with alpha transparency)
|
||||
{
|
||||
uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber);
|
||||
// This swaps RRGGBBAA for AARRGGBB, which Color.FromArgb() wants
|
||||
iColor = ((iColor & 0xFFFFFF00) >> 8) | ((iColor & 0x000000FF) << 24);
|
||||
this.txtInput.ForeColor = Color.FromArgb((int)iColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeBackColor(string) -- changes the background color, supports 6 and 8-digit hex or a series of 3 or 4 comma-separated numbers
|
||||
public void ChangeBackColor(string sColor)
|
||||
{
|
||||
try
|
||||
{
|
||||
sColor = sColor.Trim();
|
||||
|
||||
if (sColor.Contains(",")) // #,#,# or #,#,#,# format
|
||||
{
|
||||
string[] sParts = sColor.Trim().Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.None);
|
||||
this.txtInput.BackColor = Color.FromArgb(int.Parse(sParts[0]), int.Parse(sParts[1]), int.Parse(sParts[2]));
|
||||
|
||||
// Change 0-255 transparency to a 0.0-1.0 transparency range
|
||||
double dTrans = (double)int.Parse(sParts[3]);
|
||||
dTrans /= 255.0;
|
||||
this.Opacity = dTrans;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sColor.Length == 6) // 6-digit hex (no alpha transparency)
|
||||
{
|
||||
uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber);
|
||||
this.txtInput.BackColor = Color.FromArgb((int)(0xFF000000 | iColor));
|
||||
// Since it was omitted, force full opacity (not transparent at all)
|
||||
this.Opacity = 1.0;
|
||||
}
|
||||
else if (sColor.Length == 8) // 8-digit hex (with alpha transparency)
|
||||
{
|
||||
uint iColor = uint.Parse(sColor, System.Globalization.NumberStyles.HexNumber);
|
||||
// This swaps RRGGBBAA for AARRGGBB, which Color.FromArgb() wants
|
||||
iColor = ((iColor & 0xFFFFFF00) >> 8) | ((iColor & 0x000000FF) << 24);
|
||||
this.txtInput.BackColor = Color.FromArgb((int)((0xFF000000) | (0x00FFFFFF & iColor)));
|
||||
|
||||
// Change 0-255 transparency to a 0.0-1.0 transparency range
|
||||
double dTrans = (double)((iColor & 0xFF000000) >> 24);
|
||||
dTrans /= 255.0;
|
||||
this.Opacity = dTrans;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeStringAlign(string) -- Changes text horizontal alignment
|
||||
public void ChangeStringAlign(string sAlign)
|
||||
{
|
||||
try
|
||||
{
|
||||
sAlign = sAlign.ToUpper().Trim();
|
||||
|
||||
if (sAlign == "LEFT")
|
||||
this.txtInput.TextAlign = HorizontalAlignment.Left;
|
||||
else if (sAlign == "CENTER")
|
||||
this.txtInput.TextAlign = HorizontalAlignment.Center;
|
||||
else if (sAlign == "RIGHT")
|
||||
this.txtInput.TextAlign = HorizontalAlignment.Right;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeFontSize(string) -- changes the font's point size (supports floating-point values)
|
||||
public void ChangeFontSize(string sSize)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.txtInput.Font = new Font(this.txtInput.Font.OriginalFontName, float.Parse(sSize));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region MakeTopmost() -- forces the form to have the 'Always On Top' property
|
||||
public void MakeTopmost()
|
||||
{
|
||||
this.TopMost = true;
|
||||
}
|
||||
#endregion
|
||||
#region MakePassword() -- causes the textbox to be password style
|
||||
public void MakePassword()
|
||||
{
|
||||
this.txtInput.PasswordChar = '*';
|
||||
}
|
||||
#endregion
|
||||
#region ChangeFontStringStyle() -- changes the font's bold/italic styles
|
||||
public void ChangeFontStringStyle(string sStyle)
|
||||
{
|
||||
try
|
||||
{
|
||||
sStyle = sStyle.ToUpper().Trim();
|
||||
|
||||
if (sStyle == "NORMAL")
|
||||
this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Regular);
|
||||
else if (sStyle == "BOLD")
|
||||
this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Bold);
|
||||
else if (sStyle == "ITALIC")
|
||||
this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Italic);
|
||||
else if (sStyle == "BOLDITALIC")
|
||||
this.txtInput.Font = new Font(this.txtInput.Font, FontStyle.Bold | FontStyle.Italic);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeW(string) -- changes the width of the input textbox
|
||||
public void ChangeW(string sWidth)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.txtInput.Width = int.Parse(sWidth);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region ChangeH(string) -- changes the height of the input textbox
|
||||
public void ChangeH(string sHeight)
|
||||
{
|
||||
try
|
||||
{
|
||||
this.txtInput.Height = int.Parse(sHeight);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#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)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If the position is changed, make sure the form's auto-location is disabled.
|
||||
if (this.StartPosition != FormStartPosition.Manual)
|
||||
this.StartPosition = FormStartPosition.Manual;
|
||||
|
||||
// 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);
|
||||
}
|
||||
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)
|
||||
{
|
||||
try
|
||||
{
|
||||
// If the position is changed, make sure the form's auto-location is disabled.
|
||||
if (this.StartPosition != FormStartPosition.Manual)
|
||||
this.StartPosition = FormStartPosition.Manual;
|
||||
|
||||
// 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));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
#endregion
|
||||
#region DefaultValue(string) -- sets the default text to appear in the input textbox
|
||||
public void DefaultValue(string val)
|
||||
{
|
||||
this.txtInput.Text = val;
|
||||
}
|
||||
#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;
|
||||
}
|
||||
|
||||
private void txtInput_Leave(object sender, EventArgs e)
|
||||
{
|
||||
if (this._FocusDismiss)
|
||||
{
|
||||
this.drBackup = DialogResult.Cancel;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void InputBox_Leave(object sender, EventArgs e)
|
||||
{
|
||||
if (this._FocusDismiss)
|
||||
{
|
||||
this.drBackup = DialogResult.Cancel;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void InputBox_Deactivate(object sender, EventArgs e)
|
||||
{
|
||||
if (this._FocusDismiss)
|
||||
{
|
||||
this.drBackup = DialogResult.Cancel;
|
||||
this.Close();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnOK_Click(object sender, EventArgs e)
|
||||
{
|
||||
_FocusDismiss = false;
|
||||
this.sTextValue = this.txtInput.Text.Trim();
|
||||
this.drBackup = DialogResult.OK;
|
||||
this.DialogResult = DialogResult.OK;
|
||||
this.Close();
|
||||
}
|
||||
|
||||
private void btnCancel_Click(object sender, EventArgs e)
|
||||
{
|
||||
_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();
|
||||
}
|
||||
}
|
||||
}
|
120
Plugins/PluginInputText/InputBox.resx
Normal file
120
Plugins/PluginInputText/InputBox.resx
Normal file
@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
173
Plugins/PluginInputText/Main.cs
Normal file
173
Plugins/PluginInputText/Main.cs
Normal file
@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using Rainmeter;
|
||||
|
||||
namespace InputText
|
||||
{
|
||||
public class Main
|
||||
{
|
||||
/// <summary>
|
||||
/// 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
|
||||
1.05,
|
||||
|
||||
// E-mail
|
||||
"psouza4@gmail.com",
|
||||
|
||||
// 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()
|
||||
{
|
||||
return Rainmeter.Version(Plugin.Version);
|
||||
}
|
||||
|
||||
[DllExport]
|
||||
public unsafe static char* GetPluginAuthor()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
Plugin.AddInstance(iniFile, section, id); // required: do not remove
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// You may add code here, if necessary
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
return 0;
|
||||
}
|
||||
|
||||
[DllExport]
|
||||
public static void Finalize(IntPtr instance, UInt32 id)
|
||||
{
|
||||
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 ***
|
||||
|
||||
|
||||
/// <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>
|
||||
/// 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'.
|
||||
return Rainmeter.String(new YourPlugin().GetString(Plugin, id));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#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));
|
||||
return;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dummy attribute to mark method as exported for DllExporter.exe.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DllExport : Attribute
|
||||
{
|
||||
public DllExport()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
476
Plugins/PluginInputText/PluginCode.cs
Normal file
476
Plugins/PluginInputText/PluginCode.cs
Normal file
@ -0,0 +1,476 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
// The bulk of your plugin's code belongs in this file.
|
||||
namespace InputText
|
||||
{
|
||||
class PluginCode
|
||||
{
|
||||
// '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)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public double Update2(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
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(" "))
|
||||
{
|
||||
// Assume that the parameter is the name of the variable
|
||||
string sVariableName = Command.Trim();
|
||||
|
||||
// Ask for input
|
||||
string sInput = GetUserInput(Instance);
|
||||
|
||||
// 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("\"", "\\\"") + "\"");
|
||||
|
||||
// Note that the skin needs DynamicVariables=1 in the measure's settings or the above
|
||||
// code will have no effect.
|
||||
return;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#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);
|
||||
|
||||
// If the first parameter is 'ExecuteBatch' (not case sensitive)...
|
||||
if (sParts[0].Trim().ToUpper() == "EXECUTEBATCH")
|
||||
{
|
||||
// ExecuteBatch tells this plugin to go through the measure's settings to look
|
||||
// for lines beginning with "Command" and executing Rainmeter bangs for each one.
|
||||
// If a line contains $UserInput$, then an input textbox is opened and command
|
||||
// execution pauses until the user enters text or dismisses the textbox. If the
|
||||
// textbox is dismissed (Escape key, for example), all processing ends, otherwise
|
||||
// it continues depending on the range of commands selected.
|
||||
//
|
||||
// Each "Command" line allows overriding all settings that the input textbox
|
||||
// supports, therefor some checking and substitution is performed, thus a
|
||||
// more complex parser has been implemented.
|
||||
//
|
||||
// ExecuteBatch expects this syntax:
|
||||
// ExecuteBatch [All|#|#-#]
|
||||
//
|
||||
// This allows Rainmeter to call the plugin to execute a range including:
|
||||
// All All commands in the measure
|
||||
// # Only a single command in the measure
|
||||
// #-# A specific range of commands in the measure
|
||||
|
||||
#region Determine range
|
||||
// Determine range. Default is 1 to 1,000,000,000, although if processing finds
|
||||
// that a requested line is blank, it will stop all processing (so 'All' will
|
||||
// only parse 14 lines if "Command15" does not exist or is blank).
|
||||
int iMin = 1;
|
||||
int iMax = 1000000000;
|
||||
try
|
||||
{
|
||||
if (sParts[1].Trim().ToUpper() != "ALL")
|
||||
{
|
||||
if (sParts[1].Contains("-"))
|
||||
{
|
||||
string[] sSubParts = sParts[1].Split(new string[] { "-" }, StringSplitOptions.None);
|
||||
iMin = int.Parse(sSubParts[0]);
|
||||
iMax = int.Parse(sSubParts[1]);
|
||||
}
|
||||
else
|
||||
iMin = iMax = int.Parse(sParts[1]);
|
||||
}
|
||||
}
|
||||
catch // handle all errors above
|
||||
{
|
||||
// Any error above will be ignored and the default range used instead.
|
||||
// This can occur if the measure asks to ExecuteBatch an invalid range
|
||||
// or the range could not be translated to an acceptable format.
|
||||
//
|
||||
// For example: ExecuteBatch asdf
|
||||
iMin = 1;
|
||||
iMax = 1000000000;
|
||||
}
|
||||
#endregion
|
||||
#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.
|
||||
for (int i = iMin; i <= iMax; i++)
|
||||
{
|
||||
// Read this command's line
|
||||
string sCurrentLine = Instance.INI_Value("Command" + i.ToString());
|
||||
|
||||
// If empty/non-existent, abort
|
||||
if (string.IsNullOrEmpty(sCurrentLine))
|
||||
break;
|
||||
|
||||
// Execute the line, but if there's a problem (error or they cancel the
|
||||
// input textbox), then abort
|
||||
if (!ExecuteLine(Instance, sCurrentLine))
|
||||
break;
|
||||
|
||||
// Continue to the next line, if there is any
|
||||
}
|
||||
#endregion
|
||||
return;
|
||||
}
|
||||
|
||||
// Unhandled command, log the message but otherwise do nothing
|
||||
Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Received command \"" + sParts[0].Trim() + "\", left unhandled");
|
||||
|
||||
#endregion
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#region This is all code custom to this plugin
|
||||
|
||||
#region Parse the current command line
|
||||
private bool ExecuteLine(Rainmeter.Settings.InstanceSettings Instance, string sLine)
|
||||
{
|
||||
// If this line contains a $UserInput$ token, then we need to do some extra
|
||||
// parsing
|
||||
if (sLine.ToUpper().Contains("$USERINPUT$"))
|
||||
{
|
||||
try
|
||||
{
|
||||
#region Handle in-line overrides
|
||||
// Create a blank list of overrides
|
||||
Dictionary<string, string> Overrides = new Dictionary<string, string>();
|
||||
|
||||
// Start looking for overridable settings and adjust the list accordingly,
|
||||
// stripping out settings from the line if they are discovered.
|
||||
//
|
||||
// The supporting TagData() function allows for whitespace if quotes are
|
||||
// used. For example:
|
||||
//
|
||||
// DefaultValue="hello there, how are you"
|
||||
sLine = ScanAndReplace(sLine, "DefaultValue", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "X", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "Y", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "W", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "H", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "StringStyle", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "StringAlign", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "FocusDismiss", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "FontColor", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "FontFace", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "SolidColor", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "Password", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "FontSize", ref Overrides);
|
||||
sLine = ScanAndReplace(sLine, "TopMost", ref Overrides);
|
||||
#endregion
|
||||
|
||||
// Get user input
|
||||
string sInput = GetUserInput(Instance, Overrides);
|
||||
if (sInput == null)
|
||||
{
|
||||
// Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Aborted, user cancelled text box");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Swap out the $UserInput$ token with what the user typed
|
||||
sLine = Replace(sLine, "$USERINPUT$", sInput);
|
||||
}
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
#endregion
|
||||
#region GetUserInput() -- creates an input textbox and handles all INI and override settings
|
||||
|
||||
private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
// No INI overrides provided, so create an empty list
|
||||
return GetUserInput(Instance, new Dictionary<string,string>());
|
||||
}
|
||||
private string GetUserInput(Rainmeter.Settings.InstanceSettings Instance, Dictionary<string,string> sOverrides)
|
||||
{
|
||||
// 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");
|
||||
|
||||
// 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"))
|
||||
{
|
||||
input.MakeFocusDismiss(sOverrides["FocusDismiss"] == "1");
|
||||
bFocusDismiss = sOverrides["FocusDismiss"] == "1";
|
||||
}
|
||||
else
|
||||
{
|
||||
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")
|
||||
{
|
||||
input.MakeTopmost();
|
||||
bAutoTopMost = false;
|
||||
}
|
||||
else if (sOverrides["TopMost"] == "0")
|
||||
bAutoTopMost = false;
|
||||
}
|
||||
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());
|
||||
|
||||
#endregion
|
||||
|
||||
if (bFocusDismiss)
|
||||
{
|
||||
input.Show(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
|
||||
|
||||
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
|
||||
{
|
||||
input.ShowDialog(new WindowWrapper(Rainmeter.GetConfigWindow(Instance)));
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
#region Replace() -- case-insensitive string replacement
|
||||
private static string Replace(string sIn, string sFind, string sReplace)
|
||||
{
|
||||
int iReplace = sIn.ToUpper().IndexOf(sFind.ToUpper());
|
||||
|
||||
string sLineNew = string.Empty;
|
||||
|
||||
if (iReplace > 0)
|
||||
sLineNew += sIn.Substring(0, iReplace);
|
||||
sLineNew += sReplace;
|
||||
sLineNew += sIn.Substring(iReplace + (sFind.ToUpper()).Length);
|
||||
|
||||
return sLineNew;
|
||||
}
|
||||
private static string Replace(string sIn, int iStart, int iLength, string sReplace)
|
||||
{
|
||||
int iReplace = iStart;
|
||||
|
||||
string sLineNew = string.Empty;
|
||||
|
||||
if (iReplace > 0)
|
||||
sLineNew += sIn.Substring(0, iReplace);
|
||||
sLineNew += sReplace;
|
||||
sLineNew += sIn.Substring(iReplace + iLength);
|
||||
|
||||
return sLineNew;
|
||||
}
|
||||
#endregion
|
||||
#region TagLoc(), TagData(), FindTag() -- text parsing utilities for the override tags
|
||||
private int TagLoc(string sLine, string sTag)
|
||||
{
|
||||
if (!FindTag(sLine, sTag))
|
||||
return -1;
|
||||
|
||||
return sLine.ToUpper().IndexOf(" " + sTag.ToUpper() + "=") + 1;
|
||||
}
|
||||
|
||||
private string TagData(string sLine, string sTag)
|
||||
{
|
||||
if (!FindTag(sLine, sTag))
|
||||
return string.Empty;
|
||||
|
||||
int iStart = TagLoc(sLine, sTag) + sTag.Length + 1;
|
||||
|
||||
string sTagData = string.Empty;
|
||||
bool bInQuote = false;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
for (int i = 0; ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (sLine[i + iStart] == '"')
|
||||
{
|
||||
bInQuote = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sLine[i + iStart] == '"')
|
||||
break;
|
||||
|
||||
if (!bInQuote)
|
||||
if (char.IsWhiteSpace(sLine[i + iStart]))
|
||||
break;
|
||||
|
||||
sTagData += sLine[i + iStart];
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (bInQuote == true)
|
||||
return "\"" + sTagData + "\"";
|
||||
|
||||
return sTagData;
|
||||
}
|
||||
|
||||
private bool FindTag(string sLine, string sTag)
|
||||
{
|
||||
return (sLine.ToUpper().Contains(" " + sTag.ToUpper() + "="));
|
||||
}
|
||||
#endregion
|
||||
#region ScanAndReplace() -- searches for a tag and its value, adding it to overrides if found, and then removing it from the input line
|
||||
private string ScanAndReplace(string sLine, string sTagName, ref Dictionary<string, string> Overrides)
|
||||
{
|
||||
if (FindTag(sLine, sTagName))
|
||||
{
|
||||
string sTagData = TagData(sLine, sTagName);
|
||||
// Rainmeter.Log(Rainmeter.LogLevel.Debug, "InputText: Overriding " + sTagName + " with " + sTagData);
|
||||
if (sTagData.StartsWith("\""))
|
||||
Overrides.Add(sTagName, sTagData.Substring(1, sTagData.Length - 2));
|
||||
else
|
||||
Overrides.Add(sTagName, sTagData);
|
||||
sLine = Replace(sLine, TagLoc(sLine, sTagName) - 1, 1 + sTagName.Length + 1 + sTagData.Length, string.Empty);
|
||||
}
|
||||
|
||||
return sLine;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
114
Plugins/PluginInputText/PluginInputText.csproj
Normal file
114
Plugins/PluginInputText/PluginInputText.csproj
Normal file
@ -0,0 +1,114 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{2CFEC79A-E39E-4FFD-ABC2-C4A69DD1E44D}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Rainmeter</RootNamespace>
|
||||
<AssemblyName>InputText</AssemblyName>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<UpgradeBackupLocation />
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>$(SolutionDir)TestBench\x32\Debug\Plugins\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>1607</NoWarn>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>$(SolutionDir)TestBench\x32\Release\Plugins\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<NoWarn>1607</NoWarn>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>$(SolutionDir)TestBench\x64\Debug\Plugins\</OutputPath>
|
||||
<DefineConstants>TRACE;DEBUG;X64</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<NoWarn>1607</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
|
||||
<OutputPath>$(SolutionDir)TestBench\x64\Release\Plugins\</OutputPath>
|
||||
<DefineConstants>TRACE;X64</DefineConstants>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>none</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<NoWarn>1607</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<RunPostBuildEvent>OnOutputUpdated</RunPostBuildEvent>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AssemblyInfo.cs" />
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="PluginCode.cs" />
|
||||
<Compile Include="Rainmeter.cs" />
|
||||
<Compile Include="InputBox.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="InputBox.designer.cs">
|
||||
<DependentUpon>InputBox.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(SolutionDir)Version.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="InputBox.resx">
|
||||
<DependentUpon>InputBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
<PropertyGroup>
|
||||
<PostBuildEvent>"$(SolutionDir)Plugins\API\DllExporter.exe" "$(ConfigurationName)" "$(PlatformName)" "$(TargetDir)\" "$(TargetFileName)" "$(TargetedFrameworkDir)\ilasm.exe" "$(FrameworkSDKDir)bin\ildasm.exe"</PostBuildEvent>
|
||||
</PropertyGroup>
|
||||
</Project>
|
766
Plugins/PluginInputText/Rainmeter.cs
Normal file
766
Plugins/PluginInputText/Rainmeter.cs
Normal file
@ -0,0 +1,766 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
|
||||
// This is a utility class / toolkit for communicating with Rainmeter and managing
|
||||
// logging, INI settings, bangs, window positioning, multiple instances, and temporary
|
||||
// data storage.
|
||||
//
|
||||
// You should not need to edit this code except to expand the toolkit support.
|
||||
//
|
||||
// Rather, most of your plugin's code should go in PluginCode.cs or additional files
|
||||
// that you create (such as new forms, classes, and controls).
|
||||
namespace InputText
|
||||
{
|
||||
public class WindowWrapper : System.Windows.Forms.IWin32Window
|
||||
{
|
||||
public WindowWrapper(IntPtr handle)
|
||||
{
|
||||
_hwnd = handle;
|
||||
}
|
||||
|
||||
public IntPtr Handle
|
||||
{
|
||||
get { return _hwnd; }
|
||||
}
|
||||
|
||||
private IntPtr _hwnd;
|
||||
}
|
||||
|
||||
public class Rainmeter
|
||||
{
|
||||
#region Methods for getting the screen-relative location of the current skin
|
||||
|
||||
public static IntPtr GetConfigWindow(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
return (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
}
|
||||
public static int ConfigX(string sSkin)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Left;
|
||||
}
|
||||
public static int ConfigX(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Left;
|
||||
}
|
||||
|
||||
public static int ConfigY(string sSkin)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Top;
|
||||
}
|
||||
public static int ConfigY(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Top;
|
||||
}
|
||||
|
||||
public static int ConfigWidth(string sSkin)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Right - rct.Left;
|
||||
}
|
||||
public static int ConfigWidth(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Right - rct.Left;
|
||||
}
|
||||
|
||||
public static int ConfigHeight(string sSkin)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", sSkin)));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + sSkin + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Bottom - rct.Top;
|
||||
}
|
||||
public static int ConfigHeight(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
RECT rct;
|
||||
if (!GetWindowRect(hwnd, out rct))
|
||||
{
|
||||
Rainmeter.Log(LogLevel.Error, "Rainmeter told us the HWND for window '" + Rainmeter.PluginBridge("GetConfig", Instance.INI_File) + "' is " + hwnd.ToInt32().ToString() + "L, but couldn't receive a proper RECT from it");
|
||||
return 0;
|
||||
}
|
||||
return rct.Bottom - rct.Top;
|
||||
}
|
||||
|
||||
#region GetWindowRect() platform invoke to get the size/location of a window
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetWindowRect(IntPtr hwnd, out RECT lpRect);
|
||||
|
||||
#endregion
|
||||
#region GetParent() platform invoke to get the handle of a parent window
|
||||
|
||||
[DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr GetParent(IntPtr hWnd);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT
|
||||
{
|
||||
public int Left; // x position of upper-left corner
|
||||
public int Top; // y position of upper-left corner
|
||||
public int Right; // x position of lower-right corner
|
||||
public int Bottom; // y position of lower-right corner
|
||||
}
|
||||
#endregion
|
||||
#region SendMessage -- SendMessage (this variant is only for WM_COPYSTRUCT messages)
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
struct COPYDATASTRUCT
|
||||
{
|
||||
public UInt32 dwData;
|
||||
public int cbData;
|
||||
public IntPtr lpData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region FindWindowByClass -- platform invoke to find a window given a class name
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
|
||||
private static extern IntPtr FindWindowByClass(string lpClassName, IntPtr ZeroOnly);
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetWindowInfo -- platform invoke to check a window's Z-order (Topmost=Auto)
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetWindowInfo(IntPtr hwnd, ref WINDOWINFO pwi);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct WINDOWINFO
|
||||
{
|
||||
public uint cbSize;
|
||||
public RECT rcWindow;
|
||||
public RECT rcClient;
|
||||
public uint dwStyle;
|
||||
public uint dwExStyle;
|
||||
public uint dwWindowStatus;
|
||||
public uint cxWindowBorders;
|
||||
public uint cyWindowBorders;
|
||||
public ushort atomWindowType;
|
||||
public ushort wCreatorVersion;
|
||||
|
||||
public WINDOWINFO(Boolean? filler)
|
||||
: this() // Allows automatic initialization of "cbSize" with "new WINDOWINFO(null/true/false)".
|
||||
{
|
||||
cbSize = (UInt32)(Marshal.SizeOf(typeof(WINDOWINFO)));
|
||||
}
|
||||
}
|
||||
|
||||
// Call this function to determine if the parent skin is topmost
|
||||
public static bool ParentIsTopmost(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
IntPtr hwnd = (IntPtr)(UInt32.Parse(Rainmeter.PluginBridge("GetWindow", Rainmeter.PluginBridge("GetConfig", Instance.INI_File))));
|
||||
WINDOWINFO info = new WINDOWINFO(true);
|
||||
GetWindowInfo(hwnd, ref info);
|
||||
return ((info.dwExStyle & 0x00000008L) > 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
#region SkinName -- gets the current skin name
|
||||
|
||||
public static string SkinName(Rainmeter.Settings.InstanceSettings Instance)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Instance.ConfigName;
|
||||
/*
|
||||
if (Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString() == string.Empty)
|
||||
{
|
||||
string sAppDataPath = System.Environment.GetEnvironmentVariable("AppData").Trim();
|
||||
string sRainmeterINIText = System.IO.File.ReadAllText(sAppDataPath + "\\Rainmeter\\Rainmeter.ini");
|
||||
string sSkinPath = Chopper(sRainmeterINIText.Replace('\n', '\r'), "SkinPath=", "\r").Trim().TrimEnd(new char[] { '\\' });
|
||||
Instance.SetTempValue("_internal_SkinPath", sSkinPath);
|
||||
}
|
||||
|
||||
System.IO.FileInfo fi = new System.IO.FileInfo(Instance.INI_File);
|
||||
return fi.DirectoryName.Replace(Instance.GetTempValue("_internal_SkinPath", string.Empty).ToString(), string.Empty).TrimEnd(new char[] { '\\' }).TrimStart(new char[] { '\\' });
|
||||
*/
|
||||
}
|
||||
catch { }
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region Chopper -- string manipulation
|
||||
|
||||
public static string Chopper(string sText, string sSearch, string sEnd, int offset)
|
||||
{
|
||||
string sIntermediate = "";
|
||||
|
||||
try
|
||||
{
|
||||
if ((sSearch == null) || (sSearch == string.Empty))
|
||||
{
|
||||
sIntermediate = sText.Substring(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sText.Contains(sSearch) == false)
|
||||
return sText;
|
||||
|
||||
sIntermediate = sText.Substring(sText.IndexOf(sSearch) + sSearch.Length + offset);
|
||||
}
|
||||
|
||||
if ((sEnd == null) || (sEnd == string.Empty))
|
||||
return sIntermediate;
|
||||
|
||||
if (sIntermediate.Contains(sEnd) == false)
|
||||
return sIntermediate;
|
||||
|
||||
return sIntermediate.Substring(0, sIntermediate.IndexOf(sEnd));
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (sIntermediate == "")
|
||||
return sText;
|
||||
return sIntermediate;
|
||||
}
|
||||
}
|
||||
|
||||
public static string Chopper(string sText, string sSearch, string sEnd)
|
||||
{
|
||||
return Chopper(sText, sSearch, sEnd, 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Version helpers (converts "1.04" or "1, 4" to 1004, etc.)
|
||||
|
||||
public static UInt32 Version(double dVersion)
|
||||
{
|
||||
return (UInt32)(dVersion * 1000.0);
|
||||
}
|
||||
|
||||
public static UInt32 Version(int iMajor, int iMinor)
|
||||
{
|
||||
return (UInt32)((iMajor * 1000) + iMinor);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Converts a C# 'string' to a C++ 'char *'
|
||||
public static unsafe char* String(string s)
|
||||
{
|
||||
fixed (char* p = s) return p;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Export for Rainmeter's new plugin bridge
|
||||
|
||||
[DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
|
||||
private extern static unsafe char* PluginBridge(char* sCommand, char* sData);
|
||||
|
||||
private unsafe static string PluginBridge(string sCommand, string sData)
|
||||
{
|
||||
try
|
||||
{
|
||||
return new string(PluginBridge(Rainmeter.String(sCommand), Rainmeter.String(sData)));
|
||||
}
|
||||
catch { }
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Read INI values using Rainmeter's 'ReadConfigString' export
|
||||
|
||||
// We have to use this method rather than loading the .INI file manually because Rainmeter will
|
||||
// replace tokens for us. See: http://rainmeter.net/RainCMS/?q=Settings_BuiltInVariables
|
||||
//
|
||||
// Please note that this is done during plugin initialization and stored in the Instance
|
||||
// variable. This is done automatically, so this function should not be used by plugin developers
|
||||
// directly, therefore the methods here are 'private'.
|
||||
|
||||
[DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
|
||||
private extern static unsafe char* ReadConfigString(char* sSection, char* key, char* defValue);
|
||||
|
||||
// If an INI is missing, a blank string will be returned to avoid raising exceptions
|
||||
private unsafe static string ReadConfigString(string sSection, string sKey)
|
||||
{
|
||||
try
|
||||
{
|
||||
char* szString = ReadConfigString(Rainmeter.String(sSection), Rainmeter.String(sKey), Rainmeter.String(string.Empty));
|
||||
|
||||
if (szString != null)
|
||||
return new string(szString);
|
||||
}
|
||||
catch { }
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Use Rainmeter's 'LSLog' export to log using its format and settings
|
||||
|
||||
[DllImport("Rainmeter.dll", CharSet = CharSet.Auto)]
|
||||
private extern static unsafe UInt16 LSLog(int nLevel, char* pszModule, char* pszMessage);
|
||||
public enum LogLevel : int
|
||||
{
|
||||
Error = 1,
|
||||
Warning = 2,
|
||||
Notice = 3,
|
||||
Debug = 4
|
||||
}
|
||||
|
||||
// You can call this function directly to log to Rainmeter.log
|
||||
//
|
||||
// Rainmeter needs to be configured to allow debug logging, of course.
|
||||
|
||||
public static unsafe bool Log(LogLevel level, string sText)
|
||||
{
|
||||
return (Rainmeter.LSLog((int)level, Rainmeter.String("C# plugin"), Rainmeter.String(sText)) != 0);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Send a bang to Rainmeter (prepends a '!' if necessary)
|
||||
public static void Bang(string sBang)
|
||||
{
|
||||
if (!sBang.StartsWith("!"))
|
||||
sBang = "!" + 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)
|
||||
{
|
||||
UpdateThread thread_details = new UpdateThread(Plugin.Instances[id]);
|
||||
Thread thread = new Thread(new ThreadStart(thread_details.Go));
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return (UInt32)Plugin.Instances[id].GetTempValue("__RMT_U_LastValue", 0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateThread
|
||||
{
|
||||
private Rainmeter.Settings.InstanceSettings Instance = null;
|
||||
|
||||
public UpdateThread(Rainmeter.Settings.InstanceSettings _Instance)
|
||||
{
|
||||
this.Instance = _Instance;
|
||||
}
|
||||
|
||||
public void Go()
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_U_AlreadyRunning", true);
|
||||
|
||||
try
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_U_LastValue", new PluginCode().Update(this.Instance));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message);
|
||||
}
|
||||
|
||||
this.Instance.SetTempValue("__RMT_U_AlreadyRunning", false);
|
||||
}
|
||||
}
|
||||
|
||||
public double Update2(Rainmeter.Settings Plugin, UInt32 id)
|
||||
{
|
||||
bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_U2_AlreadyRunning", false);
|
||||
if (!bAlreadyRunning)
|
||||
{
|
||||
Update2Thread thread_details = new Update2Thread(Plugin.Instances[id]);
|
||||
Thread thread = new Thread(new ThreadStart(thread_details.Go));
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return (double)Plugin.Instances[id].GetTempValue("__RMT_U2_LastValue", 0.0);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
private class Update2Thread
|
||||
{
|
||||
private Rainmeter.Settings.InstanceSettings Instance = null;
|
||||
|
||||
public Update2Thread(Rainmeter.Settings.InstanceSettings _Instance)
|
||||
{
|
||||
this.Instance = _Instance;
|
||||
}
|
||||
|
||||
public void Go()
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_U2_AlreadyRunning", true);
|
||||
|
||||
try
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_U2_LastValue", new PluginCode().Update2(this.Instance));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message);
|
||||
}
|
||||
|
||||
this.Instance.SetTempValue("__RMT_U2_AlreadyRunning", false);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetString(Rainmeter.Settings Plugin, UInt32 id)
|
||||
{
|
||||
bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_GS_AlreadyRunning", false);
|
||||
if (!bAlreadyRunning)
|
||||
{
|
||||
GetStringThread thread_details = new GetStringThread(Plugin.Instances[id]);
|
||||
Thread thread = new Thread(new ThreadStart(thread_details.Go));
|
||||
thread.Start();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return (string)Plugin.Instances[id].GetTempValue("__RMT_GS_LastValue", string.Empty);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private class GetStringThread
|
||||
{
|
||||
private Rainmeter.Settings.InstanceSettings Instance = null;
|
||||
|
||||
public GetStringThread(Rainmeter.Settings.InstanceSettings _Instance)
|
||||
{
|
||||
this.Instance = _Instance;
|
||||
}
|
||||
|
||||
public void Go()
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_GS_AlreadyRunning", true);
|
||||
|
||||
try
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_GS_LastValue", new PluginCode().GetString(this.Instance));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message);
|
||||
}
|
||||
|
||||
this.Instance.SetTempValue("__RMT_GS_AlreadyRunning", false);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExecuteBang(Rainmeter.Settings Plugin, UInt32 id, string sArguments)
|
||||
{
|
||||
bool bAlreadyRunning = (bool)Plugin.Instances[id].GetTempValue("__RMT_EB_AlreadyRunning", false);
|
||||
if (!bAlreadyRunning)
|
||||
{
|
||||
ExecuteBangThread thread_details = new ExecuteBangThread(Plugin.Instances[id], sArguments);
|
||||
Thread thread = new Thread(new ThreadStart(thread_details.Go));
|
||||
thread.Start();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
private class ExecuteBangThread
|
||||
{
|
||||
private Rainmeter.Settings.InstanceSettings Instance = null;
|
||||
private string Command = string.Empty;
|
||||
|
||||
public ExecuteBangThread(Rainmeter.Settings.InstanceSettings _Instance, string _Command)
|
||||
{
|
||||
this.Instance = _Instance;
|
||||
this.Command = _Command;
|
||||
}
|
||||
|
||||
public void Go()
|
||||
{
|
||||
this.Instance.SetTempValue("__RMT_EB_AlreadyRunning", true);
|
||||
|
||||
try
|
||||
{
|
||||
new PluginCode().ExecuteBang(this.Instance, this.Command);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Rainmeter.Log(Rainmeter.LogLevel.Error, "C# plugin in GetString(), " + ex.GetType().ToString() + ": " + ex.Message);
|
||||
}
|
||||
|
||||
this.Instance.SetTempValue("__RMT_EB_AlreadyRunning", false);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user