0

I've built a C# application that takes another window handler and its process like in this post, I can send some command from my application to the window via PostMessage and this window reacts accordingly even when inactive.

The problem appears when I press the ALT and this window reacts on ALT + my_key_command like a hotkey. Please, explain how to prevent ALT keypress event handling in specific window from my application? Is this possible?

I want to blind only this window for ALT key. Here's example:

    [DllImport("user32.dll")]
    static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

    [DllImport("user32.dll")]
    private static extern IntPtr GetForegroundWindow();

    [DllImport("user32.dll", SetLastError = true)]
    private static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

    [STAThread]
    static async Task Main()
    {
        await Task.Delay(TimeSpan.FromSeconds(5));
        IntPtr window = GetForegroundWindow();

        while (true)
        {
            int processId;
            GetWindowThreadProcessId(window, out processId);
            Process[] processes = Process.GetProcessesByName("iexplorer");
            var process = findProcessById(processes, processId);
            if (process != null)
            {
                PostMessage(process.MainWindowHandle, WM_KEYDOWN, 0x74, 0);
            }
            Thread.Sleep(5000);
        }
    }

    static private Process findProcessById(Process[] processes, int id)
    {
        Process result = null;
        foreach (Process proc in processes)
        {
            if (proc.Id == id)
                result = proc;
        }
        return result;
    }
Vit
  • 21
  • 2
  • Inject a dll that uses `SetWindowsHookEx` with a keyboard hook to hook the keys.. – Brandon May 09 '20 at 01:46
  • Be very careful with WindowsHooks - read about the various ways you can mess things up. – Flydog57 May 09 '20 at 02:07
  • What problem are you trying to solve? This question is asking about your proposed solution. A phenomenon often described as the [XY Problem](http://xyproblem.info). – IInspectable May 09 '20 at 06:01
  • I don't see any window hierarchies being established in the code. I do see a `PostMessage` with a `WM_KEYDOWN` message, though. And as we all know by now, [you can't simulate keyboard input with PostMessage](https://devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513). So, again, what's the *real* issue you are trying to solve? – IInspectable May 09 '20 at 08:28
  • I need my application to send commands like F1, F2, ... F12 to another application (window), for example Internet Explorer. This code works well for these purposes, but the application handles ALT+F5 and F5 commands different ways, so I don't need ALT+F5 at all. That's why I firstly think to block ALT key. If there are another way to solve this, I will try all approaches – Vit May 09 '20 at 11:10

1 Answers1

1

This code works well for these purposes, but the application handles ALT+F5 and F5 commands different ways, so I don't need ALT+F5 at all. That's why I firstly think to block ALT key.

Please use SetWindowsHookEx and WH_KEYBOARD.

You need to inject a dll containing the keyboard hook into the target program. By installing a keyboard hook, and prevent the return of the ALT key.

Sample code: (C++)

.dll:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <iostream>
#include <stdio.h>

HINSTANCE hinst;
#pragma data_seg(".shared")
HHOOK hhk;
#pragma data_seg()

LRESULT CALLBACK wireKeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
    if (code >= 0)
    {       
        switch (wParam)
        {
             case VK_MENU:
             {
                 return 1;
             }
        }
    }
    return CallNextHookEx(hhk, code, wParam, lParam);
}

extern "C" __declspec(dllexport) void install(unsigned long threadID) {
    hhk = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, hinst, threadID);
}
extern "C" __declspec(dllexport) void uninstall() {
    UnhookWindowsHookEx(hhk);
}

BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
    hinst = hinstDLL;
    return TRUE;
}

.cpp

#include <Windows.h>
#include <stdio.h>
#include <tchar.h>

unsigned long GetTargetThreadIdFromWindow(const char* className, const char* windowName)
{
    HWND targetWnd;
    HANDLE hProcess;
    unsigned long processID = 0;

    targetWnd = FindWindow(className, windowName);
    return GetWindowThreadProcessId(targetWnd, &processID);
}

int main() {
    unsigned long threadID = GetTargetThreadIdFromWindow("Notepad", "1.txt - Notepad"); // Use Notepad for test
    printf("TID: %i", threadID);

    HINSTANCE hinst = LoadLibrary(_T("Mydll.dll"));

    if (hinst) {
        typedef void (*Install)(unsigned long);
        typedef void (*Uninstall)();

        Install install = (Install)GetProcAddress(hinst, "install");
        Uninstall uninstall = (Uninstall)GetProcAddress(hinst, "uninstall");

        install(threadID);

        MSG msg = {};

        while (GetMessage(&msg, NULL, 0, 0)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        uninstall();
    }

    return 0;
}

I use notepad as a test object and it works fine. This is c ++ code, you can convert to C # code according to your needs.

Strive Sun
  • 5,988
  • 1
  • 9
  • 26