使用VCL样式会在TOpenDialog

时间:2016-05-25 17:51:51

标签: delphi c++builder vcl topendialog

在使用启用了VCL样式的简单TOpenDialog时遇到崩溃/异常。

如果没有启用样式,对话框当然可以正常工作。 C ++ Builder 10和10.1 Professional会出现此问题。

重现:

  1. 创建一个使用样式的简单VCL表单
  2. 将TComboBox,TButton和TOpenDialog添加到表单
  3. 将以下代码添加到按钮的OnClick事件

    OpenDialog1->Execute();
    for(int i=0; i<100; i++)
      ComboBox1->Items->Add("test text");
    ComboBox1->ItemIndex = 1;
    
  4. 运行应用程序,单击按钮并选择文件

  5. 对我来说,这会产生“超出系统资源”的异常
  6. 此错误可以在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样式的另一个问题,但无济于事。

    code

    exception

    *编辑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中选择确定

    在这里,这就是异常所需的一切。

    在我看来,对Execute()的调用搞砸了一些VCL结构(只有在启用了样式的情况下),然后访问另一个VCL项目(​​在我的情况下是组合框)会导致崩溃。

    我现在意识到不是每个人都有这种崩溃。如果不是每个人100%可验证的例子,请原谅我。

    但我和我的同事不可能是唯一发生这次崩溃的人(现在在4台不同的计算机上测试了3种不同的操作系统版本),我们可以吗?

    *编辑2016/05/27 *

    关于Tom Brunberg的单步请求,异常发生在WndProc内的某个地方,在地址005459F4的屏幕截图中。

    如果我继续前进,我将登陆TCustomCombo.WndProc。之后由于在WndProc中重复循环而很难进一步跟踪,似乎无法到达异常触发的最终位置。

    enter image description here

    *编辑2016/05/27秒*

    好的,我设法确定了崩溃的确切位置。在VCL.Graphics中的函数CopyBitmap中。在第一个屏幕截图中,异常发生在以下行:

    结果:= GDICheck(CreateCompatibleBitmap(ScreenDC,bmWidth,bmHeight))

    在第二个屏幕截图中的函数GDICheck()中,调试器中的变量Value为零,因此调用函数GDIError。在那里,ErrorCode也为零,这导致调用OutOfResources。

    希望这有助于进一步缩小范围。

    enter image description here

    enter image description here

    *编辑2016/07/19 *

    由于这里没有人似乎有这个问题,我们给了它一个不同的尝试: 我公司的一位同事用英语做了一个全新的C ++ Builder 10.1柏林安装(想想也许德国IDE是罪魁祸首), 安装完成后,首先重新创建StylesCrashTest应用程序。结果相同,选择文件后立即崩溃并在对话框中点击“打开”。 enter image description here

    我已经在这里上传了测试项目 http://fboom.me/file/9904e22ddd22b/StylesCrashTest.zip

    和我们在这里生成的发布exe http://fboom.me/file/368d0b62cc1a7/StylesCrashTest.exe

    在virustotal.com上使用许多防病毒扫描程序测试了exe。 https://www.virustotal.com/de/file/e96f2e7eb80c162c2e5998decc15f26615c9fc76efec73379dd2e2140e4eba08/analysis/1468952442/

    如果你们可以测试exe和测试项目会有所帮助,这可能导致将问题分离到计算机相关或与安装的IDE /生成的exe相关。这当然只有有人可以重现这个问题。

    使用此exe,应用程序在商业环境中的两台Windows 7 x64企业计算机上崩溃。 但是,它并没有在我的私人计算机上崩溃,因为Windows 8.1 x64教授。

    现在我已经走到尽头,慕尼黑镇外的任何人似乎都无法重现这个问题,但我们肯定会在两台不同的计算机上使用它。

    该问题也已提交给Embarcadero(需要登录): https://quality.embarcadero.com/browse/RSP-15019

    可悲的是,目前,这是我们使用VCL风格的商店。

1 个答案:

答案 0 :(得分:0)

我找到了解决崩溃问题的方法。经过一些调试后,发现每次在VCL样式的TComboBox上使用负参数调用TBitmap :: SetSize时都会发生异常。

请参阅随附屏幕截图中的调用堆栈:

TComboBoxStyleHook::ListBoxWndProc
TComboBoxStyleHook::DrawListBoxVertScroll
TBitmap::SetHeight
TBitmap::SetSize

enter image description here

在Vcl.Graphics.pas中编辑SetSize()以退出负数后,异常似乎消失了。 这不能解决异常的原因,因为在DrawListBoxVertScroll中为什么参数设置为-1仍然是未知的(bug?,也可能是此例程中更多子调用的结果),但至少它是 修复以防止异常。在所有发生异常的机器上进行测试,结果良好。

很想听听Remy Lebeau等真正的VCL专家甚至是VCL开发者的意见。

同样,我意识到不是每个人都可以重现异常,但是上面链接的测试项目,我们的系统上不可避免地会出现异常。