How to translate MainMenu using TLang in RAD studio? - c++builder

I'm creating a pretty simple app in RAD studio 10.3, c++ builder. I've decided to add languages support. I found the TLang component - it was exactly what I wanted. It works fine for all "on the form" components like Edit, Label, CheckBox, etc. But it doesn't work for the main menu (TMainMenu). It just doesn't react to language switches.
Switches are done this way
void __fastcall TForm1::EnLang_menuClick(TObject *Sender)
{
LoadLangFromStrings(Lang1->LangStr["EN"]);
// Lang1->Lang = "EN" // I tried this way - same result
}
void __fastcall TForm1::RuLang_menuClick(TObject *Sender)
{
LoadLangFromStrings(Lang1->LangStr["RU"]);
}
My guess is TLang only checks controls for strings switches, but TMainMenu isn't a child of the TControl. Anyway - how to translate a main menu using TLang? Sure, I can write something like TLang myself and make it translate any components I want, but it needs time, so I was looking for something ready to go now.

Related

Getting multiple button captions into an edit field with one fuction

I want to create a function which takes the Caption of a pressed button and put it into an Edit field. I have multiple buttons, and I don't want to have multiple OnClick events with almost the same code in each of them.
I've searched and tried out stuff for hours, but can't seem to find anything like that (but I think I am not the only one with this problem).
I am not really new to programming but neither am I good at it.
Edit: I remember that there is a parameter in the click functions in .NET which is EventArgs e, which is missing while working with Embarcadero.
private void button_Click(object sender, EventArgs e)
{
edit.Text = e.Caption; //I don't really remember the exact syntax but I hope you get what I meant
}
Most VCL/FMX event handlers have a Sender parameter, which is a pointer to the object that is firing the event. For example:
void __fastcall TMyForm::ButtonClick(TObject *Sender)
{
Edit1->Text = static_cast<TButton*>(Sender)->Caption;
}
Just assign this single event handler to the OnClick event of all of your TButton objects. The Sender will be the current button being pressed.
Note to the above answer by Remy - for VCL the property name is "Caption" but for FMX the property name for a button is "Text"

How to make modal form un-minimize after a Show Desktop (or windows + D)

When I start my application, the first and only form that shows is a login form in modal:
frmLogin = new TfrmLogin(Application);
frmLogin->Init();
if(frmLogin->ShowModal() == mrCancel)
{
//this will exit the application because user cancel the login
return -1;
}
There is code happening after the ShowModal which open the main form (not in modal) of the application.
When I press Show Desktop or do windows + D and I'm still on the modal form for the login, I can't get the login back when clicking on the taskbar.
1. Is there a way to un-minimize the modal login after a 'Show Desktop'?
2. Also, if I open my application and the login appears, I can't seem to be able to close it when right-clicking on it in the taskbar > 'Close windows'. Is there a way to close it by the taskbar? (It close perfectly when using the red 'x' in the corner of the login form though)
I'm using c++ Builder 10.1 Berlin
As #Remy Lebeau suggested, I came to the solution by overriding the CreateParams() function.
In my Login.h
protected:
virtual void __fastcall CreateParams(TCreateParams &Params);
In my Login.cpp
void __fastcall TfrmLogin::CreateParams(TCreateParams &Params)
{
TForm::CreateParams(Params);
Params.ExStyle = WS_EX_APPWINDOW;
Params.WndParent = GetDesktopWindow();
}
My code is based on the Delphi example found here:
https://forums.embarcadero.com/thread.jspa?threadID=244599
Now, my Login form is able to be un-minimized after a ctrl + D!
Hopes this helps other c++ builder programmers out there.

Vaadin - TextArea/RichTextArea with real-time text analyzing

I am working on a Vaadin (7) server-side application, and i need to use a TextArea or a RichTextArea that will analyze word-by-word the typed input, and will highlight words of a certain type, for example - dates and times.
My problem is that a RichTextArea does not have a TextChangeListener, and a regular TextArea does not have a highlighting option because it does not support HTML tags...
I tries using ShortcutKeyListener for RichTextArea and analyze the text after every Space key, but it was too slow and had also some other problems.
Is there anything else i can do?
Is there an option to analyze the text on real time when using RichTextArea? or is there any add-on youre familiar with that can do that?
Or is there a way to highlight text in TextArea after analyzing it?
Thank you!
My suggestion is a bit strange, but anyway, take a look on Vaadin AceEditor. It supports text mode and SelectionChangeListener:
ed.addSelectionChangeListener(new SelectionChangeListener() {
#Override
public void selectionChanged(SelectionChangeEvent e) {
int cursor = e.getSelection().getCursorPosition();
Notification.show("Cursor at: " + cursor);
}
});
See details here: Vaadin AceEditor

Setter on text only called after edit on Android, live on iOS

