アプリ版:「スタンプのみでお礼する」機能のリリースについて

Visual Studio 2015を使用しています。
OSはWindows10です。
SendInputを使用してプログラムを作ろうとしているのですが、うまくいかず、
サイトhttp://pgcenter.web.fc2.com/contents/csharp_send …
のサンプルを基に(そのままに近いですが)動作を確認しながら作っていこうとしています。
Any CPUではなく86でコンパイルし、エディタソフト起動(このソフトに「A」を出力)、アプリを起動して、ボタンをクリックしてもエディタには何も出力されません。
どこか間違っていますか?
(Form1.csは字数の関係で補足に記述します)

質問者からの補足コメント

  • どう思う?

    using System.Runtime.InteropServices;他のusingは省略
    namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
    {
    //
    [StructLayout(LayoutKind.Sequential)]
    private struct KEYBDINPUT
    {
    public short wVk;
    public short wScan;
    public int dwFlags;
    public int time;
    public int dwExtraInfo;
    };

      補足日時:2017/03/06 15:57
  • どう思う?

    // 各種イベント(SendInputの引数データ)
    [StructLayout(LayoutKind.Explicit)]
    private struct INPUT
    {
    [FieldOffset(0)]
    public int type;
    [FieldOffset(4)]
    public MOUSEINPUT mi;
    [FieldOffset(4)]
    public KEYBDINPUT ki;
    [FieldOffset(4)]
    public HARDWAREINPUT hi;
    };

      補足日時:2017/03/06 15:58
  • どう思う?

    // キー操作、マウス操作をシミュレート(擬似的に操作する)
    [DllImport("user32.dll")]
    private extern static void SendInput(
    int nInputs, ref INPUT pInputs, int cbsize);

    // 仮想キーコードをスキャンコードに変換
    [DllImport("user32.dll", EntryPoint = "MapVirtualKeyA")]
    private extern static int MapVirtualKey(
    int wCode, int wMapType);

      補足日時:2017/03/06 15:59
  • どう思う?

    private const int KEYEVENTF_KEYDOWN = 0x0; // キーを押す
    private const int KEYEVENTF_KEYUP = 0x2; // キーを離す
    private const int KEYEVENTF_EXTENDEDKEY = 0x1; // 拡張コード
    private const int VK_SHIFT = 0x10; // SHIFTキー



    public Form1()
    {
    InitializeComponent();
    }

      補足日時:2017/03/06 16:00
  • どう思う?

    private void button1_Click(object sender, EventArgs e)
    {
    // 自ウインドウを非表示(キーボード操作対象のウィンドウへフォーカスを移動するため)
    this.Visible = false;

    // キーボード操作実行用のデータ
    const int num = 4;
    INPUT[] inp = new INPUT[num];

    // (1)キーボード(SHIFT)を押す
    inp[0].type = INPUT_KEYBOARD;
    inp[0].ki.wVk = VK_SHIFT;

      補足日時:2017/03/06 16:01
  • どう思う?

    inp[0].ki.wScan = (short)MapVirtualKey(inp[0].ki.wVk, 0);
    inp[0].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYDOWN;
    inp[0].ki.dwExtraInfo = 0;
    inp[0].ki.time = 0;

    // (2)キーボード(A)を押す
    inp[1].type = INPUT_KEYBOARD;
    inp[1].ki.wVk = (short)Keys.A;

      補足日時:2017/03/06 16:02
  • どう思う?

    inp[1].ki.wScan = (short)MapVirtualKey(inp[1].ki.wVk, 0);
    inp[1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYDOWN;
    inp[1].ki.dwExtraInfo = 0;
    inp[1].ki.time = 0;

    // (3)キーボード(A)を離す
    inp[2].type = INPUT_KEYBOARD;
    inp[2].ki.wVk = (short)Keys.A;

      補足日時:2017/03/06 16:03
  • どう思う?

    inp[2].ki.wScan = (short)MapVirtualKey(inp[2].ki.wVk, 0);
    inp[2].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
    inp[2].ki.dwExtraInfo = 0;
    inp[2].ki.time = 0;

    // (4)キーボード(SHIFT)を離す
    inp[3].type = INPUT_KEYBOARD;
    inp[3].ki.wVk = VK_SHIFT;

      補足日時:2017/03/06 16:03
  • どう思う?

    inp[3].ki.wScan = (short)MapVirtualKey(inp[3].ki.wVk, 0);
    inp[3].ki.dwFlags = KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP;
    inp[3].ki.dwExtraInfo = 0;
    inp[3].ki.time = 0;

    // キーボード操作実行
    SendInput(num, ref inp[0], Marshal.SizeOf(inp[0]));

    // 1000ミリ秒スリープ
    System.Threading.Thread.Sleep(1000);

      補足日時:2017/03/06 16:05
  • どう思う?

    // 自ウインドウを表示
    this.Visible = true;

    }
    }
    }

      補足日時:2017/03/06 16:06

