发布时间:2026/8/6 13:15:15
让对话框窗口限制在最大和最小尺寸之间 目录1. 效果演示2. 功能介绍3. 实现过程4. 完整源码5. 相关合集1. 效果演示2. 功能介绍按住鼠标左键拖动边框在最大和最小尺寸之间调整窗口大小。3. 实现过程之前发布过一篇这样的文章让对话框窗口支持边框大小调整让对话框窗口支持边框大小调整让对话框窗口支持边框大小调整用户可以使用鼠标左键任意调整窗口大小。今天我们再对它进行一个功能拓展让对话框窗口尺寸永远限制在设定好的最大和最小尺寸之间。这对于VBA列表视图Listview等控件非常友好可以有效避免窗口尺寸过小导致数据显示不完整的情况发生。灵感晚间在搜索Windows通知时偶然发现了WM_GETMINMAXINFO通知简介描述的非常有趣当窗口的大小或位置即将更改时发送到窗口。 应用程序可以使用此消息来替代窗口的默认最大大小和位置或者其默认的最小或最大跟踪大小。这意味着我们可以在窗口大小调整时进行手动限制。于是你现在看的这篇文章诞生了。如何使用WM_GETMINMAXINFO通知要知道子类化窗口过程一共有四个参数分别是hwnd、Msg、wParam和lParam。窗口过程在每次接收到一个通知时也会接收到这四个参数的信息。其中wParam和lParam参数因通知而异比如在接收到WM_GETMINMAXINFO通知时lParam参数包含了专属结构MINMAXINFO的全部信息而wParam参数却没有用到。3.1. 声明该通知的专属结构MINMAXINFOPrivate Type POINTAPI x As Long y As Long End Type Private Type MINMAXINFO ptReserved As POINTAPI ptMaxSize As POINTAPI ptMaxPosition As POINTAPI ptMinTrackSize As POINTAPI ptMaxTrackSize As POINTAPI End Type3.2. 使用RtlMoveMemory函数从内存中复制出专属结构的信息获取专属结构信息 Dim mmmm As MINMAXINFO RtlMoveMemory mmmm, ByVal lParam, LenB(mmmm)3.3. 修改结构中所需的成员值这里修改了结构成员ptMinTrackSize最小跟踪尺寸和ptMaxTrackSize最大跟踪尺寸值也就是在调整窗口大小时限制的最小尺寸和最大尺寸。指定窗口最小尺寸 mmmm.ptMinTrackSize.x 200 mmmm.ptMinTrackSize.y 150 指定窗口最大尺寸 mmmm.ptMaxTrackSize.x 320 mmmm.ptMaxTrackSize.y 2403.4. 调用RtlMoveMemory函数将修改后的结构信息复制回内存中更改内存中的结构信息 RtlMoveMemory ByVal lParam, mmmm, LenB(mmmm)3.5. 添加返回值防止系统默认处理用户已处理 WindowProcfrmMain Nuptr Exit Function4. 完整源码建议大家在了解实现原理之后亲自动手编写代码实操这样才能提升自身能力。• 代码适配32与64位系统• 代码不区分WPS或EXCEL VBA环境你只需要复制代码到一个新模块中就能运行晚间有雨伴人眠202608011619 原创代码转载或二创请标明来源 #If VBA7 And Win64 Then Private Declare PtrSafe Function IsWindow Lib user32 (ByVal hwnd As LongPtr) As Long Private Declare PtrSafe Function ShowWindow Lib user32 (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Long Private Declare PtrSafe Function FindWindowA Lib user32 (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr Private Declare PtrSafe Function CreateWindowExA Lib user32 (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal HwndParent As LongPtr, ByVal hMenu As LongPtr, ByVal Hinstance As LongPtr, lpParam As Any) As LongPtr Private Declare PtrSafe Function SetWindowLongA Lib user32 Alias SetWindowLongPtrA (ByVal hwnd As LongPtr, ByVal nIndex As Long, ByVal dwNewLong As LongPtr) As LongPtr Private Declare PtrSafe Function SetFocus Lib user32 (ByVal hwnd As LongPtr) As LongPtr Private Declare PtrSafe Function CallWindowProcA Lib user32 (ByVal lpPrevWndFunc As LongPtr, ByVal hwnd As LongPtr, ByVal msg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr Private Declare PtrSafe Function DestroyWindow Lib user32 (ByVal hwnd As LongPtr) As Long Private Declare PtrSafe Function GetWindowLongA Lib user32 Alias GetWindowLongPtrA (ByVal hwnd As LongPtr, ByVal nIndex As Long) As LongPtr Private Declare PtrSafe Sub RtlMoveMemory Lib kernel32 (Destination As Any, Source As Any, ByVal Length As LongPtr) #Else Private Declare Function IsWindow Lib user32 (ByVal hwnd As Long) As Long Private Declare Function ShowWindow Lib user32 (ByVal hwnd As Long, ByVal nCmdShow As Long) As Long Private Declare Function FindWindowA Lib user32 (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare Function CreateWindowExA Lib user32 (ByVal dwExStyle As Long, ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal HwndParent As Long, ByVal hMenu As Long, ByVal Hinstance As Long, lpParam As Any) As Long Private Declare Function SetWindowLongA Lib user32 (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function SetFocus Lib user32 (ByVal hwnd As Long) As Long Private Declare Function CallWindowProcA Lib user32 (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Private Declare Function DestroyWindow Lib user32 (ByVal hwnd As Long) As Long Private Declare Function GetWindowLongA Lib user32 Alias GetWindowLongPtrA (ByVal hwnd As Long, ByVal nIndex As Long) As Long Private Declare Sub RtlMoveMemory Lib kernel32 (Destination As Any, Source As Any, ByVal Length As Long) #End If #If VBA7 And Win64 Then Private Type POINTAPI x As Long y As Long End Type Private Type MINMAXINFO ptReserved As POINTAPI ptMaxSize As POINTAPI ptMaxPosition As POINTAPI ptMinTrackSize As POINTAPI ptMaxTrackSize As POINTAPI End Type #Else Private Type POINTAPI x As Long y As Long End Type Private Type MINMAXINFO ptReserved As POINTAPI ptMaxSize As POINTAPI ptMaxPosition As POINTAPI ptMinTrackSize As POINTAPI ptMaxTrackSize As POINTAPI End Type #End If #If VBA7 And Win64 Then Private Const Nuptr As LongPtr 0 Private Ud As UserDialogType Private Type UserDialogType Dialog As LongPtr DialogProc As LongPtr Editor As LongPtr EditorState As LongPtr End Type #Else Private Const Nuptr As Long 0 Private Ud As UserDialogType Private Type UserDialogType Dialog As Long DialogProc As Long Editor As Long EditorState As Long End Type #End If Private Const SW_SHOW 5 Private Const SW_HIDE 0 Private Const WS_VISIBLE H10000000 Private Const WS_POPUP H80000000 Private Const WS_SYSMENU H80000 Private Const WS_CAPTION HC00000 Private Const WS_EX_DLGMODALFRAME H1 Private Const GWL_WNDPROC -4 Private Const WM_CLOSE H10 Private Const WM_DESTROY H2 Private Const GWL_STYLE -16 Private Const WS_THICKFRAME H40000 Private Const WM_GETMINMAXINFO H24 Public Sub CreateUserDialog() 对话框窗口若已存在则直接显示 If IsWindow(Ud.Dialog) Then ShowWindow Ud.Dialog, SW_SHOW: Exit Sub 获取编辑器句柄并隐藏 Ud.Editor FindWindowA(wndclass_desked_gsk, vbNullString) Ud.EditorState ShowWindow(Ud.Editor, SW_HIDE) 指定对话框初始样式 Dim StyleS: StyleS WS_VISIBLE Or WS_POPUP Or WS_SYSMENU Or WS_CAPTION Dim StyleE: StyleE WS_EX_DLGMODALFRAME 创建对话框主窗口 Ud.Dialog CreateWindowExA(StyleE, #32770, UserDialog, StyleS, 15, 50, 300, 200, Nuptr, Nuptr, Nuptr, Nuptr) 添加窗口样式 SetWindowLongA Ud.Dialog, GWL_STYLE, GetWindowLongA(Ud.Dialog, GWL_STYLE) Or WS_THICKFRAME 设置对话框子类化 Ud.DialogProc SetWindowLongA(Ud.Dialog, GWL_WNDPROC, AddressOf WindowProcUdDialog) 设置焦点 SetFocus Ud.Dialog End Sub #If VBA7 And Win64 Then Private Function WindowProcUdDialog(ByVal hwnd As LongPtr, ByVal msg As Long, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As LongPtr #Else Private Function WindowProcUdDialog(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long #End If Select Case msg 窗口即将关闭时 Case WM_CLOSE 销毁窗口 DestroyWindow Ud.Dialog 用户已处理 WindowProcUdDialog Nuptr Exit Function 窗口销毁后 Case WM_DESTROY 取消子类化 SetWindowLongA Ud.Dialog, GWL_WNDPROC, Ud.DialogProc 还原编辑器的显示状态 If Ud.EditorState Then ShowWindow Ud.Editor, SW_SHOW 清理内存 Dim EmptyUd As UserDialogType: Ud EmptyUd 用户已处理 WindowProcUdDialog Nuptr Exit Function 限制窗口的最大/最小尺寸 Case WM_GETMINMAXINFO 获取专属结构信息 Dim mmmm As MINMAXINFO RtlMoveMemory mmmm, ByVal lParam, LenB(mmmm) 指定窗口最小尺寸 mmmm.ptMinTrackSize.x 200 mmmm.ptMinTrackSize.y 150 指定窗口最大尺寸 mmmm.ptMaxTrackSize.x 320 mmmm.ptMaxTrackSize.y 240 更改内存中的结构信息 RtlMoveMemory ByVal lParam, mmmm, LenB(mmmm) 用户已处理 WindowProcUdDialog Nuptr Exit Function End Select 调用默认通知处理 WindowProcUdDialog CallWindowProcA(Ud.DialogProc, hwnd, msg, wParam, lParam) End Function5. 相关合集关于#32770对话框窗口的专项开发计划