When I'm binding text to an input on iOS, my setter is called each time a character is added, on iOS, but not on Android.
If I put a breakpoint on a property that is binded to a TextField in iOS, each time a character is entered, the property setter will be called, but not on an Android EditText.
It makes more complex ViewModels with several input attached to getter/setter tested on iOS completely useless on Android since it cannot be used.
Is there a way to make the "MvxBind="Text SomeProperty" acting like iOS on Android?
Events like "AfterTextChanged" (any binding to a command) aren't property-friendly, and would break my ViewModel. I don't want to have a platform-dependent workaround.
[Edit]
// Droid. It calls the TotalAmount setter once the editing is done.
<EditText local:MvxBind="Text TotalAmount,
Mode=OneWayToSource; Text TotalAmountString, Mode=OneWay" />
// Touch. It calls the TotalAmount setter on key press.
set.Bind(MyTotalAmountTextField)
.For(v => v.Text)
.To(vm => vm.TotalAmount).OneWayToSource();
set.Bind(MyTotalAmountTextField)
.For(v => v.Text)
.To(vm => vm.TotalAmountString).OneWay();
By the way, the displayed property is always formatted with a dollar sign, that's why I'm using an half-duplex approach for binding.
Appart from this live (iOS) versus after-edit (Droid) problem, the bindings are working well.
The default behaviour for TwoWay Text binding on both Android and iOS is to do per character binding.
You can see this behaviour in, for example, the N=0 video at 18:43 - http://youtu.be/_DHDMNB_IeY?t=18m43s
If you are not seeing this behaviour in your EditText then I guess it might be down in some way to your app or perhaps to a bug (e.g. perhaps in OneWayToSource binding somehow - this certainly isn't as commonly used as other binding modes).
To workaround this, I can only think to suggest:
Log it as an issue with a reproducible case (github repo) on GitHub/MvvmCross - someone there might be able to help - or you might be able to fix it yourself.
Try TwoWay binding instead
Try creating your own custom binding or your own custom control - this is actually very easy to do - see the tutorials N=28 and n=18 on http://mvvmcross.blogspot.com - for example you could try inheriting from EditText to create something like;
public class MyEditText : EditText {
public MyEditText(Context c, IAttributeSet a) {
this.AfterTextChanged += (s,e) => MyTextChanged.Raise(this);
}
public event EventHandler MyTextChanged;
public string MyText {
get { return Text; }
set { Text = value; }
}
}

AlwaysOnTop property not behaving properly

For some reason, the AlwaysOnTop attribute for a form's design isn't properly working.
Here's the context: we are trying to have a form that stays on top of every other one when opened. Simple no? Also, we don't want to set the WindowType to Popup according to my superior for some other reason (if you have any idea why, please let me know).
So my question is, is there any parameter/security feature somewhere that somehow restricts the forms to be on top at any time?
Even WinApi's setForegroundWindow returns false with the form's hWnd. Any ideas?
Oh, also we're running on Dynamics AX 4.0.
If you want your form to have modal behavior, then call the wait method from the form itself!
public void run()
{
super();
this.wait(true);
}
The true parameter triggers the modal mode. This works on all versions of AX.
The wait may be called from the caller instead, but that is less attractive as most forms are called through menu items.
formRun.init();
formRun.run();
formRun.wait(true);
I managed this case long time ago with the lostFocus event and the setFocus method. I didn't find a proper way to make a form stay on top (I think AX prevents this specifically to avoid locking a terminal) but it worked fine this way: When the form lost focus, set the focus on the form.
I don't have the code as it was on an old project. It was for a PDA project but I think you can't ever avoid user on changing form with Alt+Tab.
This is an interesting point, please keep us updated.
EDIT:
Someome in twitter got an cute solution for modal forms. I'm pretty sure it will make the trick for you. In the init method of the form:
public void run()
{
super();
element.wait(true);
// Execution will resume at this point, only after
// the user has closed the form.
}
Source: http://gotdax.blogspot.com.es/2013/08/modal-forms-in-dynamics-ax.html
What I did to solve this was by making the form modal through WinAPI. The code below is a copy from a saved text so it might need some polishing. (Also keep in mind that it might not be working as of AX2009.)
void setFormModal(int _thisHWND, boolean _bModal)
{
DLL _winApiDLL;
DLLFunction _EnabledWindow;
DLLFunction _getTop;
DLLFunction _getNext;
DLLFunction _getParent;
void local_enableWHND(int _lHWND)
{
int lnextWnd;
lnextWnd = _getTop.call(_getParent.call(_lHWND));
while (lnextWnd)
{
if (lnextWnd != _lHWND)
_enabledWindow.call(lnextWnd, (!_bModal));
lnextWnd = _getNext.call(lnextWnd, 2);
}
}
;
_winApiDLL = new DLL('user32');
_getNext = new DLLFunction(_winApiDLL, "GetWindow");
_EnabledWindow = new DLLFunction(_winApiDLL, "EnableWindow");
_getTop = new DLLFunction(_winApiDLL, "GetTopWindow");
_getParent = new DLLFunction(_winApiDLL, "GetParent");
_getParent.returns(ExtTypes:: DWORD);
_getParent.arg(ExtTypes:: DWORD);
_EnabledWindow.returns(ExtTypes:: DWORD);
_EnabledWindow.arg(ExtTypes:: DWORD, ExtTypes:: DWORD);
_getTop.returns(ExtTypes:: DWORD);
_getTop.arg(ExtTypes:: DWORD);
_getNext.returns(ExtTypes:: DWORD);
_getNext.arg(ExtTypes:: DWORD, ExtTypes:: DWORD);
local_enableWHND(_thisHWND);
local_enableWHND(_getParent.call(_thisHWND));
}

Resources