How to set text in Carbon textfield on OSX? - c++

I'm trying to set the text of a textfield using the Carbon API like this:
ControlID editId = {'EDIT', 3};
ControlRef ctrl;
GetControlByID(GetWindowRef(), &editId, &ctrl);
CFStringRef title = CFSTR("Test");
OSErr er = SetControlData(ctrl, kControlEntireControl, kControlEditTextTextTag, CFStringGetLength(title), title);
CFRelease(title);
I'm using the C++ code template of XCode, so GetWindowRef() is a call to the predefined TWindow class. The OSErr return value gives me noErr, but my textfield only contains garbage.
It doesn't matter if I set the attribute of my textfield to Unicode or not.
Any ideas what is wrong here?

What does the GetControlID(...) return? Is it noErr?
As a ControlRef is also a HIViewRef, you can also use the function:
HIViewSetText to set the text. This is documented to work with functions that accept kControlEditTextCFStringTag.
By the way, the line you wrote:
CFRelease(title);
Will cause problems. One should only release objects that have been made using functions that have Create or Copy in the API name. You'll want to read: "Introduction to Memory Management Programming Guide for Core Foundation" -- search in the Xcode documentation.

Finally this did the trick:
SetControlData(ctrl, kControlEditTextPart, kControlStaticTextCFStringTag, sizeof(title), &title);
Since this seems to be very old API, a better way seems to be:
HIViewSetText(ctrl, title);
Thx to Lyndsey for the hints.

Related

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

A descendant of TStyledPresentationProxy has not been registered for class

I have a custom grid control that inherits from TGrid called TFmGrid. This control was working fine in Rad Studio 10 Seattle Update One. I recently upgraded to 10.1 Berlin and started noticing this error message showing up on my TFmGrid controls both when I run the application and in the designer:
A descendant of TStyledPresentationProxy has not been registered for class TFmGrid. Maybe it is necessary to add the FMX.Grid.Style module to the uses section
The image below shows how the error message shows up on my grid controls:
I started by doing as the message suggests, and adding #include <FMX.Grid.Style.hpp> to the header file of my TFmGrid control, however this seems to have done nothing.
So as far as trying to register a decendant of TStyledPresentationProxy I am not exactly sure where to start. I found this documentation about a method which:
Attempts to register the presentation proxy class with the specified name or the specified combination of control class and control type.
So I assume I need to use this method or at least something similar, but I don't understand how I am supposed to go about calling this method.
But then that brings up the question of WHERE do I call this code?
My custom control has a method in its namespace called Register() which I believe was autogenerated by the IDE when the control was created:
namespace Fmgridu
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TFmGrid)};
RegisterComponents(L"Kalos FM Controls", classes, 0);
}
}
Do I need to call something in there to register a decendant of TStyledPresentationProxy? What is the proper way to go about this?
Just override virtual method DefinePresentationName in you TfmGrid and return name of presentation name for grid:
function TfmGrid.DefinePresentationName: string;
begin
Result := 'Grid-' + GetPresentationSuffix;
end;
Fm registers presentation by string name and uses class name for it, so if you create new component (based on existed) you automatically change classname, so system cannot find presentation for you. There are two solution:
Said that you will use presentation from TGrid (DefinePresentationName)
Register existed presentation for you class (look at the initialization section of FMX.Grid.Style.pas)
P.S. Year ago i wrote article about it in common eNew approach of development of FireMonkey control “Control – Model – Presentation”. Part 1 I hope it will help you
It's simple :
Just put "StyleBook" component to your form
I had the same issue with a test component I was developing.
Complementing Yaroslav Brovin's speech, I solved the problem by adding the class register in the initialization and finalization clauses at the end of the unit, like this:
initialization
TPresentationProxyFactory.Current.Register(<COMPONENT CLASSNAME HERE>, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
finalization
TPresentationProxyFactory.Current.Unregister(<COMPONENT CLASSNAME HERE>, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
In my case looks like this:
initialization
TPresentationProxyFactory.Current.Register(TSGrid, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
finalization
TPresentationProxyFactory.Current.Unregister(TSGrid, TControlType.Styled, TStyledPresentationProxy<TStyledGrid>);
PS: Don't forget to declare the FMX.Presentation.Factory,
FMX.Presentation.Style and FMX.Grid.Style units in the uses clause

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

Supressing Script Error in IE8 (C++)

I want to prevent IE from showing JS error dialogs, I read that it can be done by setting
ScriptErrorsSuppressed = true.
Where exactly do I set it in IWebBrowser2?
Thanks
Simply use put_Silent method.
m_pWebBrowser->put_Silent(VARIANT_TRUE);
As mentioned earlier, use the put_Silent() method to turn error reporting on or off.
For example, if using a CDHtmlDialog, put this in your OnInitDialog():
m_pBrowserApp->put_Silent(VARIANT_TRUE);
and put it before the LoadFromResource() call.
Be careful though as this will suppress a lot more messages than just JavaScript errors. (Think SSL certificate notifications.)
make change in both HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE paths.
Software\\Microsoft\\Internet Explorer\\Main
RegSetValueEx (hKey, LPCSTR("Disable Script Debugger"), 0, REG_SZ, (BYTE*) "yes", 3);
RegSetValueEx (hKey, LPCSTR("DisableScriptDebuggerIE"), 0, REG_SZ, (BYTE*) "yes", 3);
The docs you are reading refer to what you can do if you embed an IE HTML rendering pane in your own application. They allow you to alter the behavior of that pane.
If you have done that, then you can use COM to QueryInterface an IWebBrowser2 interface from the component.
See more here:
http://support.microsoft.com/kb/196340
And here's how you handle errors:
http://support.microsoft.com/kb/261003
I suspect that that's not what you are trying to do, and that you are just making a web-app. In that case, you need to
Fix your JS errors
Put all of your JS code in try/catch blocks. Then you won't get JS dialogs, but you need to handle the error yourself.
The quick and easy way would be to use a global state to solve a local problem and modify the registry as described here (although Raymond would disapprove of doing so). This basically deactivates script errors entirely for the currently logged in user.
Summary:
Registry Key: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main
Value Name: Disable Script Debugger
Data Type: REG_SZ (String Value)
Value Data: yes
The more complex solution would be implementing IOleCommandTarget, as already pointed out by Lou.

Setting the version number in an NCBI c++ toolkit app

How can I set the version number in a NCBI C++ Toolkit Application?
I mean the version number which is displayed when I start my program with the parameter -version.
I read through the docs, but have not found it yet.
(I know this is a highly specific question, but I figured it was worth a try)
Give it a void Init(void) method containing code along the following lines:
// the last two parameters are optional
CVersionInfo version_info(1, 2, 3, "My App");
SetVersion(version_info);
However, this is currently broken (bug already submitted), so the workaround is to give the application class a constructor and call SetVersion from there.