B4 - Guitexteditctrl And Ctrl+alt+del (SOLVED)
by Gregory Stewart · in Torque Game Builder · 05/24/2006 (5:02 pm) · 7 replies
I originally found this bug in 1.1 Beta 1.1 while working on my game. I have since confirmed this bug in Beta 3 and 4. My system is Windows XP service pack 2. My apologies if this bug has already been reported. I was unable to locate anything similar using the search feature.
========================
Summary of Bug
========================
If a GuiTextEditCtrl currently has the focus and the user presses CTRL+ALT+DEL, upon switching back to the application, the font is invisible.
========================
Steps to reproduce this bug are as follows:
========================
1. Start T2D.exe
2. Click on File | Save As
3. Delete the text (if any) in the "File Name" edit box
4. Type something in here to make sure you have the input and its working
5. Delete your text
6. Press CTRL+ALT+DEL and then press cancel
7. Try typing.. the GuiTextEditCtrl appears to have lost the input focus
8. Use ALT+TAB to switch to "T2D - TGB Level Builder" (this regains input focus)
9. Try typing.. the font will either be invisible or appear as unknown characters
============
If anyone has any insight on how to fix this bug, I would love to hear it. I would like to get this issue fixed in my game.
Thanks.
-- Greg
========================
Summary of Bug
========================
If a GuiTextEditCtrl currently has the focus and the user presses CTRL+ALT+DEL, upon switching back to the application, the font is invisible.
========================
Steps to reproduce this bug are as follows:
========================
1. Start T2D.exe
2. Click on File | Save As
3. Delete the text (if any) in the "File Name" edit box
4. Type something in here to make sure you have the input and its working
5. Delete your text
6. Press CTRL+ALT+DEL and then press cancel
7. Try typing.. the GuiTextEditCtrl appears to have lost the input focus
8. Use ALT+TAB to switch to "T2D - TGB Level Builder" (this regains input focus)
9. Try typing.. the font will either be invisible or appear as unknown characters
============
If anyone has any insight on how to fix this bug, I would love to hear it. I would like to get this issue fixed in my game.
Thanks.
-- Greg
#2
Just for the record, I'm able to detect if Ctrl+Alt+Del is pressed by checking lParam in WM_ACTIVATEAPP. When I press Ctrl+Alt+Del, the lParam value is 0--this is the thread id. I'm not sure if this is the same on all systems.
05/28/2006 (8:36 am)
I still haven't been able to figure out why this is happening. I tried adding the code from WM_ACTIVATE into WM_ACTIVATEAPP--to include the Input::activate() and Input::deactivate(), but this did not seem to make a difference.Just for the record, I'm able to detect if Ctrl+Alt+Del is pressed by checking lParam in WM_ACTIVATEAPP. When I press Ctrl+Alt+Del, the lParam value is 0--this is the thread id. I'm not sure if this is the same on all systems.
case WM_ACTIVATEAPP:
if ((bool) wParam)
{
...
}
else
{
// CTRL+ALT+DEL is causing us to lose focus
if (lParam == 0)
{
Con::executef( 2, "echo", "CTRL+ALT+DEL was pressed" );
}
...
}
#3
GuiTextEditCtrl::onKeyDown()
Under normal circumstances, the event.ascii code would be 0x61 for a, 0x62 for b, 0x63 for c, etc. When this issue occurs with the invisible font, the event.ascii code is showing up as 0x1 for a, 0x2 for b, 0x3 for c, etc.
So, to recapp, the GuiTextEditCtrl::onKeyDown() function is receiving the incorrect ASCII codes when this issue occurs. I'll post more if I find a good solution (going to try adding 0x60 as a starter). As always, if anyone has any good suggestions, I'd love to hear them. :)
Edit:
Still slaving away on this one. :) I've narrowed it down a little, however. The problem seems to be occuring between DInputDevice::buildEvent() and GuiTextEditCtrl::onKeyDown(). The buildEvent() function is receiving the correct key presses--I wanted to make sure it wasn't an issue with DirectInput so I turned on input logging. Getting closer...
05/28/2006 (10:42 am)
Sorry for so many posts.. but I think I'm closer to figuring this out. Apparently, the ASCII codes are coming out wrong when this happens, and that's why the font does not appear. For example, take a look at the following stock code (by the way this is from 1.1 Beta 1.1, but this issue is also appearing in Beta 4):GuiTextEditCtrl::onKeyDown()
...
if ( mFont->isValidChar( event.ascii ) )
{
// Get the character ready to add to a UTF8 string.
UTF16 conv[2] = { event.ascii, 0 };
StringBuffer convertedChar(conv);
#if 0
{
UTF8 pony[10];
convertedChar.get(pony, 10);
Con::printf("Got key '%s' (0x%x)", pony, event.ascii );
}
#endif
//see if it's a number field
if ( mProfile->mNumbersOnly )
{
...Under normal circumstances, the event.ascii code would be 0x61 for a, 0x62 for b, 0x63 for c, etc. When this issue occurs with the invisible font, the event.ascii code is showing up as 0x1 for a, 0x2 for b, 0x3 for c, etc.
So, to recapp, the GuiTextEditCtrl::onKeyDown() function is receiving the incorrect ASCII codes when this issue occurs. I'll post more if I find a good solution (going to try adding 0x60 as a starter). As always, if anyone has any good suggestions, I'd love to hear them. :)
Edit:
Still slaving away on this one. :) I've narrowed it down a little, however. The problem seems to be occuring between DInputDevice::buildEvent() and GuiTextEditCtrl::onKeyDown(). The buildEvent() function is receiving the correct key presses--I wanted to make sure it wasn't an issue with DirectInput so I turned on input logging. Getting closer...
#4
The problem was that because the keyboardState[] array had an extra keypress, the ToUnicode() function in processKeyMessage() in winWindow.cc was returning the wrong ASCII value--the keycode was correct, but the ASCII value was incorrect.
The solution is to clear the keyboardState[] array when we return from a Ctrl+Alt+Del keypress. You can do this in WindowProc (winWindow.cc) by doing something like this:
NOTE: This applies to both TGE and TGB/T2D.
05/29/2006 (9:44 am)
Ok, I figured it out. Here's the deal. When Ctrl+Alt+Del is pressed, the keyboard state receives a keydown signal for ASCII code 19 (0x13). This is a Device Control 3 signal (?) that sends a push signal but does not send a release signal.The problem was that because the keyboardState[] array had an extra keypress, the ToUnicode() function in processKeyMessage() in winWindow.cc was returning the wrong ASCII value--the keycode was correct, but the ASCII value was incorrect.
The solution is to clear the keyboardState[] array when we return from a Ctrl+Alt+Del keypress. You can do this in WindowProc (winWindow.cc) by doing something like this:
[b]bool ctrlAltDelWasPressed = false;[/b]
static LRESULT PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
...
case WM_ACTIVATEAPP:
if ((bool) wParam)
{
Video::reactivate();
ShowCursor(false);
if ( Video::isFullScreen() )
hideTheTaskbar();
// HACK: Windows 98 (after switching from fullscreen to windowed mode)
SetForegroundWindow( winState.appWindow );
[b]// GDS /////////////////////////////////
if (ctrlAltDelWasPressed)
{
for (int i = 0; i < 256; i++)
keyboardState[i] = 0;
ctrlAltDelWasPressed = false;
}
//////////////////////////////////////// [/b]
}
else
{
[b]// GDS ///////////////////////////////////////////////////////////
// CTRL+ALT+DEL is causing us to lose focus
if (lParam == 0)
{
ctrlAltDelWasPressed = true;
}
////////////////////////////////////////////////////////////////// [/b]
Video::deactivate();
restoreTheTaskbar();
}
break;
...NOTE: This applies to both TGE and TGB/T2D.
#5
Thank you for finding this bug, and resolving it, it looks to have been a bugger! This was actually listed in my bug list for tonight so imagine my surprise to find you had already fixed it! I've looked over your fix and have come up with an 'official' implementation that will go into our repo for our next release. You can find it below.
winWindow.cc Line ~630
Thanks once again Gregory, this saved me a good amount of time I'd imagine!
Best Regards,
-Justin
05/29/2006 (9:41 pm)
Gregory,Thank you for finding this bug, and resolving it, it looks to have been a bugger! This was actually listed in my bug list for tonight so imagine my surprise to find you had already fixed it! I've looked over your fix and have come up with an 'official' implementation that will go into our repo for our next release. You can find it below.
winWindow.cc Line ~630
[b]bool sgKeyboardStateDirty = false;[/b]
//--------------------------------------
static LRESULT PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch ( message )
{
case WM_POWERBROADCAST:
{
if(wParam == PBT_APMQUERYSUSPEND)
return BROADCAST_QUERY_DENY;
return true;
}
case WM_ACTIVATEAPP:
if ((bool) wParam)
{
Video::reactivate();
ShowCursor(false);
if ( Video::isFullScreen() )
hideTheTaskbar();
// HACK: Windows 98 (after switching from fullscreen to windowed mode)
SetForegroundWindow( winState.appWindow );
[b]// If our keyboard state is dirty, clear it
if( sgKeyboardStateDirty == true )
{
sgKeyboardStateDirty = false;
InitInput();
}[/b]
}
else
{
[b]// Window lost focus with a privileged (0 process identifier)
// thread becoming active, this corrupts the keyboard state so
// flag it as such. When we're reactivated we'll re-initialize
// input to clear the state.
if ( lParam == 0 )
sgKeyboardStateDirty = true;[/b]
Video::deactivate();
restoreTheTaskbar();
}
break;Thanks once again Gregory, this saved me a good amount of time I'd imagine!
Best Regards,
-Justin
#6
Keep up the great work on TGB!
05/30/2006 (4:44 am)
No problem, Justin. Glad to be of help. By the way, don't forget to clear your sgKeyboardStateDirty flag after you call InitInput(). :)Keep up the great work on TGB!
#7
10/07/2011 (4:24 am)
That fix got broken again somewhere along the way - stateDirty flag is never set for last version.
Torque Owner Gregory Stewart
You don't have to be in the text edit control for this to happen. Start T2D and press CTRL+ALT+DEL and then cancel. The next time you try to edit any text, the font will be either invisible or unknown characters. I will post more if I find anything else out or come up with a solution.