192 lines
5.1 KiB
C#
192 lines
5.1 KiB
C#
|
using System;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Windows.Forms;
|
|||
|
|
|||
|
// ReSharper disable InconsistentNaming
|
|||
|
|
|||
|
namespace IPCamAppBar
|
|||
|
{
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
internal struct RECT
|
|||
|
{
|
|||
|
public int left;
|
|||
|
public int top;
|
|||
|
public int right;
|
|||
|
public int bottom;
|
|||
|
}
|
|||
|
|
|||
|
[StructLayout(LayoutKind.Sequential)]
|
|||
|
internal struct APPBARDATA
|
|||
|
{
|
|||
|
public int cbSize;
|
|||
|
public IntPtr hWnd;
|
|||
|
public int uCallbackMessage;
|
|||
|
public int uEdge;
|
|||
|
public RECT rc;
|
|||
|
public IntPtr lParam;
|
|||
|
}
|
|||
|
|
|||
|
internal enum ABMsg
|
|||
|
{
|
|||
|
ABM_NEW = 0,
|
|||
|
ABM_REMOVE,
|
|||
|
ABM_QUERYPOS,
|
|||
|
ABM_SETPOS,
|
|||
|
ABM_GETSTATE,
|
|||
|
ABM_GETTASKBARPOS,
|
|||
|
ABM_ACTIVATE,
|
|||
|
ABM_GETAUTOHIDEBAR,
|
|||
|
ABM_SETAUTOHIDEBAR,
|
|||
|
ABM_WINDOWPOSCHANGED,
|
|||
|
ABM_SETSTATE
|
|||
|
}
|
|||
|
|
|||
|
internal enum ABNotify
|
|||
|
{
|
|||
|
ABN_STATECHANGE = 0,
|
|||
|
ABN_POSCHANGED,
|
|||
|
ABN_FULLSCREENAPP,
|
|||
|
ABN_WINDOWARRANGE
|
|||
|
}
|
|||
|
|
|||
|
internal enum ABEdge
|
|||
|
{
|
|||
|
ABE_LEFT = 0,
|
|||
|
ABE_TOP,
|
|||
|
ABE_RIGHT,
|
|||
|
ABE_BOTTOM
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public enum AppBarPosition
|
|||
|
{
|
|||
|
Top,
|
|||
|
Left,
|
|||
|
Bottom,
|
|||
|
Right
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public class AppBar : IDisposable
|
|||
|
{
|
|||
|
[DllImport("SHELL32", CallingConvention = CallingConvention.StdCall)]
|
|||
|
private static extern uint SHAppBarMessage(int dwMessage, ref APPBARDATA pData);
|
|||
|
|
|||
|
[DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
|
|||
|
private static extern bool MoveWindow(IntPtr hWnd, int x, int y, int cx, int cy, bool repaint);
|
|||
|
|
|||
|
[DllImport("User32.dll", CharSet = CharSet.Auto)]
|
|||
|
private static extern int RegisterWindowMessage(string msg);
|
|||
|
|
|||
|
|
|||
|
private class PositionParameters
|
|||
|
{
|
|||
|
public Screen Monitor { get; set; }
|
|||
|
public AppBarPosition Position { get; set; }
|
|||
|
public int Size { get; set; }
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private bool disposed;
|
|||
|
private APPBARDATA appBarData;
|
|||
|
private PositionParameters lastPosition;
|
|||
|
|
|||
|
|
|||
|
|
|||
|
public AppBar(IntPtr windowHandle)
|
|||
|
{
|
|||
|
appBarData.cbSize = Marshal.SizeOf(appBarData);
|
|||
|
appBarData.hWnd = windowHandle;
|
|||
|
appBarData.uCallbackMessage = RegisterWindowMessage("AppBarMessage");
|
|||
|
|
|||
|
SHAppBarMessage((int)ABMsg.ABM_NEW, ref appBarData);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void Dispose()
|
|||
|
{
|
|||
|
if (disposed)
|
|||
|
throw new ObjectDisposedException(GetType().Name);
|
|||
|
|
|||
|
SHAppBarMessage((int)ABMsg.ABM_REMOVE, ref appBarData);
|
|||
|
disposed = true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void SetPosition(Screen monitor, AppBarPosition position, int size)
|
|||
|
{
|
|||
|
appBarData.rc.top = monitor.Bounds.Top;
|
|||
|
appBarData.rc.left = monitor.Bounds.Left;
|
|||
|
appBarData.rc.bottom = monitor.Bounds.Bottom;
|
|||
|
appBarData.rc.right= monitor.Bounds.Right;
|
|||
|
|
|||
|
ApplyPosition(position, size);
|
|||
|
SHAppBarMessage((int)ABMsg.ABM_QUERYPOS, ref appBarData);
|
|||
|
|
|||
|
ApplyPosition(position, size);
|
|||
|
SHAppBarMessage((int)ABMsg.ABM_SETPOS, ref appBarData);
|
|||
|
|
|||
|
MoveWindow(
|
|||
|
appBarData.hWnd,
|
|||
|
appBarData.rc.left,
|
|||
|
appBarData.rc.top,
|
|||
|
appBarData.rc.right - appBarData.rc.left,
|
|||
|
appBarData.rc.bottom - appBarData.rc.top,
|
|||
|
true);
|
|||
|
|
|||
|
lastPosition = new PositionParameters
|
|||
|
{
|
|||
|
Monitor = monitor,
|
|||
|
Position = position,
|
|||
|
Size = size
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
public void HandleMessage(Message m)
|
|||
|
{
|
|||
|
if (m.Msg == appBarData.uCallbackMessage && m.WParam.ToInt32() == (int)ABNotify.ABN_POSCHANGED)
|
|||
|
UpdatePosition();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void UpdatePosition()
|
|||
|
{
|
|||
|
if (lastPosition == null)
|
|||
|
return;
|
|||
|
|
|||
|
SetPosition(lastPosition.Monitor, lastPosition.Position, lastPosition.Size);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private void ApplyPosition(AppBarPosition position, int size)
|
|||
|
{
|
|||
|
switch (position)
|
|||
|
{
|
|||
|
case AppBarPosition.Top:
|
|||
|
appBarData.uEdge = (int)ABEdge.ABE_TOP;
|
|||
|
appBarData.rc.bottom = appBarData.rc.top + size;
|
|||
|
break;
|
|||
|
|
|||
|
case AppBarPosition.Left:
|
|||
|
appBarData.uEdge = (int)ABEdge.ABE_LEFT;
|
|||
|
appBarData.rc.right = appBarData.rc.left + size;
|
|||
|
break;
|
|||
|
|
|||
|
case AppBarPosition.Bottom:
|
|||
|
appBarData.uEdge = (int)ABEdge.ABE_BOTTOM;
|
|||
|
appBarData.rc.top = appBarData.rc.bottom - size;
|
|||
|
break;
|
|||
|
|
|||
|
case AppBarPosition.Right:
|
|||
|
appBarData.uEdge = (int)ABEdge.ABE_RIGHT;
|
|||
|
appBarData.rc.left = appBarData.rc.right - size;
|
|||
|
break;
|
|||
|
|
|||
|
default:
|
|||
|
throw new ArgumentOutOfRangeException(nameof(position), position, @"Invalid position value");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|