From cd89f30f6d2d72729d92f20796731d963db7a13d Mon Sep 17 00:00:00 2001 From: CreepyCrafter24 <33260128+CreepyCrafter24@users.noreply.github.com> Date: Thu, 16 Jan 2020 19:50:31 +0100 Subject: [PATCH] Stuffs --- Misc/Misc.csproj | 3 + Misc/RotatingIndicator.cs | 153 +++++++++++++++++++ W32.Test/MainForm.Designer.cs | 82 +++++++--- W32.Test/MainForm.cs | 136 +++++++++-------- W32/DCDrawer/DCBuffered.cs | 8 +- W32/DCDrawer/DCUnbuffered.cs | 2 +- W32/DeskMan.cs | 48 +++--- W32/GenericExtensions.cs | 6 +- W32/Native/user32.cs | 23 +-- W32/Power.cs | 1 - W32/Privileges.cs | 10 +- W32/ScreenMan.cs | 3 +- W32/Wnd32.cs | 274 +++++++++++++++++++++++++--------- 13 files changed, 548 insertions(+), 201 deletions(-) create mode 100644 Misc/RotatingIndicator.cs diff --git a/Misc/Misc.csproj b/Misc/Misc.csproj index ad7000d..ec5f059 100644 --- a/Misc/Misc.csproj +++ b/Misc/Misc.csproj @@ -61,6 +61,9 @@ + + Component + Form diff --git a/Misc/RotatingIndicator.cs b/Misc/RotatingIndicator.cs new file mode 100644 index 0000000..171f088 --- /dev/null +++ b/Misc/RotatingIndicator.cs @@ -0,0 +1,153 @@ +using System; +using System.ComponentModel; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Windows.Forms; +using Timer = System.Timers.Timer; + +namespace CC_Functions.Misc +{ + /// + /// Animated control similar to update screens in Windows 8 and 10 + /// + public sealed class RotatingIndicator : Control + { + private const double IndicatorOffset = Math.PI / 16; + private const int MaximumIndicators = 6; + private const int SizeFactor = 20; + private const double StartAt = (2 * Math.PI) / 3; + private const double TimerInterval = 100.0; + private readonly Indicator[] indicators = new Indicator[MaximumIndicators]; + private readonly Timer timer; + private int indicatorCenterRadius; + private int indicatorDiameter; + + /// + /// Instantiates the control + /// + public RotatingIndicator() + { + for (int i = 0; i < 6; i++) + indicators[i] = new Indicator(StartAt + (i * IndicatorOffset)); + SetStyle( + ControlStyles.DoubleBuffer | ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | + ControlStyles.SupportsTransparentBackColor, true); + UpdateStyles(); + ForeColorChanged += (sender, e) => Invalidate(); + SizeChanged += (sender, e) => + { + int indicatorRadius = (int) Math.Round(Height / (double) SizeFactor); + indicatorDiameter = 2 * indicatorRadius; + Height = SizeFactor * indicatorRadius; + Width = Height; + int outerRadius = Height / 2; + int innerRadius = outerRadius - indicatorDiameter; + indicatorCenterRadius = innerRadius + indicatorRadius; + Invalidate(); + }; + OnSizeChanged(null); + timer = new Timer(); + timer.Elapsed += (sender, e) => + { + try + { + if (InvokeRequired) + Invoke((Action) Refresh); + else Refresh(); + } + catch + { + // ignored + } + }; + timer.Interval = TimerInterval; + timer.Enabled = true; + } + + /// + /// Start/stops indicator animation + /// + [Category("Appearance")] + [Description("Start/stops indicator animation")] + [DefaultValue(true)] + [Bindable(true)] + public bool Animate + { + get => timer.Enabled; + set => timer.Enabled = value; + } + + /// + /// Specifies indicator rotational refresh + /// + [Category("Appearance")] + [Description("Specifies indicator rotational refresh")] + [DefaultValue(200)] + [Bindable(true)] + public double RefreshRate + { + get => timer.Interval; + set + { + timer.Interval = Math.Max(Math.Min(value, 200), 10); + Invalidate(); + } + } + + /// + /// Disposes used objects and the control itself + /// + /// + protected override void Dispose(bool disposing) + { + if (disposing) timer.Dispose(); + base.Dispose(disposing); + } + + /// + /// Paints the control and cycles the animation + /// + /// Arguments specifying the painting target + protected override void OnPaint(PaintEventArgs e) + { + GraphicsContainer state = e.Graphics.BeginContainer(); + e.Graphics.TranslateTransform(-Left, -Top); + Rectangle clip = e.ClipRectangle; + clip.Offset(Left, Top); + PaintEventArgs pea = new PaintEventArgs(e.Graphics, clip); + InvokePaintBackground(Parent, pea); + InvokePaint(Parent, pea); + e.Graphics.EndContainer(state); + e.Graphics.Clear(BackColor); + Brush brush = new SolidBrush(ForeColor); + for (int i = MaximumIndicators - 1; i >= 0; i--) + { + double degrees = indicators[i].Radians; + if (degrees < 0.0) + degrees += 2 * Math.PI; + int dx = (int) Math.Round(indicatorCenterRadius * Math.Cos(degrees)) + indicatorCenterRadius; + int dy = indicatorCenterRadius - (int) Math.Round(indicatorCenterRadius * Math.Sin(degrees)); + e.Graphics.FillEllipse(brush, + new Rectangle(new Point(dx, dy), new Size(indicatorDiameter, indicatorDiameter))); + degrees -= indicators[i].Speed * IndicatorOffset; + if (indicators[i].Speed > 1.0) indicators[i].Speed += 0.25; + if (degrees < 0.0) indicators[i].Speed = 1.25; + else if (degrees < StartAt) indicators[i].Speed = 1.0; + indicators[i].Radians = degrees; + } + brush.Dispose(); + } + } + + internal struct Indicator + { + public Indicator(double radians) + { + Radians = radians; + Speed = 1.0; + } + + public double Radians { get; set; } + public double Speed { get; set; } + } +} \ No newline at end of file diff --git a/W32.Test/MainForm.Designer.cs b/W32.Test/MainForm.Designer.cs index 87cd04f..4778182 100644 --- a/W32.Test/MainForm.Designer.cs +++ b/W32.Test/MainForm.Designer.cs @@ -160,8 +160,11 @@ // // wnd_action_pos_h_label // + this.wnd_action_pos_h_label.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); this.wnd_action_pos_h_label.AutoSize = true; - this.wnd_action_pos_h_label.Location = new System.Drawing.Point(135, 395); + this.wnd_action_pos_h_label.Location = new System.Drawing.Point(135, 284); this.wnd_action_pos_h_label.Name = "wnd_action_pos_h_label"; this.wnd_action_pos_h_label.Size = new System.Drawing.Size(19, 15); this.wnd_action_pos_h_label.TabIndex = 19; @@ -169,8 +172,11 @@ // // wnd_action_pos_w_label // + this.wnd_action_pos_w_label.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); this.wnd_action_pos_w_label.AutoSize = true; - this.wnd_action_pos_w_label.Location = new System.Drawing.Point(135, 367); + this.wnd_action_pos_w_label.Location = new System.Drawing.Point(135, 256); this.wnd_action_pos_w_label.Name = "wnd_action_pos_w_label"; this.wnd_action_pos_w_label.Size = new System.Drawing.Size(21, 15); this.wnd_action_pos_w_label.TabIndex = 18; @@ -178,22 +184,31 @@ // // wnd_action_pos_h_bar // - this.wnd_action_pos_h_bar.Location = new System.Drawing.Point(159, 395); + this.wnd_action_pos_h_bar.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); + this.wnd_action_pos_h_bar.Location = new System.Drawing.Point(159, 284); this.wnd_action_pos_h_bar.Name = "wnd_action_pos_h_bar"; this.wnd_action_pos_h_bar.Size = new System.Drawing.Size(121, 45); this.wnd_action_pos_h_bar.TabIndex = 21; // // wnd_action_pos_w_bar // - this.wnd_action_pos_w_bar.Location = new System.Drawing.Point(159, 367); + this.wnd_action_pos_w_bar.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); + this.wnd_action_pos_w_bar.Location = new System.Drawing.Point(159, 256); this.wnd_action_pos_w_bar.Name = "wnd_action_pos_w_bar"; this.wnd_action_pos_w_bar.Size = new System.Drawing.Size(121, 45); this.wnd_action_pos_w_bar.TabIndex = 20; // // wnd_action_pos_y_label // + this.wnd_action_pos_y_label.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); this.wnd_action_pos_y_label.AutoSize = true; - this.wnd_action_pos_y_label.Location = new System.Drawing.Point(7, 395); + this.wnd_action_pos_y_label.Location = new System.Drawing.Point(7, 284); this.wnd_action_pos_y_label.Name = "wnd_action_pos_y_label"; this.wnd_action_pos_y_label.Size = new System.Drawing.Size(17, 15); this.wnd_action_pos_y_label.TabIndex = 15; @@ -201,8 +216,11 @@ // // wnd_action_pos_x_label // + this.wnd_action_pos_x_label.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); this.wnd_action_pos_x_label.AutoSize = true; - this.wnd_action_pos_x_label.Location = new System.Drawing.Point(7, 367); + this.wnd_action_pos_x_label.Location = new System.Drawing.Point(7, 256); this.wnd_action_pos_x_label.Name = "wnd_action_pos_x_label"; this.wnd_action_pos_x_label.Size = new System.Drawing.Size(17, 15); this.wnd_action_pos_x_label.TabIndex = 13; @@ -210,21 +228,28 @@ // // wnd_action_pos_y_bar // - this.wnd_action_pos_y_bar.Location = new System.Drawing.Point(20, 395); + this.wnd_action_pos_y_bar.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); + this.wnd_action_pos_y_bar.Location = new System.Drawing.Point(20, 284); this.wnd_action_pos_y_bar.Name = "wnd_action_pos_y_bar"; this.wnd_action_pos_y_bar.Size = new System.Drawing.Size(121, 45); this.wnd_action_pos_y_bar.TabIndex = 17; // // wnd_action_pos_x_bar // - this.wnd_action_pos_x_bar.Location = new System.Drawing.Point(20, 367); + this.wnd_action_pos_x_bar.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); + this.wnd_action_pos_x_bar.Location = new System.Drawing.Point(20, 256); this.wnd_action_pos_x_bar.Name = "wnd_action_pos_x_bar"; this.wnd_action_pos_x_bar.Size = new System.Drawing.Size(121, 45); this.wnd_action_pos_x_bar.TabIndex = 16; // // wnd_action_pos // - this.wnd_action_pos.Location = new System.Drawing.Point(101, 337); + this.wnd_action_pos.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.wnd_action_pos.Location = new System.Drawing.Point(101, 226); this.wnd_action_pos.Name = "wnd_action_pos"; this.wnd_action_pos.Size = new System.Drawing.Size(87, 27); this.wnd_action_pos.TabIndex = 14; @@ -349,7 +374,8 @@ // // wnd_action_destroy // - this.wnd_action_destroy.Location = new System.Drawing.Point(7, 337); + this.wnd_action_destroy.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.wnd_action_destroy.Location = new System.Drawing.Point(7, 226); this.wnd_action_destroy.Name = "wnd_action_destroy"; this.wnd_action_destroy.Size = new System.Drawing.Size(87, 27); this.wnd_action_destroy.TabIndex = 2; @@ -359,7 +385,8 @@ // // wnd_action_front // - this.wnd_action_front.Location = new System.Drawing.Point(196, 337); + this.wnd_action_front.Anchor = System.Windows.Forms.AnchorStyles.Bottom; + this.wnd_action_front.Location = new System.Drawing.Point(196, 226); this.wnd_action_front.Name = "wnd_action_front"; this.wnd_action_front.Size = new System.Drawing.Size(84, 27); this.wnd_action_front.TabIndex = 10; @@ -369,8 +396,11 @@ // // wnd_action_enabled // + this.wnd_action_enabled.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); this.wnd_action_enabled.AutoSize = true; - this.wnd_action_enabled.Location = new System.Drawing.Point(7, 275); + this.wnd_action_enabled.Location = new System.Drawing.Point(7, 167); this.wnd_action_enabled.Name = "wnd_action_enabled"; this.wnd_action_enabled.Size = new System.Drawing.Size(68, 19); this.wnd_action_enabled.TabIndex = 9; @@ -380,7 +410,10 @@ // // wnd_action_title_get // - this.wnd_action_title_get.Location = new System.Drawing.Point(237, 270); + this.wnd_action_title_get.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); + this.wnd_action_title_get.Location = new System.Drawing.Point(237, 159); this.wnd_action_title_get.Name = "wnd_action_title_get"; this.wnd_action_title_get.Size = new System.Drawing.Size(43, 27); this.wnd_action_title_get.TabIndex = 8; @@ -474,7 +507,7 @@ this.wnd.Controls.Add(this.wnd_select_self); this.wnd.Location = new System.Drawing.Point(14, 135); this.wnd.Name = "wnd"; - this.wnd.Size = new System.Drawing.Size(287, 456); + this.wnd.Size = new System.Drawing.Size(287, 345); this.wnd.TabIndex = 6; this.wnd.TabStop = false; this.wnd.Text = "CC-Functions.W32.Wnd32"; @@ -491,8 +524,11 @@ // // wnd_action_overlay // + this.wnd_action_overlay.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); this.wnd_action_overlay.AutoSize = true; - this.wnd_action_overlay.Location = new System.Drawing.Point(162, 275); + this.wnd_action_overlay.Location = new System.Drawing.Point(162, 167); this.wnd_action_overlay.Name = "wnd_action_overlay"; this.wnd_action_overlay.Size = new System.Drawing.Size(66, 19); this.wnd_action_overlay.TabIndex = 25; @@ -502,9 +538,13 @@ // // wnd_action_style // + this.wnd_action_style.Anchor = + ((System.Windows.Forms.AnchorStyles) (((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left) | + System.Windows.Forms.AnchorStyles.Right))); this.wnd_action_style.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.wnd_action_style.FormattingEnabled = true; - this.wnd_action_style.Location = new System.Drawing.Point(7, 306); + this.wnd_action_style.Location = new System.Drawing.Point(7, 195); this.wnd_action_style.Name = "wnd_action_style"; this.wnd_action_style.Size = new System.Drawing.Size(238, 23); this.wnd_action_style.TabIndex = 24; @@ -513,8 +553,11 @@ // // wnd_action_visible // + this.wnd_action_visible.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Left))); this.wnd_action_visible.AutoSize = true; - this.wnd_action_visible.Location = new System.Drawing.Point(90, 275); + this.wnd_action_visible.Location = new System.Drawing.Point(90, 167); this.wnd_action_visible.Name = "wnd_action_visible"; this.wnd_action_visible.Size = new System.Drawing.Size(60, 19); this.wnd_action_visible.TabIndex = 23; @@ -524,9 +567,12 @@ // // wnd_action_icon // + this.wnd_action_icon.Anchor = + ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Bottom | + System.Windows.Forms.AnchorStyles.Right))); this.wnd_action_icon.BackColor = System.Drawing.SystemColors.ControlLight; this.wnd_action_icon.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.wnd_action_icon.Location = new System.Drawing.Point(253, 303); + this.wnd_action_icon.Location = new System.Drawing.Point(253, 193); this.wnd_action_icon.Name = "wnd_action_icon"; this.wnd_action_icon.Size = new System.Drawing.Size(27, 27); this.wnd_action_icon.TabIndex = 22; diff --git a/W32.Test/MainForm.cs b/W32.Test/MainForm.cs index 49461f4..9c0229d 100644 --- a/W32.Test/MainForm.cs +++ b/W32.Test/MainForm.cs @@ -12,26 +12,18 @@ namespace CC_Functions.W32.Test public partial class MainForm : Form { private static Wnd32 tmpWnd32_obj; - private Wnd32 tmpWnd - { - get => tmpWnd32_obj; - set { - tmpWnd32_obj = value; - Wnd_action_title_get_Click(null, null); - } - } private static MainForm mainF; private static Form frm; private static Label lab; private readonly KeyboardHook kHook; private readonly MouseHook mHook; - Label[] readerLabels; + private readonly Label[] readerLabels; public MainForm() { InitializeComponent(); mainF = this; - tmpWnd32_obj = Wnd32.fromForm(this); + tmpWnd32_obj = Wnd32.FromForm(this); #if DEBUG tmpWnd32_obj.MakeOverlay(); #endif @@ -45,10 +37,10 @@ namespace CC_Functions.W32.Test wnd_action_pos_w_bar.Maximum = Screen.PrimaryScreen.Bounds.Width; wnd_action_pos_h_bar.Maximum = Screen.PrimaryScreen.Bounds.Height; wnd_action_style.DataSource = Enum.GetValues(typeof(FormWindowState)); - wnd_action_style.SelectedItem = tmpWnd32_obj.state; + wnd_action_style.SelectedItem = tmpWnd32_obj.State; readerLabels = Enum.GetValues(typeof(Keys)).OfType().OrderBy(s => s.ToString()).Select(s => { - Label lab = new Label { Tag = s }; + Label lab = new Label {Tag = s}; readerFlow.Controls.Add(lab); return lab; }).ToArray(); @@ -57,6 +49,16 @@ namespace CC_Functions.W32.Test screen_get_Click(null, null); } + private Wnd32 tmpWnd + { + get => tmpWnd32_obj; + set + { + tmpWnd32_obj = value; + Wnd_action_title_get_Click(null, null); + } + } + public void set_up_box(ComboBox box, Type enumT) { box.DataSource = Enum.GetNames(enumT); @@ -72,32 +74,36 @@ namespace CC_Functions.W32.Test public object get_box_value(ComboBox box) => ((object[]) box.Tag)[box.SelectedIndex]; - private void Power_execute_Click(object sender, EventArgs e) => RaiseEvent((ShutdownMode)get_box_value(power_mode_box), (ShutdownReason)get_box_value(power_reason_box), - (ShutdownMod)get_box_value(power_mod_box)); + private void Power_execute_Click(object sender, EventArgs e) => RaiseEvent( + (ShutdownMode) get_box_value(power_mode_box), (ShutdownReason) get_box_value(power_reason_box), + (ShutdownMod) get_box_value(power_mod_box)); - private void Wnd_select_self_Click(object sender, EventArgs e) => tmpWnd = Wnd32.fromForm(this); + private void Wnd_select_self_Click(object sender, EventArgs e) => tmpWnd = Wnd32.FromForm(this); - private void wnd_select_list_Click(object sender, EventArgs e) => tmpWnd = SelectBox.Show(Wnd32.Visible, "Please select a window") ?? tmpWnd; + private void wnd_select_list_Click(object sender, EventArgs e) => + tmpWnd = SelectBox.Show(Wnd32.Visible, "Please select a window") ?? tmpWnd; - private void Wnd_select_title_button_Click(object sender, EventArgs e) => tmpWnd = Wnd32.fromMetadata(null, wnd_select_title_box.Text); + private void Wnd_select_title_button_Click(object sender, EventArgs e) => + tmpWnd = Wnd32.FromMetadata(null, wnd_select_title_box.Text); - private void Wnd_selet_class_button_Click(object sender, EventArgs e) => tmpWnd = Wnd32.fromMetadata(wnd_select_class_box.Text); + private void Wnd_selet_class_button_Click(object sender, EventArgs e) => + tmpWnd = Wnd32.FromMetadata(wnd_select_class_box.Text); - private void Wnd_action_title_set_Click(object sender, EventArgs e) => tmpWnd.title = wnd_select_title_box.Text; + private void Wnd_action_title_set_Click(object sender, EventArgs e) => tmpWnd.Title = wnd_select_title_box.Text; private void Wnd_action_title_get_Click(object sender, EventArgs e) { - if (!tmpWnd.stillExists) - tmpWnd = Wnd32.fromForm(this); - wnd_select_title_box.Text = tmpWnd.title; - wnd_action_enabled.Checked = tmpWnd.enabled; - wnd_select_selected.Text = "Selected: " + tmpWnd.hWnd; - wnd_action_style.SelectedIndex = (int) tmpWnd.state; - wnd_select_class_box.Text = tmpWnd.className; - wnd_action_visible.Checked = tmpWnd.shown; + if (!tmpWnd.StillExists) + tmpWnd = Wnd32.FromForm(this); + wnd_select_title_box.Text = tmpWnd.Title; + wnd_action_enabled.Checked = tmpWnd.Enabled; + wnd_select_selected.Text = "Selected: " + tmpWnd.HWnd; + wnd_action_style.SelectedIndex = (int) tmpWnd.State; + wnd_select_class_box.Text = tmpWnd.ClassName; + wnd_action_visible.Checked = tmpWnd.Shown; try { - wnd_action_icon.BackgroundImage = tmpWnd.icon.ToBitmap(); + wnd_action_icon.BackgroundImage = tmpWnd.Icon.ToBitmap(); } catch { @@ -106,7 +112,7 @@ namespace CC_Functions.W32.Test try { - wnd_action_pos_x_bar.Value = tmpWnd.position.X; + wnd_action_pos_x_bar.Value = tmpWnd.Position.X; } catch { @@ -114,7 +120,7 @@ namespace CC_Functions.W32.Test try { - wnd_action_pos_y_bar.Value = tmpWnd.position.Y; + wnd_action_pos_y_bar.Value = tmpWnd.Position.Y; } catch { @@ -122,7 +128,7 @@ namespace CC_Functions.W32.Test try { - wnd_action_pos_w_bar.Value = tmpWnd.position.Width; + wnd_action_pos_w_bar.Value = tmpWnd.Position.Width; } catch { @@ -130,7 +136,7 @@ namespace CC_Functions.W32.Test try { - wnd_action_pos_h_bar.Value = tmpWnd.position.Height; + wnd_action_pos_h_bar.Value = tmpWnd.Position.Height; } catch { @@ -138,20 +144,20 @@ namespace CC_Functions.W32.Test } private void Wnd_action_enabled_CheckedChanged(object sender, EventArgs e) => - tmpWnd.enabled = wnd_action_enabled.Checked; + tmpWnd.Enabled = wnd_action_enabled.Checked; private void Wnd_action_visible_CheckedChanged(object sender, EventArgs e) => - tmpWnd.shown = wnd_action_visible.Checked; + tmpWnd.Shown = wnd_action_visible.Checked; - private void Wnd_action_front_Click(object sender, EventArgs e) => tmpWnd.isForeground = true; + private void Wnd_action_front_Click(object sender, EventArgs e) => tmpWnd.IsForeground = true; private void Wnd_action_destroy_Click(object sender, EventArgs e) => tmpWnd.Destroy(); private void Wnd_select_mouse_Click(object sender, EventArgs e) { WindowState = FormWindowState.Minimized; - tmpWnd = Wnd32.fromForm(this); - tmpWnd.enabled = false; + tmpWnd = Wnd32.FromForm(this); + tmpWnd.Enabled = false; frm = new Form(); frm.BackColor = Color.White; frm.Opacity = 0.4f; @@ -162,16 +168,16 @@ namespace CC_Functions.W32.Test lab = new Label(); frm.Controls.Add(lab); frm.Show(); - Wnd32.fromForm(frm).overlay = true; + Wnd32.FromForm(frm).Overlay = true; } private void Frm_Click(object sender, EventArgs e) { frm.Hide(); frm.WindowState = FormWindowState.Minimized; - Wnd32 tmp = Wnd32.fromPoint(MousePosition); - tmpWnd.enabled = true; - tmpWnd.isForeground = true; + Wnd32 tmp = Wnd32.FromPoint(MousePosition); + tmpWnd.Enabled = true; + tmpWnd.IsForeground = true; tmpWnd = tmp; mainF.WindowState = FormWindowState.Normal; frm.Close(); @@ -179,7 +185,7 @@ namespace CC_Functions.W32.Test private void Frm_MouseMove(object sender, MouseEventArgs e) { - lab.Text = Wnd32.fromPoint(MousePosition).ToString(); + lab.Text = Wnd32.FromPoint(MousePosition).ToString(); lab.Location = new Point(Cursor.Position.X + 5, Cursor.Position.Y + 5); } @@ -194,7 +200,8 @@ namespace CC_Functions.W32.Test private void MHook_OnMouse(MouseHookEventArgs args) => mouse_log.Text = args.Message + " -|- " + args.Point + "\r\n" + mouse_log.Text; - private void Mouse_log_TextChanged(object sender, EventArgs e) => mouse_log.Lines = mouse_log.Lines.Take(9).ToArray(); + private void Mouse_log_TextChanged(object sender, EventArgs e) => + mouse_log.Lines = mouse_log.Lines.Take(9).ToArray(); private void Keyboard_enabled_CheckedChanged(object sender, EventArgs e) { @@ -207,27 +214,28 @@ namespace CC_Functions.W32.Test private void KHook_OnKeyPress(KeyboardHookEventArgs args) => keyboard_log.Text = args.Key + "\r\n" + keyboard_log.Text; - private void Keyboard_log_TextChanged(object sender, EventArgs e) => keyboard_log.Lines = keyboard_log.Lines.Take(8).ToArray(); + private void Keyboard_log_TextChanged(object sender, EventArgs e) => + keyboard_log.Lines = keyboard_log.Lines.Take(8).ToArray(); private void Wnd_action_pos_Click(object sender, EventArgs e) => - tmpWnd.position = new Rectangle(wnd_action_pos_x_bar.Value, wnd_action_pos_y_bar.Value, + tmpWnd.Position = new Rectangle(wnd_action_pos_x_bar.Value, wnd_action_pos_y_bar.Value, wnd_action_pos_w_bar.Value, wnd_action_pos_h_bar.Value); private void Wnd_action_style_SelectedIndexChanged(object sender, EventArgs e) { Enum.TryParse(wnd_action_style.SelectedValue.ToString(), out FormWindowState status); - tmpWnd.state = status; + tmpWnd.State = status; } private void wnd_action_overlay_CheckedChanged(object sender, EventArgs e) => - tmpWnd.overlay = wnd_action_overlay.Checked; + tmpWnd.Overlay = wnd_action_overlay.Checked; private void readerUpdate_Tick(object sender, EventArgs e) { for (int i = 0; i < readerLabels.Length; i++) { Label s = readerLabels[i]; - Keys key = (Keys)s.Tag; + Keys key = (Keys) s.Tag; s.Text = $"{key.ToString()}: {key.IsDown()}"; } } @@ -239,37 +247,39 @@ namespace CC_Functions.W32.Test using IDCDrawer drawer = DeskMan.CreateGraphics(); Graphics g = drawer.Graphics; Pen eye = new Pen(new SolidBrush(Color.Red), 2); - g.DrawCurve(eye, new PointF[] { makePoint(20, 50), makePoint(50, 65), makePoint(80, 50) }); - g.DrawCurve(eye, new PointF[] { makePoint(20, 50), makePoint(50, 35), makePoint(80, 50) }); - g.DrawEllipse(eye, new RectangleF(PointF.Subtract(makePoint(50, 50), makeSizeY(15, 15)), makeSizeY(30, 30))); + g.DrawCurve(eye, new[] {makePoint(20, 50), makePoint(50, 65), makePoint(80, 50)}); + g.DrawCurve(eye, new[] {makePoint(20, 50), makePoint(50, 35), makePoint(80, 50)}); + g.DrawEllipse(eye, + new RectangleF(PointF.Subtract(makePoint(50, 50), makeSizeY(15, 15)), makeSizeY(30, 30))); } - public static PointF makePoint(float xPercent, float yPercent) => new PointF(Screen.PrimaryScreen.Bounds.Width * xPercent / 100, - Screen.PrimaryScreen.Bounds.Height * yPercent / 100); + public static PointF makePoint(float xPercent, float yPercent) => new PointF( + (Screen.PrimaryScreen.Bounds.Width * xPercent) / 100, + (Screen.PrimaryScreen.Bounds.Height * yPercent) / 100); - public static SizeF makeSizeY(float xPercent, float yPercent) => new SizeF(Screen.PrimaryScreen.Bounds.Height * xPercent / 100, - Screen.PrimaryScreen.Bounds.Height * yPercent / 100); + public static SizeF makeSizeY(float xPercent, float yPercent) => new SizeF( + (Screen.PrimaryScreen.Bounds.Height * xPercent) / 100, + (Screen.PrimaryScreen.Bounds.Height * yPercent) / 100); private void desk_set_Click(object sender, EventArgs e) { OpenFileDialog dlg = new OpenFileDialog(); dlg.Filter = "Images (*.jpg, *.jpeg, *.jpe, *.jfif, *.png)|*.jpg;*.jpeg;*.jpe;*.jfif;*.png"; - if (dlg.ShowDialog() == DialogResult.OK) - { - DeskMan.Wallpaper = Image.FromFile(dlg.FileName); - } + if (dlg.ShowDialog() == DialogResult.OK) DeskMan.Wallpaper = Image.FromFile(dlg.FileName); } - private void screen_get_Click(object sender, EventArgs e) => screen_img.BackgroundImage = ScreenMan.CaptureScreen(); + private void screen_get_Click(object sender, EventArgs e) => + screen_img.BackgroundImage = ScreenMan.CaptureScreen(); private void screen_draw_Click(object sender, EventArgs e) { using IDCDrawer drawer = ScreenMan.GetDrawer(false); Graphics g = drawer.Graphics; Pen eye = new Pen(new SolidBrush(Color.Red), 2); - g.DrawCurve(eye, new PointF[] { makePoint(20, 50), makePoint(50, 65), makePoint(80, 50) }); - g.DrawCurve(eye, new PointF[] { makePoint(20, 50), makePoint(50, 35), makePoint(80, 50) }); - g.DrawEllipse(eye, new RectangleF(PointF.Subtract(makePoint(50, 50), makeSizeY(15, 15)), makeSizeY(30, 30))); + g.DrawCurve(eye, new[] {makePoint(20, 50), makePoint(50, 65), makePoint(80, 50)}); + g.DrawCurve(eye, new[] {makePoint(20, 50), makePoint(50, 35), makePoint(80, 50)}); + g.DrawEllipse(eye, + new RectangleF(PointF.Subtract(makePoint(50, 50), makeSizeY(15, 15)), makeSizeY(30, 30))); } } } \ No newline at end of file diff --git a/W32/DCDrawer/DCBuffered.cs b/W32/DCDrawer/DCBuffered.cs index 8f1db38..218de19 100644 --- a/W32/DCDrawer/DCBuffered.cs +++ b/W32/DCDrawer/DCBuffered.cs @@ -6,9 +6,13 @@ namespace CC_Functions.W32.DCDrawer { public class DCBuffered : IDCDrawer { - private readonly DCUnbuffered drawer; private readonly BufferedGraphics buffer; - public DCBuffered(IntPtr ptr) : this(ptr, IntPtr.Zero) {} + private readonly DCUnbuffered drawer; + + public DCBuffered(IntPtr ptr) : this(ptr, IntPtr.Zero) + { + } + public DCBuffered(IntPtr ptr, IntPtr hWnd) { drawer = new DCUnbuffered(ptr, hWnd); diff --git a/W32/DCDrawer/DCUnbuffered.cs b/W32/DCDrawer/DCUnbuffered.cs index e0fc250..2010dd0 100644 --- a/W32/DCDrawer/DCUnbuffered.cs +++ b/W32/DCDrawer/DCUnbuffered.cs @@ -6,8 +6,8 @@ namespace CC_Functions.W32.DCDrawer { public class DCUnbuffered : IDCDrawer { + private readonly IntPtr hWnd; private readonly IntPtr ptr; - private IntPtr hWnd; public DCUnbuffered(IntPtr ptr, IntPtr hWnd) { diff --git a/W32/DeskMan.cs b/W32/DeskMan.cs index c1bc7b8..20b2c63 100644 --- a/W32/DeskMan.cs +++ b/W32/DeskMan.cs @@ -10,36 +10,15 @@ namespace CC_Functions.W32 { public static class DeskMan { - public static IDCDrawer CreateGraphics(bool buffered = false) - { - Wnd32 progman = Wnd32.fromMetadata("Progman"); - IntPtr result = IntPtr.Zero; - user32.SendMessageTimeout(progman.hWnd, 0x052C, new IntPtr(0), IntPtr.Zero, 0x0, 1000, out result); - IntPtr workerW = IntPtr.Zero; - user32.EnumWindows((tophandle, topparamhandle) => - { - IntPtr p = user32.FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", IntPtr.Zero); - if (p != IntPtr.Zero) - { - workerW = user32.FindWindowEx(IntPtr.Zero, tophandle, "WorkerW", IntPtr.Zero); - } - return true; - }, IntPtr.Zero); - IntPtr dc = user32.GetDCEx(workerW, IntPtr.Zero, 0x403); - if (dc == IntPtr.Zero) - { - throw new Exception("Something went wrong when creatiing the Graphics object"); - } - return buffered ? (IDCDrawer)new DCBuffered(dc) : new DCUnbuffered(dc); - } - public static Image Wallpaper { - get + get { - using (var bmpTemp = new Bitmap(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\Microsoft\Windows\Themes\TranscodedWallpaper")) + using (Bitmap bmpTemp = + new Bitmap(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + + @"\Microsoft\Windows\Themes\TranscodedWallpaper")) { - return (Image)bmpTemp.Clone(); + return (Image) bmpTemp.Clone(); } } set @@ -53,5 +32,22 @@ namespace CC_Functions.W32 File.Delete(tempPath); } } + + public static IDCDrawer CreateGraphics(bool buffered = false) + { + Wnd32 progman = Wnd32.FromMetadata("Progman"); + IntPtr result = IntPtr.Zero; + user32.SendMessageTimeout(progman.HWnd, 0x052C, new IntPtr(0), IntPtr.Zero, 0x0, 1000, out result); + IntPtr workerW = IntPtr.Zero; + user32.EnumWindows((tophandle, topparamhandle) => + { + IntPtr p = user32.FindWindowEx(tophandle, IntPtr.Zero, "SHELLDLL_DefView", IntPtr.Zero); + if (p != IntPtr.Zero) workerW = user32.FindWindowEx(IntPtr.Zero, tophandle, "WorkerW", IntPtr.Zero); + return true; + }, IntPtr.Zero); + IntPtr dc = user32.GetDCEx(workerW, IntPtr.Zero, 0x403); + if (dc == IntPtr.Zero) throw new Exception("Something went wrong when creatiing the Graphics object"); + return buffered ? (IDCDrawer) new DCBuffered(dc) : new DCUnbuffered(dc); + } } } \ No newline at end of file diff --git a/W32/GenericExtensions.cs b/W32/GenericExtensions.cs index c7b93cb..7cc836c 100644 --- a/W32/GenericExtensions.cs +++ b/W32/GenericExtensions.cs @@ -6,9 +6,9 @@ namespace CC_Functions.W32 { public static class GenericExtensions { - public static Wnd32 GetWindow(this IntPtr handle) => Wnd32.fromHandle(handle); - public static Wnd32 GetMainWindow(this Process handle) => Wnd32.getProcessMain(handle); - public static Wnd32 GetWnd32(this Form frm) => Wnd32.fromForm(frm); + public static Wnd32 GetWindow(this IntPtr handle) => Wnd32.FromHandle(handle); + public static Wnd32 GetMainWindow(this Process handle) => Wnd32.GetProcessMain(handle); + public static Wnd32 GetWnd32(this Form frm) => Wnd32.FromForm(frm); public static bool IsDown(this Keys key) => KeyboardReader.IsKeyDown(key); public static Privileges.SecurityEntity GetEntity(this Privileges.SecurityEntity2 entity) => diff --git a/W32/Native/user32.cs b/W32/Native/user32.cs index a1b7fa8..cfc60c9 100644 --- a/W32/Native/user32.cs +++ b/W32/Native/user32.cs @@ -6,13 +6,17 @@ namespace CC_Functions.W32.Native { internal static class user32 { + public delegate bool EnumDelegate(IntPtr hWnd, int lParam); + + public delegate IntPtr LowLevelProc(int nCode, IntPtr wParam, IntPtr lParam); + [DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool ExitWindowsEx(Power.ExitWindows uFlags, Power.ShutdownReason dwReason); - + [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] public static extern short GetKeyState(int keyCode); @@ -35,11 +39,11 @@ namespace CC_Functions.W32.Native [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam); - + [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool IsWindowVisible(IntPtr hWnd); - + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Ansi)] public static extern long GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); @@ -104,10 +108,10 @@ namespace CC_Functions.W32.Native SetLastError = true)] public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumDelegate lpEnumCallbackFunction, IntPtr lParam); - + [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int SystemParametersInfo(int uAction, int uParam, string lpvParam, int fuWinIni); - + [DllImport("user32.dll")] public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, uint flags); @@ -116,12 +120,11 @@ namespace CC_Functions.W32.Native public static extern bool EnumWindows(EnumDelegate lpEnumFunc, IntPtr lParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)] - public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, IntPtr windowTitle); + public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, + IntPtr windowTitle); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] - public static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, uint flags, uint timeout, out IntPtr result); - - public delegate IntPtr LowLevelProc(int nCode, IntPtr wParam, IntPtr lParam); - public delegate bool EnumDelegate(IntPtr hWnd, int lParam); + public static extern IntPtr SendMessageTimeout(IntPtr windowHandle, uint Msg, IntPtr wParam, IntPtr lParam, + uint flags, uint timeout, out IntPtr result); } } \ No newline at end of file diff --git a/W32/Power.cs b/W32/Power.cs index 2522367..6643e2f 100644 --- a/W32/Power.cs +++ b/W32/Power.cs @@ -1,5 +1,4 @@ using System; -using System.Runtime.InteropServices; using CC_Functions.W32.Native; using static CC_Functions.W32.Privileges; diff --git a/W32/Privileges.cs b/W32/Privileges.cs index 0890445..300c10b 100644 --- a/W32/Privileges.cs +++ b/W32/Privileges.cs @@ -88,6 +88,11 @@ namespace CC_Functions.W32 SE_UNSOLICITED_INPUT_NAME_TEXT } + internal const int SE_PRIVILEGE_ENABLED = 0x00000002; + internal const int ERROR_NOT_ALL_ASSIGNED = 1300; + internal const uint TOKEN_QUERY = 0x0008; + internal const uint TOKEN_ADJUST_PRIVILEGES = 0x0020; + public static void EnablePrivilege(SecurityEntity securityEntity) { if (!Enum.IsDefined(typeof(SecurityEntity), securityEntity)) @@ -155,11 +160,6 @@ namespace CC_Functions.W32 } public static SecurityEntity EntityToEntity(SecurityEntity2 entity) => (SecurityEntity) entity; - - internal const int SE_PRIVILEGE_ENABLED = 0x00000002; - internal const int ERROR_NOT_ALL_ASSIGNED = 1300; - internal const uint TOKEN_QUERY = 0x0008; - internal const uint TOKEN_ADJUST_PRIVILEGES = 0x0020; [StructLayout(LayoutKind.Sequential)] internal struct LUID diff --git a/W32/ScreenMan.cs b/W32/ScreenMan.cs index fc68215..67b4ada 100644 --- a/W32/ScreenMan.cs +++ b/W32/ScreenMan.cs @@ -8,6 +8,7 @@ namespace CC_Functions.W32 { public static class ScreenMan { + private const int SRCCOPY = 13369376; public static Image CaptureScreen() => CaptureWindow(user32.GetDesktopWindow()); public static Image CaptureWindow(IntPtr handle) @@ -44,7 +45,5 @@ namespace CC_Functions.W32 public static Rectangle GetBounds() => Screen.PrimaryScreen.Bounds; public static void Refresh() => shell32.SHChangeNotify(0x8000000, 0x1000, IntPtr.Zero, IntPtr.Zero); - - private const int SRCCOPY = 13369376; } } \ No newline at end of file diff --git a/W32/Wnd32.cs b/W32/Wnd32.cs index 2a65348..ce9b05d 100644 --- a/W32/Wnd32.cs +++ b/W32/Wnd32.cs @@ -10,123 +10,199 @@ using CC_Functions.W32.Native; namespace CC_Functions.W32 { + /// + /// Object representing a window handle in the Windows API. Provides a simplified interface for basic interactions + /// public sealed class Wnd32 : IEquatable { #region Exposed #region CreateInstance - private Wnd32(IntPtr wndref) => hWnd = wndref; + private Wnd32(IntPtr handle) => HWnd = handle; - public static Wnd32 fromHandle(IntPtr handle) => new Wnd32(handle); + /// + /// Base method. Generates a window object from the specified handle + /// + /// The handle + /// The window + public static Wnd32 FromHandle(IntPtr handle) => new Wnd32(handle); - public static Wnd32 getProcessMain(Process process) => fromHandle(process.MainWindowHandle); + /// + /// Gets the main window of the process + /// + /// The process + /// The window. Might be IntPtr.Zero + public static Wnd32 GetProcessMain(Process process) => FromHandle(process.MainWindowHandle); - public static Wnd32 fromMetadata(string? lpClassName = null, string? lpWindowName = null) => - fromHandle(user32.FindWindow(lpClassName, lpWindowName)); + /// + /// Generates a window from metadata. Parameters should be null if they are not used + /// + /// + /// The class name of the window. Use the name you found before using the ClassName-parameter of + /// a window + /// + /// The windows name (title) + /// The window. Might be IntPtr.Zero + public static Wnd32 FromMetadata(string? lpClassName = null, string? lpWindowName = null) => + FromHandle(user32.FindWindow(lpClassName, lpWindowName)); - public static Wnd32 fromPoint(Point point) => fromHandle(user32.WindowFromPoint(point.X, point.Y)); + /// + /// Gets the window that is visible at the specified point + /// + /// The point to scan + /// The window. Might be IntPtr.Zero + public static Wnd32 FromPoint(Point point) => FromHandle(user32.WindowFromPoint(point.X, point.Y)); - public static Wnd32 fromForm(Form form) => fromHandle(form.Handle); + /// + /// Gets the window associated with the forms handle + /// + /// Form to get window from + /// The window. Might be IntPtr.Zero + public static Wnd32 FromForm(Form form) => FromHandle(form.Handle); + /// + /// Gets ALL windows. In most cases you will want to use Wnd32.Visible + /// + /// public static Wnd32[] All { - get { WindowHandles = new List(); + get + { + _windowHandles = new List(); if (!user32.EnumDesktopWindows(IntPtr.Zero, FilterCallback, IntPtr.Zero)) throw new Win32Exception("There was a native error. This should never happen!"); - return WindowHandles.Select(s => fromHandle(s)).ToArray(); } + return _windowHandles.Select(s => FromHandle(s)).ToArray(); + } } - public static Wnd32[] Visible => All.Where(s => user32.IsWindowVisible(s.hWnd) && !string.IsNullOrEmpty(s.title)).ToArray(); - public static Wnd32 Foreground => fromHandle(user32.GetForegroundWindow()); - public static Wnd32 ConsoleWindow => fromHandle(kernel32.GetConsoleWindow()); + /// + /// Gets all visible windows with valid titles + /// + public static Wnd32[] Visible => + All.Where(s => user32.IsWindowVisible(s.HWnd) && !string.IsNullOrEmpty(s.Title)).ToArray(); + + /// + /// Gets the foreground window + /// + public static Wnd32 Foreground => FromHandle(user32.GetForegroundWindow()); + + /// + /// The current programs console window. Do NOT use this if you are not targeting a console app or allocating a console + /// + public static Wnd32 ConsoleWindow => FromHandle(kernel32.GetConsoleWindow()); #endregion CreateInstance #region InstanceActions - public string title + /// + /// The windows title + /// + public string Title { get { - int length = user32.GetWindowTextLength(hWnd); + int length = user32.GetWindowTextLength(HWnd); StringBuilder sb = new StringBuilder(length + 1); - user32.GetWindowText(hWnd, sb, sb.Capacity); + user32.GetWindowText(HWnd, sb, sb.Capacity); return sb.ToString(); } - set => user32.SetWindowText(hWnd, value); + set => user32.SetWindowText(HWnd, value); } - public Rectangle position + /// + /// The windows position in screen-space + /// + public Rectangle Position { get { - RECT Rect = new RECT(); - user32.GetWindowRect(hWnd, ref Rect); - return new Rectangle(new Point(Rect.Left, Rect.Top), - new Size(Rect.Width, Rect.Height)); + RECT rect = new RECT(); + user32.GetWindowRect(HWnd, ref rect); + return new Rectangle(new Point(rect.Left, rect.Top), + new Size(rect.Width, rect.Height)); } set { - RECT Rect = new RECT(); - user32.GetWindowRect(hWnd, ref Rect); - user32.MoveWindow(hWnd, value.X, value.Y, value.Width, value.Height, true); + RECT rect = new RECT(); + user32.GetWindowRect(HWnd, ref rect); + user32.MoveWindow(HWnd, value.X, value.Y, value.Width, value.Height, true); } } - public bool isForeground + /// + /// Gets whether the window is the foreground window or brings it to the front. "False" must not be assigned! + /// + /// Thrown when the value is "False" + public bool IsForeground { - get => user32.GetForegroundWindow() == hWnd; + get => user32.GetForegroundWindow() == HWnd; set { if (value) - user32.SetForegroundWindow(hWnd); + user32.SetForegroundWindow(HWnd); else throw new InvalidOperationException( "You can't set a Window not to be in the foreground. Move another one over it!"); } } - public bool enabled + /// + /// Whether the window is enabled. Functionally similar to WinForms' "Control.Enabled" + /// + public bool Enabled { - get => user32.IsWindowEnabled(hWnd); - set => user32.EnableWindow(hWnd, value); + get => user32.IsWindowEnabled(HWnd); + set => user32.EnableWindow(HWnd, value); } - public Icon icon + /// + /// Gets the windows icon + /// + public Icon Icon { get { - IntPtr hicon = user32.SendMessage(hWnd, 0x7F, 1, 0); - if (hicon == IntPtr.Zero) - hicon = user32.SendMessage(hWnd, 0x7F, 0, 0); - if (hicon == IntPtr.Zero) - hicon = user32.SendMessage(hWnd, 0x7F, 2, 0); - return Icon.FromHandle(hicon); + IntPtr hIcon = user32.SendMessage(HWnd, 0x7F, 1, 0); + if (hIcon == IntPtr.Zero) + hIcon = user32.SendMessage(HWnd, 0x7F, 0, 0); + if (hIcon == IntPtr.Zero) + hIcon = user32.SendMessage(HWnd, 0x7F, 2, 0); + return Icon.FromHandle(hIcon); } } - public bool shown + /// + /// Whether the window is visible + /// + public bool Shown { - get => user32.IsWindowVisible(hWnd); - set => user32.ShowWindow(hWnd, value ? 9 : 0); + get => user32.IsWindowVisible(HWnd); + set => user32.ShowWindow(HWnd, value ? 9 : 0); } - public string className + /// + /// Gets the windows class name, This is basically only useful for finding window class-names of specified programs + /// + public string ClassName { get { - StringBuilder ClassName = new StringBuilder(256); - user32.GetClassName(hWnd, ClassName, ClassName.Capacity); - return ClassName.ToString(); + StringBuilder className = new StringBuilder(256); + user32.GetClassName(HWnd, className, className.Capacity); + return className.ToString(); } } - public FormWindowState state + /// + /// Sets the window state + /// + public FormWindowState State { get { - int style = user32.GetWindowLong(hWnd, -16); + int style = user32.GetWindowLong(HWnd, -16); if ((style & 0x01000000) == 0x01000000) return FormWindowState.Maximized; if ((style & 0x20000000) == 0x20000000) @@ -138,50 +214,107 @@ namespace CC_Functions.W32 switch (value) { case FormWindowState.Minimized: - user32.ShowWindow(hWnd, 11); + user32.ShowWindow(HWnd, 11); break; case FormWindowState.Normal: - user32.ShowWindow(hWnd, 1); + user32.ShowWindow(HWnd, 1); break; case FormWindowState.Maximized: - user32.ShowWindow(hWnd, 3); + user32.ShowWindow(HWnd, 3); break; + + default: + throw new ArgumentException("The provided WindowState was invalid", "value"); } } } - public bool overlay + /// + /// Overlays the window over others + /// + public bool Overlay { set { - Rectangle tmp = position; - user32.SetWindowPos(hWnd, value ? HWND_TOPMOST : HWND_NOTOPMOST, tmp.X, tmp.Y, tmp.Width, tmp.Height, - value ? SWP_NOMOVE | SWP_NOSIZE : 0); + Rectangle tmp = Position; + user32.SetWindowPos(HWnd, value ? new IntPtr(-1) : new IntPtr(-2), tmp.X, tmp.Y, tmp.Width, tmp.Height, + value ? (uint) 3 : 0); } } - public bool Destroy() + /// + /// Forces the window to close + /// + /// Thrown if the window could not be closed + public void Destroy() { - if (user32.DestroyWindow(hWnd)) - return true; - throw new Exception("Failed."); + if (!user32.DestroyWindow(HWnd)) + throw new Exception("Failed."); } - public bool stillExists => user32.IsWindow(hWnd); + /// + /// Whether the IntPtr is a window and still exists + /// + public bool StillExists => user32.IsWindow(HWnd); - public override string ToString() => hWnd + "; " + title + "; " + position; + /// + /// Creates a user-readable string from the windows hWnd, title and position + /// + /// The created string + public override string ToString() => $"{HWnd}; {Title}; {Position}"; + /// + /// Equality operator, uses the hWnd field + /// + /// Object (Window) to compare + /// Equality result public override bool Equals(object obj) => Equals(obj as Wnd32); - public bool Equals(Wnd32 other) => other != null && EqualityComparer.Default.Equals(hWnd, other.hWnd); + /// + /// Equality operator, uses the hWnd field + /// + /// Window to compare + /// Equality result + public bool Equals(Wnd32 other) => !IsNull(other) && other != null && HWnd.Equals(other.HWnd); - public override int GetHashCode() => -75345830 + EqualityComparer.Default.GetHashCode(hWnd); + /// + /// Equality operator, uses the hWnd field + /// + /// Equality result + public override int GetHashCode() => HWnd.GetHashCode(); - public static bool operator ==(Wnd32 left, Wnd32 right) => EqualityComparer.Default.Equals(left, right); + /// + /// Equality operator, uses the hWnd field + /// + /// Window to compare + /// Window to compare + /// Equality result + public static bool operator ==(Wnd32 left, Wnd32 right) => !AreNull(left, right) && left.HWnd == right.HWnd; - public static bool operator !=(Wnd32 left, Wnd32 right) => !(left == right); + /// + /// Equality operator, uses the hWnd field + /// + /// Window to compare + /// Window to compare + /// Equality result + public static bool operator !=(Wnd32 left, Wnd32 right) => AreNull(left, right) || left.HWnd != right.HWnd; + + private static bool AreNull(params Wnd32[] windows) => windows.Any(IsNull); + + private static bool IsNull(Wnd32 window) + { + try + { + window.ToString(); + return false; + } + catch (NullReferenceException) + { + return true; + } + } #endregion InstanceActions @@ -189,20 +322,21 @@ namespace CC_Functions.W32 #region Internal - public IntPtr hWnd; + /// + /// The windows' handle + /// + public readonly IntPtr HWnd; + + private static List _windowHandles; - private static readonly IntPtr HWND_TOPMOST = new IntPtr(-1); - private static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2); - private const uint SWP_NOSIZE = 0x0001; - private const uint SWP_NOMOVE = 0x0002; - private static List WindowHandles; private static bool FilterCallback(IntPtr hWnd, int lParam) { StringBuilder sbTitle = new StringBuilder(1024); user32.GetWindowText(hWnd, sbTitle, 1024); - WindowHandles.Add(hWnd); + _windowHandles.Add(hWnd); return true; } + #endregion Internal } } \ No newline at end of file