DLL 中的 VCL 样式正在影响应用程序中的 TMenuItem

2023-11-22

我使用的是Delphi XE6 和VCL 样式。我有主要的应用程序和 dll。我的主应用程序已启用运行时主题,并且我正在使用 vcl 样式文件。我对 DLL 做了非常相似的事情。我启用了运行时主题,并在使用和资源文件下添加了 VCL.Themes、VCL.Styles,其中包含 VCL 样式文件。当加载 DLL 时,我从资源加载 VCL 样式并将其设置为 DLL gui。主应用程序和 DLL 不是使用运行时包构建的。

现在我有了用自己的风格设计的主应用程序 GUI,也用自己的风格设计了 DLL gui。这似乎工作正常,直到......

当我单击主应用程序中的按钮时,该事件将打开 TPopupMenu,其样式与 DLL GUI 的样式相同,而不是主应用程序样式。如果我浏览菜单,我也会收到 AV 并且程序崩溃。看看附图。

What am I doing wrong? The only workaround I currently see would be to make my own customized TPopupMenu derived from some other control.enter image description here


正如我所承诺的,我准备了与我的应用程序类似的简单演示程序。它由具有自己风格的主机应用程序和添加到资源的风格的 DLL 组成。运行它并单击弹出按钮,然后尝试从弹出窗口中选择某些内容。它会崩溃并停止在某些 StdWindowProc 或类似的东西中。另外,如果您进入窗口系统菜单(左上角),当您尝试从该菜单中选择某些内容时,您会注意到系统菜单的样式为 DLL gui 并且也会崩溃。 rar 文件链接:dropbox.com/sh/f2jmbsmw18akpyg/AAA6SWdBmVhf6n6K-mvYLLmua?dl=0

enter image description here

感谢您的帮助。


这是 VCL 样式及其菜单样式方式的一个基本问题。样式是通过进程范围的钩子来实现的。具体来说,是通过调用安装的 CBT 挂钩SetWindowsHookEx from TCustomStyleEngine.CreateSysHook in the Vcl.Themes单元。事实上,该钩子仅适用于 GUI 线程,但这是进程范围内的,因为进程中只有一个 GUI 线程。

由于您的应用程序中有多个 VCL 实例(一个在 DLL 中,一个在应用程序中),因此安装了两个挂钩。那太多了。最近安装的挂钩(恰好是 DLL)获胜,这就是 DLL 菜单样式感染您的可执行文件的原因。以及为什么会遇到访问冲突。 DLL 正在尝试对属于可执行文件的菜单进行操作。因此,尽管您尽了最大努力,但最终还是得到了从主机可执行文件访问 VCL 对象的 DLL 代码。

没有简单的方法可以解决这个问题并在两个模块中完全支持样式。我们这里得到的是设计的基本结果。该系统并未设计为支持多个 VCL 实例。如果您希望在多个模块中使用 VCL 样式,那么设计者希望您使用运行时包。

我想您也许能够通过在完全不同的线程中操作 DLL 来获得一些吸引力。这将涉及从该不同的线程加载 DLL,以便 VCL 在该线程中初始化。对 DLL 的所有调用都必须来自该线程。并且您需要在该线程中运行消息循环。你可能能够做到这一点,但我对此表示怀疑。即使提到了所有的附带条件,您仍然必须处理这样一个事实:您有两个 GUI 线程,这会带来输入队列处理的各种问题。

也许另一种方法是从 DLL 中卸载挂钩。只要您的 DLL 不显示菜单,那么您就可以卸载该挂钩。它会禁用 DLL 显示的菜单样式,但这也许是可以接受的。

这个版本的 DLL(在我对其进行了一些简化之后)会卸载该钩子。

library VCLStyleDLL;

{$R 'Style.res' 'Style.rc'}

uses
  VCL.Styles,
  VCL.Themes,
  VCL.SysStyles; // to gain access to TSysPopupStyleHook

{$R *.res}

begin
  TStyleManager.TrySetStyle('Glossy', false);
  TCustomStyleEngine.UnRegisterSysStyleHook('#32768', TSysPopupStyleHook);
end.

