【发布时间】:2016-05-25 17:51:51
【问题描述】:
我在使用启用了 VCL 样式的简单 TOpenDialog 时遇到崩溃/异常。
如果不启用样式,对话框当然可以正常工作。 C++ Builder 10 和 10.1 Professional 会出现此问题。
复制:
- 创建一个使用样式的简单 VCL 表单
- 在表单中添加一个 TComboBox、一个 TButton 和一个 TOpenDialog
-
将以下代码添加到按钮的 OnClick 事件中
OpenDialog1->Execute(); for(int i=0; i<100; i++) ComboBox1->Items->Add("test text"); ComboBox1->ItemIndex = 1; 运行应用程序,点击按钮并选择一个文件
- 对我来说,这会导致异常“系统资源不足”
此错误可以在 Windows 7 Enterprise 和 Windows 8.1 Pro 上重现。 TSaveDialog 也有同样的问题。
对我来说奇怪的是,关于这个例外,我在网上找不到类似的问题。在我看来,只需要 VCL 样式和 TOpenDialog 就可以了,我希望在网络上有更多关于这个的信息。
我只发现了一些非常相似的东西,但那里没有例外,也没有关于原生 VCL 样式的解决方案:
Using custom styles shows invalid characters when right-clicking a file in TOpenDialog
我还尝试禁用 SystemHooks shDialogs(请参阅屏幕截图),我在某处读到有关 VCL 样式的另一个问题,但无济于事。
* 编辑 2016/05/26 *
Remy Lebeau 要求获得 MCVE。我试图将所有内容都放在问题中,但为了清楚起见,这里是一个 MCVE 的摘要:
- 使用默认设置创建新的 VCL 项目
- 将 TComboBox、TButton 和 TOpenDialog 拖放到表单中
-
将以下代码添加到按钮的 OnClick 事件中:
void __fastcall TForm1::Button1Click(TObject *Sender) { OpenDialog1->Execute(); for (int i=0; i<100; i++) ComboBox1->Items->Add(L"test text"); ComboBox1->ItemIndex = 1; // <- exception occurs here } 在项目选项中启用 VCL 样式“Smokey Quartz Kamri”
- 运行程序,按下按钮,选择任意文件并在TOpenDialog中选择OK
这里,这就是异常所需的全部内容。
在我看来,对 Execute() 的调用会弄乱一些 VCL 结构(仅在启用样式的情况下),然后访问另一个 VCL 项(在我的例子中是组合框)会导致崩溃。
我现在知道并不是每个人都有这个崩溃。如果这不是对你们每个人都 100% 可验证的示例,请原谅我。
但是我和我的同事不可能是唯一发生此崩溃的人(现在在 4 台不同的计算机上测试了 3 个不同的操作系统版本),可以吗?
* 编辑 2016/05/27 *
关于 Tom Brunberg 的单步请求,异常发生在 WndProc 中的某处,在调用中地址 005459F4 的屏幕截图中。
如果我更进一步,我将登陆 TCustomCombo.WndProc 中的某个位置。之后由于在 WndProc 中重复循环,很难进一步跟进,似乎无法到达引发异常的最终位置。
* 编辑 2016/05/27 秒 *
好的,我设法查明了坠机的确切位置。在VCL.Graphics 内的函数CopyBitmap 中。在第一个屏幕截图中,异常发生在以下行:
结果 := GDICheck(CreateCompatibleBitmap(ScreenDC, bmWidth, bmHeight))
在第二张截图的函数 GDICheck() 中,调试器中的变量 Value 为零,因此又调用了函数 GDIError。在那里,ErrorCode 也为零,这导致调用 OutOfResources。
希望这有助于进一步缩小范围。
* 2016/07/19 编辑 *
由于这里似乎没有人遇到此问题,因此我们进行了不同的尝试: 我公司的一位同事用英语安装了新的 C++ Builder 10.1 Berlin(我认为可能是德国 IDE 是罪魁祸首), 安装后的第一件事是重新创建 StylesCrashTest 应用程序。结果是一样的,它在选择一个文件并在对话框中点击“打开”后立即崩溃。
我已经在这里上传了测试项目 http://fboom.me/file/9904e22ddd22b/StylesCrashTest.zip
和我们生成的发布 exe 在这里 http://fboom.me/file/368d0b62cc1a7/StylesCrashTest.exe
该 exe 已通过 virustotal.com 上的许多防病毒扫描程序进行测试。 https://www.virustotal.com/de/file/e96f2e7eb80c162c2e5998decc15f26615c9fc76efec73379dd2e2140e4eba08/analysis/1468952442/
如果你们可以测试 exe 和测试项目,这将很有帮助,这可能会导致问题与计算机相关或与已安装的 IDE/生成的 exe 相关。这当然只有在有人可以重现该问题的情况下。
使用此 exe,应用程序在商业环境中的两台 Windows 7 x64 Enterprise 计算机上崩溃。 但是,它不会在装有 Windows 8.1 x64 Prof. 的私人计算机上崩溃。
现在我陷入了死胡同,慕尼黑城外似乎没有人能够重现这个问题,但我们肯定在两台不同的计算机上都有它。
问题也提交给 Embarcadero(需要登录): https://quality.embarcadero.com/browse/RSP-15019
可悲的是,目前,这是我们使用 VCL 样式的障碍。
【问题讨论】:
-
FWIW,在 Windows 7 Pro 上使用 Delphi 10 Seattle,我无法重现该问题。错误消息是否类似于“系统资源不足”?它发生在哪一行?
-
无法使用 Amakrits 或 Aqua Graphite 样式在 C++ Builder 或 Delphi 10.1 Berlin 或 Seattle 中复制。
-
这可能没什么,但您正在传递一个 char 数组来添加函数。尝试通过
L"test text"。看看有什么不同。 -
@TomBrunberg 是的,执行是“系统资源不足”。它发生在 'ComboBox1->ItemIndex = 1;' 行我认为这可能是因为 VCL 风格的 Execute() 弄乱了一些内部 VCL 结构,在这种情况下是组合框。
标签: delphi c++builder vcl topendialog