0
[DllImport("User32.dll")]
public static extern void SendMessage(IntPtr hWnd, int uMsg, int wParam);
public static void Pac()
{
    System.Threading.Thread.Sleep(2000);
    var dHWnd = FindWindow(null, "Открыть");
    SendMessage(dHWnd, 0x0102, 0x41);
}

Пробовал так - не работает. Хотя HWnd ненулевой возвращает.

Mart
  • 397
  • 1
    Если вы хотите заполнить EDIT - то будет проще сделать GetWindowText и SetWindowText. Но... всеравно нужно правильно HANDLE указать. Скачайте старенькую утилиту Spy.exe которая играется окнами, и поиграйте ею с окнами. – nick_n_a Jan 23 '19 at 08:36

1 Answers1

2

WinApi/винапи отправка нажатий на клавиатуру.

В случае с Foreground окном достаточно и IntPtr самого окна.

Но в случае Background окна этого недостаточно. Нужно искать IntPtr поля окна, а не самого окна. А потом уже в него делать SendMessage();

Соответственно это и есть причиной неудачи.

using Keyboard;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestApp
{
    class Program
    {
        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, String lpWindowName);

        [DllImport("User32.dll")]
        public static extern int SendMessage(IntPtr hWnd, uint uMsg, int wParam, string lParam);

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);


        const int WM_SETTEXT = 0X000C;

        static void Main(string[] args)
        {
            Process.Start("notepad.exe");

            Thread.Sleep(5000);//на время этого ожидания сделай другое окно активным

            var dialogHWnd = FindWindow(null, "Untitled - Notepad");

            IntPtr notepadTextbox = FindWindowEx(dialogHWnd, IntPtr.Zero, "Edit", null);

            SendMessage(notepadTextbox, WM_SETTEXT, 0, "This is the new Text!!! прапрао");

            Thread.Sleep(1000);
        }


    }
}
  • Да. IntPtr поля ввода окна (т.е. самого Edit). – nick_n_a Jan 23 '19 at 08:37
  • PostMessage - асинхронно отправлять, с СендМесаг может и не получиться, иногда сообщения не доходят. Самое забавное, что если отправлять в режиме открытого дебагера, то и СендМесаг работает без сбоев. А в живом коде, не успевает отправить, судя по всему. – NewView Jan 23 '19 at 17:21
  • И ещё, если приложение свернуть в трей, ничего не выйдет, надо его сперва развернуть. – NewView Jan 23 '19 at 17:29
  • @NewView а чем технически отличается minimized от сворачивания в трей? Я как-то думал что сворачивание в трей это minimized + hide с панели + создание иконки в трее. – Andrew Stop_RU_war_in_UA Jan 23 '19 at 17:33
  • Там кажется обрезается очередь принимаемых сообщений, зависит от автора, в общем, при сворачивании проверяет например WM_PAINT или нет. Но как правило - нет. – NewView Jan 23 '19 at 17:35
  • полезные замечания автору, а мне просто интересные :) Спасибо – Andrew Stop_RU_war_in_UA Jan 23 '19 at 17:38
  • 1
    Вот примерчик как с этим бороться https://github.com/ClnViewer/GameDev/blob/5f7278d8f984b66b43408dc20d53354d2416b3e1/Wnd.cpp#L56 :) – NewView Jan 23 '19 at 17:44
  • @Andrew а как в игру передать нажатие клавиш ? – Андрей Reyz Dec 21 '19 at 00:32
  • @АндрейReyz Ищется по "c# global keypress event". Например: https://www.codeproject.com/Articles/7294/Processing-Global-Mouse-and-Keyboard-Hooks-in-C Но в даном случае игра будет активной на экране и будут просто имитироваться нажатия клавиш на клавиатуре – Andrew Stop_RU_war_in_UA Dec 21 '19 at 05:35
  • @Andrew можно как то без активного окна передавать значение игру ? – Андрей Reyz Dec 21 '19 at 09:13
  • Пробуй смотреть в сторону SendMessage. Как раз в этом ответе. – Andrew Stop_RU_war_in_UA Dec 21 '19 at 10:32