• ベストアンサー

GetKeyStateの戻り値

GetKeyStateという関数はキーが押されると負の値をとるようですが、具体的にはどんな値をとっているのでしょうか?ダブルクリックとかでも値が違ってくるような気がするのですが。また、押さない場合は0だけでなく1の値もとるのでしょうか?詳しい方よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

たぶん、最上位ビットと最下位ビット以外は正式には使えないかと(システムによって違うかも)。。 例えば、GetKeyState('A')としたとき、 押してない・・・0001 Aを押す・・・・ff80 Aを離す・・・・0000 Aを押す・・・・ff81 Aを離す・・・・0001 の繰り返しになると思います。最上位ビットが押されていることをあらわします。最下位ビットは押して離すたびに0と1が入れ替わります。(トグルするといいます) >0x8000は10進数にすると8×10^3=32768ということでいいでしょうか? 16進数なので8×16^3=32768ですね。答えはあってます。

Rossana
質問者

お礼

回答ありがとうございます。 GetKeyStateの戻り値はどうやら1回押すと-127で離すと0に戻り2回目(連打でかなぁ?)押すと-128そして離すと1に戻っているような気がするんですが、これとJaritenCatさんの言われる数字ff80などが関係しているのでしょうか?でもff80と-127は同じなんでしょうか?? >最下位ビットは押して離すたびに0と1が入れ替わりま>す。(トグルするといいます) ということはこれが1回目押すと0で2回目押すと1で3回目押すと0というようになっている原因でしょうか。

その他の回答 (7)

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.8

16進の補数は、0x1 -> 0xE, 0x2 -> 0xD, ...と個別に見るしかないと思います。 Cでは、補数を取る演算子がありますので、それを使えばいいと思います。 手計算したいなら、0x8000 のビットを見て負数なら、残りのビットの補数を取り、1を加えて、-1 を掛けて負数にするということになるでしょう。 一般的に n 進法の値は、1桁目の数+2桁目の数×n + 3桁目の数×n の2乗+... で求まるでしょう。 ビット列は、2進法だし、8進法も使われます。 16進法は勿論16進だし、時間の分秒は60進だし、ヤードポンド法には12進がありますので、10進法に捕らわれない見方が必要でしょう。 単に換算が必要なら、PCのアクセサリに電卓がありますので、それで値は求まります。(スタートメニューからプログラムを表示させれば出てくるでしょう)

Rossana
質問者

お礼

回答ありがとうございます。 >Cでは、補数を取る演算子がありますので 補数を取る演算子というのはどういったものですか? #3の方の言われる事象を確認したいのですが,GetKeyStateを入れたサンプルプログラムはどのようにするといいのでしょうか?

Rossana
質問者

補足

サンプルプログラムを作って確認した所,#3の方の回答が一番信頼できるというか実際にそうなっているっぽいことがわかりました. Aを押す・・・・0xFF80 Aを押す・・・・0xFF81 この順番が逆になることもあったのですが,この現象は気まぐれなのでしょうか?

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.7

例えば、 #include <stdio.h> #include <stdlib.h> void main(void){ short i = 0x7fff, j = 0x8000, k = 0xffff; printf{"%d %d %d\n", i, j, k); exit(0); } を実行するとそう出てくると思います。

Rossana
質問者

お礼

サンプルプログラムを具体的に教えていただきありがとうございます. 理論的に(手計算で) 16進数  short  unsigned short 0x7FFF  32767  32767 0x8000  -32768  32768 0xFFFF  -1   65535 というのはどうすれば計算できるのでしょうか??

Rossana
質問者

補足

あっなんか今気付いたのですが, 0xffffを2進数にすると 1111 1111 1111 1111だから 反転0000 0000 0000 0000して1足せば 0000 0000 0000 0001 0x0001 となって1となり-1に対応しますね.なんか自己解決しました.でも16進数の補数??でやる場合はどのようになるやればいいのでしょう??

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.6