使用此版本的 DLL,主机可执行文件不会遇到您在问题中描述的问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DLL 中的 VCL 样式正在影响应用程序中的 TMenuItem 的相关文章

  • 为什么 {$ifopt FINITEFLOAT ON} 无法编译?

    我有这样的构造 ifopt FINITEFLOAT ON message FINITEFLOAT option ON else message FINITEFLOAT option OFF endif 在我的源代码中 它不会编译 这一定是一
  • 将数据从一个数据集结构移动到另一个数据集结构的更快方法(在 TDatasetProvider 中)

    我有一个自定义的 TDatasetProvider 它允许为其提供的任何数据创建新字段 因此 假设您在原始数据集上获得了以下字段 客户ID Name Age 您需要使用显示位图在 DBGrid 上选择它 好吧 你可以 因为我的 DSP 可以
  • 在 Delphi 中编程延迟的最佳方法是什么?

    我正在开发的 Delphi 应用程序必须延迟一秒 有时甚至两秒 我想使用最佳实践来对此延迟进行编程 在阅读 stackoverflow 上有关 Delphi Sleep 方法的条目时 我发现了以下两条评论 我遵循这样的格言 如果你觉得需要使
  • 加载 DLL 及其依赖项

    如何加载 dll 及其依赖项 我不想将每个依赖的 dll 都放在 Assembly Load 中 我宁愿只加载一个 dll 然后加载依赖项 当我的应用程序启动时 上面的 dll 不会被加载 它们仅在用户执行特定操作时加载 然后冻结 gui
  • 所见即所得与 Unicode

    我在 Delphi 中编写了一个 Windows 程序 该程序使用 GetCharWidth 和 Em Square 将文本非常精确地放置并换行到屏幕和打印机 这对于 ANSI 文本效果很好 您只需要检索和计算 255 个字符的宽度 但当您
  • Delphi 将面板流传输至文件

    今天我有一个关于将表单的一部分流式传输到文件的问题 在此示例中 我使用 Tmemo 而不是文件来查看流 这是我的表格 表单右上角的面板有一些控件 如标签 编辑等 使用 保存面板 按钮将面板保存在 TStream 上 这里是代码 proced
  • Delphi - 获取和设置 ListView 的滚动条位置

    这似乎是一个愚蠢而简单的问题 然而 我一直无法找到令人满意的答案 基本上 我有一个列表视图 样式 vsReport 与数据 有时 我必须更新它 因此 我必须清除列表视图并用更新的数据再次填充它 但是 当我这样做时 滚动条位置将重置为 0 我
  • TThread.resume 在 Delphi-2010 中已弃用,应该在什么地方使用?

    在我的多线程应用程序中 I use TThread 挂起 and TThread resume 自从将我的应用程序移至 Delphi 2010 后 我收到以下警告消息 DCC 警告 xxx pas 277 W1000 符号 Resume 已
  • 在 Visual Studio 2010 Express 中自动从 dll 生成 C# 包装类?

    我的一位同事告诉我 Visual Studio 允许人们指向 dll并自动神奇地生成一个 C 包装类 这真的可能吗 如果是这样 如何实现这一目标 我浏览过网页 但没有想出任何东西 谢谢大家 我想我也会分享这些资源 如何 创建 COM 包装器
  • 使用 Delphi 的 7-Zip?

    我想使用 Delphi 的 7 Zip DLL 但一直找不到合适的文档或示例 有谁知道如何使用 Delphi 的 7 Zip DLL 自版本 1 102 起JEDI 代码库 http wiki delphi jedi org index p
  • 无法在 SAMSUNG GALAXY S7 EDGE 上调试

    为什么我无法在 RAD STUDIO 10 Seattle upd 1 中的 SAMSUNG GALAXY S7 EDGE ANDROID 6 0 1 上调试我的应用程序 当我调试时 设备上的应用程序启动 但 RAD STUDIO Delp
  • 安装软件包时出现无法加载软件包 %s 错误

    我正在 Delphi 2007 上进行测试 我的小组项目由 2 个包组成 包运行 bpl 它被标记为 仅运行时 并包含一个名为 uMyTestRun pas 的单元 其中定义了一个空的 TFrame 后代 unit uMyTestRun i
  • 从 C++ .dll 到 Delphi Forms 应用程序的 PostMessage 问题

    我有用 Delphi 7 编写的 Windows 窗体应用程序和使用 MFC 编写的 C dll 目前 我正在尝试实现从 dll 到主可执行文件的基本消息发布 以在进度条上显示用户计算过程 但遇到了几个问题 让我先描述一下我的方法 我在 D
  • 如何改变TDateTimePicker的颜色?

    如何更改 a 的颜色TDateTimePicker A 日期和时间选择器可以有一种颜色 通常这是通过设置来完成的Color procedure TForm1 FormCreate Sender TObject begin DateTimeP
  • 在 C# 中使用 COM dll

    我们有用 C 编写的 COM dll 并已被用 vb 6 0 编写的应用程序使用 我的公司计划在 Net 平台上编写新版本的应用程序 就性能而言 在 C 项目中使用 COM dll 时 我应该从下面列出的 3 个选项中选择什么 只需添加 d
  • 在这些情况下限制破折号的正则表达式模式

    Scenario 我正在使用第三方文件重命名软件 该软件是用 Delphi 编写的 并且具有 pascal 脚本支持 该应用程序允许使用正则表达式来重命名文件 这意味着 如果我需要对文件名执行的操作不能仅使用一个正则表达式来完成 那么我可以
  • 当应用程序最小化时隐藏表单

    我有一个主表单和一个状态表单 当我的应用程序中的工作正在进行时 我会显示它们 如果工作完成我就打电话Hide状态表上出现 状态表消失 当我最小化主窗体而等待窗体可见时 就会出现问题 然后两种形式都被隐藏 这就是我想要的 但是 如果工作完成时
  • 惠普定制 OEM Windows 上的 Delphi 平台错误

    我在设置我的计算机以便运行 Delphi 时不断遇到相同的错误 我已经在PLATFORM环境变量 将其转换为 win32 但仍然给出相同的错误 错误错误 平台变量 HPD 无效 PLATFORM 必须是以下之一 Win32 Win64 An
  • 从 C# 调用 C++ DLL

    我想使用 C 中的 C DLL C DLL 是win32 控制台应用程序 我已成功调用它 并希望在 C 中处理来自 C 的数据 然而 C 应用程序在执行 DLL 后退出 即这一行 GetArrayFromDLL 我是 C 和 Visual
  • 良好的 Delphi Prism 在线资源

    在 Google 上搜索 delphi prism delphi prism 资源 或 delphi prism 代码片段 几乎找不到好的网站 是否有任何好的编程网站提供大量有关 Delphi Prism 的代码片段和教程 提前致谢 oma

