C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 142 を表示中)
■83044 / )  Re[3]: C#で他アプリにALT+"Fキー"などの押した状態を送信
□投稿者/ 魔界の仮面弁士 (1151回)-(2017/03/01(Wed) 01:18:52)
No83037 (ぼっさっさ さん) に返信
> IntPtr hwnd = GetDesktopWindow();
> hwnd = FindWindowEx(hwnd, IntPtr.Zero, "notepad", null);
> hwnd = FindWindowEx(hwnd, IntPtr.Zero, "edit", null);

Alt + F の送出なら、edit まで辿らなくても
notepad に直接送り付ければ十分かも。


> PostMessage(hWnd, WM_SYSKEYDOWN, Keys.Menu, 0x20380001);
> PostMessage(hWnd, WM_SYSKEYDOWN, Keys.F, 0x20210001);

hWnd ではなく
hwnd だったのでは?


> ちなみにLPARAMの値は、何を表していますでしょうか。
> どこで調べるとよいでしょうか。
LPARAM の値はメッセージによって異なります。
WM_SYSKEYDOWN の場合はこちらをご覧ください。
https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms646286.aspx


今回の場合は 32bitの整数で、各ビットに以下の意味があります。

 16bit (0~15bit目) キーリピート数(今回は 0x1)
 8bit (16~23bit目) スキャンコード
 1bit (24bit目) 拡張キーが押されたかどうか(今回は 0)
 4bit (25~28bit目) 未使用(0 固定)
 1bit (29bit目) コンテキストコード
 1bit (30bit目) 直前にキーが押されていたか(今回は 0)
 1bit (31bit目) 変換状態(0 固定)


キーリピートは、キーを押し続けたときにカウントアップされる値です。

スキャンコードはキーに割り当てられた番号です。たとえばこんな値。
  Esc キーなら 0x01
  A キーなら 0x1E
  S キーなら 0x1F
  D キーなら 0x20
  F キーなら 0x21
  G キーなら 0x22
  Alt キーなら 0x38

拡張キーは、たとえば日本語109キーボードの場合、
左 Alt の時は 0、右 Alt の時は 1 です。

コンテキストコードは、Alt キーが押下されているかを示します。


> PostMessage(hWnd, WM_SYSKEYDOWN, Keys.Menu, 0x20380001);
> PostMessage(hWnd, WM_SYSKEYDOWN, Keys.F, 0x20210001);
この場合、両者の LParam はスキャンコード(16~23bit目)のみが異なっており、
前者は 0x38、後者は 0x21 が指定されているというわけです。



> メモ帳を操作するために

あえて API を使わず、マネージコードのみで操作してみました。

private void button1_Click(object sender, EventArgs e)
{
  foreach (var p in Process.GetProcessesByName("notepad"))
  {
    var title = p.MainWindowTitle;
    var desktop = this.CreateAccessibilityInstance().Parent.Parent;
    var window = desktop.Navigate(AccessibleNavigation.FirstChild);
    while (window != null)
    {
      if (window.Role == AccessibleRole.Window && window.Name == title)
      {
        window.Select(AccessibleSelection.TakeFocus);

        var notepadItem = window.Navigate(AccessibleNavigation.FirstChild);
        while ((notepadItem = notepadItem.Navigate(AccessibleNavigation.Next)) != null)
        {
          if (notepadItem.Role == AccessibleRole.MenuBar)
          {
            var menu = notepadItem.Navigate(AccessibleNavigation.FirstChild);
            while (menu != null)
            {
              if (menu.Name == "ファイル(F)")
              {
                menu.DoDefaultAction();
                return;
              }
              menu = menu.Navigate(AccessibleNavigation.Next);
            }
          }
        }
      }
      window = window.Navigate(AccessibleNavigation.Next);
    }
  }
}

返信 編集キー/


管理者用

- Child Tree -