ctrl + v のエミュレーション

解決


ヒカル  2003-09-29 09:52:24  No: 52210  IP: [192.*.*.*]

こんにちは、ヒカルと申します。

ctrl & v のエミュレーションができずに困っています。

私のコーディング例です。

char ClipText[256] = "サンプルデータ";

OpenClipboard(NULL);
EmptyClipboard();
SetClipboardData(CF_TEXT, ClipText);

//ctrl & v のエミュレーション
keybd_event(VK_CONTROL, 0, 0, 0);
keybd_event(VK_V, 0, 0, 0);
keybd_event(VK_V, 0, KEYEVENTF_KEYUP, 0);
keybd_event(VK_CONTROL, 0, KEYEVENTF_KEYUP, 0);

CloseClipboard();

VK_Vが定義されていませんとコンパイルエラーになっています。
VK_CONTROLはコンパイル通るのに何故なのでしょうか?

また、このようなことをしたい場合、もっと良い方法はありますか?

SendInputもやってみたのですがネットで探せるサンプルが少なく
て私には手がでませんでした。

宜しくお願いします。

編集 削除
瀬戸っぷ  2003-09-29 10:54:56  No: 52211  IP: [192.*.*.*]

> VK_Vが定義されていませんとコンパイルエラーになっています。
> VK_CONTROLはコンパイル通るのに何故なのでしょうか?

エラーメッセージのとおり、定義されていないからです。
VK_CONTROLでヘッダファイルをGrepすると、WINUSER.Hが見つかると思います。
(WINUSER.RHもありますが)

