D
D
Dmitry Timofeev2013-02-08 19:23:05
Delphi
Dmitry Timofeev, 2013-02-08 19:23:05

What's the smartest way to disable touchscreen touch preprocessing in Windows 8?

Hello.
I am writing my graphics editor in Delphi. One of its functions is drawing with a stylus or a finger on the touch screen. All clicks on the Image, which lies in such a normal ScrollBox ( blackstrip.ru/tmp/pcw120ni/1.jpg screen ), must be transferred to the program.
I have a rather old laptop (Asus T101MT) with a resistive touch overlay on the screen that recognizes up to 2 touches at the same time (multi-touch). In Windows XP, this screen is recognized even without drivers, and all screen touches are recognized by the operating system as “moving the cursor to the touched place and pressing the left mouse button there”, releasing the screen as “release the left button”, touching + dragging + releasing as “pressing the left mouse button , dragging the mouse while holding the left button, releasing the left button”, and clicking in one place on the screen and then in another is like “pressing the right button”. Those. simple direct transfer of all touches as left mouse button clicks + right click feature.
In Windows 8, this is a problem - it recognized my touch screen, even shows it in the touch input settings. And now when I move my finger across the window, Windows intercepts all touches and decides for itself what to do. For example, when I navigate an Image in a ScrollBox, Windows thinks that I want to scroll the ScrollBox and moves the Image there to the beat of my finger movements.
I was looking for how to program this business - I found a French article Delphi et le multi-touch (here it is andnotor.developpez.com/tutoriels/delphi/delphi-et... ).
According to this article, Windows 7 and Windows 8 introduced API functions for registering a touch-controlled window, and for setting permissions about what I want to do and what I don't want to do.
For example, in the section "VII. Désactivation de la fonction Press&Hold" describes how to turn off the ability to "press and hold" (it can also "press and drag" at the same time). I do everything that is described there, I create this atom, but Windows 8 does not listen to me, and rotates the Image in the ScrollBox as if nothing had happened. And the rest of the "hold to right click" type is not affected either.
I suspect that it is necessary to register a window and only then play with atoms. And I also suspect that by default in Windows 8 all windows are registered as touch-sensitive with all features such as finger scrolling enabled. But my program works in all Windows from 95 to 8, so you can’t roughly include links to DLLs (otherwise it won’t work in XP and earlier versions), you will have to load the DLL in the process of working, find out if there are such functions, etc. . It's reluctant to do it.
I found another rough but effective (at least on my asus) way is to disable the Microsoft Input Configuration Device in Device Manager under HID Devices. After turning off this device and restarting the computer, all interception of touches with drawing "circles" and "crosses" by Windows disappears, and my touch screen starts working like in XP - just like the left mouse button. But this is somehow not good, suddenly someone likes to touch the screen like that, hold the finger for a long time for the right click, scroll objects in scrollboxes.
How to make it softer? Is there a simple API function in Windows 8 or some other thing to "disable for this particular window all touch screen bugs and skip touches to the mouse cursor and directly to the window without preprocessing"? Has anyone encountered a similar problem?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Timofeev, 2018-03-24
@blackstrip

For anyone interested in the answer to this question, or who stumbles upon this post on the web, here's how to disable:
For each component we want to remove the "touch layer" from, so that the stylus/finger instantly presses the component when pressed and releases it when the finger is released without delay , right click on a long press, etc.:
1) Call RegisterTouchWindow from user32.dll with two parameters: the HWND of the component and the TWF_WANTPALM flag (the flag tells Windows not to calculate the position of pressing across the entire palm pressed, but to quickly take the first touch to the sensor, so as not to waste time recognizing the average coordinates of pressing the "palm" on the screen).
If you want to remove the touch layer for TImage, then you need to specify the HWND of the parent component on which the TImage lies.
If you have a program for different versions of Windows, including XP and earlier (where this function was not), then you can get around this business like this:

type TRTW = function(hwnd: HWND; ulFlags: Cardinal): BOOL; stdcall;
type UTRTW = function(hwnd: HWND): BOOL; stdcall;

const
TWF_WANTPALM = $00000002;

