xsharp.eu • CapsLock(), InsMode() , NumLock()
Page 1 of 2

CapsLock(), InsMode() , NumLock()

Posted: Sun Apr 11, 2021 11:22 am
by Karl-Heinz
Guys,

i'm looking at the mentioned VFP functions. The help description doesn' t give an answer, but after looking at some VFP sites it seems that these funcs change the global input state, and not the input state of the calling thread only. Is that correct ?

regards
Karl-Heinz

CapsLock(), InsMode() , NumLock()

Posted: Sun Apr 11, 2021 3:55 pm
by atlopes
Karl-Heinz, the functions CAPSLOCK() and NUMLOCK() set the global state. As for the INSMODE() function, I assume "yes," also, but I'm not quite sure of that.

CapsLock(), InsMode() , NumLock()

Posted: Sun Apr 11, 2021 8:26 pm
by Karl-Heinz
Hi Antonio,

The insert mode is a special beast. Notepad ignores the setting and Winword seems to have its own on/off insert implementation. But it works in a VO/X# window if the edit control uses the OVERWRITE_ONKEY setting.

The attached file is a XIDE viaef. When you look at the Keyboard.prg you'll see that most of the code is encapsulated in the internal class win32, and that GetKeyState() and SendInput() is used to toggle the Capslock, Insert or Num key. Currently there are two unused structures (winHardwareInput and winMouseInput ) included. i'll deactvate or remove them later. As long as the XIDE checkbox '[x] Define debug' is checked you can see in the console when a switch occurs. Later on, i'll also remove the '#ifdef DEBUG ... #endif' code.

Don't be surprised how you have to leave the console window :-) , otherwise its not possible to run the app as a exe. I noticed that a simple 'wait' instead of the 'do while .. enddo' automatically quits the exe. This does not happen if all InsMode() calls are deactivated .... very strange.

Give it a try and let me know how it goes.

regards
Karl-Heinz

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 6:32 am
by robert
Karl-Heinz
I think the only relevant thread for these values is the UI Thread. So this should be set globally.
Robert

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 8:05 am
by robert
Karl-Heinz,
Is there a reason why you coded this to the Win32 API and did not use Control.isKeyLocked from System.Windows.Forms ?

Robert

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 11:43 am
by Karl-Heinz
robert wrote:Karl-Heinz,
Is there a reason why you coded this to the Win32 API and did not use Control.isKeyLocked from System.Windows.Forms ?

Robert
because of the System.Windows.Forms dependency, so from my understanding that doesn t help in a console app ? i also looked at this option:

Code: Select all

USING System.Windows.Input

// required Dll references:  Windowsbase , PresentationCore

FUNCTION KeysTest() AS VOID 
	
 // System.Windows.Input.xxx

 ? Keyboard.IsKeyToggled(Key.NumLock) 
 ? Keyboard.IsKeyToggled(Key.CapsLock)
 ? Keyboard.IsKeyToggled(Key.Insert)
 ? 
  
RETURN

When i get the time i'll take a closer look at the available options. Do you agree that both, windows form and console apps should be supported ?

regards
Karl-Heinz

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 11:51 am
by robert
Karl Heinz,
This is the (C#) code inside Control.IsKeyLocked

Code: Select all

public static bool IsKeyLocked(Keys keyVal)
{
	if (keyVal == Keys.Insert || keyVal == Keys.NumLock || keyVal == Keys.Capital || keyVal == Keys.Scroll)
	{
		int keyState = UnsafeNativeMethods.GetKeyState((int)keyVal);
		if (keyVal == Keys.Insert || keyVal == Keys.Capital)
		{
			return (keyState & 1) != 0;
		}
		return (keyState & 0x8001) != 0;
	}
	throw new NotSupportedException(SR.GetString("ControlIsKeyLockedNumCapsScrollLockKeysSupportedOnly"));
}
I think it does exactly what you did to read the state. But it does NOT change the state.
Maybe this code can be used to set the state:
https://stackoverflow.com/questions/136 ... s-lock-key
This does not need all the extra structures.

Robert

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 4:22 pm
by Karl-Heinz
Hi Robert,

i'm aware of the keybd_event() function and it gives the same results as SendInput(). However, it is recommended to use SendInput() instead.

https://docs.microsoft.com/en-us/window ... eybd_event

regards
Karl-Heinz

CapsLock(), InsMode() , NumLock()

Posted: Mon Apr 12, 2021 6:18 pm
by robert
Karl-Heinz,

Ok, I see. In that case you may want to consider to replace the InputUnion in the winInput structure with just the winKeyboardInput structure, since you are not using the MouseInput and the HardwareInput. That will make the code a bit smaller and easier to understand.
Of course you will have to a few dummy items to the structure because the MouseInput structure is larger (I think you would have to use 2 dummy LONG or DWORD items to get the same size).

Robert

CapsLock(), InsMode() , NumLock()

Posted: Tue Apr 13, 2021 6:27 pm
by Karl-Heinz
Hi Robert;

the modified class now looks like

Code: Select all

INTERNAL CLASS Win32  

	CONST INTERNAL KEYEVENTF_KEYUP := 2 AS INT
	CONST INTERNAL VK_INSERT := 45 AS INT
	CONST INTERNAL VK_NUMLOCK := 144 AS INT
	CONST INTERNAL VK_CAPITAL := 20 AS INT 
    	CONST INTERNAL TYPE_KEYBOARD := 1 AS INT
    
		
	[DllImport("user32.dll", SetLastError := TRUE)] ;
	INTERNAL STATIC METHOD SendInput(nInputs AS DWORD , pInputs AS winInput[], cbSize AS LONG ) AS DWORD

	[DllImport("user32.dll", SetLastError := TRUE)] ;
	INTERNAL STATIC METHOD GetKeyState(nVirtkey AS INT) AS SHORTINT
		
	[StructLayout(LayoutKind.Sequential)];	
	INTERNAL STRUCTURE winKeyboardInput2
		INTERNAL wVk AS WORD 
		INTERNAL wScan AS WORD
		INTERNAL dwFlags AS DWORD
		INTERNAL time AS DWORD
		INTERNAL dwExtraInfo AS IntPtr
		INTERNAL Dummy1 AS DWORD  // <-----
		INTERNAL Dummy2 AS DWORD  // <-----		
	END STRUCTURE 		

	
	[StructLayout(LayoutKind.Sequential)] ;
	INTERNAL STRUCTURE winInput
		INTERNAL Type AS DWORD
		INTERNAL Input AS winKeyboardInput2 
	END STRUCTURE 

END CLASS 

What's still missing are the names i should use:
- name of the modified winKeyboardInput structure ? - currently winKeyboardInput2
- name of the 2 new members ? - currently dummy1 and dummy2

regards
Karl-Heinz