C#+WinAPI отправка сообщений в окно

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by FlyBird, 15 Apr 2010.

  1. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    У меня возникла проблема.
    Не получается отправить в окно сообщение о нажатой кнопке F1
    Капаюсь уже в таблицах ассема, в лекциях с инста, но разве в них что-то найдешь после 2-х лет перекладывания с места на место.
    /
    Code:
    //**********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 кода, но вот хоть убейте, не могу вспомнить второй и как его отправить.

    Может кто чем поможет?
     
  2. Feonor

    Feonor Elder - Старейшина

    Joined:
    23 Jul 2008
    Messages:
    128
    Likes Received:
    52
    Reputations:
    19
    какая буква пишется?)
     
  3. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    На Delphi
    SendKey(FindWindow(),'F');
     
  4. BrainDeaD

    BrainDeaD Elder - Старейшина

    Joined:
    9 Jun 2005
    Messages:
    780
    Likes Received:
    293
    Reputations:
    214
    Key.F1 слать пробовал?
     
  5. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Мне же не только F1 отправить нужно. Но и F2, F3, F4 и т.д.
    Вообще системные клавиши.
     
  6. flacs

    flacs Member

    Joined:
    28 Jan 2009
    Messages:
    81
    Likes Received:
    31
    Reputations:
    6
    коды виртуальных клавиш
    F1 - F12 (112 - 123), соотвественно

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

     
  7. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0

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

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

    St0nX Elder - Старейшина

    Joined:
    19 May 2007
    Messages:
    257
    Likes Received:
    46
    Reputations:
    0
    Вообщем проблема может быть еще в том что ты не в то окно шлеш. Попробуй дочернии поперебирать.
     
  9. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Окно то. Сообщение о закрытии окна получает то окно, которое я хочу закрыть.
    Что качается блокнота. Если я хочу написать символ, то он его пишет. Коды верно воспринимает, а вот системные кнопки нет
     
  10. St0nX

    St0nX Elder - Старейшина

    Joined:
    19 May 2007
    Messages:
    257
    Likes Received:
    46
    Reputations:
    0
    http://www.edgeofnowhere.cc/viewtopic.php?t=396398
     
    3 people like this.
  11. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Похоже на то, что мне нужно. Спасибо, буду дальше махиначить
     
  12. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    И все же это чуточку не то.
    У него такого же рода проблема. Список констант, которые вроде пашут, а вроде и нет.
     
  13. ViLKaa

    ViLKaa Member

    Joined:
    24 Jul 2009
    Messages:
    41
    Likes Received:
    7
    Reputations:
    5
    Эм...
    SendKeys.Send("{F1}");

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

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Что-то тогда не ясно, как отправить это окну, которое в фокусе.
     
  15. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Решение найдено.
    Вилка прав(а)
    http://msdn.microsoft.com/en-us/library/ms171548.aspx
     
  16. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Что-то замучала эта задачка.
    Когда идет посылка SendKeys.Send("{F1}"); приходится ждать ответа.
    А я хочу слать кажду секунду сообщение о нажатой кнопке .
     
  17. W!z@rD

    [email protected] Борец за русский язык

    Joined:
    12 Feb 2006
    Messages:
    973
    Likes Received:
    290
    Reputations:
    43
    DDoS какой-то.

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

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

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Неее... можно выставить, что типо окно в фокусе и слать ему сообщения, хотя ты его сам активным не делаешь.
     
  19. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    FlyBird, если не охота ждать то посылай сообщения через PostMessage, так сообщения ставятся в очередь и ты сразу получишь управления после вызова функции, при использовании SendMessage сообщения отправляются на прямую, и тебе придется ждать...
    Раз ты проверял все на блокноте то небольшой пример, правда на Delphi
    Code:
     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;
    
     
    1 person likes this.
  20. FlyBird

    FlyBird Elder - Старейшина

    Joined:
    14 Oct 2007
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Спасибо большое за ответ.
    За пару дней до вашего я все же достиг того, что нужно. Помогли на одном форуме. Я что-то совсем про ПОСТ забыл.
    Даже был вариант самому себе посылать подтверждение, но потом напомнили про ПОСТ. WipAPI только в инсте проходил и ни шагу дальше.
    Пример кода.


    Code:
    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.
     
Loading...