Disable mouse promotion - wpf

Is there any way to disable mouse promotion from code, that is preventing windows to interpret touch events as mouse events?
I capture touch events in my WPF application, and I don't want these interactions to effect mouse pointer visibility and position.
There is a TouchFrameEventArgs.SuspendMousePromotionUntilTouchUp Method that seems to be doing exactly that. Unfortunately it's available only for Silverlight and Windows Phone.
In addition there are some system settings you can use to disable double click and right click promotion, but nothing to disable mouse promotion as a whole.
A Windows 8 specific solution or a low level solution would also help.

The plain Win32 API way of disabling touch promotion to mouse is to handle WM_POINTER* messages in your window's WindowProc (actually, it seems just WM_POINTERDOWN is enough) and NOT call DefWindowProc().
This is what we actually do in some of our commercial applications, and what is suggested here.
This is ONLY available from Windows 8 and later, since the WM_POINTER* messages are not generated by Windows 7 and below.
Now, in the WPF world, this gets more complicated.
First of all, in order to get proper WM_POINTER* handling by the WPF stack, you first need to
Use .NET 4.7
Change some configuration in your WPF app:
(Reporting the code here, just in case the MS page disappears) You need to insert this in your app.config file:
<configuration>
<runtime>
<AppContextSwitchOverrides value="Switch.System.Windows.Input.Stylus.EnablePointerSupport=true"/>
</runtime>
</configuration>
Now the new shiny WPF stack is activated, but it's bugged and moves the mouse cursor even if you handle the OnTouchDown, OnTouchUp, OnTouchMove events and set the Handled flag to true.
We discovered, through the use of a HwndSourceHook and blocking the WM_POINTERDOWN message, that the mouse cursor was finally staying still (although we were blocking all touch-down interactions!)
So, we deducted that the shiny new WPF is actually calling DefWindowProc, even if we are handling the OnTouch* events.
Our soultion was to use Microsoft Detours, in order to intercept the DefWindowProc call, and block the WM_POINTERDOWN from reaching the real DefWindowProc.
The detour code is:
#include <Windows.h>
#include <detours.h>
static LRESULT(WINAPI * _originalDefWindowProcA)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = DefWindowProcA;
static LRESULT(WINAPI * _originalDefWindowProcW)(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) = DefWindowProcW;
static LRESULT WINAPI myDefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_POINTERDOWN:
return 0;
default:
return _originalDefWindowProcA(hWnd, Msg, wParam, lParam);
}
}
static LRESULT WINAPI myDefWindowProcW(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch (Msg)
{
case WM_POINTERDOWN:
return 0;
default:
return _originalDefWindowProcW(hWnd, Msg, wParam, lParam);
}
}
void SetupDefWindowProcDetour()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)_originalDefWindowProcA, myDefWindowProcA);
DetourAttach(&(PVOID&)_originalDefWindowProcW, myDefWindowProcW);
DetourTransactionCommit();
}
NOTE: SetupDefWindowProcDetour must be called by the main (UI) thread of your app.

public static class PreventTouchToMousePromotion
{
public static void Register(FrameworkElement root)
{
root.PreviewMouseDown += Evaluate;
root.PreviewMouseMove += Evaluate;
root.PreviewMouseUp += Evaluate;
}
private static void Evaluate(object sender, MouseEventArgs e)
{
if (e.StylusDevice != null)
{
e.Handled = true;
}
}
}
Excample Usage:
public MainWindow()
{
InitializeComponent();
PreventTouchToMousePromotion.Register(this);
}
or take a look at this post
http://social.msdn.microsoft.com/Forums/vstudio/en-US/9b05e550-19c0-46a2-b19c-40f40c8bf0ec/prevent-a-wpf-application-to-interpret-touch-events-as-mouse-events?forum=wpf#9965f159-04a4-41ed-b199-30394991f120

There doesn't seem to be any such option (at least up to Windows 8.1 and .NET 4.5).
The only way to disable mouse promotion is to disable finger input completely, either from within the system control panel (open control panel, open "Pen and Touch", select "Touch" tab, disbale "Use your finger as an input device") or via Registry (HKLM\Software\Microsoft\Wisp\Touch, TouchGate = 0 =disable touch)
Then you can still process touch input using one of the following (nasty) alternatives:
Write your own WinUSB driver for your touch device
Get raw touch input data using the RawInput API
Find a 3rd party USB driver for your device (e.g. UPDD TouchBase)
Finally, you can inject the collected touch data into your application using custom routed events or using touch injection.
In any case you will, of course, loose touch support for any other application on your system, so this solution will in general not be too helpfull to you.

