Input to TextEditor on Windows Tablet PC


#1

Hello!

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?

Thank you,
Andreas


#2

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!


#3

Hello!

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?

Regards,
Andreas


#4

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?


#5

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.

Best regards,
Andreas


#6

Thanks - that’s really interesting. I’ll have a go at juceifying this and see if I can fit it in there neatly…


#7

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.


#8

Ok, have checked something in to do this now…


#9

OK, works fine.


#10

Andreas, did you see this thread:

http://www.rawmaterialsoftware.com/juceforum/viewtopic.php?p=16669#16669

My preferred fix would be this:

[code] void textInputRequired (int x, int y)
{
if (! hasCreatedCaret)
{
hasCreatedCaret = true;
CreateCaret (hwnd, 0, 0, 0);
}

    ShowCaret (hwnd);
    SetCaretPos (-1, -1);
}[/code]

to show it off-screen, but can you let me know if that still works with your tablet input device.


#11

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.

Sorry for the delay!


#12

How is it legal to cast 1 to a HBITMAP? Does that mean “solid white” or something?


#13

The Microsoft documentation says the following:

[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.


#14

Ok, well that sounds good then. I’ll make the change.


#15

Has this been implemented? Can’t seem to find it anywhere… :slight_smile:


#16

Yes, I’m sure I remember doing that.


#17