Exception in TOpenDialog when closing program - c++

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;

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.

One possible workaround is to disable styling for common dialogs:
TStyleManager::SystemHooks = TStyleManager::SystemHooks >> TStyleManager::TSystemHook::shDialogs;

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

Related

WinUI 3 Desktop XAML Databinding - WinRT originate error - 0x8001010E when the Property is changed

I am following the BookStore data binding example, documented at XAML controls; bind to a C++/WinRT property, up to and including the "Bind the button to the Title property" section.
My starting point is a new "Blank App, Packaged (WinUI 3 in Desktop)" project in Visual Studio.
[EDIT] Starting from a "Blank App (C++/WinRT)" project, which is for UWP apps, works perfectly. The problem persists with "WinUI 3 in Desktop" projects.
The initial data binding works and the button content L"Atticus" is read from the BookSku title property. However calling MainViewModel().BookSku().Title(L"To Kill a Mockingbird"); in the click handler, as directed in article, throws the exception
Exception thrown at 0x00007FFC801B4ED9 (KernelBase.dll) in BookStore.exe: WinRT originate error - 0x8001010E : 'The application called an interface that was marshalled for a different thread.'.
Stepping through the code, the call
m_propertyChanged(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Title" });
in void BookSku::Title(hstring const& value) is where the exception is thrown from within.
I can change the button content manually, not through the binding property.
The first example in the Data binding in depth article describes a very similar, though slightly less complicated, data binding scenario. It throws the same exception.
I am using latest Microsoft.Windows.CppWinRT version 2.0.210825.3 and Windows App SDK version 0.8.3
This issue #4547 was the key to figuring out the solution. You need to use the Microsoft namespace, not Windows. For documentation purposes this is what the BookSku.idl file should look like:
// BookSku.idl
namespace Bookstore
{
runtimeclass BookSku : Microsoft.UI.Xaml.Data.INotifyPropertyChanged
{
BookSku(String title);
String Title;
}
}
The application called an interface that was marshalled for a different thread
The problem is you update the property in the no-uithread, so it will throw the above exception, you could use the following to go back to ui-thread before updating the property.
co_await winrt::resume_foreground(Dispatcher(), CoreDispatcherPriority::Normal);
For more detail please refer to document here.

Loading VCL-Styles from Reources

Does anyone have experience with using resource for styles. I'm working on a program for which we created a custom Style. We saved it as .style and as .vsf. Because we don't want the user to see/change the style of the programm we want to include it in our resource file (.res) This is done as explained in next Link: Customizing and Creating VCL Styles Afterwards the created file (Tested with .style and .vsf) is placed in the Resourcefile as RC Data.
Thats the preparation, now what didn't work. (tWinMain)
TStyleManager::SetStyle(TStyleManager::LoadFromResource((unsigned int)HInstance, "StyleName", RT_RCDATA));
This also doesn't work:
TStyleManager::LoadFromResource((unsigned int)HInstance, "StyleName", RT_RCDATA);
TStyleManager::SetStyle("StyleName");
also not working
TStyleManager_TStyleServicesHandle MyStyle;
MyStyle = TStyleManager::LoadFromResource((unsigned int)HInstance, "StyleName", RT_RCDATA);
TStyleManager::SetStyle(MyStyle);
All three methodes resulting in the error message: Invalid Style-handle
Loading the same style from a file works:
TStyleManager::LoadFromFile(stylePath + "StyleName.vsf");
TStyleManager::SetStyle("StyleName");
I had the same problem in Delphi (DX10.3) and the following worked for me
Basically the same call of "TStyleManager::LoadFromResource", but without the specification of the optional parameter "RT_RCDATA".
MyStyle = TStyleManager::LoadFromResource((unsigned int)HInstance, "StyleName");
TStyleManager::SetStyle(MyStyle);
But then the resource type "VCLSTYLE" is necessary to load the style correctly. When adding the resource in the IDE, with [Project] > [Resources and Pics...] you can only specify RCDATA in the dialog, which is bad. But you can enter the resource type directly manual with the keyboard as "VCLSTYLE". The IDE remembers this setting and now the resource is available as the correct type. As said before, it works with Delphi 10.3, with the Builder it depends on one try.
Resource-type manual input in IDE dialog
Best regards, Matthias

How to change visibility of TMenuItem in c++ builder?

I'm using C++ Builder to develop an application.
I want to iterate through all the TMenuItems inside my MainMenu, because I want to change the caption of some of them.
I used this code:
int numAction = MainMenu1->Items->Count;
for (int i=0;i<numAction;i++)
{
TMenuItem* tmpAction = &MainMenu1->Items[i];
tmpAction->Caption = "Test Caption";
}
I think it should work, but I always get a crash of the application. With this kind of message:
Debugger Exception Notification Project Project1.exe raised exception class EAccessViolation with message Access violation at address
501C380E in module vcl120.bpl. Read of address 0000003C.
Any help will be appreciated.
TMenu has a property of type
_property TMenuItem* Items
which in turns has a property of array type
__property TMenuItem* Items[int Index]
So, the solution is (as n.m. already noticed) to write
TMenuItem* tmpAction = MainMenu1->Items->Items[i];

Load image from KnownFolders into BitmapImage

auto task = create_task(Windows::Storage::KnownFolders::PicturesLibrary->GetFilesAsync(Windows::Storage::Search::CommonFileQuery::OrderBySearchRank));
task.then([&sstrpath](Windows::Foundation::Collections::IVectorView<Windows::Storage::StorageFile^>^ files)
{
CCLog("num of files detected %d",files->Size);
Platform::String^ pathstr = files->GetAt(0)->Path;
OutputDebugStringW(pathstr->Data());
auto task2 = create_task(files->GetAt(0)->OpenAsync(Windows::Storage::FileAccessMode::Read));
task2.then([](Windows::Storage::Streams::IRandomAccessStream^ filestream)
{
Windows::UI::Xaml::Media::Imaging::BitmapImage^ bmp = ref new Windows::UI::Xaml::Media::Imaging::BitmapImage();
bmp->SetSource(filestream);
}
);
}
);
This was done on a Win8 RTM with a VS express RTM in C++ (cocos2dx framework). I am trying to load an image from the Picture library and create a BitmapImage out of it. Next was to somehow use the BitmapImage for CCSprite in cococs2dx, but that's not the issue here. The program was able to run all the way into task2 but then crash at when I try to ref new the BitmmapImage. The following was in the output console
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:
Platform::WrongThreadException ^ at memory location 0x02D1D794. HRESULT:0x8001010E
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception: [rethrow] at memory location 0x00000000.
First-chance exception at 0x75004B32 in myGame.exe: Microsoft C++ exception:
Platform::WrongThreadException ^ at memory location 0x02D1E5F0. HRESULT:0x8001010E
Unhandled exception at 0x622C9AD1 (msvcr110d.dll) in PixBlitz.exe: An invalid parameter was passed to a function that considers invalid parameters fatal.
I am not really sure what I have done wrong as most tutorials out there are Javascript or XAML based for Win8 app development.
Creating tasks like that moves code onto different threads. You're getting Platform::WrongThreadException when you access an object from the wrong thread. You have to access GUI components from the same thread every time.
I believe if you RunAsync onto the Dispatcher, that will get the threading right. Pass a delegate to RunAsync, and have that delegate include creating the BitmapImage, and whatever else you want to do with the BitmapImage.
As requested, an example.
I'm not familiar with Win8 development, though I am familiar with the WPF that it's based on. (If C++/CLI supports lambdas now, I'll have to go back and revise some old answers on the subject.)
I believe this is what you want. I may have some of the syntax slightly off on that delegate.
Stream^ filesteam = files->GetAt(0)->Open(FileAccessMode::Read); // we're already on a background thread, no need for a Task if we're not going to call 'then'.
// I'm assuming 'this' is a subclass of Windows.UI.Xaml.Window, or something similar.
this->Dispatcher->RunAsync(CoreDispatcherPriority::Low, []()
{
BitmapImage^ bmp = ref new BitmapImage();
bmp->SetSource(filestream);
}
);

How can I catch an invalid fgetpos call as a C++ exception on Windows?

In Visual C++ 2008, I want to "catch" an exception generated as shown here:
try {
int foo = 20;
::fgetpos(0, (fpos_t*)&foo);
}
//...
Here are adjustments I've made to attempt a successful catch:
SEH is activated (/eha)
I've added a catch(...)
I've added a _set_se_translator vector.
I've added/adjusted to SEH syntax: __try / __except(EXCEPTION_EXECUTE_HANDLER)
In short, I've tried "everything in the book" and I still can't catch the exception. If I replace the call to ::fgetpos with int hey = foo / 0 then suddenly all of the above techniques work as expected. So the exception I'm dealing with from ::fgetpos is somehow "extra special."
Can someone explain why this ::fgetpos error seems uncatchable, and how to work around it?
update When executed in the VS IDE, the output window doesn't name an exception. All it says is this:
Microsoft Visual Studio C Runtime Library has detected a fatal error in MyProgram.exe.
Not very helpful. When I run the console app from the command line, I get a crash dialogue. The "problem details" section of the dialogue includes this information:
Problem Event Name: BEX
Exception Offset:0002fd30
Exception Code: c0000417
Exception Data: 00000000
Additional Information 1:69ad
Additional Information 2:69addfb19767b2221c8e3e7a5cd2f4ae
Additional Information 3:b1ff
Additional Information 4:b1ffca30cadddc78c19f19b6d150997f
Since the code in your dump corresponds to STATUS_INVALID_CRUNTIME_PARAMETER, try _set_invalid_parameter_handler
Most likely, the runtime catches it for you and issues a debug dialog without returning or propagating the exception- that is a CRT call and they may add whatever exception catching code in there they like. It's well within Visual Studio's rights to catch a hardware exception inside a library function, especially if you are running from within the IDE or in debug mode, then it is expected of the runtime.
Of course, when you divide by zero, then there is no library call here to write that extra catching code.