Related

Disabling close button in messageboxa with the use of sc_close [duplicate]

This question already has answers here:
Disable X-Button Icon on the top of the right in Messagebox Using C++ Win32 API?
(4 answers)
Closed 2 years ago.
I had this problem for quite a while now.
In my message box, I have a cancel button. I don't want the close button to interfere because my cancel button does something, which shouldn't happen if I press the close button.
I used a loop-and-find trick, but when I open a folder that also has the same title as the message box, the code disables the close button of Explorer, which is very annoying.
This was what I used to disable the close button that also interferes with other windows that have the same title:
DWORD WINAPI CreateMessageBox(void *argr){
*(int*)argr = MessageBoxA( NULL,
"Time is past active hours\nPlease save your work\nSystem is shutting down in 1 minute.\n",
"Warning",
MB_OKCANCEL|MB_ICONSTOP|MB_SYSTEMMODAL );
return 0;
}
thread = CreateThread(NULL, 0, CreateMessageBox, &opt, 0, NULL);
while (!(msg = FindWindow(NULL, "Warning")));
style = GetWindowLongPtr(msg, GWL_STYLE);
SetWindowLongPtr(msg, GWL_STYLE, style & ~WS_SYSMENU);
WaitForSingleObject(thread, INFINITE);
But now, I read somewhere that there is this SC_CLOSE thing that also disables the close button exclusively to that window. How do I use it? I've gone through some posts about it, but none of them uses MessageBox() and that just overwhelms me.
Please, can somebody help me?
Your call to FindWindow() is not specifying a class name, thus it will find any top-level window with a matching title. In your case, an Explorer window. Provide the actual class name for the MessageBox window, which is "#32770", eg:
msg = FindWindow("#32770", "Warning")
However, there is a much more reliable approach that doesn't invoke searching window titles - get rid of the calls to CreateThread() and FindWindow() completely, and instead make the thread that calls MessageBox() use a local WH_CBT hook via SetWindowsHookEx() to catch the HWND that MessageBox() creates, then you can manipulate that window as desired, eg:
LRESULT CALLBACK MyCBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode == HCBT_CREATEWND)
{
((CBT_CREATEWND*)lParam)->lpcs->style & ~WS_SYSMENU;
}
/* alternatively:
if (nCode == HCBT_ACTIVATE)
{
HWND hwnd = (HWND)wParam;
LONG_PTR style = GetWindowLongPtr(hwnd, GWL_STYLE);
SetWindowLongPtr(hwnd, GWL_STYLE, style & ~WS_SYSMENU);
}
*/
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
...
HHOOK hHook = SetWindowsHookEx(WH_CBT, &MyCBTProc, NULL, GetCurrentThreadId());
opt = MessageBoxA(NULL,
"Time is past active hours\nPlease save your work\nSystem is shutting down in 1 minute.\n",
"Warning",
MB_OKCANCEL|MB_ICONSTOP|MB_SYSTEMMODAL);
if (hHook)
UnhookWindowsHookEx(hHook);
Alternatively, simply use TaskDialog() or TaskDialogIndirect() instead of MessageBox(). A Task Dialog does not have a close button in the title bar, unless you call TaskDialogIndirect() with the TDF_ALLOW_DIALOG_CANCELLATION flag enabled:
Indicates that the dialog should be able to be closed using Alt-F4, Escape, and the title bar's close button even if no cancel button is specified in either the dwCommonButtons or pButtons members.
TaskDialog(NULL, NULL,
L"Warning",
L"Time is past active hours",
L"Please save your work\nSystem is shutting down in 1 minute.",
TDCBF_OK_BUTTON | TDCBF_CANCEL_BUTTON,
TD_ERROR_ICON,
&opt);

Windows C: LoadBitmap() function is not working

