精易论坛

标题: 自动缩放界面组件-改进下,修复分组框,增加锚点 [打印本页]

作者: zxxiaopi    时间: 2024-9-29 16:29
标题: 自动缩放界面组件-改进下,修复分组框,增加锚点
改进下上次那个自动缩放,增加了控件锚点,同时,修复分组框这种父控件的问题,记得也要缩放父控件,然后子控件就可以了。父控件和子控件实测没有先后。
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
子程序名返回值类型公开备 注
__启动窗口_创建完毕  
调试输出 (初始化自动缩放 (取窗口句柄 ()))
添加自动缩放组件 (编辑框1.取窗口句柄 (), 0, 0, 1, 0)
添加自动缩放组件 (编辑框2.取窗口句柄 (), 0, 0, 1, 0)
添加自动缩放组件 (按钮1.取窗口句柄 (), 1, 0, 1, 0)
添加自动缩放组件 (分组框1.取窗口句柄 (), 1, 1, 1, 1)
子程序名返回值类型公开备 注
__启动窗口_可否被关闭逻辑型 
释放自动缩放 ()


i支持库列表   支持库注释   
spec特殊功能支持库
还是基于.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();
        }
    }
}


  
DLL命令名返回值类型公开备 注
初始化自动缩放逻辑型 
DLL库文件名:
AutoScalingDLL.dll
在DLL库中对应命令名:
InitializeAutoScaling
参数名类 型传址数组备 注
hWnd整数型
DLL命令名返回值类型公开备 注
添加自动缩放组件逻辑型 
DLL库文件名:
AutoScalingDLL.dll
在DLL库中对应命令名:
AddControlToAutoScale
参数名类 型传址数组备 注
hWnd整数型控件句柄
anchorLeft整数型左边,=1,那就保持和界面左边比列不变,会缩放,=0,就是不动
anchorTop整数型上边
anchorRight整数型右边
anchorBottom整数型下边
DLL命令名返回值类型公开备 注
释放自动缩放 
DLL库文件名:
AutoScalingDLL.dll
在DLL库中对应命令名:
FinalizeAutoScaling
参数名类 型传址数组备 注



AutoScalingDLL.rar

3.56 KB, 下载次数: 41, 下载积分: 精币 -2 枚


作者: 笨来无一悟    时间: 2024-9-29 16:33
功德无量
作者: jysoft2022    时间: 2024-9-29 16:45
谢谢分享
作者: quary    时间: 2024-9-29 16:54
上次那个不支持多窗口,这个支持吗
谢谢楼主分享!!!
好人一生平安!!!

作者: wjswzj0    时间: 2024-9-29 17:14
支持开源~!感谢分享
作者: hmbbya    时间: 2024-9-29 20:42
感谢大佬开源
作者: 亿万    时间: 2024-9-29 20:50
感谢分享
作者: 艾玛克138    时间: 2024-9-29 21:38
谢谢大佬,很好很实用的教程。
作者: a623539929    时间: 2024-9-29 21:48
测试了下,子控件缩放会闪烁!
作者: pipicool    时间: 2024-9-30 00:20
学习一下
作者: renhe2018    时间: 2024-9-30 07:30
不断精进,强大。
作者: 查过    时间: 2024-9-30 07:30
已经顶贴,感谢您对论坛的支持!
作者: 豆豆灰常开心    时间: 2024-9-30 07:35
感谢您对论坛的支持!
作者: 杨明煜    时间: 2024-9-30 07:52
学习看看..!....
作者: year1970    时间: 2024-9-30 08:07
感谢分享,更新很快啊
作者: wuqingg    时间: 2024-9-30 08:51
楼主很听劝,是个做大事的人
作者: wuqingg    时间: 2024-9-30 09:19
请问“anchorLeft”为0和1的区别是?我怎么感觉都一样呀?
作者: 一指温柔    时间: 2024-9-30 09:20
感谢分享
作者: ctry78985    时间: 2024-9-30 09:21
感谢分享
作者: wuqingg    时间: 2024-9-30 09:34
增加高级选择夹之后就黑化了嘿嘿

录制_2024_09_30_09_26_23_211.gif (1.41 MB, 下载次数: 0)

录制_2024_09_30_09_26_23_211.gif

例子.e

152.86 KB, 下载次数: 0, 下载积分: 精币 -2 枚


作者: wgqxj    时间: 2024-9-30 09:48
谢谢分享
作者: kyo9766    时间: 2024-9-30 09:50
很好用,不过每次需要拖着一个dll,不是很方便啊,感谢分享
作者: kuaishou    时间: 2024-9-30 14:00
干货满满,感谢分享
作者: 初学者1    时间: 2024-9-30 15:29
        支持开源~!感谢分享
作者: kantal    时间: 2024-10-1 07:39
感谢分享,很给力!~
作者: 查过    时间: 2024-10-1 07:42
感谢您对论坛的支持!
作者: 豆豆灰常开心    时间: 2024-10-1 07:47
感谢楼主分享!
作者: KEY心碎    时间: 2024-10-1 08:31
能懒人版  无需添加一堆组件进去吗?
作者: please    时间: 2024-10-1 09:37
感谢分享,支持开源!!!
作者: xtavoxing    时间: 2024-10-1 11:37
感谢分享,很给力!~
作者: byronzhj    时间: 2024-10-2 10:34
感谢分享,之前版本也使用过
作者: please    时间: 2024-10-3 09:39
感谢分享,支持开源!!!
作者: Av0x    时间: 2024-10-3 12:27
666大佬
作者: lzptts    时间: 2024-10-3 12:44

感谢分享
作者: nymanyim    时间: 2024-11-6 16:21
新版EXUI无效,旧版不支持容器内的子组件一起缩放
作者: xuaswq    时间: 2024-11-13 15:19
感谢分享
作者: 熊不熊    时间: 2024-12-4 10:53
感谢分享,很给力!~
作者: aijianli    时间: 2024-12-8 10:54
例子发上来呗  我的咋提示 错误(10003): 指定Dll命令名称“初始化自动缩放”未找到。  加了DLL命令了啊




欢迎光临 精易论坛 (https://125.confly.eu.org/) Powered by Discuz! X3.4