开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1353|回复: 37
收起左侧

[易语言纯源码] 自动缩放界面组件-改进下,修复分组框,增加锚点

[复制链接]
结帖率:0% (0/1)
发表于 2024-9-29 16:29:51 | 显示全部楼层 |阅读模式   上海市上海市
分享源码
界面截图:
是否带模块: 纯源码
备注说明: -
改进下上次那个自动缩放,增加了控件锚点,同时,修复分组框这种父控件的问题,记得也要缩放父控件,然后子控件就可以了。父控件和子控件实测没有先后。
  
窗口程序集名保 留  保 留备 注
窗口程序集_启动窗口   
子程序名返回值类型公开备 注
__启动窗口_创建完毕  
调试输出 (初始化自动缩放 (取窗口句柄 ()))
添加自动缩放组件 (编辑框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, 下载次数: 36, 下载积分: 精币 -2 枚

评分

参与人数 3好评 +1 精币 +4 收起 理由
wa690602724 + 1 感谢分享,很给力!~
kyo9766 + 1 感谢分享,很给力!~
quary + 1 + 2 支持开源~!感谢分享

查看全部评分


结帖率:100% (3/3)

签到天数: 13 天

发表于 2024-12-8 10:54:11 | 显示全部楼层   河南省南阳市
例子发上来呗  我的咋提示 错误(10003): 指定Dll命令名称“初始化自动缩放”未找到。  加了DLL命令了啊
回复 支持 反对

使用道具 举报

签到天数: 3 天

发表于 2024-12-4 10:53:01 | 显示全部楼层   北京市北京市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

发表于 2024-11-13 15:19:23 | 显示全部楼层   湖北省天门市
感谢分享
回复 支持 反对

使用道具 举报

发表于 2024-11-6 16:21:37 | 显示全部楼层   四川省成都市
新版EXUI无效,旧版不支持容器内的子组件一起缩放
回复 支持 反对

使用道具 举报

签到天数: 18 天

发表于 2024-10-3 12:44:54 | 显示全部楼层   广西壮族自治区柳州市

感谢分享
回复 支持 反对

使用道具 举报

结帖率:90% (9/10)

签到天数: 6 天

发表于 2024-10-3 12:27:38 | 显示全部楼层   云南省大理白族自治州
666大佬
回复 支持 反对

使用道具 举报

签到天数: 22 天

发表于 2024-10-3 09:39:35 | 显示全部楼层   浙江省宁波市
感谢分享,支持开源!!!
回复 支持 反对

使用道具 举报

结帖率:50% (1/2)

签到天数: 4 天

发表于 2024-10-2 10:34:33 | 显示全部楼层   四川省泸州市
感谢分享,之前版本也使用过
回复 支持 反对

使用道具 举报

结帖率:83% (25/30)

签到天数: 4 天

发表于 2024-10-1 11:37:44 | 显示全部楼层   湖南省长沙市
感谢分享,很给力!~
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表