On a Windows Tablet PC in a standard (MFC,…) Windows application when you set the focus to a text input control, an small icon is popped up, that allows the user to access the onscreen-keyboard (PenInputPanel) to be able to enter text characters.
Using an application that is built with the JUCE TextEditor control does not provide this feature of an automatic popup icon. The user has to manually activate the onscreen-keyboard via the taskbar. The onscreen-keyboard then works with JUCE. If it is manually activated you can input text to a JUCE TextEditor.
The problem in my application is, that I want to build an application that uses the full screen and does not allow the user access to the taskbar. So I need the feature of an automatic popup of the onscreen-keyboard to be able to enter text, if no keyboard is attached to the system.
The Microsoft documentation says: "Input Panel shows either itself or a simple invocation user interface (UI) near the system caret or the text-accepting control with focus. It makes itself available whenever a stylus-up event results in the appearance or location change of the caret."
Does that help or to you know of any other way to invoke the onscreen-keyboard in a simple way?
agh… tablet PCs! I imagine there’s some kind of win32 call that will make the keyboard pop-up, but I don’t know anything about this kind of thing. If you can find a function that I can call that does this, I’d be happy to patch the texteditor to use it!
I have been searching for a Win32-function quite a while now, and I did not find one. What I found is the statement in the documentation about the auto-activation: "It makes itself available whenever a stylus-up event results in the appearance or location change of the caret."
And I found a complicated (as usual) COM/.NET Class and Interface “PenInputPanel/IPenInputPanel”.
There is a stylus-up event documented in the .NET Framework 3.0, but I do not know what the Win32 equivalent is. Do you have any idea?
Ok, well by the sound of it, changing the caret might trigger it. Juce doesn’t use the normal windows caret, but there might be a way to pretend to use it for this purpose.
Maybe hacking a call to SetCaretPos into the TextEditor::mouseUp method might do the trick?
Well, after several tries: that really works, but you have to explicitly call CreateCaret und DestroyCaret to do that.
I implemented it the following way:
I added a method:
/** Activate system caret */
virtual void activateSystemCaret (int x, int y);
to the ComponentPeer class, implemented it as empty in ComponentPeer and with the following code in Win32ComponentPeer:
void activateSystemCaret (int x, int y)
{
if (!haveSystemCaret)
{
haveSystemCaret = true;
if (!::CreateCaret(hwnd, 0, 0, 0))
{
Logger::writeToLog(T("Unable to create system caret"));
}
}
if (!::ShowCaret(hwnd))
{
Logger::writeToLog(T("Unable to show system caret"));
}
if (!::SetCaretPos(x, y))
{
Logger::writeToLog(T("Unable to set system caret"));
}
}
additionally I added a member variable haveSystemCaret and the following to Win32ComponentPeer:
case WM_KILLFOCUS:
if (haveSystemCaret)
{
haveSystemCaret = false;
::DestroyCaret();
}
handleFocusLoss();
break;
At last I call
getPeer()->activateSystemCaret (getX(), getY());
in the TextEditor::focusGained method. That seems to handle all cases where it should pop up automatically. It seems to be necessary to call ShowCaret to activate it. The system caret is nevertheless not visible in the application, so nothing disturbs the user.
Probably not a very elegant solution, but it works for me and I really need it.
Thank you for version 1.46, but this fix didn’t get into it. I made the same changes as in the previous version and the text input works again on a tablet PC.
I understand that you might not feel comfortable with this “hack”, but the Juce framework also functions very well on tablet PCs and that’s the only thing I am missing.
Maybe you can add it masked by a “#define” in “juce_Config.h” and switch it off by default, otherwise I will always have to reapply this fix.
Showing the caret off-screen is not a good solution for a tablet input device, because the positioning of the caret influences the positioning of the popup for the text input. With using “SetCaretPos (-1, -1)” this pops up always on the upper left corner of the screen, regardless where the text editor is positioned. Not really good for the user.
As alternative I tried to use the following
With this I cannot see any blinking pixel in my tablet pc application, but I cannot guarantee, that this is true for all possible colour configurations. Using CreateCaret in this way is documented in the MSDN.
[quote]hBitmap
[in] Handle to the bitmap that defines the caret shape. If this parameter is NULL, the caret is solid. If this parameter is (HBITMAP) 1, the caret is gray.[/quote]
I just tried it and expected to see a less obvious blinking pixel. But with “(HBITMAP) 1” I can’t see any blinking pixel. I tried it also with different colours for the “TextEditor::focusedOutlineColourId” (red, blue, black, white, yellow), but I can’t see it. And the popup for the text input on a tablet pc is still on the position you need it.