随机推荐

  • Android 请求多个权限

    我正在修改现有的面部跟踪器应用程序 Android 的面部识别示例项目 我在请求多个永久权限时遇到问题 下面的方法是现有方法的修改版本 成功创建了一个弹出窗口来请求相机权限 我正在尝试使用存储权限来复制此内容 但到目前为止我还没有成功 并且
  • 如何通过API获取维基百科文章的一小段文字和主图?

    我正在尝试创建一个简单的维基百科克隆 允许用户搜索某个主题 然后显示 10 个包含文章图像和一小段文本的结果 我已经能够将用户提供的搜索字段传递给我的 ajax 打电话没有问题 但现在我无法检索图像 我已经阅读了 StackOverflow
  • 将线程分配给特定的CPU核心

    AFAIK 在 Linux 中可以将线程分配给 CPU 核心 看this 但是 我的问题是我可以使用以下方法实现此功能吗boost如果可能的话 又是如何实现的呢 请注意 操作系统也不能决定哪个对我来说更好 而是假设我想在设计中控制这种行为
  • Java 通过谓词将流拆分为流的流

    我正在阅读数百个大型 6GB gzip 日志文件GZIPInputStream是我想解析的 假设每一项的格式如下 Start of log entry 1 some log details some log details some log
  • 在 BigQuery 中查询多个重复字段

    我有一个架构 其中包含多个未嵌套的重复字段 我正在尝试查询叉积 但出现错误 无法查询重复字段的叉积 如果我只查询 2 个重复字段 我可以将其中之一展平 然而 我有兴趣查询超过 2 个重复字段 并且我无法理解 FLATTEN 语法如何支持这一
  • 如何将 Android Studio 完全安装到非默认 (D:) 驱动器

    我将从高级 常识 问题开始 然后进入技术细节 高级问题 在 Windows 10 中运行 Android Studio 安装程序时 我告诉它安装到 D 驱动器 而不是默认的 C 驱动器 为什么它坚持将某些组件安装到 C 驱动器上 安装到非默
  • 在 Java Web 应用程序中加载外部库

    我的场景如下 我有一个部署到 servlet 容器的 WebApp war 此 WebApp war 在 WEB INF lib 中包含以下库 lib a jar lib b jar 我还有另一个库 例如 lib vendor jar 由于
  • 在 xcode 中仍然出现 文件未找到错误

    我是 PhoneGap 的新手 通过 Xcode 制作应用程序 但我发现了一个错误CDVViewController h 然而 该文件实际上存在于那里 我正在使用 Xcode 4 6 和 Cordova 2 2 0 伙计 这个问题有很多转移
  • AWS ECS 运行任务时出错:在集群中找不到容器实例

    我正在尝试部署一个docker容器镜像到AWS using ECS 但未创建 EC2 实例 我在互联网上搜索了有关为什么收到以下错误的解释 调用 RunTask 操作时发生客户端错误 InvalidParameterException 在集
  • 为什么使用 0 作为“停止”的切片表示法反转列表不会返回整个列表?

    在以下示例中 foo red white blue 1 2 3 foo 0 6 1 将打印所有元素foo 然而 foo 6 0 i 1 将省略第 1 个或第 0 个元素 gt gt gt foo 6 0 1 3 2 1 blue white
  • 在 R 公式中使用带有特殊字符的列

    我正在尝试使用 rpart 使用大约 200 列的数据框来制作决策树 其中一些列的名称中包含数字 一些列的名称中包含特殊字符 例如 当我尝试生成树时 出现如下错误 R gt gg rpart lt rpart nospecialchar S
  • Oracle 中的 Unique 与 Distinct 关键字

    我对这些词的用法有点困惑 我有一个包含以下列的表格 站点 纬度 长 名称 我想要具有独特 或不同 LAT LONG 的结果 我该如何实现这一目标 select unique colA colB from atable select dist
  • 持久化 hashlib 状态

    我想创建一个hashlib实例 update 然后以某种方式保留其状态 稍后 我想使用此状态数据重新创建对象 并继续update 它 最后 我想得到hexdigest 数据的总累积运行 状态持久性必须在多次运行中保持不变 Example i
  • H.264 RTSP 绝对时间戳

    是否可以从安讯士摄像机通过 RTSP 发送的 H 264 流中读取绝对时间戳 有必要知道相机何时拍摄该帧 谢谢 安德里亚 正如拉尔夫已经说过的 RTP 时间戳与随机时钟相关 它们仅用于计算两个帧 或一般的 RTP 数据包 之间的差异 为了将
  • 如何在运行时检查内存地址是否可写?

    如何在运行时检查内存地址是否可写 例如 我想在以下代码中实现 is writable address 是否可以 include
  • 使用 JSON 返回 Razor 部分视图 (ASP MVC 3)

    在使用常规视图引擎的 MVC 2 中 我可以通过字符串返回 ascx 部分视图return Json 但对于新的 Razor cshtml 视图 我不知道如何做到这一点 我不断得到Type ASP CustomerForm cshtml d
  • SonarQube LDAP 身份验证似乎已加载,但不允许通过域用户登录

    我一直在尝试使用 LDAP 身份验证插件 v1 4 设置 SonarQube v4 1 但我无法让它针对我的域用户进行身份验证 我的配置设置如下 LDAP configuration General Configuration sonar
  • 如何在 android 中使用 xmlpullparser 从嵌套 xml 中提取文本?

  • 在 spritekit 中模拟水/使精灵“漂浮”在水面上

    我正在努力为我的比赛加水 除了背景颜色不同之外 没有什么其他的 不过 我想要player sprite漂浮在它的顶部 或一半 如果玩家只是从下面走进水中 我希望他浮到上面 如果他摔倒了 我希望他能慢慢改变方向并浮起来 当他在水中时 我尝试将
  • DLL 中的 VCL 样式正在影响应用程序中的 TMenuItem

    我使用的是Delphi XE6 和VCL 样式 我有主要的应用程序和 dll 我的主应用程序已启用运行时主题 并且我正在使用 vcl 样式文件 我对 DLL 做了非常相似的事情 我启用了运行时主题 并在使用和资源文件下添加了 VCL The