Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   C#+WinAPI отправка сообщений в окно (https://forum.antichat.xyz/showthread.php?t=196355)

FlyBird 15.04.2010 10:33

C#+WinAPI отправка сообщений в окно
 
У меня возникла проблема.
Не получается отправить в окно сообщение о нажатой кнопке F1
Капаюсь уже в таблицах ассема, в лекциях с инста, но разве в них что-то найдешь после 2-х лет перекладывания с места на место.
/
Код:


//**********WinAPI функции*********

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string _ClassName, string _WindowName);
 
        [DllImport("user32.dll", EntryPoint = "FindWindowEx")]
        private static extern IntPtr FindWindowEx(IntPtr hwndPrnt, IntPtr hwndChildAfter, string _ClassName, string _WindowName);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern int MessageBox(IntPtr hWnd, String text, String caption, uint type);

        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        public static extern int DestroyWindow(IntPtr hWnd);

//*********/WinAPI функции*********



**********WinAPI константы*********
        const int BM_SETSTATE = 243;
        const int WM_LBUTTONDOWN = 513;
        const int WM_LBUTTONUP = 514;
        const int WM_KEYDOWN = 256;
        const int WM_CHAR = 258;
        const int WM_KEYUP = 257;
        const int WM_SETFOCUS = 7;
        const int WM_SYSCOMMAND = 274;
        const int SC_MINIMIZE = 32;
        const int WM_CLOSE = 0x0010;
//*********/WinAPI константы*********

...
...
...
private void SentMes_Click(object sender, EventArgs e)
{

            IntPtr hWnd = FindWindow(null, comboBox1.SelectedItem.ToString());
            IntPtr t1;
            if (hWnd == IntPtr.Zero)
            {
                MessageBox(new IntPtr(0), "Not found main", "Error", 0);
                return;
            }
           

            retValue = SendMessage(hWnd, WM_SETFOCUS, nul, nul);
            retValue = SendMessage(hWnd, WM_KEYDOWN, t1, nul);
            retValue = SendMessage(hWnd, WM_KEYUP, t1, nul);
}

Где-то тут зарылся косяк.
В тестируется все в блокноте. Сообщения о нажатых символах идут. Но если отправить код 112, то напишется буква. Помню, что у системных клавишь 2 кода, но вот хоть убейте, не могу вспомнить второй и как его отправить.

Может кто чем поможет?

Feonor 15.04.2010 22:34

какая буква пишется?)

flacs 15.04.2010 23:57

На Delphi
Цитата:

procedure SendShift(H: HWnd; Down: Boolean);
var vKey, ScanCode, wParam: Word;
lParam: longint;
begin
vKey:= $10;
ScanCode:= MapVirtualKey(vKey, 0);
wParam:= vKey or ScanCode shl 8;
lParam:= longint(ScanCode) shl 16 or 1;
if not(Down) then lParam:= lParam or $C0000000;
SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;

procedure SendCtrl(H: HWnd; Down: Boolean);
var vKey, ScanCode, wParam: Word;
lParam: longint;
begin
vKey:= $11;
ScanCode:= MapVirtualKey(vKey, 0);
wParam:= vKey or ScanCode shl 8;
lParam:= longint(ScanCode) shl 16 or 1;
if not(Down) then lParam:= lParam or $C0000000;
SendMessage(H, WM_KEYDOWN, vKey, lParam);
end;


procedure SendKey(H: Hwnd; Key: char);
var vKey, ScanCode, wParam: Word;
lParam, ConvKey: longint;
Shift, Ctrl: boolean;
begin
ConvKey:= OemKeyScan(ord(Key));
Shift:= (ConvKey and $00020000) <> 0;
Ctrl:= (ConvKey and $00040000) <> 0;
ScanCode:= ConvKey and $000000FF or $FF00;
vKey:= ord(Key);
wParam:= vKey;
lParam:= longint(ScanCode) shl 16 or 1;
if Shift then SendShift(H, true);
if Ctrl then SendCtrl(H, true);
SendMessage(H, WM_KEYDOWN, vKey, lParam);
SendMessage(H, WM_CHAR, vKey, lParam);
lParam:= lParam or $C0000000;
sleep(50);
SendMessage(H, WM_KEYUP, vKey, lParam);
if Shift then SendShift(H, false);
if Ctrl then SendCtrl(H, false);
end;
SendKey(FindWindow(),'F');

BrainDeaD 16.04.2010 00:19

Key.F1 слать пробовал?

FlyBird 16.04.2010 10:01

Мне же не только F1 отправить нужно. Но и F2, F3, F4 и т.д.
Вообще системные клавиши.

flacs 16.04.2010 10:29

коды виртуальных клавиш
F1 - F12 (112 - 123), соотвественно

Пример отправки F1

Цитата:

SendKey(FindWindow(),chr(112));

FlyBird 16.04.2010 14:17

Цитата:

Сообщение от flacs
коды виртуальных клавиш
F1 - F12 (112 - 123), соотвественно

Пример отправки F1


Вероятно вы просто не заметили. Одно из этих числ было указано в первом топике (112). Если послать сообщение с кодом 112 то окно поймет, что вы ему шлете код символа, который похож на "р", а не как не F1.
Попробуйте в блокном отправить код 116 (вроде как F5 должно быть). Если в блокноте появится дата и время, то это действительно F5. Но скорее всего будет символ.

У системных клавишь 2 кода. Один совпадает с символом, другой говорит ОС, что была нажата системная клавишь.

St0nX 16.04.2010 14:51

