Skip to content

Commit

Permalink
fix: make DPI aware
Browse files Browse the repository at this point in the history
  • Loading branch information
teetow committed Apr 16, 2022
1 parent 30f51d8 commit 8d79b13
Show file tree
Hide file tree
Showing 15 changed files with 643 additions and 74 deletions.
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# This .gitignore file was automatically created by Microsoft(R) Visual Studio.
################################################################################

/.vs/screenzap/v15
/packages/Nito.AsyncEx.3.0.1
/screenzap
/.vs
/packages
/screenzap/obj
/screenzap/bin
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
screenzap
35 changes: 19 additions & 16 deletions screenzap/App.config
Original file line number Diff line number Diff line change
@@ -1,18 +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="screenzap.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<userSettings>
<screenzap.Properties.Settings>
<setting name="currentCombo" serializeAs="String">
<value>Ctrl+Alt+Shift+4</value>
</setting>
</screenzap.Properties.Settings>
</userSettings>
</configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="screenzap.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<System.Windows.Forms.ApplicationConfigurationSection>
<add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
<userSettings>
<screenzap.Properties.Settings>
<setting name="currentCombo" serializeAs="String">
<value>Ctrl+Alt+Shift+4</value>
</setting>
</screenzap.Properties.Settings>
</userSettings>
</configuration>
124 changes: 124 additions & 0 deletions screenzap/ClipboardMonitor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace screenzap
{
public sealed class ClipboardMonitor : IDisposable
{
/// <summary>
/// Places the given window in the system-maintained clipboard format listener list.
/// </summary>
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AddClipboardFormatListener(IntPtr hwnd);

/// <summary>
/// Removes the given window from the system-maintained clipboard format listener list.
/// </summary>
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool RemoveClipboardFormatListener(IntPtr hwnd);

/// <summary>
/// Sent when the contents of the clipboard have changed.
/// </summary>
private const int WM_CLIPBOARDUPDATE = 0x031D;

private class Window : NativeWindow, IDisposable
{
public Window()
{
// create the handle for the window.
this.CreateHandle(new CreateParams());
AddClipboardFormatListener(this.Handle);
}

/// <summary>
/// Overridden to get the notifications.
/// </summary>
/// <param name="m"></param>
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);

if (m.Msg == WM_CLIPBOARDUPDATE)
{
IDataObject iData = Clipboard.GetDataObject(); // Clipboard's data.

/* Depending on the clipboard's current data format we can process the data differently.
* Feel free to add more checks if you want to process more formats. */
if (iData.GetDataPresent(DataFormats.Text))
{
string text = (string)iData.GetData(DataFormats.Text);
OnUpdateText(this, text);
}
else if (iData.GetDataPresent(DataFormats.Bitmap))
{
Bitmap image = (Bitmap)iData.GetData(DataFormats.Bitmap);
OnUpdateImage(this, image);
}
}
}
public event EventHandler<string> OnUpdateText;
public event EventHandler<Bitmap> OnUpdateImage;
public void Dispose()
{
RemoveClipboardFormatListener(this.Handle);
this.DestroyHandle();
}
}

private Window _window;
public ClipboardMonitor()
{
_window = new Window();
_window.OnUpdateImage += _window_OnUpdateImage;
_window.OnUpdateText += _window_OnUpdateText;
}

public bool isListening = false;

private void _window_OnUpdateText(object sender, string e)
{
if (isListening)
OnUpdateText?.Invoke(sender, e);
}

private void _window_OnUpdateImage(object sender, Bitmap e)
{
if (isListening)
OnUpdateImage?.Invoke(sender, e);
}

public event EventHandler<string> OnUpdateText;
public event EventHandler<Bitmap> OnUpdateImage;
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls

void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
_window.Dispose();
}

// TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
// TODO: set large fields to null.

disposedValue = true;
}
}

