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

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];

Related

Exception in TOpenDialog when closing program

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;

Bing Map throws exception in 'Windows Runtime Component' project

First of all I want to apologize for the English.
I'am develop windows 8.1 store app. On C++/CX language. My solution contains several projects. One of projects has the 'Windows Runtime Component' type, and perform geocoding and reverse geocoding.
For a geocoding I use 'Bing Maps SDK for Windows 8.1 Store apps'(link).
Here's my algorithm:
void addressByLocation(double latitude, double longitude)
{
ResourceLoader^ loader = ref new ResourceLoader();
String^ credentials = loader->GetString("BingMapCredentials");
Location^ location = ref new Location(latitude, longitude);
ReverseGeocodeRequestOptions^ requestOptions = ref new ReverseGeocodeRequestOptions(location);
Map^ map = ref new Map();
map->Credentials = credentials;
SearchManager^ searchManager = map->SearchManager;
task<LocationDataResponse^> reverseGeocodeTask(searchManager->ReverseGeocodeAsync(requestOptions));
reverseGeocodeTask.then([=](LocationDataResponse^ response)
{
if (!response->HasError)
{
//
}
});
}
I've got the problem in this line:
Map^ map = ref new Map();
It always generates an exception with text:
"Platform::DisconnectedException ^ at memory location 0x0396DF80.
HRESULT:0x80010108 The object invoked has disconnected from its clients.
WinRT information: The object invoked has disconnected from its clients."
But I noticed something weird. If add project to the solution which contains UI(xaml), my code in this project works perfectly fine, without any exceptions.
Can somebody specify an error to me? Or give the explanation for this strange behavior.
There is probably other methods to perform geocoding for windows 8.1 store apps, which I don't know yet.
Thanks.

Qt ActiveX dynamicCall: bad parameter count

I am trying to use an ActiveX control in my program.
QAxWidget* mAX = new QAxWidget();
mAX->setControl("{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}");
I know that there is a function:
put_ChannelType(long newValue)
But when I try to execute it:
mAX->dynamicCall("put_ChannelType(long)",2);
mAX->dynamicCall("put_ChannelType(int)",2);
mAX->dynamicCall("put_ChannelType(long)",QVariant(2));
mAX->dynamicCall("put_ChannelType(int)",QVariant(2));
I get:
QAxBase: Error calling IDispatch member put_ChannelType: Bad parameter count
Any idea what is going wrong ?
EDIT:
Weird thing is if I call
mAX->dynamicCall("put_ChannelType()");
I do not get any error message...
EDIT 2:
This also fails (as Constantin suggested)
QList<QVariant> varlist;
varlist << (int)1;
mAX->dynamicCall("put_ChannelType(int)",varlist);
Got this solved using the generateDocumentation() function.
I was using this ActiveX control in another application, but an MFC one.
It seems the function names I was referring to (which were in a machine generated IDispatch wrapper class created by VS) were not the same as the ones Qt listed.
i.e. put_ChannelType is actually SetChannelType...
Maybe this is just a version issue ?
Anyways, important part is knowing that generateDocumentation() can list you all the functions you can call with dynamicCall.
Is it OK?
mAX->dynamicCall("put_ChannelType(const QVariant &)", (long)2);

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);
}
);

COM Error 0x80004003 (Invalid Pointer) access MS Outlook contacts

I am some ATL code that uses smart COM pointers to iterate through MS Outlook contacts, and on some PC's I am getting a COM error 0x80004003 ('Invalid Pointer') for each contact. The same code works fine on other PCs. The code looks like this:
_ApplicationPtr ptr;
ptr.CreateInstance(CLSID_Application);
_NameSpacePtr ns = ptr->GetNamespace(_T("MAPI"));
MAPIFolderPtr folder = ns->GetDefaultFolder(olFolderContacts);
_ItemsPtr items = folder->Items;
const long count = items->GetCount();
for (long i = 1; i <= count; i++)
{
try
{
_ContactItemPtr contactitem = items->Item(i);
// The following line throws a 0x80004003 exception on some machines
ATLTRACE(_T("\tContact name: %s\n"), static_cast<LPCTSTR>(contactitem->FullName));
}
catch (const _com_error& e)
{
ATLTRACE(_T("%s\n"), e.ErrorMessage());
}
}
I wonder if any other applications/add-ins could be causing this? Any help would be welcome.
FullName is a property and you do the GET operation (it's probably something like this in IDL: get_FullName([out,retval] BSTR *o_sResult)). Such operation works ok with null values.
My assumption is that contactItem smart pointer points to any valid COM object. In such case the formatting operation done by ATLTRACE can cause the problem. Internally it behaves probably like standard sprintf("",args...) function.
To avoid such problems just do something like below:
ATLTRACE(_T("\tContact name: %s\n"),
_bstr_t(contactitem->FullName)?static_cast<LPCTSTR>(contactitem->FullName):"(Empty)")
Just a guess:
Maybe the "FullName" field in the address book is empty and that's why the pointer is invalid?
hard to tell, because your code doesn't indicate which COM-interfaces you're using.
Does this make any difference?
ATLTRACE(_T("\tContact name: %s\n"), static_cast<LPCTSTR>(contactitem->GetFullName()));
In my example you format NULL value to a proper text value.
If the question is about the difference between FullName(as a property) and GetFullName() (as a method) then the answer is no. Property and method should give the same result. Sometimes property can be mapped to different methods then setXXX and getXXX. It can be achieved by using some specific syntax in IDL (and in reality in TLB after compilation of IDL to TLB). If property FullName is not mapped to method GetFullName then you will achieve different result.
So please examine file *.tlh after importing some type library to your project...