Вообщем проблема может быть еще в том что ты не в то окно шлеш. Попробуй дочернии поперебирать.

FlyBird 16.04.2010 15:07

Окно то. Сообщение о закрытии окна получает то окно, которое я хочу закрыть.
Что качается блокнота. Если я хочу написать символ, то он его пишет. Коды верно воспринимает, а вот системные кнопки нет

St0nX 16.04.2010 15:55

http://www.edgeofnowhere.cc/viewtopic.php?t=396398

FlyBird 19.04.2010 13:05

Похоже на то, что мне нужно. Спасибо, буду дальше махиначить

FlyBird 22.04.2010 11:00

И все же это чуточку не то.
У него такого же рода проблема. Список констант, которые вроде пашут, а вроде и нет.

ViLKaa 22.04.2010 12:07

Эм...
SendKeys.Send("{F1}");

или я что то не понимаю)

FlyBird 23.04.2010 18:57

Что-то тогда не ясно, как отправить это окну, которое в фокусе.

FlyBird 23.04.2010 20:27

Решение найдено.
Вилка прав(а)
http://msdn.microsoft.com/en-us/library/ms171548.aspx

FlyBird 17.05.2010 10:21

Что-то замучала эта задачка.
Когда идет посылка SendKeys.Send("{F1}"); приходится ждать ответа.
А я хочу слать кажду секунду сообщение о нажатой кнопке .

W!z@rD 17.05.2010 10:51

DDoS какой-то.

надо учитывать что SendKeys отправляет сообщение активному окну.

чтобы не ждать "ответа" нужно асинхронно посылать сообщения.

FlyBird 17.05.2010 10:52

Неее... можно выставить, что типо окно в фокусе и слать ему сообщения, хотя ты его сам активным не делаешь.

alexey-m 17.05.2010 15:48

Цитата:

Сообщение от FlyBird
Что-то замучала эта задачка.
Когда идет посылка SendKeys.Send("{F1}"); приходится ждать ответа.
А я хочу слать кажду секунду сообщение о нажатой кнопке .

FlyBird, если не охота ждать то посылай сообщения через PostMessage, так сообщения ставятся в очередь и ты сразу получишь управления после вызова функции, при использовании SendMessage сообщения отправляются на прямую, и тебе придется ждать...
Раз ты проверял все на блокноте то небольшой пример, правда на Delphi
Код:

procedure TFormMain.Button1Click(Sender: TObject);
var
  hWnd,hChild: THandle;
begin
// Ещем окно с классом 'Notepad'
  hWnd:= FindWindowA('Notepad',nil);
  if hWnd<>0 then begin
    hChild:= FindWindowExA(hWnd,0,'Edit',nil);      // Ищем текстовое поле
    if hChild<>0 then begin
      SendMessage(hChild, WM_CHAR, Word('-'), 0);    // Посылаем символ "-"
      PostMessage(hChild, WM_KEYDOWN, VK_RETURN, 0); // Переводим строку
    end;
    PostMessage(hWnd, WM_KEYDOWN, VK_F5, 0); // Посылаем главному окну о нажатии клавиши F5
  end else
    ShowMessage('Notepad not found');
end;


FlyBird 20.05.2010 11:17

Цитата:

Сообщение от alexey-m
FlyBird, если не охота ждать то посылай сообщения через PostMessage, так сообщения ставятся в очередь и ты сразу получишь управления после вызова функции, при использовании SendMessage сообщения отправляются на прямую, и тебе придется ждать...
Раз ты проверял все на блокноте то небольшой пример, правда на Delphi
Код:

procedure TFormMain.Button1Click(Sender: TObject);
var
  hWnd,hChild: THandle;
begin
// Ещем окно с классом 'Notepad'
  hWnd:= FindWindowA('Notepad',nil);
  if hWnd<>0 then begin
    hChild:= FindWindowExA(hWnd,0,'Edit',nil);      // Ищем текстовое поле
    if hChild<>0 then begin
      SendMessage(hChild, WM_CHAR, Word('-'), 0);    // Посылаем символ "-"
      PostMessage(hChild, WM_KEYDOWN, VK_RETURN, 0); // Переводим строку
    end;
    PostMessage(hWnd, WM_KEYDOWN, VK_F5, 0); // Посылаем главному окну о нажатии клавиши F5
  end else
    ShowMessage('Notepad not found');
end;


Спасибо большое за ответ.
За пару дней до вашего я все же достиг того, что нужно. Помогли на одном форуме. Я что-то совсем про ПОСТ забыл.
Даже был вариант самому себе посылать подтверждение, но потом напомнили про ПОСТ. WipAPI только в инсте проходил и ни шагу дальше.
Пример кода.


Код:

if (hWnd == IntPtr.Zero)
            {
                MessageBox.Show("Процесс не найден", "FlyBird(Ошибка)");
                return;
            }
            IntPtr hEdit = FindWindowEx(hWnd, IntPtr.Zero, "Edit", "");
            if (hEdit == IntPtr.Zero)
            {
                MessageBox.Show("Not found child", "Error");
                return;
            }

            IntPtr t1 = (IntPtr)ComBoxSelectItem_1;
            IntPtr nul = IntPtr.Zero;

            //PostMessage(hWnd, WM_KEYUP, t1, nul);
            PostMessage(hWnd, WM_KEYDOWN, t1, nul);

Теперь проблема в том, как достучаться до меню сторонний программы и отправить команду на выполнения поункта меню и дальше вбить в TextBox нужные символы и нажать Button.


Время: 05:35