A 回答 (4件)

実行して試していないのでアレですが……。


ボタン押した後、自フォームが約1秒ほど消える筈ですが消えていますか?
# イベントハンドラ内でthis.Visibleプロパティを操作してちゃんと反応するのかは不明ですが……。

ちと、実験するには時間がないのでもろもろもろもろ未確認です。
    • good
    • 0
この回答へのお礼

ありがとうございます。
>ボタン押した後、自フォームが約1秒ほど消える筈ですが消えていますか?

はい、フォームは1秒ほど消えてその後現れます。

お礼日時:2017/03/06 18:43

Windows10 64Bit


VS2015 community
で、掲示されたページのものをコピペ。
プロジェクトをWindowsフォームアプリケーションで作成したので
正確にはちょっと違いますが。

using System.Runtime.InteropServices;
をコピぺ。
// マウスイベント(mouse_eventの引数と同様のデータ)
から
private const int VK_SHIFT = 0x10; // SHIFTキー
までをコンストラクタの上にコピペ。
フォームにボタンコントロールを配置してClickイベントのハンドラを追加。
ハンドラ内にButton1_Click()の中身をコピペ。

AnyCPUのままビルドして実行。

秀丸を起動。
そのまま今回のフォームをクリックしてアクティブ状態を切り替え。
で、ボタン押下で秀丸に"A"が追加されました。
    • good
    • 0
この回答へのお礼

>プロジェクトをWindowsフォームアプリケーションで作成したので
>正確にはちょっと違いますが。

私もWindowsフォームアプリケーションで作成しました。
ここと同じ手順で実行(debug、release両方で、 開始ボタンで実行)しましたが、秀丸には何も表示されません。
AnyCPUでビルドしています。

フォームのボタンを押すとエディタ(秀丸)が一瞬色が濃くなり、アクティブになっているようです。

お礼日時:2017/03/07 10:17

>エディタソフト起動(このソフトに「A」を出力)、アプリを起動して、ボタンをクリック



この順番だったとしたらエディタには入力されないかと。
1)エディタ起動(入力先ががエディタに切り替わる)
2)VS2015をアクティブに切り替え(入力先がVS2015に切り替わる)
3)F5キーかメニュー操作かコマンドボタンでアプリを起動(入力先がアプリに切り替わる)
4)ボタンをクリック(this.Visible = falseにより、アプリのフォームが一時的に消えてアプリの前にアクティブだったVS2015に入力先が切り替わる)
5)SendInput()によりキーボード入力を実施(VS2015の入力フォーカスによるのでどこに入るかは不明 3)の時の状態次第)
6)this.Visible = trueによりフォームを再表示。ボタンクリックの状態なので入力フォーカスはボタンに設定。

アプリの起動がエクスプローラのexeファイルのダブルクリックだった場合はエクスプローラに入力が送られます。
exeファイルのあるフォルダにaから始まるフォルダ/ファイルがなければエクスプローラは無視するだけでしょう。
# a.txtとかあれば選択状態がexeからa.txtに切り替わると思われます。


SendInputだと共有リソースであるマウスやキーボードの操作をエミュレーションしますので状態によっては期待動作しない可能性があることには気を付けた方がいいでしょう。
# UACやファイル削除確認のダイアログにも送れるんですかねぇ?
    • good
    • 0
この回答へのお礼

ありがとうございます。
新しくプロジェクトを作り直し、No.2に書かれていた通りにしたところ「A」の文字が秀丸に入力されました。
たぶん、キーボードの部分しか使わないので、それ以外のコードを消してしまったことが原因のようです。
重要な部分が解決できたので大いに助かりました。

お礼日時:2017/03/08 10:32

>ここと同じ手順で実行(debug、release両方で、 開始ボタンで実行)しましたが、秀丸には何も表示されません。



「開始ボタンで実行」した後、エディタをアクティブ→アプリをアクティブ→ボタン押下…
ですよね?

>フォームのボタンを押すとエディタ(秀丸)が一瞬色が濃くなり、アクティブになっているようです。

私の方で動作確認した時は、「フォームが消えている間」は秀丸がアクティブでしたね。
VS2015で妙なところにブレークポイント貼っていたりした場合はその限りではないでしょうが…。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!