SetForegroundWindow Windows 11 doesn't work - setforegroundwindow

I use without problems a program that uses [SetForegroundWindow] in C# to bring the window to the foreground and activate in Windows 7 and Windows 10 operating systems, but now with Windows 11 it stopped working.
I need help, does anyone know how to be able to use SetForegroundWindow on Windows 11?
Site: https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setforegroundwindow
//windows forms project
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("USER32.DLL")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
//use
IntPtr janela = FindWindow(null, "Seleção de Cliente");
SetForegroundWindow(janela);

Related

Disable mouse promotion

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.

Window size/positions changed after remote desktop session

I use Remote Desktop to connect from a laptop with Windows XP Professional SP3 and one screen to a remote PC running Windows 7 Professional with two monitors.
The laptop resolution is around 1024x768 and each monitor on the remote PC is around 1600x900.
Before I start the Remote Desktop session, I move all windows on the second monitor of the Windows 7 PC to the first monitor. (Both laptop and PC are in the same office area.)
The Remote Desktop session works, but after closing the session on the laptop and returning to work on the remote Windows 7 PC, I usually have to relocate and resize many of the windows to get back to the original arrangement.
With my current configuration, how can I avoid the "relocate and resize" step above?
If the laptop had Windows 7 Professional, would that help solve this problem?
You should probably move this to superuser, but since you asked on StackOverflow, you could implement a program that does what you describe.
In pseudocode:
class WindowPosition {
IntPtr hWnd;
RECT Location;
}
List<WindowPosition> positions = null;
void OnCaptureWindowPositionHotkey() {
positions = new List<WindowPosition>();
EnumWindows(enumStoreWindows, null);
}
void OnResetWindowPositionHotkey() {
EnumWindows(enumStoreWindows, null);
}
void enumSetWindows(IntPtr hwnd, IntPtr obj) {
positions.Add(new WindowPosition() {
hWnd = hwnd,
Location = GetWndLocation(hwnd)
};
}
RECT GetWndLocation(IntPtr hwnd) {
RECT outrect = null;
GetWindowRect(hwnd, out outrect);
return outrect;
}
void enumSetWindows(IntPtr hwnd, IntPtr obj) {
var loc = (from wl in positions
where wl.hWnd == hwnd
select wl).FirstOrDefault();
if (loc == null) return;
SetWindowPos(hwnd, null,
loc.Location.X,
loc.Location.Y,
loc.Location.Width,
loc.Location.Height,
0);
}
where EnumWindows, SetWindowPos and GetWindowRect are all Win32 functions. See:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms633497(v=vs.85).aspx, http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545(v=vs.85).aspx, and http://msdn.microsoft.com/en-us/library/windows/desktop/ms633519(v=vs.85).aspx.

Problems writing up WebBrowser COM events

I'm developing a project that needs to show HTML that is returned by a third party service. I am currently using a WPF WebBrowser to show this output. However this creates a potential security problem in the eyes of my customers. When focus is set to this control you can open any webpage by using CTRL+O or open Internet Explorer by using Ctrl+N. My application is targeted for a kiosk-like environment (Terminal Services).
In the past I've used the WinForms WebBrowser control and was able to sink into the events through COM, however those tactics don't seem to work with the WPF version. My development partners are adamant that we develop a pure WPF application instead of mixing in the WinForms option.
Has anyone had success getting to the IWebBrowserEvets2COM interface of the WPF WebBrowser? I have been able cast the WebBrowser.Document to an IWebBrowser, but haven't got to where I need.
Please help me tap into the events so that I can stop the user from creating new windows and other events that might cause "security" problems for my clients. Or is there a better control out there to do the rendering of HTML and basic navigation?
Thanks in advance,
Jerod
You can try to use Windows hooks here. Find browser window and install proper keyboard hooks for it. This externals should be helpful for you:
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, IntPtr windowTitle);
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern IntPtr SetWindowsHookEx(Int32 idHook, HookProc lpfn, IntPtr hInstance, Int32 threadId);
And here is a sample how to use those, but you have to implement KeyboardHookProcedure according to your needs.
private IntPtr FindExplorerWindow()
{
IntPtr wnd = Browser.Handle;
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero);
if (wnd != IntPtr.Zero)
{
wnd = FindWindowEx(wnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero);
return wnd;
}
}
return IntPtr.Zero;
}
private void InstallHook()
{
if (_hHook.ToInt32() > 0) return;
IntPtr wnd = FindExplorerWindow();
if (wnd != IntPtr.Zero)
{
if (_hookProc == null)
{
_hookProc = new HookProc(KeyboardHookProcedure);
}
_hHook = SetWindowsHookEx(WH_KEYBOARD, _hookProc, (IntPtr)0, GetCurrentThreadId());
}
}
Good luck!

WPF identify remote access (Not Winforms)

How can a WPF app know if its getting remotely operated (via VNC or remote desktop)?
In winforms there is System.Windows.Forms.SystemInformation.TerminalServerSession as per Detecting remote desktop connection but is there a strightforward way for this in WPF?
I guess the hack for now could be to have an invisible Winforms host on WPF and use its own capacity to host dummy win form that can identify the same... but that looks lame to me!
Any inputs would be appreciated!
Thx
I guess the hack for now could be to have an invisible Winforms host on WPF and use its own capacity to host dummy win form that can identify the same... but that looks lame to me!
You don't need an invisible WinForms host... you can just add a reference to the System.Windows.Forms assembly, and use the SystemInformation.TerminalServerSession static property.
If you don't want a dependency on WinForms, you can use the GetSystemMetrics Win32 API:
const int SM_REMOTESESSION = 0x1000;
[DllImport("user32")]
static extern int GetSystemMetrics(int nIndex);
public static bool IsTerminalServerSession()
{
return (GetSystemMetrics(SM_REMOTESESSION) & 1) != 0;
}
This method does not require a Windows Forms Window, only a reference to the DLL.
If you don't want to reference this, you can call the method to check this yourself, the implementation is as follows (I've wrapped it in a class):
static class SystemInformation
{
[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
private static extern int GetSystemMetrics(int nIndex);
public static bool IsTerminalServerSession
{
get
{
//copied the Windows Forms implementation
return (GetSystemMetrics(0x1000) & 1) != 0;
}
}
}

wpf console application not returning to prompt

I've got a wpf "console" application with the following application class:
public partial class App : Application
{
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool FreeConsole();
const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
AttachConsole(ATTACH_PARENT_PROCESS);
Console.WriteLine("test1");
FreeConsole();
System.Environment.Exit(0);
}
}
When i start it from the console the text "test1" appears but then the console cursor just blinks and the prompt does not appear until I hit Enter. I did remove the StartupURI statement.
How to force the application to behave like a console app and return to prompt after the execution? (Windows 7 32 bit).
Instead of setting it as a Windows Application output, use a Console Application output type. The only drawback is that the console will stay open while the windows application is running. I suppose since you can get the processId of the console, you might be able to kill it after launch.

Resources