I write simple windows c program to display the bitmap at the place where the left mouse button is pressed. At the first time when I click my left mouse button, the bitmap appears. But on the second time on words the bitmap is not getting displayed on the place where I made a left mouse click.
Here is my code.........
LRESULT CALLBACK myHandler(HWND hw, UINT m, UINT mextra, long co_ord)
{
HDC hdc, hmemdc;
PAINTSTRUCT ps;
HBITMAP hbmp;
RECT r;
HGDIOBJ holdbmp;
int x, y;
switch(m)
{
case WM_LBUTTONDOWN:
hdc = BeginPaint(hw,&ps);
hmemdc = CreateCompatibleDC(hdc);
hbmp = LoadBitmap(h, MAKEINTRESOURCE(IDB_BITMAP1));
holdbmp = SelectObject(hmemdc, hbmp);
x = LOWORD(co_ord);
y = HIWORD(co_ord);
BitBlt(hdc, x, y, 190, 220, hmemdc, 0, 0, SRCCOPY);
EndPaint(hw,&ps);
SelectObject(hmemdc, holdbmp);
DeleteObject(hbmp);
DeleteDC(hmemdc);
DeleteDC(hdc);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hw,m,mextra,co_ord);
}
return 0L;
}
The code is wrong about seven different ways from Sunday. Even after the changes you've made in response to WhozCraig's comments, it is still wrong.
For starters, the only place you are allowed to call BeginPaint and EndPaint is in response to a WM_PAINT message. You are trying to call these functions in response to a WM_LBUTTONDOWN message. That cannot work. What you'll want to do is trigger a WM_PAINT message from within your WM_LBUTTONDOWN message handler, which you can do by calling the InvalidateRect() function, passing your window handle and NULL for the rectangle to invalidate (to invalidate your entire window). Then, inside of the WM_PAINT message handler, you can call BeginPaint/EndPaint and do your drawing. If you want the drawing to be different depending on whether the left mouse button is down, you can either set a flag inside of the WM_LBUTTONDOWN message handler and test the value of that flag inside of your WM_PAINT message handler, or you can use something like GetKeyState to determine whether the mouse button is down (VK_LBUTTON).
You are also leaking GDI objects because you are not correctly releasing/destroying them. A bitmap that has been loaded with LoadBitmap needs to be destroyed by calling DeleteObject. (However, loading a bitmap repeatedly inside of a WM_PAINT message handler will lead to poor performance. Instead, prefer to load the bitmap a single time in response to the WM_CREATE message, cache its handle in a global or class-level variable, use it when necessary, and destroy the bitmap via that handle in response to the WM_DESTROY message.)
The LOWORD and HIWORD macros should never be used for extracting cursor coordinates. These are liable to return the wrong result on multiple monitor systems. Instead, you should use GET_X_LPARAM and GET_Y_LPARAM. This is specifically mentioned in the MSDN documentation for the WM_LBUTTONDOWN message. Always read the documentation for things you are unfamiliar with!
Finally, the signature for your window procedure is also completely wrong. I have no idea where you got that signature, but not only do you have non-standard parameter names that obscures the actual meaning of those arguments, but you have the wrong types. A window procedure looks like this:
LRESULT CALLBACK myHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
...
}
It is extremely difficult to learn Windows API programming by just hacking around, especially if you aren't disciplined about reading the MSDN documentation. If you really want to learn it, consider purchasing a book, like Charles Petzold's classic Programming Windows, 5th edition (yes, you need the 5th edition, not a newer edition).

Are there any good options for creating functional windows forms for C?

I have been learning C# and use Microsoft Visual Studio which makes it very easy and enjoyable to create windows forms with various controls like progress bars, drop down menus, file-system browsers etc..
Can the same thing be done with C, and are there any recommended programs?
(I have learned some C and would like to make graphical interfaces a step further than just in the console, I guess this is quite hard?).
The windows API was (and still is) a C API. Documented on msdn.microsoft.com.
The simplest way to create a Windows application with a simple form, in C, without using any external frameworks is this program:
#include <Windows.h>
#include "Resource.h"
BOOL CALLBACK DialogProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch(uMsg)
{
case WM_INITDIALOG:
return TRUE;
}
return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hNull, LPTSTR cmdLine, int cmdShow)
{
return DialogBoxParam(hInstance,MAKEINTRESOURCE(IDD_MAINDIALOG),NULL,DialogProc,0L);
}
The assumption is that, in addition to this main.c file, you use the Visual Studio resource editor to create a resource script file (.rc) with a dialog resource that you lay out your controls on.
If you are using Visual Studio Express a resource editor is not included and you will need a 3rd party editor (they are available) to lay out the dialog.
GTK+ at http://www.gtk.org/documentation.php

global keyboard hooks in c