該当ファイルを開いて見ていくと、
/* VK_0 thru VK_9 are the same as ASCII '0' thru '9' (0x30 - 0x39) */
/* VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
と書かれています。
MSDNのVirtual-Key Codesのページには16進数での指定方法が書かれていますが。

> また、このようなことをしたい場合、もっと良い方法はありますか?

クリップボード系の操作を組んだコトがないので、
こちらに関しては不明です。

編集 削除
ヒカル  2003-09-29 11:13:40  No: 52212  IP: [192.*.*.*]

瀬戸っぷ

>エラーメッセージのとおり、定義されていないからです。

CONTROLが定義されていたのでこのあたりも定義済みかと思ってしまって
いました。

keybd_event('V', 0, 0, 0);
keybd_event('V', 0, KEYEVENTF_KEYUP, 0);

これでも良いのでしょうか?

>MSDNのVirtual-Key Codesのページには16進数での指定方法が書かれていますが。

でした、書かれていました。
ありがとうございます。

編集 削除
瀬戸っぷ  2003-09-29 11:53:38  No: 52213  IP: [192.*.*.*]

> keybd_event('V', 0, 0, 0);
> keybd_event('V', 0, KEYEVENTF_KEYUP, 0);
> これでも良いのでしょうか?

仮想キーコードとしてはOKなハズです。
期待通りの動作をするかは…なんとも言えませんが。
keybd_event()も使ったコトないですし、クリップボード操作系も……
そのヘンは他の方からのレスがないコトには…

WM_PASTEなんてのもあるようですが…
CBS_DROPDOWNLISTスタイルのコンボボックスにしか使えないらしい……

編集 削除
ヒカル  2003-09-29 13:36:22  No: 52214  IP: [192.*.*.*]

瀬戸っぷ さん

>仮想キーコードとしてはOKなハズです。

ありがとうございますm(__)m

>keybd_event()も使ったコトないですし、クリップボード操作系も……
>そのヘンは他の方からのレスがないコトには…

実際には、リストボックスのアイテムを取得しクリップボードへ
貼り付けてペーストするような手順になっています。

私のほうも解決しましたらご報告させて頂きます。

編集 削除
ヒカル  2003-10-01 08:57:15  No: 52215  IP: [192.*.*.*]

こんにちは、ヒカルです。

SendInputを使ってみました。

もっと汎用的にこれを関数化してみたいのですが、
VBのRedim PreserveみたいにINPUT構造体の配列を
引き伸ばしてあげたいのですが、newとかmallocとか
調べているのですがちょっと難しくてです。

関数化なので構造体をグローバルな変数で
使わないと、呼び出しでローカルな構造体を
渡して、またこれを戻り値で呼び出し元に
返してあげないとダメですので、このあたりの
処理にまだ自信がありません。

このあたりも含めましてアドバイスお願いします。

INPUT KeyInputs[4];
int KeyInputCount = 0;

void KeybdInput(Byte VKey, Bool Flags){

  KeyInputCount++;

  KeyInputs[KeyInputCount - 1].Itype = INPUT_KEYBOARD;
  KeyInputs[KeyInputCount - 1].ki.wVk = VKey;
  KeyInputs[KeyInputCount - 1].ki.wScan = MapVirtualKey(wVk, 0);
  if (Flags) {
    KeyInputs[KeyInputCount - 1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY || KEYEVENTF_KEYUP;

  }else{
    KeyInputs[KeyInputCount - 1].ki.dwFlags = KEYEVENTF_EXTENDEDKEY || 0;
  }
  KeyInputs[KeyInputCount - 1].ki.time = 0;
  KeyInputs[KeyInputCount - 1].ki.dwExtraInfo = 0;

}

//呼び出し
KeybdInput(VK_SHIFT, 0);
KeybdInput('V', 0);
KeybdInput('V', true);
KeybdInput(VK_SHIFT, true);

SendInput(KeyInputCount, KeyInputs, sizeof(INPUT);

編集 削除
fuku  2003-10-01 14:28:46  No: 52216  IP: [192.*.*.*]

>INPUT構造体の配列を引き伸ばしてあげたいのですが
あとから配列を引き伸ばす事を前提とするより、
最初から必要と思われる十分な量を確保する方がいいです。

newを使ってメモリを確保する場合、この場合なら私は次のようにします。

INPUT *KeyInputs=NULL;//作成したメモリ領域へのポインタを受け取るポインタ変数
try{//例外ブロック
   KeyInputs=new INPUT[4];//メモリ確保
}
catch(...){
   return;//失敗時の処理
}
...//確保したメモリを使う処理
delete[] KeyInputs;//メモリの開放

>関数化なので構造体をグローバルな変数で
>使わないと、呼び出しでローカルな構造体を
>渡して、またこれを戻り値で呼び出し元に
>返してあげないとダメですので
ポインタやクラス経由で受け取れば戻り値に返す必要はないです。
この関数をクラスメンバにすれば、変数をグローバルに出す必要もありませんし、
必要ならKeyInputsの再確保を適切なタイミングで実行することもできます。
KeyInputsの再確保をするような関数とともにクラス化してはいかがですか?
その場合上記の
INPUT *KeyInputsはクラスメンバとして宣言し、
newはコンストラクタ、
deleteはデストラクタで行います。

>void KeybdInput(Byte VKey, Bool Flags){
下の呼び出し方から考えると、Bool型はbool型ですよね?

編集 削除
ヒカル  2003-10-01 15:50:21  No: 52217  IP: [192.*.*.*]

fuku さん

>あとから配列を引き伸ばす事を前提とするより、
>最初から必要と思われる十分な量を確保する方がいいです。

呼び出し元で確保してしまえば良い訳ですね。
要素が分らないのを前提にしていましたが、
でも、そんなことなかったですね、
この時点では要素がいくつかは分っている訳ですから。

>ポインタやクラス経由で受け取れば戻り値に返す必要はないです。

ローカルでもポインタを渡してそこへ書き込ませてあげれば
良かったのですね。

発送の転換ができず泥沼にはまり込んでいました。

>KeyInputsの再確保をするような関数とともにクラス化してはいかがですか?

C++は経験が無くてです、そのようにクラス化できれば良いですが。
C++はどうも敷居が高くてなかなか勉強をはじめられずにいます。

下の呼び出し方から考えると、Bool型はbool型ですよね?

そうです、bool型です失礼しました。

一応、これで悩み解決ということで頑張りたいと思います。

ありがとうございますがm(__)m

編集 削除