using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace GHelper.Helpers
{
public class OSDNativeForm : NativeWindow, IDisposable
{
private bool _disposed = false;
private byte _alpha = 250;
private Size _size = new Size(350, 50);
private Point _location = new Point(50, 50);
protected virtual void PerformPaint(PaintEventArgs e)
{
}
protected internal void Invalidate()
{
UpdateLayeredWindow();
}
private void UpdateLayeredWindow()
{
Bitmap bitmap1 = new Bitmap(Size.Width, Size.Height, PixelFormat.Format32bppArgb);
using (Graphics graphics1 = Graphics.FromImage(bitmap1))
{
Rectangle rectangle1;
SIZE size1;
POINT point1;
POINT point2;
BLENDFUNCTION blendfunction1;
rectangle1 = new Rectangle(0, 0, Size.Width, Size.Height);
PerformPaint(new PaintEventArgs(graphics1, rectangle1));
nint ptr1 = User32.GetDC(nint.Zero);
nint ptr2 = Gdi32.CreateCompatibleDC(ptr1);
nint ptr3 = bitmap1.GetHbitmap(Color.FromArgb(0));
nint ptr4 = Gdi32.SelectObject(ptr2, ptr3);
size1.cx = Size.Width;
size1.cy = Size.Height;
point1.x = Location.X;
point1.x = Location.X;
point1.y = Location.Y;
point2.x = 0;
point2.y = 0;
blendfunction1 = new BLENDFUNCTION();
blendfunction1.BlendOp = 0;
blendfunction1.BlendFlags = 0;
blendfunction1.SourceConstantAlpha = _alpha;
blendfunction1.AlphaFormat = 1;
User32.UpdateLayeredWindow(Handle, ptr1, ref point1, ref size1, ptr2, ref point2, 0, ref blendfunction1, 2); //2=ULW_ALPHA
Gdi32.SelectObject(ptr2, ptr4);
User32.ReleaseDC(nint.Zero, ptr1);
Gdi32.DeleteObject(ptr3);
Gdi32.DeleteDC(ptr2);
}
}
public virtual void Show()
{
if (Handle == nint.Zero) //if handle don't equal to zero - window was created and just hided
CreateWindowOnly();
User32.ShowWindow(Handle, User32.SW_SHOWNOACTIVATE);
}
public virtual void Hide()
{
if (Handle == nint.Zero)
return;
User32.ShowWindow(Handle, User32.SW_HIDE);
DestroyHandle();
}
public virtual void Close()
{
Hide();
Dispose();
}
private void CreateWindowOnly()
{
CreateParams params1 = new CreateParams();
params1.Caption = "FloatingNativeWindow";
int nX = _location.X;
int nY = _location.Y;
Screen screen1 = Screen.FromHandle(Handle);
if (nX + _size.Width > screen1.Bounds.Width)
{
nX = screen1.Bounds.Width - _size.Width;
}
if (nY + _size.Height > screen1.Bounds.Height)
{
nY = screen1.Bounds.Height - _size.Height;
}
_location = new Point(nX, nY);
Size size1 = _size;
Point point1 = _location;
params1.X = nX;
params1.Y = nY;
params1.Height = size1.Height;
params1.Width = size1.Width;
params1.Parent = nint.Zero;
uint ui = User32.WS_POPUP;
params1.Style = (int)ui;
params1.ExStyle = User32.WS_EX_TOPMOST | User32.WS_EX_TOOLWINDOW | User32.WS_EX_LAYERED | User32.WS_EX_NOACTIVATE | User32.WS_EX_TRANSPARENT;
CreateHandle(params1);
UpdateLayeredWindow();
}
protected virtual void SetBoundsCore(int x, int y, int width, int height)
{
if (X != x || Y != y || Width != width || Height != height)
{
if (Handle != nint.Zero)
{
int num1 = 20;
if (X == x && Y == y)
{
num1 |= 2;
}
if (Width == width && Height == height)
{
num1 |= 1;
}
User32.SetWindowPos(Handle, nint.Zero, x, y, width, height, (uint)num1);
}
else
{
Location = new Point(x, y);
Size = new Size(width, height);
}
}
}
#region # Properties #
///
/// Get or set position of top-left corner of floating native window in screen coordinates
///
public virtual Point Location
{
get { return _location; }
set
{
if (Handle != nint.Zero)
{
SetBoundsCore(value.X, value.Y, _size.Width, _size.Height);
RECT rect = new RECT();
User32.GetWindowRect(Handle, ref rect);
_location = new Point(rect.left, rect.top);
UpdateLayeredWindow();
}
else
{
_location = value;
}
}
}
///
/// Get or set size of client area of floating native window
///
public virtual Size Size
{
get { return _size; }
set
{
if (Handle != nint.Zero)
{
SetBoundsCore(_location.X, _location.Y, value.Width, value.Height);
RECT rect = new RECT();
User32.GetWindowRect(Handle, ref rect);
_size = new Size(rect.right - rect.left, rect.bottom - rect.top);
UpdateLayeredWindow();
}
else
{
_size = value;
}
}
}
///
/// Gets or sets the height of the floating native window
///
public int Height
{
get { return _size.Height; }
set
{
_size = new Size(_size.Width, value);
}
}
///
/// Gets or sets the width of the floating native window
///
public int Width
{
get { return _size.Width; }
set
{
_size = new Size(value, _size.Height);
}
}
///
/// Get or set x-coordinate of top-left corner of floating native window in screen coordinates
///
public int X
{
get { return _location.X; }
set
{
Location = new Point(value, Location.Y);
}
}
///
/// Get or set y-coordinate of top-left corner of floating native window in screen coordinates
///
public int Y
{
get { return _location.Y; }
set
{
Location = new Point(Location.X, value);
}
}
///
/// Get rectangle represented client area of floating native window in client coordinates(top-left corner always has coord. 0,0)
///
public Rectangle Bound
{
get
{
return new Rectangle(new Point(0, 0), _size);
}
}
///
/// Get or set full opacity(255) or full transparency(0) or any intermediate state for floating native window transparency
///
public byte Alpha
{
get { return _alpha; }
set
{
if (_alpha == value) return;
_alpha = value;
UpdateLayeredWindow();
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (!_disposed)
{
DestroyHandle();
_disposed = true;
}
}
#endregion
}
#region # Win32 #
[StructLayout(LayoutKind.Sequential)]
internal struct POINT
{
public int x;
public int y;
}
[StructLayout(LayoutKind.Sequential)]
internal struct RECT
{
public int left;
public int top;
public int right;
public int bottom;
}
[StructLayout(LayoutKind.Sequential)]
internal struct SIZE
{
public int cx;
public int cy;
}
[StructLayout(LayoutKind.Sequential)]
internal struct TRACKMOUSEEVENTS
{
public uint cbSize;
public uint dwFlags;
public nint hWnd;
public uint dwHoverTime;
}
[StructLayout(LayoutKind.Sequential)]
internal struct MSG
{
public nint hwnd;
public int message;
public nint wParam;
public nint lParam;
public int time;
public int pt_x;
public int pt_y;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct BLENDFUNCTION
{
public byte BlendOp;
public byte BlendFlags;
public byte SourceConstantAlpha;
public byte AlphaFormat;
}
internal class User32
{
public const uint WS_POPUP = 0x80000000;
public const int WS_EX_TOPMOST = 0x8;
public const int WS_EX_TOOLWINDOW = 0x80;
public const int WS_EX_LAYERED = 0x80000;
public const int WS_EX_TRANSPARENT = 0x20;
public const int WS_EX_NOACTIVATE = 0x08000000;
public const int SW_SHOWNOACTIVATE = 4;
public const int SW_HIDE = 0;
public const uint AW_HOR_POSITIVE = 0x1;
public const uint AW_HOR_NEGATIVE = 0x2;
public const uint AW_VER_POSITIVE = 0x4;
public const uint AW_VER_NEGATIVE = 0x8;
public const uint AW_CENTER = 0x10;
public const uint AW_HIDE = 0x10000;
public const uint AW_ACTIVATE = 0x20000;
public const uint AW_SLIDE = 0x40000;
public const uint AW_BLEND = 0x80000;
// Methods
private User32()
{
}
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool AnimateWindow(nint hWnd, uint dwTime, uint dwFlags);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool ClientToScreen(nint hWnd, ref POINT pt);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool DispatchMessage(ref MSG msg);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool DrawFocusRect(nint hWnd, ref RECT rect);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint GetDC(nint hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint GetFocus();
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern ushort GetKeyState(int virtKey);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool GetMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint GetParent(nint hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool GetClientRect(nint hWnd, [In, Out] ref RECT rect);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern int GetWindowLong(nint hWnd, int nIndex);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint GetWindow(nint hWnd, int cmd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool GetWindowRect(nint hWnd, ref RECT rect);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool HideCaret(nint hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool InvalidateRect(nint hWnd, ref RECT rect, bool erase);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint LoadCursor(nint hInstance, uint cursor);
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int MapWindowPoints(nint hWndFrom, nint hWndTo, [In, Out] ref RECT rect, int cPoints);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool MoveWindow(nint hWnd, int x, int y, int width, int height, bool repaint);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool PeekMessage(ref MSG msg, int hWnd, uint wFilterMin, uint wFilterMax, uint wFlag);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool PostMessage(nint hWnd, int Msg, uint wParam, uint lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool ReleaseCapture();
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern int ReleaseDC(nint hWnd, nint hDC);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool ScreenToClient(nint hWnd, ref POINT pt);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern uint SendMessage(nint hWnd, int Msg, uint wParam, uint lParam);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint SetCursor(nint hCursor);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern nint SetFocus(nint hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern int SetWindowLong(nint hWnd, int nIndex, int newLong);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern int SetWindowPos(nint hWnd, nint hWndAfter, int X, int Y, int Width, int Height, uint flags);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool SetWindowRgn(nint hWnd, nint hRgn, bool redraw);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool ShowCaret(nint hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool SetCapture(nint hWnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern int ShowWindow(nint hWnd, short cmdShow);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool SystemParametersInfo(uint uiAction, uint uiParam, ref int bRetValue, uint fWinINI);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool TrackMouseEvent(ref TRACKMOUSEEVENTS tme);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool TranslateMessage(ref MSG msg);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool UpdateLayeredWindow(nint hwnd, nint hdcDst, ref POINT pptDst, ref SIZE psize, nint hdcSrc, ref POINT pprSrc, int crKey, ref BLENDFUNCTION pblend, int dwFlags);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool UpdateWindow(nint hwnd);
[DllImport("User32.dll", CharSet = CharSet.Auto)]
internal static extern bool WaitMessage();
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern bool AdjustWindowRectEx(ref RECT lpRect, int dwStyle, bool bMenu, int dwExStyle);
}
internal class Gdi32
{
// Methods
private Gdi32()
{
}
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern int CombineRgn(nint dest, nint src1, nint src2, int flags);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern nint CreateBrushIndirect(ref LOGBRUSH brush);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern nint CreateCompatibleDC(nint hDC);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern nint CreateRectRgnIndirect(ref RECT rect);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern bool DeleteDC(nint hDC);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern nint DeleteObject(nint hObject);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern int GetClipBox(nint hDC, ref RECT rectBox);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern bool PatBlt(nint hDC, int x, int y, int width, int height, uint flags);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern int SelectClipRgn(nint hDC, nint hRgn);
[DllImport("gdi32.dll", CharSet = CharSet.Auto)]
internal static extern nint SelectObject(nint hDC, nint hObject);
}
[StructLayout(LayoutKind.Sequential)]
public struct LOGBRUSH
{
public uint lbStyle;
public uint lbColor;
public uint lbHatch;
}
#endregion
}