delphi - 关闭 word 侧面板时 MS Word 奇数 ole 容器对齐问题
问题描述
我不确定这是否是德尔福特有的问题。我有一个带有顶部对齐工具栏和 alClient 对齐 OleContainer 的表单。当我打开表单并将 Word 加载到 olecontainer 中时,它会正确对齐并且 Word 对象会按您的预期显示。
如果您随后打开任何 word 侧面板(例如 F1 打开右侧的帮助面板,Ctrl+F 打开左侧的搜索等),这些面板会正确打开并相应地减小 word 文档的大小以适应自己,但是当您关闭侧面板,word 文档不会调整大小以回收该面板占用的空间。添加一个函数来重新对齐容器什么都不做。
很明显,单词侧面板(以及功能区本身)没有在 ole 容器中打开。
我在 Google 上进行了搜索,发现了在客户端对齐面板中创建子表单并将容器作为子表单的父级的建议,但这并不能解决 Word 侧面板关闭时的文档重新对齐问题。
解决方案
我想出了一种解决侧板关闭后重新对齐问题的方法。它涉及调用 ole 容器的 doVerb 方法以刷新容器内的文档。然而,这在视觉上没有吸引力并且稍微费时,并且只应在必要时调用,即当 Word 侧窗格实际关闭时。这不容易被发现。没有 VBA 事件等。它涉及一个鼠标钩子,通过分析鼠标下方的窗口来拦截鼠标。不幸的是,各种 Word 侧窗格上的退出按钮的窗口类和窗口标题与整体工具栏相同,后者通常还包含一个下拉菜单,以允许移动、调整大小和关闭。下拉菜单有不同的类名,但是每个菜单项都与菜单具有相同的类名。简而言之,仅从类名中无法判断退出按钮是否已被单击。我想出的办法是添加一个间隔约为 250 毫秒的计时器。钩子函数启用定时器,定时器事件检查侧面板是否消失。我已经列出了我为此设计的代码。我相信它可以很好地改进。
在钩子过程中:
var
hw: hwnd;
clsName, wText: array [0 .. 255] of Char;
PT: tpoint;
begin
GetCursorPos(pt);
HW:= WindowFromPoint (PT);
GetClassName (HW, clsName, 256);
GetWindowText (HW, wText, 256);
if (uppercase(clsName) = 'MSOCOMMANDBAR')
Or ((uppercase(clsName) = 'MSOCOMMANDBARPOPUP')
And (uppercase(wText) = 'WORKPANE OPTIONS MENU')) then begin
HookMsg.Result := 0;
Timer1.Enabled := true;
end;
end;
在 onTimer 事件中:
var
PT: TPoint;
HW: hwnd;
clsName, wText: array [0 .. 255] of Char;
begin
timer1.Enabled:=false;
GetCursorPos(PT);
Hdl := WindowFromPoint (PT);
GetClassName (HW, clsName, 256);
GetWindowText (HW, wText, 256);
if (uppercase(clsName) <> 'MSOCOMMANDBAR')
And (uppercase(clsName) <> 'MSOCOMMANDBARPOPUP')
And (uppercase(wText) <> 'WORKPANE OPTIONS MENU') then
OLEContainer1.DoVerb(ovSHow);
end;
据我所知,所有 Word 侧窗格的两个类名都是相同的。
推荐阅读
- parallel-processing - STM32L4 //基于中断的并行SPI
- sql - 通过@timestamp 查询 ElasticSearch SQL 过滤
- c++ - 隐式移动构造函数和赋值运算符
- firebase - 在 FLutter 中返回 null 的函数
- wordpress - Wordpress 显示 single.php 两次
- ios - 根据百分比划分两个视图的空间
- python - 如何在 Pandas 中初始化数据框时从文件中读取满足某些条件的特定行和列?
- amazon-web-services - 具有特定 Fargate 平台版本的 ECS 计划任务(在 CDK 上)
- discord.js - 从成员短语调用 Exports.run async
- laravel - Pusher 接收具有空值的事件