var
touchinited:boolean=false;
HLib:THandle;
tou:TRTW;
utou:UTRTW;

procedure TForm1.InitTouch();
begin
try
Hlib:=LoadLibrary('USER32.DLL');
if HLib>HINSTANCE_ERROR then
begin
tou:=GetProcAddress(Hlib,'RegisterTouchWindow');
utou:=GetProcAddress(Hlib,'UnregisterTouchWindow');
if Assigned(tou) and Assigned(utou) then touchinited:=true;
end;
except
if HLib>HINSTANCE_ERROR then FreeLibrary(HLib);
touchinited:=false;
end;
end;

And then the registration call will look like:
2. After registering the component as a touch component, call this procedure, passing it the HWND of the component (it works in any Windows, even in Windows 95, but without the previous step with RegisterTouchWindows - it will not really work in either Windows 8 or Windows 10 ):
procedure TForm1.DisablePressAndHold(handa:HWND);
var
  Atom :TAtom;
const
  tabletAtom = 'MicrosoftTabletPenServiceProperty';
  TABLET_DISABLE_PRESSANDHOLD = $00000001;
  TABLET_DISABLE_PENTAPFEEDBACK      =$00000008;
  TABLET_DISABLE_PENBARRELFEEDBACK   =$00000010;
  TABLET_DISABLE_FLICKS              =$00010000;
  TABLET_DISABLE_TOUCHUIFORCEON      =$00000100;
  TABLET_DISABLE_TOUCHUIFORCEOFF     =$00000200;
  TABLET_DISABLE_TOUCHSWITCH         =$00008000;
  TABLET_ENABLE_FLICKSONCONTEXT      =$00020000;
  TABLET_ENABLE_FLICKLEARNINGMODE    =$00040000;
  TABLET_DISABLE_SMOOTHSCROLLING     =$00080000;
  TABLET_DISABLE_FLICKFALLBACKKEYS   =$00100000;
  TABLET_ENABLE_MULTITOUCHDATA       =$01000000;
  TABLET_ALL = TABLET_DISABLE_PRESSANDHOLD or TABLET_DISABLE_PENTAPFEEDBACK or TABLET_DISABLE_PENBARRELFEEDBACK or TABLET_DISABLE_FLICKS or TABLET_DISABLE_TOUCHSWITCH or TABLET_DISABLE_SMOOTHSCROLLING or TABLET_DISABLE_FLICKFALLBACKKEYS or TABLET_DISABLE_TOUCHUIFORCEON or TABLET_DISABLE_TOUCHUIFORCEOFF;
begin
  Atom := GlobalAddAtom(tabletAtom);
  if Atom <> 0 then
  begin
    SetProp(handa, tabletAtom, TABLET_ALL);
  GlobalDeleteAtom(Atom);
  end;
end;

3. Before closing the program, you need to "unregister" the touch components back like this:
or for the case of dynamic loading of the library: And then release the library (although, in theory, user32.dll will remain in memory, because it is very likely involved other programs/libraries):
procedure TForm1.FreeTouch();
begin
if HLib>HINSTANCE_ERROR then FreeLibrary(HLib);
end;

And then all the components that are registered and hung with touch-properties will react briskly to the finger / stylus, instantly pressed, while holding - hold the mouse as it should be in the pressed state of the left button, when released - release.
All components that are not weighted - will work as before (with a right click on a long hold, etc.). This feature does not apply to child components (you cannot throw such a thing on the window and all its components so that they automatically become like this with simple taps with the stylus). Therefore, with the handles we throw RegisterTouchWindow and then DisablePressAndHold on each component that is untied from the "touch overlay". And everything seems to be working. Checked:
- on a laptop with Win8 and a resistive screen, on which you can press even with a stylus, even with a finger, even with a wooden toothpick
- on a tablet with Win10 and an electronic stylus a la wacom, which is even just near the screen without touching - it already crawls with a dot on the screen
ps on the Internet, they are also considering the option of tracking the message queue with highlighting touch messages. You can approach this problem from the other end, but this was enough for me (I had to make TImage drawable with a stylus, and make another ten TPanel pressable with a finger).

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question