public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
}
#endregion
}
}
132 changes: 132 additions & 0 deletions screenzap/ImageOverlayForm.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace screenzap
{
class ImageOverlayForm : Form
{
private Point mouseHit;
private Point formPosition;
private bool isMouseDown;
private bool isCtrlDown;
private decimal zoomLevel = 1m;
private decimal[] zoomLevels = { 0.1m, 0.25m, 1 / 3m, 0.5m, 2 / 3m, 0.75m, 1.0m, 1.25m, 4 / 3m, 1.5m, 5 / 3m, 2m, 3m, 4m, 6m, 8m, 10m, 15m, 20m, 30m, 40m, };

public ImageOverlayForm()
{
this.Cursor = Cursors.Cross;
this.TopMost = true;
//this.ShowInTaskbar = false;
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.Gray;
this.TransparencyKey = Color.Red;
this.Opacity = 0.5;
this.Width = Screen.PrimaryScreen.WorkingArea.Width;
this.Height = Screen.PrimaryScreen.WorkingArea.Height;
//this.WindowState = FormWindowState.Maximized;
this.DoubleBuffered = true;
this.BackgroundImageLayout = ImageLayout.Stretch;
}

public void setImage(Bitmap image)
{
this.BackgroundImage = image;
this.Width = image.Width;
this.Height = image.Height;
}

protected override void OnKeyDown(KeyEventArgs e)
{
this.isCtrlDown = e.Control;

base.OnKeyDown(e);
}

protected override void OnKeyPress(KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Escape)
this.Hide();

base.OnKeyPress(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
this.isCtrlDown = e.Control;

base.OnKeyUp(e);
}

protected override void OnMouseDown(MouseEventArgs e)
{
isMouseDown = true;
mouseHit = e.Location;
formPosition = ((Form)TopLevelControl).Location;

base.OnMouseDown(e);
}

protected override void OnMouseUp(MouseEventArgs e)
{
isMouseDown = false;

base.OnMouseUp(e);
}

protected override void OnMouseMove(MouseEventArgs e)
{
if (isMouseDown)
{
int dx = e.Location.X - mouseHit.X;
int dy = e.Location.Y - mouseHit.Y;
Point newLocation = new Point(formPosition.X + dx, formPosition.Y + dy);
((Form)TopLevelControl).Location = newLocation;
formPosition = newLocation;
}

base.OnMouseMove(e);
}

protected override void OnMouseWheel(MouseEventArgs e)
{
try
{
if (this.isCtrlDown)
{
if (e.Delta > 0)
setZoom(zoomLevel + 0.1m);
else
setZoom(zoomLevel - 0.1m);
}
else
{
if (e.Delta > 0) // pos, zoom in
setZoom(zoomLevels.Where(x => x > this.zoomLevel).First());
else
setZoom(zoomLevels.Where(x => x < this.zoomLevel).Last());
}
}
catch (Exception zoomException)
{
Console.WriteLine("zoomException");
}

base.OnMouseWheel(e);
}

private void setZoom(decimal zoomLevel)
{
Point oldCenter = new Point(this.Left + this.Width / 2, this.Top + this.Height / 2);
this.Width = (int)(this.BackgroundImage.Width * zoomLevel);
this.Height = (int)(this.BackgroundImage.Height * zoomLevel);
this.Left = oldCenter.X - this.Width / 2;
this.Top = oldCenter.Y - this.Height / 2;
this.zoomLevel = zoomLevel;
}

}
}
6 changes: 3 additions & 3 deletions screenzap/KeyboardHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ public KeyboardHook()
/// <summary>
/// Registers a hot key in the system.
/// </summary>
/// <param name="modifier">The modifiers that are associated with the hot key.</param>
/// <param name="modifiers">The modifiers that are associated with the hot key.</param>
/// <param name="key">The key itself that is associated with the hot key.</param>
public void RegisterHotKey(ModifierKeys modifier, Keys key)
public void RegisterHotKey(ModifierKeys modifiers, Keys key)
{
// increment the counter.
_currentId = _currentId + 1;

// register the hot key.
if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifier, (uint)key))
if (!RegisterHotKey(_window.Handle, _currentId, (uint)modifiers, (uint)key))
throw new InvalidOperationException("Couldn’t register the hot key.");
}

Expand Down
4 changes: 0 additions & 4 deletions screenzap/Overlay.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace screenzap
Expand Down
7 changes: 4 additions & 3 deletions screenzap/Program.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace screenzap
{
static class Program
{
[System.Runtime.InteropServices.DllImport("user32.dll")]
public static extern bool SetProcessDPIAware();

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
SetProcessDPIAware();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Screenzap());
Expand Down
Loading

0 comments on commit 8d79b13

Please sign in to comment.