GetKeyState() が返す値は short です。符号付き。 で、まぎわらしいので今まで 16 進で書きました。 尚、16進数の10進数表記は次の通りです。ビット列をどう解釈するかで値は異なります。 16進数  short  unsigned short 0x7FFF  32767  32767 0x8000  -32768  32768 0xFFFF  -1   65535 #5 さんが書かれた INT 21H は、アセンブル・コードです。レジスタに機能を指定する値やデータの値を入れてこれを呼ぶと、MS-DOS が備えている機能を利用できます。 windows でも使えます。 下記は int 21h ではありませんが、 beep を鳴らすCの関数です。 void myBeep(void){ __asm{ mov al,7h int 29h } }

Rossana
質問者

お礼

回答ありがとうございます.アセンブル・コ-ドというものなのですね.難しい~f(^^; 16進数  short 0x7FFF  32767 0x8000  -32768 0xFFFF  -1    となるのはどういう計算をしているのですか?ご教授お願いします.

回答No.5

GetKeyState関数ってWin32APIの話ですよね??仮想キーコードを引数に入れてコールしたらそのキーの状態が分かるだけだと思っていました。キーコードが返ってくるというのは知りませんでした。。。 MS-DOSといえば、INT21Hのシステムコールですか?なつかしい。

Rossana
質問者

お礼

回答ありがとうございます。 >GetKeyState関数ってWin32APIの話ですよね?? おっしゃられる通りです。Visual C++のAPI関数GetKeyStateについての質問です。 >MS-DOSといえば、INT21Hのシステムコールですか? みなさんよく知っておられて話についていけない現状ですf(^^;INT21Hとかシステムコールとかってなんですか?無知ですいません。

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.4

ちょっとMS-DOS時代のことでうろ憶えですが、 キーを押したときに返るコードは、キーボードのタイプで異なり、 どのキーを押したときにどの文字(ASCII)コードを返して欲しいかは、定義テーブルで(MS-DOSでのエディタでは termcapとか言ったと思います)指定出来たと思います。 Windows でも定義テーブルを持っていると思います。 従って、0x8001 のビット以外は、文字コードに対応するコードが入っているでしょう。どんなコードかはキーボードによります。 定義テーブルがどれかは知りませんが、自分の使用中のキーボードがどんなコードを返すかは、 GetKeyState() が返す値を表示するプログラムを組んでキーを押して見ればすぐ分かるでしょう。 getchar() も組み込んで見ると違いも分かるのでは。

Rossana
質問者

お礼

回答ありがとうございます。キーボードのタイプとかでも違うのですね。

Rossana
質問者

補足

>そのキーが押されていると、0x8000 が返って来ま >す。 すいません。ちょっとおかしな疑問に気付いたのですが,キーが押されると負の値(最上位ビット1)となるということは0x8000は負の値であるはずですよね。 16進数8000→10進数8×16^3=32768 と僕は答えましたが,これって正の値だしどこかおかしいですよね。補数表示とかでしょうか?でも16進数の補数とかってどうやれば…。2進数だったら1の補数はビットを反転して2の補数はそれに1を足してやればいいというのは知っているのですが。 何度もすいません。

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.2

この関数の引数に指定のキーコード(VK_...など)を渡すと、 そのキーが押されていると、0x8000 が返って来ます。 AND を取って調べれば分かります。 toggle key (CapsLockなど)は 0x0001 が返って来るようです。 キーの状態を調べるものですから、ダブルクリックってのは、趣旨が違うのでは。 私は、例えば Ctrl キーを押し下げてメニューを選ぶと GetLastError() 情報を MessageBox で出すなどに使っています。

Rossana
質問者

お礼

回答ありがとうございます。0x8000は10進数にすると8×10^3=32768ということでいいでしょうか? GetKeyState('A')とかしたとき なんか1回キーを押した時と2回目に押した時で違う値が返ってきているようなんです…。

回答No.1

負数に見えるのは、最上位ビットが押されていることをあらわすからでは?

Rossana
質問者

お礼

>負数に見えるのは、最上位ビットが押されていること>をあらわすからでは? 回答ありがとうございます。はいおっしゃられる通りです。最上位ビットは押されると1、押されていないと0というのは本とかにも書いてあるのですが、具体的な値がいくつになっているのかということが知りたいです。ご存知であれば教えて頂きたいです。

関連するQ&A

  • 関数の戻り値がこうなる理由が分かりません。

    かなり簡単なプログラムだと思いますが、関数内で出力した場合と、呼び出し側で出力した場合で値が異なります。理由が分からないので教えていただけますか? #include <stdio.h> #include <stdlib.h> Table(int num, double ltable) { double temp[] = { 0.99852, // 1 0.99410, // 2 0.98677 // 3 }; ltable=temp[num]; printf("%f\n",ltable); } main (int argc, char *argv[]) { int num ; double ltable ; num=1; Table(num, ltable); printf("%f\n",ltable); } 実行結果 0.994100 0.000000

  • UWSCの仮想キーについて

    if GETKEYSTATE(VK_F1) then 例えば GETKEYSTATEで CtrlキーとF1キーを同時に押されている時にthenとしたい場合 どう表現したら良いのでしょうか? if GETKEYSTATE(VK_F1&VK_CTRL) thenとなるのでしょうか? それとも KBD(VK_CTRL,DOWN,秒) KBD(VK_F1,CLICK,秒) KBD(VK_CTRL,UP,秒) のような表記でしか使えないのでしょうか?

  • long double型の戻り値を持つ関数について

    文字列を浮動小数点に変換したいと思っています。 StrToFloat()を用いたのですが、有効数値がケタ落ちしてしまいました。 そこで、次のように関数を定義して実行したところ、やはり戻り値の値がケタ落ちしました。 long double StrToValue(AnsiString str) { ・・・・・ return value; } 具体的にはlong doubleの有効数値がdouble型の有効数値にまで落ちてしまっています。 次にポインタを使い、次のように変更したのですが、結果は同じでした。 void StrToValue(AnsiString str, long double *value) { ・・・・・ *value=・・・; ・・・・・ } どなたか、この解決方法と、できれば理由を教えてください。 なお使用した言語は、C++Builder 5 環境はWindows 98 です。

  • 関数から戻り値を得る方法について

    知り合いの方から関数の戻り値をえるときにreturn以外に例えば File(&i,&k);←関数呼び出し int File(int **j, double *k)←関数 {      ~      ~ } とやると(double *k)は関数からの出力として、呼び出しているFile(&i,&k)の(&k)に返されると聞きました。しかも、戻り値はint File()のintに依存しないと言われて試してみたのですが、どうもうまくいきません。 正しいやり方知っている方いましたら、教えて下さい。あと複数戻り値を返したいときはどうすればいいんでしょうか?

  • 関数戻り値が連想配列の場合

    こんにちわ。 PHP5について質問です。 あるユーザ関数の戻り値が連想配列である場合、 ユーザ関数の実行~戻値の特定のキーの値を取得 までを1行で取得する方法があれば教えてください。 例) function hoge() {  return array("fuga" => "1", "moge" => "2"); } ここで"moge"の値を一発で参照したいと考えています。 通常では、 $result = hoge(); print $result["moge"]; のようにしていますが、これを一行で実現できる方法はありますでしょうか。

    • ベストアンサー
    • PHP
  • C言語 exitで終了した関数の戻り値

    引数が負の整数であればエラーを表示し終了、0以上の整数であればそのまま戻り値とする関数 int example(int a) { if( a < 0 ) { printf("Error!\n");   exit(1); } return(a); } があったとします。 ここでたとえば  int s1,s2; に対して、 s1 = example(3); とすれば、 s1 = 3 となりますが、 s2 = example(-5); とすれば、 s2 には何が代入されているのでしょうか? 例に書いた関数はしょーもないものですが、 もう少し難しい関数を使って変数に値を入れて、その値で後でfor文などを使って仕分けていくようにしたいのですが、エラー時に代入されるものがわからなくて困っています。 エラー時のみに目印となる値、たとえば -1 などを戻り値とすることはできません。 おねがいします。

  • recvfrom関数の戻り値について

    初めて質問させて頂きます。 現在、LinuxのUnixドメインを使用した内部通信プログラムを 作成しているのですが、recvfrom関数の戻り値で-512という値が 返ってきて頭を悩ませています。 いろいろなHP等でrecvfrom関数の戻り値について記述されている内容は 受信サイズか-1となっているのですが・・・-512という値については さっぱりでした。 -1の場合は、errnoが入るようなのですが、-512の場合、errnoが0のままで何もはいっていないように見えます。 どの様な問題が発生しているかの見当もつかない状態です。 すみませんが、宜しくお願い致します。

  • main関数の戻り値

    C言語のmain関数の戻り値はint型ですよね。 私もそういう決まりだと思って守ってきました。 しかし、「mainが戻り値を返すって、どこに返すの?」ということが、私は理解できていません。 私が調べたところでは、「ホスト実行環境」という言葉がこの問題に関係あるようですが、この言葉の意味はよくわからないですし、似た言葉で「ホスト環境」ということばがあるのですが意味も関係もわかりません。 これらは、OSとは違うと思うんですが、自信はありません。 それでも、ない知識を振り絞っていろいろ考えてみると、次のようなことらしいのですが、正しいでしょうか。 ・OSはプログラムの実行に先立ちホスト実行環境を作る。 ・静的記憶域のオブジェクトを初期化するのはホスト実行環境である。 ・関数が、main関数を呼ぶことは可能である。(以下では、main関数が関数から呼ばれる場合は除く。) ・main関数を呼ぶのは、ホスト実行環境が行なう。 ・main関数の中のreturnによってプログラムが終了するのと、exit関数でプログラムが終了することに違いはない。 ・main関数の戻り値は、ホスト実行環境に返される。 ・returnによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・exitによってホスト実行環境に返される値は、int型である限りなんでもよい。 ・必ずexitで値が返されるならば、main関数の中にreturnはなくてもよい。 main関数からの戻り値をどうしようと構わないんだと思うんですが、皆さんの経験の中で、実例としてこういうふうに使われる、というのは何かないのでしょうか。 (ホスト実行環境に値が返される、といっても無視するのでは意味はないと思うのです。 その値の使用例としては、 0が返ってくると「プログラムは正常終了しました。」と表示するとか、0以外の値が返されると別のプログラムが走るとか、 そういうことだと思うんですが。)

  • 配列を関数の戻り値に使う

    こんばんわ。 PHP5で配列を関数の戻り値として返す方法がわからず今回投稿させていただきました。 配列は1次元で 1,2,3 の値が a という配列に格納されています。 呼び出された関数(testメソッド)で a配列を返し、bで受けようとするのですが、bの値には NULL となっています。 返す際に return $a; としており、 $b=$obj-〉test(); で、aをbで受けようと考えております。 配列を返す場合は普通にretuneで返すだけではダメなのでしょうか。 解決方法がお分りの方がいらっしゃいましたらご教授のほうおねがいします。

    • ベストアンサー
    • PHP
  • EXCELについて:ある範囲の中に混在する正の値と負の値を各々計算したい

    MS-EXCELの関数で教えて欲しいのですが。 次のようなことが関数で出来ますか? あるセル範囲の中に正の値と負の値が混在しています。 その中から、正の値のみ、負の値のみを各々計算するような関数を作成するにはどうしたら良いでしょうか? ex.A1~A10までの10個のセルの中に正の値が7個、負の値が3個あると仮定します。A11に正の値を計算する(7個のみを判断して計算)式を、A12に負の値(3個のみを判断して計算)を計算する式を作成したいのです。 お分かりになる方教えてください。

専門家に質問してみよう