Cで、ファンクションキーを含む、キーボードのオン・
オフした際の、仮想キーコード、及び、スキャンコード
を拾いたいんです。

画面で何を押したか確認できるような簡単なAPを業務の
必要にせまられて作りたいのですが、サンプルコード
とかどこかに落ちていないでしょうか。

仕様
例えば、vf3, vf4, vf5の各キ-を押したとき、以下の
スキャンコ-ドと仮想キ-コ-ドを発生する。

vf3 : 0x45+E0, VK_NUMLOCK
vf4 : 0x46, VK_OEM_SCROLL
vf5 : 0x29, VK_DBE_SBCSCHAR/VK_DBE_DBCSCHAR

雑誌の付録にあったよ、とか以前こんなの作ったこと
あるよ、とかどんな小さな情報でも結構です。
ご存知の方がいましたらなにとぞよろしくお願いします。
m(__)m m(__)m m(__)m

このQ&Aに関連する最新のQ&A

A 回答 (1件)

仮想keyCodeはGetAsyncKeyState()APIを使えば取得可能です。


ScanCodeはMapVirtualKey()APIで出来そうですね。

ただ質問を見るとシステム全体のキーボード入力をトラップしたい様に見受けられます。
フック自体はSetWindowsHookEx()APIで出来ますが、システム全体にフックを掛ける場合、DLLでの実装が必要です。
確かなぜDLLでなければならないかの解説もwebにあったとおもったのですが・・・失念しました(^^;

で、サンプルソースですが、webに結構転がってます。キーボードカスタマイズ系アプリケーションでソース公開されているものは大体同様の手法を取っているのでそれを探してくればOKではないかとおもいます。

とりあえずぱっと思い出した所で私が普段使ってるKeymacsというユーティリティのsrcが公開されているようです。確かこれもシステムフックを使っていたはずなので、これを参考にしてみるのはいかがでしょうか?

参考URL:http://michiko.shiratori.riec.tohoku.ac.jp/~jir/ …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!!
半ばあきらめていたのですが、ありがたい情報を
いただきました。
連休明けにさっそく挑んでみたいと思います。
感謝いたします。

お礼日時:2001/09/23 22:49

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QSendMessage(hW,WM_CREATE,0,0);を

SendMessage(hW,WM_CREATE,0,0);
を実行するとシステムがWM_DOWNやWM_CHARを発行しなくなるみたいです
というのはそれ以降キー入力を無視するようになるのです
いったんアプリをアイコン化してウィンドウ化するとWM_DOWNやWM_CHARを発行するようになります
WM_CREATEを送ってもWM_DOWNやWM_CHARを発行しなくなるのを阻止するために何か方法はないでしょうか?

Aベストアンサー

>プログラムのイニシャライズのために送ったのですが送らないで住むプログラムに変更しました

普通はそんな方法はとりません。
システムが何をするか分からないからです。

自分でメッセージを定義して、初期化処理を行うようするためのメッセージを送るほうが無難です。
WM_CREATEと同じ処理を初期化処理として行わせたいのであれば、初期化処理を関数化して自分で定義したメッセージでも呼び出せばいいのですし。


>作ったプッシュボタンを押してシステムがWM_COMMANDを送ってきた後キー関係のメッセージを送ってくれなくなります

プッシュボタンがキーボードフォーカスを持ってのるでは?

ボタンがキーボードフォーカスを持っていてもキー関連のメッセージを親ウィンドウが受け取りたいのであれば、サブクラス化をするしかないでしょう。

Q0x8, スペース, 0x8をプログラムで組むと

『scanfを使わずに_getch()でキーボードからファイル名を入力していき、入力した文字をprintfで表示する流れについて質問です。
表示された文字をバックスペースで消していっても打ち込んだ文字は消えないですよね?
間違ったファイル名を入力してしまった際に文字が残っているので、正しく入力し直しても間違ったファイル名となってします。
一度打った文字を消す方法はありますでしょうか?


以前このような質問をさせていただき、_getch()で得た文字のキーボード上での削除の仕方は分かりました。
今度はそのやり方をプログラムで作るとしたら、どう組んでいけば良いのか教えて頂けないでしょうか。
できればそのプログラムを教えて頂けたら嬉しいです。

今現在書いてるプログラムのgetchを使っている部分です。
ファイルがオープンできたら別の処理に移行しますが、その関数は長くなるので省略しています。

#include <stdio.h>
#include <conio.h>

int main() {

int key;
int i;
char file_name[256] = { 0 };
FILE *fp;
errno_t e;

while(1)
{
i = 0;
// エンタキーが押されるまで入力を続ける
do
{
printf("%c", key);
file_name[i] = key;
key = _getch();
i++;
} while(key != 0x0d);

printf("\n");

if(e = fopen_s(&fp, file_name, "rb") != 0) {
printf("ファイルが存在しません\n");
return 0;
}
else {
// 成功したらプログラムの処理をする関数に移行
return 1;
}
}
}

『scanfを使わずに_getch()でキーボードからファイル名を入力していき、入力した文字をprintfで表示する流れについて質問です。
表示された文字をバックスペースで消していっても打ち込んだ文字は消えないですよね?
間違ったファイル名を入力してしまった際に文字が残っているので、正しく入力し直しても間違ったファイル名となってします。
一度打った文字を消す方法はありますでしょうか?


以前このような質問をさせていただき、_getch()で得た文字のキーボード上での削除の仕方は分かりました。
今度はそ...続きを読む

Aベストアンサー

#include <stdio.h>
#include <conio.h>

int main() {

int key;
int i;
char file_name[256] = { 0 };
FILE *fp;
errno_t e;

while(1)
{
i = 0;
// エンタキーが押されるまで入力を続ける
do
{
key = _getch();
if (key == '\b') { //このif文と次の行のif文を1行にまとめて
if (i) { //if ((key == '\b') && (i)) {にするとバグるので注意
printf("\b \b");
i--;
}
} else if (key != '\r') {
printf("%c", key);
file_name[i] = key;
i++;
}
file_name[i] = '\0';
} while(key != '\r');

printf("\n");

if(e = fopen_s(&fp, file_name, "rb") != 0) {
printf("ファイルが存在しません\n");
return 0;
}
else {
// 成功したらプログラムの処理をする関数に移行
return 1;
}
}
}

#include <stdio.h>
#include <conio.h>

int main() {

int key;
int i;
char file_name[256] = { 0 };
FILE *fp;
errno_t e;

while(1)
{
i = 0;
// エンタキーが押されるまで入力を続ける
do
{
key = _getch();
if (key == '\b') { //このif文と次の行のif文を1行にまとめて
if (i) { //if ((key == '\b') && (i)) {にするとバグるので注意
printf("\b \b");
i--;
}
} else if (key != '\r') {
printf("%c", key);
file_name[i] = key;
i++;
}
file_name[i] = '\0';
} while(key != '\r');

printf("\n");

if...続きを読む

Qc 文字列の終わりを示すコードは 0x00 それとも '?0' , '/0' ?

cの本を参考にプログラムをかじっているのですが、
本には '?0' と書いてあり、それで出力してみるとうまくいかず
いろいろインターネットで調べたのですが、
0x00 だとうまくいきました。
良くわからないのですが、なぜでしょう?

スミマセンおねがいします。

Aベストアンサー

文字列の最後には'\0'(NULL)が必要になります。
0x00で上手くいったのは、
NULLも「整数値の0」だからです。

Qint select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout)について

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識だとreadfds,writefdsが引数として与えられているとしても、
どちらかのfd_setのうち、一つでも動きがあればselect文は
抜けてしまうことになります。とすると、戻り値として
「readfds, writefds, exceptfds 中の 1 になっているビットの総数」
は常に1ということになってしまいます。しかし、総数というからには
複数同時に1になることもあるはずです。

私の認識が間違っているとは思うのですが、どう間違っているのかわかりません。
select文の動きについて詳しく教えていただけないでしょうか。
または良いページがあれば教えてください。

見当違いな質問かもしれませんがお願いします。

複数のソケットを監視する際にselectを使う場合のことですが、
selectの動作と戻り値について疑問があります。

http://www.linux.or.jp/JM/html/LDP_man-pages/man2/select.2.html
ここを参照すると、selectの戻り値は
「更新された 3 つのディスクリプタ集合に含まれているディスクリプタの数 (つまり、 readfds, writefds, exceptfds 中の 1 になっているビットの総数) を返す。」
とあります。
私の中でselectは登録してあるFDのうち、一つでも動きが...続きを読む

Aベストアンサー

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビットが一度にONになっているはずです。
一方、相手が、一切電文を送ってない状態で、selectを呼び出した場合は、何れかのビットがONになればリターンするので、そのときは、貴方が想像しているように
ビットの総数は1になる可能性が高いです。
従って、相手が電文を送る前にselectを呼び出すか、送った後にselectを呼び出すかは、その時のタイミングにより異なります。従って、ビット数の総和が常に1であるとは、考えない方が無難です。(1つのソケットしか使用しない場合は別ですが・・・)

>私の中でselectは登録してあるFDのうち、一つでも動きがあれば即座にselectを抜けるもの、という認識です。
この認識はあっています。
しかし、selectを呼び出す以前にOKになっているFDがあれば、それらは全てビットがONになります。

話しを簡単にする為に、受信のみのソケットを3つ作成したとします。
これらの3つのソケットに向けて相手が電文を送ったとします。
その状態でまだ、こちらはselectを呼び出さずにいます。しばらくしてから、selectを呼び出すと、selectは即座にリターンし、3つのビ...続きを読む

Qdc.TextOut(0 ,0 , *str) ;について

環境 WIN98 VC++6.0 MFC にて

パターンBはOKですが、パターンAだと不正な処理で落ちてしまいます。

どうしてなのかお教えください。

void CFffView::OnPaint()
{
CPaintDC dc(this);
//パターンA
CString* str ;
str = (CString*)("999");
dc.TextOut(0 ,0 , *str) ;

//パターンB
CString aaa ;
aaa = (CString)("999");
dc.TextOut(0 ,0 , aaa) ;
}

Aベストアンサー

両方ダメ。
Aのパターンで動くのは、たまたま。

CString aaa ;
aaa = "999";
dc.TextOut(0 ,0 , aaa) ;

これで十分。

あえてキャストするんだったら、
CString aaa ;
aaa = (LPCSTR)"999";
dc.TextOut(0 ,0 , aaa) ;


aaa=のところでは、ただの代入が行われているわけではありません。
オーバーロードされたオペレータが呼ばれています。


>str = (CString*)m_array.GetAt(i) ;

これは、m_arrayの要素にCString*を入れていて、初めて成り立つ式です。
値をいれているところと、m_arrayの宣言を確認してください。

str = (CString*)("999");
も、
aaa = (CString)("999");
も、リテラル文字列をつっこもうとしています。
リテラル文字列とCStringはまったく別物です。


人気Q&Aランキング

おすすめ情報