SetForegroundWindow Win32-API not always works on Windows-7
BIG NOTE
After messing with this API for the last 2 months, the solution/s below are all not stable solutions, but they work in some/most cases, depends on your environment, so keep that in mind.
The solution
The trick is to make windows ‘think’ that our process and the target window (hwnd) are related by attaching the threads (using AttachThreadInput
API) and using an alternative API: BringWindowToTop
.
Forcing Window/Internet Explorer to the foreground
private static void ForceForegroundWindow(IntPtr hWnd)
{
uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(),
IntPtr.Zero);
uint appThread = GetCurrentThreadId();
const uint SW_SHOW = 5;
if (foreThread != appThread)
{
AttachThreadInput(foreThread, appThread, true);
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
AttachThreadInput(foreThread, appThread, false);
}
else
{
BringWindowToTop(hWnd);
ShowWindow(hWnd, SW_SHOW);
}
}
A more advanced implementation of AttachedThreadInputAction pattern
The idea is to attach to the target process thread and preform an action.
public static void AttachedThreadInputAction(Action action)
{
var foreThread = GetWindowThreadProcessId(GetForegroundWindow(),
IntPtr.Zero);
var appThread = GetCurrentThreadId();
bool threadsAttached = false;
try
{
threadsAttached =
foreThread == appThread ||
AttachThreadInput(foreThread, appThread, true);
if (threadsAttached) action();
else throw new ThreadStateException("AttachThreadInput failed.");
}
finally
{
if (threadsAttached)
AttachThreadInput(foreThread, appThread, false);
}
}
Usage
public const uint SW_SHOW = 5;
///<summary>
/// Forces the window to foreground.
///</summary>
///hwnd”>The HWND.</param>
public static void ForceWindowToForeground(IntPtr hwnd)
{
AttachedThreadInputAction(
() =>
{
BringWindowToTop(hwnd);
ShowWindow(hwnd, SW_SHOW);
});
}
public static IntPtr SetFocusAttached(IntPtr hWnd)
{
var result = new IntPtr();
AttachedThreadInputAction(
() =>
{
result = SetFocus(hWnd);
});
return result;
}
Importing Win32-API to do the job
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd,
out uint lpdwProcessId);
// When you don't want the ProcessId, use this overload and pass
// IntPtr.Zero for the second parameter
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd,
IntPtr ProcessId);
[DllImport("kernel32.dll")]
public static extern uint GetCurrentThreadId();
/// The GetForegroundWindow function returns a handle to the
/// foreground window.
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern bool AttachThreadInput(uint idAttach,
uint idAttachTo, bool fAttach);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool BringWindowToTop(HandleRef hWnd);
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, uint nCmdShow);
Abstract
After an interesting research, a solution found to force a window to the top in order to simulate user key presses using SendKeys
.
Problem description
We want to type-keys to simulation user key presses like: strings, enters, tabs…
We are using SendKeys
API. This API require that the wanted target window will be in the foreground and the wanted control will be in focus.
Seems that since 2007, Vista added UAC (User Account Control) and , in a nutshell, SetForegroundWindow
is not working as expected.
After researching the problem, the behavior is that calling SetForegroundWindow for the first time fails (returns false).
After extensive research and readings, it seems that ‘SetForegroundWindow’ have new rules (for security reasons) and the main idea is that ‘An application can’t force another application to be in the foreground, unless it created it or related to it somehow’ (the full rules can be found here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx, see ‘Rules’)
Resources
- SetForegroundWindow not always works [Archive] – Xtreme Visual Basic Talk.
- pinvoke.net: the interop wiki!
- Force Window to Front (not blink in taskbar) – Microsoft: Visual FoxPro FAQ – Tek-Tips.
- Bring Process to the front – CodeProject.
- SetForegroundWindow - http://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx
- BringWindowToTop - http://msdn.microsoft.com/en-us/library/windows/desktop/ms632673(v=vs.85).aspx
SetForegroundWindow Win32-API not always works on Windows-7的更多相关文章
- C#调用Win32 api学习总结
从.NET平台调用Win32 API Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微 ...
- 【.Net】从.NET平台调用Win32 API
小序 Win32 API可以直接控制Microsoft Windows的核心,因为API(Application Programming Interface)本来就是微软留给我们直接控制 ...
- Win32 API编程——前言
一丶什么是Win32 API? 微软为了保护操作系统的安全性和稳定性,把系统分为内核层和用户层(内核层的代码只能在当CPU的特权级为R0状态下执行,用户层的代码在CPU特权级为R0和R3都能执行),w ...
- How to change windows applicatioin's position via Win32 API
可以使用的Win32 API是: [DllImport("user32.dll")] private extern static bool SetWindowPos(IntPtr ...
- WIN32 API ------ 最简单的Windows窗口封装类
1 开发语言抉择 1.1 关于开发Win32 程序的语言选择 C还是C++ 在决定抛弃MFC,而使用纯Win32 API 开发Window桌面程序之后,还存在一个语言的选择,这就是是否使用C++.C+ ...
- 初次认识 C# win32 api
第一次接触win32api,刚开始的时候有点迷迷糊糊的. Windows API 就是windows应用程序接口. win api向上就是windows应用程序,向下就是windows操作系统核心. ...
- Serial Port Programming using Win32 API(转载)
In this tutorial we will learn How to communicate with an external device like a microcontroller boa ...
- 【温故Delphi】GAEA用到Win32 API目录
Delphi是Windows平台下著名的快速应用程序开发工具,它在VCL中封装并使用了大量的Win32 API. GAEA基于VCL开发的工具类产品,在程序中使用了大量的Win32 API,将经常用到 ...
- 【C#】分享基于Win32 API的服务操作类(解决ManagedInstallerClass.InstallHelper不能带参数安装的问题)
注:这里的服务是指Windows 服务. ------------------201508250915更新------------------ 刚刚得知TransactedInstaller类是支持带 ...
- C#中导入Win32 API函数
C#中导入Win32 API的方法: 1.引用命名空间 using System.Net.Security; using System.Runtime.InteropServices; 2. [Dll ...
随机推荐
- pkg-config 详解
转载自:https://blog.csdn.net/newchenxf/article/details/51750239 1 什么是pkg-config pkg-config是一个linux下的命令, ...
- 支持向量机(SVM)
SVM 简介 SVM:Support Vector Machine , 支持向量机, 是一种分类算法. 同Logistic 分类方法目的一样,SVM 试图想寻找分割线或面,将平面或空间里的样本点一分为 ...
- [Unity][安卓]Unity和Android Studio 3.0 交互通讯(1)Android Studio 3.0 设置
[安卓]Android Studio 3.0 JDK安卓环境配置(2017.10) http://blog.csdn.net/bulademian/article/details/78387052 [ ...
- CSAPP:第一章学习笔记:斗之气1段
一.信息就是位+上下文:系统中的所有信息(包括磁盘文件.内存中的程序.网络上传送的数据),都是由一串比特表示,根据上下文对这些比特表示进行翻译. 二.C程序编译过程 1.源码结构 // test.c ...
- PHP yii框架FormWidget组件
本篇文章介绍的是PHP yii框架Form组件,方便在view层更好调用此功能,话不多说上代码:1.先继承yii本身Widget类 <?php/** * User: lsh */ namespa ...
- Json数据产生树形结构
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <hea ...
- Python使用DDA算法和中点Bresenham算法画直线
title: "Python使用DDA算法和中点Bresenham算法画直线" date: 2018-06-11T19:28:02+08:00 tags: ["图形学&q ...
- OAuth授权 | 把这一篇丢给他
OAuth授权 一.背景 上一篇我们介绍了单点登录(SSO),它能够实现多个系统的统一认证.今天我们来谈一谈近几年来非常流行的,大名鼎鼎的OAuth.它也能完成 统一认证,而且还能做更多的事情.至于O ...
- awk if print
awk -F"," '{ if($4=="abc" && $5=="def"){print $1} else {prin ...
- STM32F103引脚功能定义