initial build

This commit is contained in:
NinjaPug
2025-04-12 13:15:42 -04:00
parent ba8d1fbd77
commit 76a6e93130
14 changed files with 1571 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
/bin
/obj

21
App.config Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="OledMonitor.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
<section name="OledMonitor.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<userSettings>
<OledMonitor.Settings>
<setting name="LastIconDirectory" serializeAs="String">
<value />
</setting>
</OledMonitor.Settings>
<OledMonitor.Properties.Settings>
<setting name="LastIconDirectory" serializeAs="String">
<value></value>
</setting>
</OledMonitor.Properties.Settings>
</userSettings>
</configuration>

317
IconBrowser.Designer.cs generated Normal file
View File

@@ -0,0 +1,317 @@
namespace OledMonitor
{
partial class IconBrowser
{
/// <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.panelTop = new System.Windows.Forms.Panel();
this.btnBrowse = new System.Windows.Forms.Button();
this.txtIconDirectory = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.panelBottom = new System.Windows.Forms.Panel();
this.txtIconDimensions = new System.Windows.Forms.TextBox();
this.label5 = new System.Windows.Forms.Label();
this.numY = new System.Windows.Forms.NumericUpDown();
this.numX = new System.Windows.Forms.NumericUpDown();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.txtIconName = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.btnCancel = new System.Windows.Forms.Button();
this.btnInsert = new System.Windows.Forms.Button();
this.lblStatus = new System.Windows.Forms.Label();
this.splitContainer = new System.Windows.Forms.SplitContainer();
this.lstIcons = new System.Windows.Forms.ListBox();
this.flowLayoutPanel = new System.Windows.Forms.FlowLayoutPanel();
this.panelTop.SuspendLayout();
this.panelBottom.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numY)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.numX)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
this.splitContainer.Panel1.SuspendLayout();
this.splitContainer.Panel2.SuspendLayout();
this.splitContainer.SuspendLayout();
this.SuspendLayout();
//
// panelTop
//
this.panelTop.Controls.Add(this.btnBrowse);
this.panelTop.Controls.Add(this.txtIconDirectory);
this.panelTop.Controls.Add(this.label1);
this.panelTop.Dock = System.Windows.Forms.DockStyle.Top;
this.panelTop.Location = new System.Drawing.Point(0, 0);
this.panelTop.Name = "panelTop";
this.panelTop.Size = new System.Drawing.Size(584, 40);
this.panelTop.TabIndex = 0;
//
// btnBrowse
//
this.btnBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.btnBrowse.Location = new System.Drawing.Point(497, 9);
this.btnBrowse.Name = "btnBrowse";
this.btnBrowse.Size = new System.Drawing.Size(75, 23);
this.btnBrowse.TabIndex = 2;
this.btnBrowse.Text = "Browse...";
this.btnBrowse.UseVisualStyleBackColor = true;
this.btnBrowse.Click += new System.EventHandler(this.btnBrowse_Click);
//
// txtIconDirectory
//
this.txtIconDirectory.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.txtIconDirectory.Location = new System.Drawing.Point(119, 10);
this.txtIconDirectory.Name = "txtIconDirectory";
this.txtIconDirectory.Size = new System.Drawing.Size(372, 23);
this.txtIconDirectory.TabIndex = 1;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(12, 13);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(101, 15);
this.label1.TabIndex = 0;
this.label1.Text = "Icons Directory:";
//
// panelBottom
//
this.panelBottom.Controls.Add(this.txtIconDimensions);
this.panelBottom.Controls.Add(this.label5);
this.panelBottom.Controls.Add(this.numY);
this.panelBottom.Controls.Add(this.numX);
this.panelBottom.Controls.Add(this.label4);
this.panelBottom.Controls.Add(this.label3);
this.panelBottom.Controls.Add(this.txtIconName);
this.panelBottom.Controls.Add(this.label2);
this.panelBottom.Controls.Add(this.btnCancel);
this.panelBottom.Controls.Add(this.btnInsert);
this.panelBottom.Controls.Add(this.lblStatus);
this.panelBottom.Dock = System.Windows.Forms.DockStyle.Bottom;
this.panelBottom.Location = new System.Drawing.Point(0, 341);
this.panelBottom.Name = "panelBottom";
this.panelBottom.Size = new System.Drawing.Size(584, 120);
this.panelBottom.TabIndex = 1;
//
// txtIconDimensions
//
this.txtIconDimensions.Location = new System.Drawing.Point(119, 39);
this.txtIconDimensions.Name = "txtIconDimensions";
this.txtIconDimensions.ReadOnly = true;
this.txtIconDimensions.Size = new System.Drawing.Size(100, 23);
this.txtIconDimensions.TabIndex = 10;
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(12, 42);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(77, 15);
this.label5.TabIndex = 9;
this.label5.Text = "Dimensions:";
//
// numY
//
this.numY.Location = new System.Drawing.Point(119, 82);
this.numY.Maximum = new decimal(new int[] {
200,
0,
0,
0});
this.numY.Name = "numY";
this.numY.Size = new System.Drawing.Size(60, 23);
this.numY.TabIndex = 8;
//
// numX
//
this.numX.Location = new System.Drawing.Point(119, 68);
this.numX.Maximum = new decimal(new int[] {
200,
0,
0,
0});
this.numX.Name = "numX";
this.numX.Size = new System.Drawing.Size(60, 23);
this.numX.TabIndex = 7;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(12, 84);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(67, 15);
this.label4.TabIndex = 6;
this.label4.Text = "Y Position:";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(12, 70);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(67, 15);
this.label3.TabIndex = 5;
this.label3.Text = "X Position:";
//
// txtIconName
//
this.txtIconName.Location = new System.Drawing.Point(119, 10);
this.txtIconName.Name = "txtIconName";
this.txtIconName.ReadOnly = true;
this.txtIconName.Size = new System.Drawing.Size(200, 23);
this.txtIconName.TabIndex = 4;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(12, 13);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(101, 15);
this.label2.TabIndex = 3;
this.label2.Text = "Selected Icon:";
//
// btnCancel
//
this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnCancel.Location = new System.Drawing.Point(497, 85);
this.btnCancel.Name = "btnCancel";
this.btnCancel.Size = new System.Drawing.Size(75, 23);
this.btnCancel.TabIndex = 2;
this.btnCancel.Text = "Cancel";
this.btnCancel.UseVisualStyleBackColor = true;
this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
//
// btnInsert
//
this.btnInsert.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnInsert.Location = new System.Drawing.Point(416, 85);
this.btnInsert.Name = "btnInsert";
this.btnInsert.Size = new System.Drawing.Size(75, 23);
this.btnInsert.TabIndex = 1;
this.btnInsert.Text = "Insert";
this.btnInsert.UseVisualStyleBackColor = true;
this.btnInsert.Click += new System.EventHandler(this.btnInsert_Click);
//
// lblStatus
//
this.lblStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.lblStatus.AutoSize = true;
this.lblStatus.Location = new System.Drawing.Point(325, 13);
this.lblStatus.Name = "lblStatus";
this.lblStatus.Size = new System.Drawing.Size(0, 15);
this.lblStatus.TabIndex = 0;
//
// splitContainer
//
this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer.Location = new System.Drawing.Point(0, 40);
this.splitContainer.Name = "splitContainer";
//
// splitContainer.Panel1
//
this.splitContainer.Panel1.Controls.Add(this.lstIcons);
this.splitContainer.Panel1Collapsed = true;
this.splitContainer.Panel1MinSize = 0;
//
// splitContainer.Panel2
//
this.splitContainer.Panel2.Controls.Add(this.flowLayoutPanel);
this.splitContainer.Size = new System.Drawing.Size(584, 301);
this.splitContainer.SplitterDistance = 194;
this.splitContainer.TabIndex = 2;
//
// lstIcons
//
this.lstIcons.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstIcons.FormattingEnabled = true;
this.lstIcons.ItemHeight = 15;
this.lstIcons.Location = new System.Drawing.Point(0, 0);
this.lstIcons.Name = "lstIcons";
this.lstIcons.Size = new System.Drawing.Size(194, 301);
this.lstIcons.TabIndex = 0;
//
// flowLayoutPanel
//
this.flowLayoutPanel.AutoScroll = true;
this.flowLayoutPanel.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.flowLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel.Name = "flowLayoutPanel";
this.flowLayoutPanel.Padding = new System.Windows.Forms.Padding(10);
this.flowLayoutPanel.Size = new System.Drawing.Size(584, 301);
this.flowLayoutPanel.TabIndex = 0;
//
// IconBrowser
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(584, 461);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.panelBottom);
this.Controls.Add(this.panelTop);
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(400, 400);
this.Name = "IconBrowser";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Icon Browser";
this.Load += new System.EventHandler(this.IconBrowser_Load);
this.panelTop.ResumeLayout(false);
this.panelTop.PerformLayout();
this.panelBottom.ResumeLayout(false);
this.panelBottom.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numY)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.numX)).EndInit();
this.splitContainer.Panel1.ResumeLayout(false);
this.splitContainer.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
this.splitContainer.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private Panel panelTop;
private Button btnBrowse;
private TextBox txtIconDirectory;
private Label label1;
private Panel panelBottom;
private Button btnCancel;
private Button btnInsert;
private Label lblStatus;
private SplitContainer splitContainer;
private ListBox lstIcons;
private FlowLayoutPanel flowLayoutPanel;
private TextBox txtIconName;
private Label label2;
private NumericUpDown numY;
private NumericUpDown numX;
private Label label4;
private Label label3;
private TextBox txtIconDimensions;
private Label label5;
}
}

