2

When I use TOpenDialog, after closing the program, there is an exception in the Vcl.Forms module.

Program I'm using:

std::auto_ptr<TOpenDialog> OpenDialog (new TOpenDialog(this));
if ( OpenDialog->Execute() ){}

Exception: 'access violation at 0x008133a4: read of address 0x000000c4'

Highlighted is line: if not FHandleCreated then

function TApplication.GetDialogHandle: HWND;
begin
  if not FHandleCreated then
    Result := SendMessage(Handle, CM_DIALOGHANDLE, 1, 0)
  else
    Result := FDialogHandle;
end;
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Jacek
  • 63
  • 1
  • 8
  • Which version of C++Builder are you using? The AV is saying a NULL pointer is being accessed. What you describe suggests the `TApplication` object itself is being accessed after it is destroyed. That has nothing to do with the C++ code you have shown, since the `TOpenDialog` will have been destroyed long before that time. Use the debugger to view the call stack at the time of the AV and see who is actually calling `TApplication.GetDialogHandle()` late. – Remy Lebeau May 18 '21 at 17:49
  • In any case, when using a smart pointer like `std::auto_ptr`/`std::unique_ptr` to manage the lifetime of the `TOpenDialog`, you should set the dialog's `Owner` to `NULL`/`nullptr` instead of `this`: `std::auto_ptr OpenDialog (new TOpenDialog(NULL));`. Although it is perfectly safe to use `this`, it is redundant to do so in this case. – Remy Lebeau May 18 '21 at 17:50
  • Builder 10.4 v. 27.0.40680.4203. For nullptr - Undefined symbol 'nullptr'. When I don`t enter TOpenDialog the program is closed normally. – Jacek May 18 '21 at 18:40
  • `nullptr` is only in C++11 and later. The fact that you are using `auto_ptr` rather than `unique_ptr` suggests you are using the "classic" Borland compiler, which does not support C++11. You can use `NULL` instead. In any case, there is nothing in `TOpenDialog` that can cause `TApplication.GetDialogHandle()` to be called after the `TApplication` object has been destroyed. Did you try debugging your app, like I suggested? – Remy Lebeau May 18 '21 at 19:08
  • Near as I can see, `TOpenDialog` doesn't use `Application.DialogHandle` at all (`TFindDialog` does, though). – Remy Lebeau May 18 '21 at 22:39
  • https://zapodaj.net/a49551d724449.png.html – Jacek May 19 '21 at 06:11
  • I have to use "classic" Borland compiler as there is Excel component in project Excel_2k and using other one there is error: no matching conversion for functional-style cast from 'Excel_2k::XlVAlign' to 'TVariant' (aka 'TVariantT') – Jacek May 19 '21 at 06:36
  • that screenshot clearly shows `GetDialogHandle()` being called via a NULL `TApplication` pointer. Why, I can't see. Try enabling "Use Debug DCUs" in the project options and then put a breakpoint on `GetDialogHandle()` itself, maybe you'll get a better call stack to look at. – Remy Lebeau May 19 '21 at 14:27
  • There isn such option "DEBUG DCU" – Jacek May 19 '21 at 15:53
  • It is under the [Delphi Compiler Debugging options](http://docwiki.embarcadero.com/RADStudio/Sydney/en/Compiling), but it applies to C++Builder, too. Enabling Debug DCUs allows you to step through the VCL/RTL source code with the debugger. – Remy Lebeau May 19 '21 at 16:33
  • I can`t find GetDialogHandle() in Vcl.Forms https://zapodaj.net/cd924235db027.png.html – Jacek May 20 '21 at 06:33
  • it is in there. You quoted it verbatim in your question – Remy Lebeau May 20 '21 at 06:34

3 Answers3

0

I confirm this issue. I have project that uses TOpenDialog component. There was no problem with RAD C++ Builder 10.2 (Tokyo). But now I get same error after upgrading to RAD C++ Builder 10.4 Update 2 (Sydney). I don't use dynamic creation TOpenDialog with auto_ptr. Instead, I just dragged component on my form. So code is very simple:

if(!OpenDialog1->Execute())
     return;

It's enough to open this dialog, do nothing, press cancel and then close app. After that I got the same access violation like Jacek had. So problem is in C++ Builder 10.4

UPDATE: The problem is not in C++ Builder 10.4 itself. The error raises when application uses Custom Styles (Themes). I just disabled Custom Styles in my app and there is no error with OpenDialog.

vitaly
  • 1
  • 2
0

One possible workaround is to disable styling for common dialogs:

TStyleManager::SystemHooks = TStyleManager::SystemHooks >> TStyleManager::TSystemHook::shDialogs;
0

Another possible workaround is to set the option ofOldStyleDialog. The dialog looks old-style but has colors compatible with Widows Themes.

OpenDialog1->Options << ofOldStyleDialog;