i want to write a global keyboard hook to disallow task switching.When i googled i found a whole lot of codes in c#,cpp (and delphi), but i need some basic concepts about hooking (would be the best if examples are in C).So, kindly suggest the resources,links that can help me understand the thing in C's perspective.
PS: I found one good working example(works on winXP and older versions),but when i tried compiling the code it gives me:
And i tried searching the "IDC_" constants in all the headers(default ones that come with MinGW gcc installation and the ones provided by developer),but no luck...If any one can compile the code and make it run please help me.I have not uploaded the source itself here as there are a few header file dependencies and in that case i'd have to post all the code here.
winXP is the target environment but would be better if i get it to run Win7 also.
I will go out on a limb here assuming you are on Windows and you want to capture global keystrokes. A way to do this is to use LowLevelHooks. Look at the following example:
Define this callback function somewhere in your code:
//The function that implements the key logging functionality
LRESULT CALLBACK LowLevelKeyboardProc( int nCode, WPARAM wParam, LPARAM lParam )
{
char pressedKey;
// Declare a pointer to the KBDLLHOOKSTRUCTdsad
KBDLLHOOKSTRUCT *pKeyBoard = (KBDLLHOOKSTRUCT *)lParam;
switch( wParam )
{
case WM_KEYUP: // When the key has been pressed and released
{
//get the key code
pressedKey = (char)pKeyBoard->vkCode;
}
break;
default:
return CallNextHookEx( NULL, nCode, wParam, lParam );
break;
}
//do something with the pressed key here
....
//according to winapi all functions which implement a hook must return by calling next hook
return CallNextHookEx( NULL, nCode, wParam, lParam);
}
And then somewhere inside your main function you would set the hook like so:
//Retrieve the applications instance
HINSTANCE instance = GetModuleHandle(NULL);
//Set a global Windows Hook to capture keystrokes using the function declared above
HHOOK test1 = SetWindowsHookEx( WH_KEYBOARD_LL, LowLevelKeyboardProc, instance,0);
More general information about hooks can be found here.
You can also capture other global events with the same exact way only following the directions given in SetWindowsHooksEX documentation.

Structuring Win32 GUI code

I wish to improve my code and file structure in larger Win32 projects with plenty of windows and controls. Currently, I tend to have one header and one source file for the entire implementation of a window or dialog. This works fine for small projects, but now it has come to the point where these implementations are starting to reach 1000-2000 lines, which is tedious to browse.
A typical source file of mine looks like this:
static LRESULT CALLBACK on_create(const HWND hwnd, WPARAM wp, LPARAM lp) {
setup_menu(hwnd);
setup_list(hwnd);
setup_context_menu(hwnd);
/* clip */
return 0;
}
static LRESULT CALLBACK on_notify(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
const NMHDR* header = (const NMHDR*)lp;
/* At this point I feel that the control's event handlers doesn't
* necessarily belong in the same source file. Perhaps I could move
* each control's creation code and event handlers into a separate
* source file? Good practice or cause of confusion? */
switch (header->idFrom) {
case IDC_WINDOW_LIST:
switch (header->code) {
case NM_RCLICK:
return on_window_list_right_click(hwnd, wp, lp);
/* clip */
}
}
}
static LRESULT CALLBACK wndmain_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) {
switch (msg) {
case WM_CREATE:
return on_create(hwnd, wp, lp);
case WM_CLOSE:
return on_close(hwnd, wp, lp);
case WM_NOTIFY:
return on_notify(hwnd, wp, lp);
/* It doesn't matter much how the window proc looks as it just forwards
* events to the appropriate handler. */
/* clip */
default:
return DefWindowProc(hwnd, msg, wp, lp);
}
}
But now as the window has a lot more controls, and these controls in turn have their own message handlers, and then there's the menu click handlers, and so on... I'm getting lost, and I really need advice on how to structure this mess up in a good and sensible way.
I have tried to find good open source examples of structuring Win32 code, but I just get more confused since there are hundreds of files, and within each of these files that seem GUI related, the Win32 GUI code seems so far encapsulated away. And when I finally find a CreateWindowEx statement, the window proc is nowhere to be found.
Any advice on how to structure all the code while remaining sane would be greatly appreciated.
Thanks!
I don't wish to use any libraries or frameworks as I find the Win32 API interesting and valuable for learning.
Any insight into how you structure your own GUI code could perhaps serve as inspiration.
For starters, I'd take a look at the message crackers in windowsx.h; they'll save you writing tedious case statements in your window procedures, and they suggest a certain discipline in function names.

Resources