215
IconBrowser.cs Normal file
View File

@@ -0,0 +1,215 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace OledMonitor
{
public partial class IconBrowser : Form
{
private string _selectedIconPath = "";
private int _selectedIconWidth = 0;
private int _selectedIconHeight = 0;
public string SelectedIconName { get; private set; } = "";
public IconBrowser()
{
InitializeComponent();
}
private void IconBrowser_Load(object? sender, EventArgs e)
{
// Load last used directory from settings if available
string lastDir = Properties.Settings.Default.LastIconDirectory;
if (!string.IsNullOrEmpty(lastDir) && Directory.Exists(lastDir))
{
txtIconDirectory.Text = lastDir;
LoadIconsFromDirectory(lastDir);
}
}
private void btnBrowse_Click(object? sender, EventArgs e)
{
using FolderBrowserDialog dialog = new();
if (!string.IsNullOrEmpty(txtIconDirectory.Text) && Directory.Exists(txtIconDirectory.Text))
{
dialog.InitialDirectory = txtIconDirectory.Text;
}
if (dialog.ShowDialog() == DialogResult.OK)
{
txtIconDirectory.Text = dialog.SelectedPath;
LoadIconsFromDirectory(dialog.SelectedPath);
// Save the directory for next time
Properties.Settings.Default.LastIconDirectory = dialog.SelectedPath;
Properties.Settings.Default.Save();
}
}
private void LoadIconsFromDirectory(string directory)
{
try
{
lstIcons.Items.Clear();
flowLayoutPanel.Controls.Clear();
string[] xbmFiles = Directory.GetFiles(directory, "*.bin");
if (xbmFiles.Length == 0)
{
MessageBox.Show("No XBM icon files found in the selected directory.",
"No Icons Found", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
foreach (string file in xbmFiles)
{
// Create a button for each icon
Button iconButton = new();
// Parse the XBM file to get dimensions
(int width, int height) = ParseXbmDimensions(file);
string fileName = Path.GetFileNameWithoutExtension(file);
iconButton.Text = $"{fileName} ({width}x{height})";
iconButton.Tag = new IconInfo
{
Path = file,
Name = fileName,
Width = width,
Height = height
};
iconButton.Size = new Size(150, 40);
iconButton.Click += IconButton_Click;
flowLayoutPanel.Controls.Add(iconButton);
}
lblStatus.Text = $"Found {xbmFiles.Length} XBM files";
}
catch (Exception ex)
{
MessageBox.Show($"Error loading icons: {ex.Message}",
"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private (int width, int height) ParseXbmDimensions(string filePath)
{
int width = 0;
int height = 0;
try
{
// Read the first few lines of the XBM file
using StreamReader reader = new(filePath);
string line;
while ((line = reader.ReadLine()) != null && (width == 0 || height == 0))
{
// Look for width and height definitions in XBM format
if (line.Contains("_width"))
{
width = ExtractNumberFromLine(line);
}
else if (line.Contains("_height"))
{
height = ExtractNumberFromLine(line);
}
}
}
catch
{
// If we can't parse, default to unknown dimensions
width = 0;
height = 0;
}
return (width, height);
}
private int ExtractNumberFromLine(string line)
{
// Extract the numeric value from a line like "#define icon_width 16"
try
{
string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (parts.Length >= 3)
{
if (int.TryParse(parts[2], out int result))
{
return result;
}
}
}
catch { }
return 0;
}
private void IconButton_Click(object? sender, EventArgs e)
{
if (sender is Button button && button.Tag is IconInfo info)
{
// Highlight the selected button
foreach (Control control in flowLayoutPanel.Controls)
{
if (control is Button btn)
{
btn.BackColor = SystemColors.Control;
}
}
button.BackColor = Color.LightBlue;
// Store the selected icon info
SelectedIconName = info.Name;
_selectedIconPath = info.Path;
_selectedIconWidth = info.Width;
_selectedIconHeight = info.Height;
// Update UI
txtIconName.Text = info.Name;
txtIconDimensions.Text = $"{info.Width} x {info.Height}";
numX.Value = 0;
numY.Value = 0;
}
}
private void btnInsert_Click(object? sender, EventArgs e)
{
if (string.IsNullOrEmpty(SelectedIconName))
{
MessageBox.Show("Please select an icon first.",
"No Icon Selected", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
// Mark as success and close
DialogResult = DialogResult.OK;
Close();
}
private void btnCancel_Click(object? sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
public string GetIconMarkup()
{
if (string.IsNullOrEmpty(SelectedIconName))
return string.Empty;
return $"<icon x={numX.Value} y={numY.Value} name={SelectedIconName} />";
}
// Helper class for icon information
private class IconInfo
{
public string Path { get; set; } = "";
public string Name { get; set; } = "";
public int Width { get; set; }
public int Height { get; set; }
}
}
}

120
IconBrowser.resx Normal file
View 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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

337
MainForm.Designer.cs generated Normal file
View File

@@ -0,0 +1,337 @@
namespace OledMonitor
{
partial class MainForm
{
/// <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()
{
groupBoxConnection = new GroupBox();
lblStatus = new Label();
btnRefreshPorts = new Button();
btnConnect = new Button();
comboBoxPorts = new ComboBox();
label1 = new Label();
groupBoxMarkup = new GroupBox();
splitContainer1 = new SplitContainer();
txtMarkupEditor = new TextBox();
label3 = new Label();
txtHelpText = new TextBox();
label4 = new Label();
panelButtons = new Panel();
chkAutoUpdate = new CheckBox();
btnSendNow = new Button();
btnInsertIcon = new Button();
btnLoadExample = new Button();
btnRefreshSensors = new Button();
groupBoxPreview = new GroupBox();
txtMarkupPreview = new TextBox();
groupBoxConnection.SuspendLayout();
groupBoxMarkup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
splitContainer1.Panel1.SuspendLayout();
splitContainer1.Panel2.SuspendLayout();
splitContainer1.SuspendLayout();
panelButtons.SuspendLayout();
groupBoxPreview.SuspendLayout();
SuspendLayout();
//
// groupBoxConnection
//
groupBoxConnection.Controls.Add(lblStatus);
groupBoxConnection.Controls.Add(btnRefreshPorts);
groupBoxConnection.Controls.Add(btnConnect);
groupBoxConnection.Controls.Add(comboBoxPorts);
groupBoxConnection.Controls.Add(label1);
groupBoxConnection.Location = new Point(12, 12);
groupBoxConnection.Name = "groupBoxConnection";
groupBoxConnection.Size = new Size(351, 100);
groupBoxConnection.TabIndex = 0;
groupBoxConnection.TabStop = false;
groupBoxConnection.Text = "Connection";
//
// lblStatus
//
lblStatus.AutoSize = true;
lblStatus.Location = new Point(15, 73);
lblStatus.Name = "lblStatus";
lblStatus.Size = new Size(86, 15);
lblStatus.TabIndex = 4;
lblStatus.Text = "Not connected";
//
// btnRefreshPorts
//
btnRefreshPorts.Location = new Point(150, 38);
btnRefreshPorts.Name = "btnRefreshPorts";
btnRefreshPorts.Size = new Size(75, 23);
btnRefreshPorts.TabIndex = 3;
btnRefreshPorts.Text = "Refresh";
btnRefreshPorts.UseVisualStyleBackColor = true;
btnRefreshPorts.Click += btnRefreshPorts_Click;
//
// btnConnect
//
btnConnect.Location = new Point(242, 38);
btnConnect.Name = "btnConnect";
btnConnect.Size = new Size(89, 23);
btnConnect.TabIndex = 2;
btnConnect.Text = "Connect";
btnConnect.UseVisualStyleBackColor = true;
btnConnect.Click += btnConnect_Click;
//
// comboBoxPorts
//
comboBoxPorts.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxPorts.FormattingEnabled = true;
comboBoxPorts.Location = new Point(68, 39);
comboBoxPorts.Name = "comboBoxPorts";
comboBoxPorts.Size = new Size(76, 23);
comboBoxPorts.TabIndex = 1;
//
// label1
//
label1.AutoSize = true;
label1.Location = new Point(15, 42);
label1.Name = "label1";
label1.Size = new Size(63, 15);
label1.TabIndex = 0;
label1.Text = "COM Port:";
//
// groupBoxMarkup
//
groupBoxMarkup.Controls.Add(splitContainer1);
groupBoxMarkup.Controls.Add(panelButtons);
groupBoxMarkup.Location = new Point(12, 118);
groupBoxMarkup.Name = "groupBoxMarkup";
groupBoxMarkup.Size = new Size(776, 292);
groupBoxMarkup.TabIndex = 1;
groupBoxMarkup.TabStop = false;
groupBoxMarkup.Text = "Markup Editor";
//
// splitContainer1
//
splitContainer1.Dock = DockStyle.Fill;
splitContainer1.Location = new Point(3, 19);
splitContainer1.Name = "splitContainer1";
splitContainer1.Orientation = Orientation.Horizontal;
//
// splitContainer1.Panel1
//
splitContainer1.Panel1.Controls.Add(txtMarkupEditor);
splitContainer1.Panel1.Controls.Add(label3);
//
// splitContainer1.Panel2
//
splitContainer1.Panel2.Controls.Add(txtHelpText);
splitContainer1.Panel2.Controls.Add(label4);
splitContainer1.Size = new Size(770, 224);
splitContainer1.SplitterDistance = 110;
splitContainer1.TabIndex = 0;
//
// txtMarkupEditor
//
txtMarkupEditor.Dock = DockStyle.Fill;
txtMarkupEditor.Font = new Font("Consolas", 9.75F);
txtMarkupEditor.Location = new Point(0, 18);
txtMarkupEditor.Multiline = true;
txtMarkupEditor.Name = "txtMarkupEditor";
txtMarkupEditor.ScrollBars = ScrollBars.Vertical;
txtMarkupEditor.Size = new Size(770, 92);
txtMarkupEditor.TabIndex = 1;
//
// label3
//
label3.AutoSize = true;
label3.Dock = DockStyle.Top;
label3.Location = new Point(0, 0);
label3.Name = "label3";
label3.Padding = new Padding(0, 0, 0, 3);
label3.Size = new Size(577, 18);
label3.TabIndex = 0;
label3.Text = "Enter markup with optional {sensor_variables} (e.g., <text x=0 y=12 size=1>CPU: {CPU_Total_Load}%</text>)";
//
// txtHelpText
//
txtHelpText.Dock = DockStyle.Fill;
txtHelpText.Font = new Font("Consolas", 9F);
txtHelpText.Location = new Point(0, 18);
txtHelpText.Multiline = true;
txtHelpText.Name = "txtHelpText";
txtHelpText.ReadOnly = true;
txtHelpText.ScrollBars = ScrollBars.Vertical;
txtHelpText.Size = new Size(770, 92);
txtHelpText.TabIndex = 1;
//
// label4
//
label4.AutoSize = true;
label4.Dock = DockStyle.Top;
label4.Location = new Point(0, 0);
label4.Name = "label4";
label4.Padding = new Padding(0, 0, 0, 3);
label4.Size = new Size(144, 18);
label4.TabIndex = 0;
label4.Text = "Available sensor variables:";
//
// panelButtons
//
panelButtons.Controls.Add(chkAutoUpdate);
panelButtons.Controls.Add(btnSendNow);
panelButtons.Controls.Add(btnInsertIcon);
panelButtons.Controls.Add(btnLoadExample);
panelButtons.Controls.Add(btnRefreshSensors);
panelButtons.Dock = DockStyle.Bottom;
panelButtons.Location = new Point(3, 243);
panelButtons.Name = "panelButtons";
panelButtons.Size = new Size(770, 46);
panelButtons.TabIndex = 1;
//
// chkAutoUpdate
//
chkAutoUpdate.AutoSize = true;
chkAutoUpdate.Checked = true;
chkAutoUpdate.CheckState = CheckState.Checked;
chkAutoUpdate.Location = new Point(587, 15);
chkAutoUpdate.Name = "chkAutoUpdate";
chkAutoUpdate.Size = new Size(171, 19);
chkAutoUpdate.TabIndex = 3;
chkAutoUpdate.Text = "Auto-update display (1 sec)";
chkAutoUpdate.UseVisualStyleBackColor = true;
chkAutoUpdate.CheckedChanged += chkAutoUpdate_CheckedChanged;
//
// btnSendNow
//
btnSendNow.Location = new Point(483, 11);
btnSendNow.Name = "btnSendNow";
btnSendNow.Size = new Size(98, 26);
btnSendNow.TabIndex = 2;
btnSendNow.Text = "Send Now";
btnSendNow.UseVisualStyleBackColor = true;
btnSendNow.Click += btnSendNow_Click;
//
// btnInsertIcon
//
btnInsertIcon.Location = new Point(261, 11);
btnInsertIcon.Name = "btnInsertIcon";
btnInsertIcon.Size = new Size(123, 26);
btnInsertIcon.TabIndex = 4;
btnInsertIcon.Text = "Insert Icon";
btnInsertIcon.UseVisualStyleBackColor = true;
btnInsertIcon.Click += btnInsertIcon_Click;
//
// btnLoadExample
//
btnLoadExample.Location = new Point(132, 11);
btnLoadExample.Name = "btnLoadExample";
btnLoadExample.Size = new Size(123, 26);
btnLoadExample.TabIndex = 1;
btnLoadExample.Text = "Load Example";
btnLoadExample.UseVisualStyleBackColor = true;
btnLoadExample.Click += btnLoadExample_Click;
//
// btnRefreshSensors
//
btnRefreshSensors.Location = new Point(3, 11);
btnRefreshSensors.Name = "btnRefreshSensors";
btnRefreshSensors.Size = new Size(123, 26);
btnRefreshSensors.TabIndex = 0;
btnRefreshSensors.Text = "Refresh Sensors";
btnRefreshSensors.UseVisualStyleBackColor = true;
btnRefreshSensors.Click += btnRefreshSensors_Click;
//
// groupBoxPreview
//
groupBoxPreview.Controls.Add(txtMarkupPreview);
groupBoxPreview.Location = new Point(12, 416);
groupBoxPreview.Name = "groupBoxPreview";
groupBoxPreview.Size = new Size(776, 123);
groupBoxPreview.TabIndex = 2;
groupBoxPreview.TabStop = false;
groupBoxPreview.Text = "Markup Preview (sent to device)";
//
// txtMarkupPreview
//
txtMarkupPreview.Font = new Font("Consolas", 9F);
txtMarkupPreview.Location = new Point(14, 22);
txtMarkupPreview.Multiline = true;
txtMarkupPreview.Name = "txtMarkupPreview";
txtMarkupPreview.ReadOnly = true;
txtMarkupPreview.Size = new Size(756, 86);
txtMarkupPreview.TabIndex = 0;
//
// MainForm
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 551);
Controls.Add(groupBoxPreview);
Controls.Add(groupBoxMarkup);
Controls.Add(groupBoxConnection);
FormBorderStyle = FormBorderStyle.FixedSingle;
MaximizeBox = false;
Name = "MainForm";
StartPosition = FormStartPosition.CenterScreen;
Text = "OLED Hardware Monitor";
FormClosing += Form_FormClosing;
groupBoxConnection.ResumeLayout(false);
groupBoxConnection.PerformLayout();
groupBoxMarkup.ResumeLayout(false);
splitContainer1.Panel1.ResumeLayout(false);
splitContainer1.Panel1.PerformLayout();
splitContainer1.Panel2.ResumeLayout(false);
splitContainer1.Panel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)splitContainer1).EndInit();
splitContainer1.ResumeLayout(false);
panelButtons.ResumeLayout(false);
panelButtons.PerformLayout();
groupBoxPreview.ResumeLayout(false);
groupBoxPreview.PerformLayout();
ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBoxConnection;
private System.Windows.Forms.Label lblStatus;
private System.Windows.Forms.Button btnRefreshPorts;
private System.Windows.Forms.Button btnConnect;
private System.Windows.Forms.ComboBox comboBoxPorts;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.GroupBox groupBoxMarkup;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.Panel panelButtons;
private System.Windows.Forms.Button btnRefreshSensors;
private System.Windows.Forms.Button btnLoadExample;
private System.Windows.Forms.Button btnSendNow;
private System.Windows.Forms.CheckBox chkAutoUpdate;
private System.Windows.Forms.Button btnInsertIcon;
private System.Windows.Forms.TextBox txtMarkupEditor;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox txtHelpText;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.GroupBox groupBoxPreview;
private System.Windows.Forms.TextBox txtMarkupPreview;
}
}

299
MainForm.cs Normal file
View File

@@ -0,0 +1,299 @@
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Text;
using System.Windows.Forms;
using LibreHardwareMonitor.Hardware;
namespace OledMonitor
{
public partial class MainForm : Form
{
private readonly Computer _computer;
private SerialPort? _serialPort;
private readonly System.Windows.Forms.Timer _updateTimer = new();
private readonly Dictionary<string, float> _sensorValues = new();
private bool _autoUpdate = true;
public MainForm()
{
InitializeComponent();
// Initialize LibreHardwareMonitor
_computer = new Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsMemoryEnabled = true,
IsMotherboardEnabled = true,
IsControllerEnabled = false,
IsNetworkEnabled = false,
IsStorageEnabled = false
};
_computer.Open();
// Find available serial ports
RefreshComPorts();
// Setup timer for updates
_updateTimer.Interval = 1000; // 1 second updates
_updateTimer.Tick += UpdateTimer_Tick;
// Add sensor variable examples to help text
UpdateHelpText();
}
private void UpdateHelpText()
{
// Collect available sensors to show as examples
StringBuilder sb = new StringBuilder();
sb.AppendLine("Available sensor variables:");
sb.AppendLine();
// Update hardware readings
foreach (var hardware in _computer.Hardware)
{
hardware.Update();
foreach (var sensor in hardware.Sensors)
{
if (sensor.Value.HasValue &&
(sensor.SensorType == SensorType.Load ||
sensor.SensorType == SensorType.Temperature ||
sensor.SensorType == SensorType.Clock ||
sensor.SensorType == SensorType.Power))
{
string sensorId = GetSensorVariableName(hardware.Name, sensor.Name);
_sensorValues[sensorId] = sensor.Value.Value;
string unit = GetSensorUnit(sensor.SensorType);
sb.AppendLine($"{sensorId} = {sensor.Value.Value:F1}{unit}");
}
}
}
txtHelpText.Text = sb.ToString();
}
private string GetSensorVariableName(string hardwareName, string sensorName)
{
// Create a simplified and safe variable name
string name = $"{hardwareName}_{sensorName}"
.Replace(" ", "_")
.Replace("%", "Percent")
.Replace("#", "Num")
.Replace("/", "_")
.Replace("\\", "_")
.Replace("(", "")
.Replace(")", "")
.Replace(",", "");
return name;
}
private string GetSensorUnit(SensorType sensorType)
{
return sensorType switch
{
SensorType.Temperature => "°C",
SensorType.Load => "%",
SensorType.Clock => "MHz",
SensorType.Power => "W",
_ => ""
};
}
private void RefreshComPorts()
{
comboBoxPorts.Items.Clear();
foreach (string port in SerialPort.GetPortNames())
{
comboBoxPorts.Items.Add(port);
}
if (comboBoxPorts.Items.Count > 0)
comboBoxPorts.SelectedIndex = 0;
}
private void btnConnect_Click(object? sender, EventArgs e)
{
if (_serialPort != null && _serialPort.IsOpen)
{
DisconnectFromDevice();
btnConnect.Text = "Connect";
lblStatus.Text = "Disconnected";
_updateTimer.Stop();
}
else
{
try
{
string selectedPort = comboBoxPorts.SelectedItem?.ToString() ?? "";
if (string.IsNullOrEmpty(selectedPort))
{
MessageBox.Show("Please select a COM port.");
return;
}
_serialPort = new SerialPort(selectedPort, 115200);
_serialPort.Open();
btnConnect.Text = "Disconnect";
lblStatus.Text = $"Connected to {selectedPort}";
_updateTimer.Start();
// Send immediately after connecting
SendMarkupToDevice();
}
catch (Exception ex)
{
MessageBox.Show($"Error connecting to device: {ex.Message}");
}
}
}
private void DisconnectFromDevice()
{
if (_serialPort != null && _serialPort.IsOpen)
{
_serialPort.Close();
_serialPort.Dispose();
_serialPort = null;
}
}
private void UpdateTimer_Tick(object? sender, EventArgs e)
{
if (_serialPort == null || !_serialPort.IsOpen)
return;
// Update all hardware readings
UpdateSensorValues();
// If set to auto-update, send markup to device
if (_autoUpdate)
{
SendMarkupToDevice();
}
}
private void UpdateSensorValues()
{
// Update all hardware readings
foreach (var hardware in _computer.Hardware)
{
hardware.Update();
foreach (var sensor in hardware.Sensors)
{
if (sensor.Value.HasValue)
{
string sensorId = GetSensorVariableName(hardware.Name, sensor.Name);
_sensorValues[sensorId] = sensor.Value.Value;
}
}
}
}
private void SendMarkupToDevice()
{
if (_serialPort == null || !_serialPort.IsOpen)
return;
try
{
string markup = ProcessVariablesInMarkup(txtMarkupEditor.Text);
_serialPort.WriteLine(markup);
txtMarkupPreview.Text = markup;
}
catch (Exception ex)
{
lblStatus.Text = $"Error: {ex.Message}";
_updateTimer.Stop();
DisconnectFromDevice();
btnConnect.Text = "Connect";
}
}
private string ProcessVariablesInMarkup(string markup)
{
// Replace variables with actual values
foreach (var sensor in _sensorValues)
{
// Look for {variable} syntax in the markup
string variablePattern = $"{{{sensor.Key}}}";
// Format value based on type (integers vs decimals)
string formattedValue;
if (Math.Abs(sensor.Value - Math.Round(sensor.Value)) < 0.01)
{
formattedValue = $"{sensor.Value:F0}";
}
else
{
formattedValue = $"{sensor.Value:F1}";
}
markup = markup.Replace(variablePattern, formattedValue);
}
return markup;
}
private void btnRefreshPorts_Click(object? sender, EventArgs e)
{
RefreshComPorts();
}
private void btnRefreshSensors_Click(object? sender, EventArgs e)
{
UpdateSensorValues();
UpdateHelpText();
}
private void btnSendNow_Click(object? sender, EventArgs e)
{
UpdateSensorValues();
SendMarkupToDevice();
}
private void chkAutoUpdate_CheckedChanged(object? sender, EventArgs e)
{
_autoUpdate = chkAutoUpdate.Checked;
}
private void Form_FormClosing(object? sender, FormClosingEventArgs e)
{
_updateTimer.Stop();
DisconnectFromDevice();
_computer.Close();
}
private void btnLoadExample_Click(object? sender, EventArgs e)
{
txtMarkupEditor.Text =
"<text x=0 y=12 size=1>CPU: {CPU_Core_i7-6700K_Total_Load}%</text>" +
"<bar x=0 y=16 w=100 h=8 val={CPU_Core_i7-6700K_Total_Load} />" +
"<text x=0 y=32 size=1>GPU: {GPU_NVIDIA_GeForce_GTX_1080_Load_GPU_Core}%</text>" +
"<bar x=0 y=36 w=100 h=8 val={GPU_NVIDIA_GeForce_GTX_1080_Load_GPU_Core} />" +
"<text x=0 y=52 size=1>RAM: {Memory_Load}%</text>" +
"<bar x=0 y=56 w=100 h=8 val={Memory_Load} />";
}
private void btnInsertIcon_Click(object? sender, EventArgs e)
{
using IconBrowser browser = new();
if (browser.ShowDialog() == DialogResult.OK)
{
// Get the icon markup and insert it at the cursor position
string iconMarkup = browser.GetIconMarkup();
if (!string.IsNullOrEmpty(iconMarkup))
{
int selectionStart = txtMarkupEditor.SelectionStart;
txtMarkupEditor.Text = txtMarkupEditor.Text.Insert(selectionStart, iconMarkup);
txtMarkupEditor.SelectionStart = selectionStart + iconMarkup.Length;
txtMarkupEditor.Focus();
}
}
}
}
}

120
MainForm.resx Normal file
View 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=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

37
Oled test.csproj Normal file
View File

@@ -0,0 +1,37 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<RootNamespace>OledMonitor</RootNamespace>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!--<ApplicationIcon>Resources\app_icon.ico</ApplicationIcon>-->
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.3" />
<PackageReference Include="System.IO.Ports" Version="9.0.3" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
</ItemGroup>
<ItemGroup>
<Folder Include="Resources\" />
</ItemGroup>
</Project>

12
Oled test.csproj.user Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
<ItemGroup>
<Compile Update="IconBrowser.cs">
<SubType>Form</SubType>
</Compile>
<Compile Update="MainForm.cs">
<SubType>Form</SubType>
</Compile>
</ItemGroup>
</Project>

27
Oled test.sln Normal file
View File

@@ -0,0 +1,27 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.13.35828.75
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Oled test", "Oled test.csproj", "{14435653-939D-4F2C-ADA3-11C784DCAA81}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8EC462FD-D22E-90A8-E5CE-7E832BA40C5D}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{14435653-939D-4F2C-ADA3-11C784DCAA81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{14435653-939D-4F2C-ADA3-11C784DCAA81}.Debug|Any CPU.Build.0 = Debug|Any CPU
{14435653-939D-4F2C-ADA3-11C784DCAA81}.Release|Any CPU.ActiveCfg = Release|Any CPU
{14435653-939D-4F2C-ADA3-11C784DCAA81}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {407FAD6B-096D-4FC1-B6AD-9CCF9F09CAC9}
EndGlobalSection
EndGlobal

17
Program.cs Normal file
View File

@@ -0,0 +1,17 @@
namespace OledMonitor
{
internal static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
// To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
Application.Run(new MainForm());
}
}
}

38
Properties/Settings.Designer.cs generated Normal file
View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace OledMonitor.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.13.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string LastIconDirectory {
get {
return ((string)(this["LastIconDirectory"]));
}
set {
this["LastIconDirectory"] = value;
}
}
}
}

View File

@@ -0,0 +1,9 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="OledMonitor" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="LastIconDirectory" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>