相关新闻

2026/8/6 13:15:15

最小二乘问题详解22:抗差估计与增量式SFM的工程稳健实现

最小二乘问题详解22:抗差估计与增量式SFM的工程稳健实现 大家好,欢迎来到《最小二乘问题详解》系列的第22篇。前几篇我们聊了标准最小二乘(LS)的推导、QR分解、Cholesky分解,还有非线性优化的高斯牛顿和LM算法。但今天…

2026/8/6 13:15:15

Python实现高效相似性检索:FAISS实战指南

1. 项目概述在数据密集型应用中,相似性检索是一个常见但极具挑战性的需求。想象一下,你手头有数百万条文本、图片或商品数据,如何快速找到与目标最相似的几条记录?这就是相似性检索要解决的核心问题。Python作为数据科学领域的主流…

2026/8/6 13:10:15

深度学习VGG网络实战:从3x3卷积原理到PyTorch实现与迁移学习

1. 项目概述:从“头歌”到VGG的深度学习实战之旅最近在“头歌”平台上看到了一个关于VGG的实践项目,这让我想起了几年前自己刚接触深度学习和计算机视觉时,对着VGG论文和代码反复琢磨的日子。VGG网络,全称Visual Geometry Group&a…

2026/8/6 15:15:24

如何让微信聊天记录真正属于你?WeChatMsg三步导出完整指南

