|
分享源码
界面截图: |
|
是否带模块: |
纯源码 |
备注说明: |
- |
改进下上次那个自动缩放,增加了控件锚点,同时,修复分组框这种父控件的问题,记得也要缩放父控件,然后子控件就可以了。父控件和子控件实测没有先后。 窗口程序集名 | 保 留 | 保 留 | 备 注 | 窗口程序集_启动窗口 | | | | 调试输出 (初始化自动缩放 (取窗口句柄 ()) )添加自动缩放组件 (编辑框1. 取窗口句柄 (), 0, 0, 1, 0 )添加自动缩放组件 (编辑框2. 取窗口句柄 (), 0, 0, 1, 0 )添加自动缩放组件 (按钮1. 取窗口句柄 (), 1, 0, 1, 0 )添加自动缩放组件 (分组框1. 取窗口句柄 (), 1, 1, 1, 1 )释放自动缩放 () 还是基于.net4.0的c#
[C#] 纯文本查看 复制代码 using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace AutoScalingDLL
{
public class AutoScaler
{
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern uint GetCurrentThreadId();
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
[DllImport("user32.dll")]
private static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
[DllImport("user32.dll")]
private static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll")]
private static extern IntPtr GetParent(IntPtr hWnd);
private const int WH_CALLWNDPROC = 4;
private const int WM_SIZE = 0x0005;
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential)]
private struct CWPSTRUCT
{
public IntPtr lParam;
public IntPtr wParam;
public int message;
public IntPtr hwnd;
}
[StructLayout(LayoutKind.Sequential)]
private struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
[StructLayout(LayoutKind.Sequential)]
private struct POINT
{
public int X;
public int Y;
}
private static IntPtr _hookHandle = IntPtr.Zero;
private static HookProc _hookProc;
private static IntPtr _mainWindowHandle;
private static Dictionary<IntPtr, ControlInfo> _controls = new Dictionary<IntPtr, ControlInfo>();
private static RECT _originalWindowRect;
private class ControlInfo
{
public float LeftRatio;
public float TopRatio;
public float WidthRatio;
public float HeightRatio;
public bool AnchorLeft;
public bool AnchorTop;
public bool AnchorRight;
public bool AnchorBottom;
public IntPtr ParentHandle;
}
[DllExport("InitializeAutoScaling", CallingConvention = CallingConvention.StdCall)]
public static bool InitializeAutoScaling(IntPtr hWnd)
{
if (_hookHandle != IntPtr.Zero)
{
return false; // Already initialized
}
_mainWindowHandle = hWnd;
GetWindowRect(_mainWindowHandle, out _originalWindowRect);
_hookProc = new HookProc(WindowProc);
_hookHandle = SetWindowsHookEx(WH_CALLWNDPROC, _hookProc, IntPtr.Zero, GetCurrentThreadId());
return _hookHandle != IntPtr.Zero;
}
[DllExport("AddControlToAutoScale", CallingConvention = CallingConvention.StdCall)]
public static bool AddControlToAutoScale(IntPtr hWnd, int anchorLeft, int anchorTop, int anchorRight, int anchorBottom)
{
if (_hookHandle == IntPtr.Zero || _controls.ContainsKey(hWnd))
{
return false;
}
RECT controlRect;
GetWindowRect(hWnd, out controlRect);
IntPtr parentHandle = GetParent(hWnd);
RECT parentRect;
GetWindowRect(parentHandle, out parentRect);
POINT topLeft = new POINT { X = controlRect.Left, Y = controlRect.Top };
POINT bottomRight = new POINT { X = controlRect.Right, Y = controlRect.Bottom };
ScreenToClient(parentHandle, ref topLeft);
ScreenToClient(parentHandle, ref bottomRight);
int parentWidth = parentRect.Right - parentRect.Left;
int parentHeight = parentRect.Bottom - parentRect.Top;
ControlInfo info = new ControlInfo
{
LeftRatio = (float)topLeft.X / parentWidth,
TopRatio = (float)topLeft.Y / parentHeight,
WidthRatio = (float)(bottomRight.X - topLeft.X) / parentWidth,
HeightRatio = (float)(bottomRight.Y - topLeft.Y) / parentHeight,
AnchorLeft = anchorLeft != 0,
AnchorTop = anchorTop != 0,
AnchorRight = anchorRight != 0,
AnchorBottom = anchorBottom != 0,
ParentHandle = parentHandle
};
_controls.Add(hWnd, info);
return true;
}
private static IntPtr WindowProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0)
{
CWPSTRUCT cwp = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT));
if (cwp.message == WM_SIZE)
{
foreach (var kvp in _controls)
{
IntPtr controlHandle = kvp.Key;
ControlInfo info = kvp.Value;
RECT parentRect;
GetWindowRect(info.ParentHandle, out parentRect);
int parentWidth = parentRect.Right - parentRect.Left;
int parentHeight = parentRect.Bottom - parentRect.Top;
int newLeft = info.AnchorLeft ? (int)(info.LeftRatio * parentWidth) : (int)(info.LeftRatio * parentWidth);
int newTop = info.AnchorTop ? (int)(info.TopRatio * parentHeight) : (int)(info.TopRatio * parentHeight);
int newRight = info.AnchorRight ? parentWidth - (int)((1 - info.LeftRatio - info.WidthRatio) * parentWidth) : newLeft + (int)(info.WidthRatio * parentWidth);
int newBottom = info.AnchorBottom ? parentHeight - (int)((1 - info.TopRatio - info.HeightRatio) * parentHeight) : newTop + (int)(info.HeightRatio * parentHeight);
int newControlWidth = newRight - newLeft;
int newControlHeight = newBottom - newTop;
MoveWindow(controlHandle, newLeft, newTop, newControlWidth, newControlHeight, true);
}
}
}
return CallNextHookEx(_hookHandle, nCode, wParam, lParam);
}
[DllExport("FinalizeAutoScaling", CallingConvention = CallingConvention.StdCall)]
public static void FinalizeAutoScaling()
{
if (_hookHandle != IntPtr.Zero)
{
UnhookWindowsHookEx(_hookHandle);
_hookHandle = IntPtr.Zero;
}
_controls.Clear();
}
}
}
|
评分
-
查看全部评分
|