mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-03-22 15:19:59 +07:00
113 lines
3.2 KiB
C++
113 lines
3.2 KiB
C++
#include <windows.h>
|
|
|
|
// NT 4 doesn't have FlashWindowEx.
|
|
typedef BOOL (WINAPI *t_FlashWindowEx)(FLASHWINFO*);
|
|
t_FlashWindowEx p_FlashWindowEx;
|
|
#define FlashWindowEx p_FlashWindowEx
|
|
|
|
#ifdef USE_DETOURS
|
|
#include "detours.h" // see http://research.microsoft.com/sn/detours/
|
|
extern "C" {
|
|
DETOUR_TRAMPOLINE(BOOL WINAPI Real_SetForegroundWindow(HWND hWnd), SetForegroundWindow);
|
|
}
|
|
#else
|
|
// IAT patching hook method. See http://www.naughter.com/hookimportfunction.html
|
|
// compile with cl /LD focuskiller.cpp HookImportFunction.cpp user32.lib
|
|
#include "HookImportFunction.h"
|
|
|
|
typedef BOOL (WINAPI *t_SetForegroundWindow)(HWND);
|
|
t_SetForegroundWindow Real_SetForegroundWindow;
|
|
#endif
|
|
|
|
DWORD mypid;
|
|
|
|
BOOL WINAPI Mine_SetForegroundWindow(HWND hWnd)
|
|
{
|
|
DWORD pid;
|
|
HWND fg = GetForegroundWindow();
|
|
HWND owner = GetWindow(hWnd, GW_OWNER);
|
|
GetWindowThreadProcessId(fg, &pid);
|
|
|
|
#ifdef _DEBUG
|
|
char buf[500];
|
|
wsprintf(buf, "SetForegroundWindow(%x): owner = %x, %d <-> %d", hWnd, owner, pid, mypid);
|
|
OutputDebugString(buf);
|
|
#endif
|
|
|
|
// Disallow if
|
|
// a) another process' window is in the foreground
|
|
// b) the window to be put in front is a top-level window (should avoid putting one IDEA project in front of another one)
|
|
if (mypid != pid || owner == NULL) {
|
|
if (FlashWindowEx != NULL) {
|
|
FLASHWINFO fw;
|
|
fw.cbSize = sizeof(fw);
|
|
fw.hwnd = hWnd;
|
|
fw.uCount = 5;
|
|
fw.dwTimeout = 0;
|
|
|
|
fw.dwFlags = FLASHW_TRAY | FLASHW_TIMERNOFG;
|
|
FlashWindowEx(&fw);
|
|
} else {
|
|
FlashWindow(hWnd, TRUE);
|
|
}
|
|
return TRUE; // fake success
|
|
}
|
|
|
|
return Real_SetForegroundWindow(hWnd);
|
|
}
|
|
|
|
void HookFunctions(HMODULE hModule)
|
|
{
|
|
#ifdef USE_DETOURS
|
|
#ifdef _DEBUG
|
|
OutputDebugString("Using Detours hook...");
|
|
#endif
|
|
|
|
DetourFunctionWithTrampoline((PBYTE)Real_SetForegroundWindow,
|
|
(PBYTE)Mine_SetForegroundWindow);
|
|
#else
|
|
#ifdef _DEBUG
|
|
OutputDebugString("Using IAT patching hook...");
|
|
#endif
|
|
|
|
HOOKFUNCDESC hook;
|
|
hook.szFunc = "SetForegroundWindow";
|
|
hook.pProc = (PROC)Mine_SetForegroundWindow;
|
|
|
|
// hooking LoadLibrary and waiting until awt.dll is being loaded by java would be more correct but this works too
|
|
HMODULE awtModule = LoadLibrary("awt.dll");
|
|
|
|
BOOL b = HookImportFunctionsByName(awtModule, "user32.dll", 1, &hook, (PROC *)&Real_SetForegroundWindow, NULL);
|
|
if (!b) {
|
|
char buf[200];
|
|
wsprintf(buf, "Hooking SetForegroundWindow failed [0x%x]", GetLastError());
|
|
OutputDebugString(buf);
|
|
}
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
OutputDebugString("Functions hooked");
|
|
#endif
|
|
}
|
|
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
|
|
{
|
|
if (fdwReason == DLL_PROCESS_ATTACH) {
|
|
#ifdef _DEBUG
|
|
char buf[200];
|
|
wsprintf(buf, "DLL Attached");
|
|
OutputDebugString(buf);
|
|
#endif
|
|
|
|
mypid = GetCurrentProcessId();
|
|
p_FlashWindowEx = (t_FlashWindowEx)GetProcAddress(GetModuleHandle("user32.dll"), "FlashWindowEx");
|
|
|
|
DisableThreadLibraryCalls((HMODULE)hinstDLL);
|
|
|
|
HookFunctions((HMODULE)hinstDLL);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|