如何让微信聊天记录真正属于你?WeChatMsg三步导出完整指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/W…

2026/8/6 15:15:24

C/C++与EasyX实战:从零构建俄罗斯方块游戏

1. 项目概述:为什么选择C/C和EasyX来复刻经典?俄罗斯方块,这个诞生于上世纪80年代的电子游戏,几乎刻进了每一个程序员的DNA里。它规则简单,逻辑清晰,但想要用代码完美地实现它,却是一个检验编程…

2026/8/6 15:15:24

【FAQ】linux登录失败或者执行命令提示bash: fork: Cannot allocate memory

一、现象 服务器登录失败或者提示失败 bash: fork: Cannot allocate memory二、盘查 1、先使用free -m 查看内存 有没有问题 2、没有问题再看最大进程数 sysctl kernel.pid_max3、然后核实下当前的进程数 ps -eLf | wc -l三、解决方法 修改最大进程数后系统恢复 echo 1000000 &…

2026/8/6 15:15:24

IGP快速重路由(FRR)原理与部署实战:实现毫秒级网络故障切换

1. 项目概述:为什么IGP的FRR特性是网络稳定的基石?在网络运维和架构设计的圈子里,有一个词经常被提起,那就是“收敛”。简单来说,就是当网络中的一条链路或者一台设备发生故障时,整个网络需要多长时间才能重…

