• ベストアンサー

コントロールキーが押されたキー入力の判定方法

chie65535の回答

  • chie65535
  • ベストアンサー率44% (8571/19474)
回答No.8

>Ctrl + A が押されたか?という判定で、 >if(Shift.Contains(ssCtrl) == true && Key == 'A'){ >というif文では不十分でしょうか? それでも可。 >この判定直後でMessageBoxを表示し、「***の処理をしても良いですか」 >という記述をした場合に、Crtl + A が連続して押される、という状況は >免れると思います。 その代わり、ボタンの方に「Crtl + Aが離された」ってイベントが飛んで行かないので、色々と問題が出るかも知れない。問題が出ないかも知れない。 キーを離したのを待たない場合、キーが押されたままフォーカスがメッセージボックスに移るので、もし、メッセージボックスの方に「Crtl + Aが離されたら、何か特殊処理をする」とかって特殊処理が施してあれば「想定外の処理が想定外のタイミングで発生」する事になる。 もちろん、ボタンの方も「Crtl + Aが離された」ってイベントが飛んで来ないので「何時までも押しっぱなし」と勘違いして、場合に拠っては「キーボードに反応しなくなる」とかの問題が出るかも知れない。問題が出ないかも知れない。 こればっかりは「やってみないと判らない」です。 >それから、この例では、ボタンのTagにはゼロが格納されている、という前提なのですよね? 設計時、フォーム上にボタンを配置し、オブジェクトインスペクタでボタンの各種プロパティを表示させ「Tag」プロパティを見ると値はゼロになっている筈。それを手で書き換えない限り、実行開始直後のTagプロパティは0。 >if ((Key == 'A') && (f & (BKEY_CTRL | BMOUSE_CTRL))) { >このif文とビット操作が良く分からないのです。 「Keyが'A'で、かつ、fにBKEY_CTRLとBMOUSE_CTRLのどれか1つ以上がオンになっているならば、真」 こういう書き方は「各ビットに意味を持たせた時に使う定石」なので、覚えておく事。 ・定石1 「AかBかCのうち、どれか1つ以上がオンなら真」 (フラグ & (A | B | C)) または ((フラグ & (A | B | C)) != 0) ・定石2 「AとBとCのうち、どれか1つ以上がオフなら真」 ((フラグ & (A | B | C)) != (A | B | C)) ・定石3 「AとBとCが、全部オンの時だけ真」 ((フラグ & (A | B | C)) == (A | B | C)) ・定石4 「AとBとCが、全部オフの時だけ真」 (!(フラグ & (A | B | C))) または ((フラグ & (A | B | C)) == 0) ・定石5 「A、B、Cが特定の組み合わせの時だけ真」 ((フラグ & (A | B | C)) == (A)) //Aがオン、BとCがオフなら真 ((フラグ & (A | B | C)) == (B)) //Bがオン、AとCがオフなら真 ((フラグ & (A | B | C)) == (C)) //Cがオン、AとBがオフなら真 ((フラグ & (A | B | C)) == (A | B)) //AとBがオン、Cがオフなら真 ((フラグ & (A | B | C)) == (A | C)) //AとCがオン、Bがオフなら真 ((フラグ & (A | B | C)) == (B | C)) //BとCがオン、Aがオフなら真 ・定石6 「Aのフラグを付ける」 フラグ |= A; ・定石7 「Aのフラグを消す」 フラグ &= ~A; 上記の定石は、ビットが3種類で説明したけど、ビットの種類が幾つあっても書き方の基本は同じ。 定石の中に必ず出て来る「フラグ & (A | B | C)」の部分は「フラグのビットのAとBとCについてのみ調べたい」と言う意味になってる。この部分のおかげで「フラグに付いてるDやGやJのビットを無視」している。 で、余計なビットを無視した上で「じゃ、無視しなかったA、B、Cの状態はどうなってる?」ってのを比較演算子「==」や「!=」を使って判断している。 慣れれば「A、B、Cのどれか1つでもオンで、かつ、D、E、Fが全部オンの時に真、または、G、H、IのうちHとIがオンでHがオフの時に真」とかって判定式も書けるようになる。 >最初の二つと、最終的に判定しているBCTRL_Aはビットの位置が違うのでは?と混乱しています。 ビット位置違って当たり前。 それぞれのビットは BKEY_CTRLは「OnKeyDownに来た時にCtrlキーが押されていればオン」 BMOUSE_CTRLは「OnMouseDownに来た時にCtrlキーが押されていればオン」 BCTRL_Aは「1度でもCtrl+Aが押されていたならオン」 と言う意味を持っている。 3つとも意味が違うんだから、同じビット位置にしちゃ駄目だってのは判りますか?

CLMN
質問者

お礼

丁寧な回答、ありがとうございました。 本題からズレた話題になりますが、ビット操作の定石、良く分かりました。 私は事務処理専門なので、この辺の知識はほとんどなく、説明してもらえて良かったです。 if (Key == VK_CONTROL) f |= BKEY_CTRL; は、Ctrlキーが押されていたら、fの最下位ビット(以下、第1ビット)に1を立てる、という意味だと理解しました。 また、Ctrlと一緒にボタンが押されたときは、BMOUSE_CTRLなので、第4ビットに1を立てています。 if ((Key == 'A') && (f & (BKEY_CTRL | BMOUSE_CTRL))) { これは「Aが押され、なおかつ、fの第1ビットまたは第4ビットに1が立っている時」という判定だと思います。 ところが、連続入力の判定は、BCTRL_A(0x40)なので、第7ビットに1が立っているか?という記述になっています。 セットするときは、第1、第4ビットなのに、その結果を判定するときは第7ビットを見ている、となり、判定位置が違うのでは?と思った次第です。 でも、よく見ると if ((Key == 'A') && (f & (BKEY_CTRL | BMOUSE_CTRL))) { の最後で、第7ビットに1を立てていますね。 これはKeyUpされると解除される訳ですね。 この文章を書き始めるまでは良く分かっていなかったのですが、質問を書き始めたら分かり始めました。 お蔭様でした。

関連するQ&A

  • Tabキーのキャンセル

    かなり短期間にこちらでいくつも質問して しまっていて申し訳ないのですが、 どうにも他で回答を調べられず…(<力不足) と言う訳で、しつこく 「IEだけでなくNetscape6以降でも動かしたい」 処理についてお聞きいたします。 IEでは上手く動いてますが、Netscape6以降でTabのキャンセルは指定できるのでしょうか? ちなみに↓のNetscape用関数は動きません(……。) 必要そうな所だけ書き出します↓ function document_onLoad() {  // IE 4以降の場合  if (isIE)  {   // 各種イベントハンドラーの初期化   document.onkeydown = document_onKeyDownIE;  }  // N6,7の場合  if (isN6)  {   window.onkeydown = document_onKeyDownN6;  } } /// tabキーが入力されたときのイベント処理(IE用) function document_onKeyDownIE() {  // TABキー  if (event.keyCode == 9)  {   // 本来のtabの処理をキャンセルする。   event.returnValue = false;  }  return; } /// tabキーが入力されたときのイベント処理(NN用) function document_onKeyDownN6(evt) {  var keyCode = evt.which;  if (keyCode == 9)  {   // 本来のtabの処理をキャンセルする。   evt.returnValue = false;   evt.cancelBubble = true;  }  return; }

  • 「何も処理をしない」を実装する方法

    キーボードのEnterキーを押した際、 何も処理をせず現在表示している画面に戻す ということを実装したいのですが、どのように記述したらよいのか分かりません。 私が作りましたソースは、 window.document.onkeydown = keytech; function keytech(){ if( event.keyCode == 13 ){   history.go(0); }else {   // Nothing } です。 このソースで「Enterキー」を押した時というイベントは取れています。 しかし、「history.go(0);」にて、 「現在表示しているページを再度読み込む」をしてしまいます。 それでは、これまでに入力したフォームのテキストの情報などが、 消えてしまいます。 入力してもらった情報を消さずに何も処理をしないということは可能でしょうか?

  • Internet Explorerのキー入力受付

    お世話になります。 例えば、 googleのサイトを開いて、検索ワードを自動で打ち込むようなプログラムを作ろうとしているのですが、 googleを立ち上げ,keybd_event()で打ち込もうとしているのですが、 googleがキー入力を受け付け可能か否かが分からないため、上手くいきません。 キー入力の受付可能かどうかの判定の仕方を教えてください。

  • テキストフィールドに半角数値以外入力させない方法…。

    お世話になります! JavaScriptで、 function checkNum() {  c = String.fromCharCode(event.keyCode);  if ("0123456789".indexOf(c,0) < 0) alert("数値以外入力できません"); } と記述し、実行してみたのですが確かに数値以外は入力できないのですが BackSpaceやEnterキー、Tabキーを押した時にもアラートが発生します…。 本を見て、 function checkNum() {  c = String.fromCharCode(event.keyCode);  if ("0123456789".indexOf(c,0) < 0) return false; return true; } と記述すると、フォーム自体に半角数字しか入力できなくなると書いてあったのですが 実行しても普通に全角入力できました…。(泣) 何か方法ありますか?ご存知の方、宜しくご教授願います★ ちなみに、勿論<input>部分にonKeyDown="***()"の記述はしてますし JavaScriptが有効な状態での実行です。

  • キーコードなどでAlt+○を認識してイベントを発生させるには?

    キーコードなどでAlt+○を認識してイベントを発生させるにはどうしたらよいのでしょうか?ひとつのキーでならできたのですが複数のキーを組み合わせることができませんでした。参考までにうまくいかなかったプログラムの関数部分を記述しておきます。このプログラムだと一回目はうまくいくのですが二回目になるとsキーを押すだけで実行されてしまいます。 document.onkeydown=keyDown; function keyDown() { keynum1=event.keyCode; if(keynum1==18)//この番号がキーに対応してる(Altキー) { document.onkeydown=pressEnter; } } function pressEnter() { keynum2=event.keyCode; if(keynum2==83)//この番号がキーに対応してる(sキー) { document.write("キーコード"); } }

  • キーコード ?と/が同じですが、区別する方法は

    onkeydownで取得するキーコードが、?と/が同じ191で困っています。 ?が入力されたときに処理を実行し、/が入力された時は処理を実行したく無いのですが、どうすれば良いでしょうか? function hoge() { if(event.keyCode == 191) 処理; } <INPUT type=text id=txt1 name=txt1 onkeydown=hoge() > 宜しくお願い致します。

  • 入力判定の仕方が分からなくて、困ってます・・

    VB.NETで、キーボードから入力してLabelに表示されている文字と 合っていれば正解、間違っていれば不正解の処理を1文字単位でやりたいのですが、正解不正解の判定のやり方が分かりません・・。 Private Sub Form1_KeyPress() If Mid(Label2.Text, a, 1) = "入力したのと同じ" Then Mid(Label2.Text, a, 1) = ""     a = a + 1 Else  ’不正解の処理 ?? End If End Sub みたいかな?と思ってプログラムを組んでみたのですが、 ifの"入力したのと同じ"ところの書き方が良く分かりません。 詳しい方、KeyPressの使い方等教えていただけませんか?

  • Flashのキーイベント処理について

    Flashのキーイベント処理でなかなか不具合が取れず、困っています。 よろしくお願いします。 今作っているFlashは1つのデータ内に複数のページが存在し、ページごとにキーイベント処理内容が異なる仕様のため、それぞれにキー処理を行っています。 内容は、下のようなスクリプトを書いています。 -<ページ(1)でのクリアキー判定>---------------- var Key_object = new Object(); Key_object.onKeyDown = function(){ code = Key.getCode(); if(code == 46){ //終了処理 } } Key.addListener(Key_object); ----------------------------------------------- -<ページ(2)でのクリアキー判定>---------------- var Key_object2 = new Object(); Key_object2.onKeyDown = function(){ code2 = Key.getCode(); if(code2 == 46){ //ページ(1)へ戻る処理 gotoAndPlay("page1"); } } Key.addListener(Key_object2); ----------------------------------------------- ですが、上の処理だとページ(2)でクリアキーを押した時にページ(1)に戻ってほしいのに、何故かページ(1)のクリアキー判定まで行われてしまい、終了処理がなされてしまいます。 この件についての原因と打開策が知識の乏しい私では見当たりません。 また、違う人に聞いたところ「ページ(2)でのクリアキー判定の方はイベントリスナーを使わずにキー判定を実装して」といわれました。 このイベントリスナーを使わずにクリアキーの判定を実装する方法がわかりません。 どなたか、上のスクリプトでの不具合原因や打開策、また「イベントリスナーを使わないクリアキーの判定方法」が分かる方、いらっしゃいませんでしょうか?

    • ベストアンサー
    • Flash
  • カレンダーの年月入力の判定

    現在C言語でカレンダープログラムを書いています。 表示させたい年月を入力するのですが、正しい形で入力されたかの判定プログラムについてご教授いただきたいです。 具体的にはYYYY/MMまたはYYYYMMの形で入力されたかどうかを判定したいと思っています。 どのようなプログラムを書けばよろしいでしょうか。

  • Processingでのキーの同時入力

    Processingでゲームを作ろうとしているのですがキーボードの同時入力がうまくいきません。 例えば下記のようなキー入力に応じて黒い四角が動くプログラムを実行しました。方向キーを一つだけ押したときはサクサク動いてくれるのですが、→と↓を同時に押しても斜めに進んでくれません。また、→と←を押した場合もどちらか片方の方に動いてしまいます。 このような問題を解決したいので、Processingでキーボードの同時入力を判定するにはどのようにすればいいのか教えてください。 float x, y; void setup(){ size(400, 400); noStroke(); smooth(); } void draw() { background(255,255,255); fill(0,0,0); rect(x,y,20, 20); if (keyPressed && key == CODED){ if (keyCode == LEFT){ x -= 2; } if (keyCode == RIGHT){ x += 2; } if (keyCode == UP){ y -= 2; } if (keyCode == DOWN){ y += 2; } } }