2026/8/6 15:15:24

国产GPGPU与科学计算软件ABACUS的协同优化实践

1. 国产GPGPU与科学计算软件的生态共建实践 最近在半导体和科学计算领域,一个值得关注的动向是国产GPGPU厂商沐曦与国产第一性原理计算软件ABACUS的深度合作。作为一名长期关注高性能计算的技术从业者,我认为这种"国产硬件国产软件"的协同创新…

2026/8/6 15:10:24

为什么越来越多学校建设智慧食堂?真正解决的不只是排队问题

从自助称重到智能结算,校园食堂如何实现降本增效?每天中午,对于学校食堂而言,都是一次高峰运营挑战。下课铃响后,大量学生集中进入食堂,窗口前迅速排起队伍。工作人员需要不断完成打餐、称重、计算金额、收…

2026/8/5 3:13:11

如何用免费工具突破游戏窗口限制:SRWE完整使用指南

如何用免费工具突破游戏窗口限制:SRWE完整使用指南 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否遇到过这样的困扰?想为心爱的游戏截图,却发现游戏不支持自定义分辨率…

2026/8/6 0:04:22

电力系统调度中的源荷不确定性建模与优化实践

1. 电力系统调度中的源荷不确定性挑战现代电力系统正面临前所未有的复杂性,其中源荷不确定性(Source-Load Uncertainty)已成为调度决策中最棘手的难题之一。我在参与某省级电网调度系统升级时,曾遇到风电预测误差导致日内调度计划…

2026/8/6 0:04:22

VGG-T3技术解析:3D重建速度的革命性突破

1. 项目概述:VGG-T3如何重新定义3D重建速度在计算机视觉领域,3D场景重建一直是个计算密集型任务。传统方法重建1000帧图像规模的场景往往需要数小时甚至更长时间,而英伟达最新发布的VGG-T3技术将这个时间压缩到了惊人的54秒。这个突破性进展来…

2026/8/6 0:04:22

深度解析旅游网站建设的意义及其对行业发展的深远影响与核心价值体现

在这个数字化浪潮席卷全球的今天,我们似乎已经忘记了,曾经有一段时间,人们想要去一个陌生的地方,只能靠在书桌前翻阅厚厚的旅游杂志,或者向刚从那里回来的朋友询问那些模糊不清的印象。那时候,“远方”是一个需要精打细算才能抵达的奢侈概念。而现在,只需要一部手机,轻…

2026/8/5 19:21:13

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/5 19:21:13

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/5 19:21:13

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…