• ベストアンサー

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

chie65535の回答

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

>Button1MouseDownイベントで判定すれば良さそうですね。 >よく確認せずに思いつきの質問をしてしまい申し訳ありませんでした。 「ボタンがクリックに反応する時」は「マウスが離された時」なのでOnMouseDownではフラグを付けるだけにとどめ、処理の本体はOnClickで処理すべきです。 そして、OnMouseDownで付けたフラグは、OnMouseUpで後始末(クリア)するようにしましょう。 もし「マウスが押された時にCtrlキーも一緒に押されてるのを調べて何かの処理をして、その後に発生する筈のOnClickで後始末の処理をする」というプログラムを組むと酷い目に遭います。 やってみると判るのですが、以下のような操作をした場合、OnClickが発生しません。 ・ボタンコントロールの上でマウスの左ボタンを押す(押したまま離さない)この時点でOnMouseDown発生。 ・マウスの左ボタンを押したまま、マウスを動かして、マウスカーソルをボタンコントロールから外す。 ・マウスの左ボタンを離す。この時点でOnMouseUp発生。 もし「押した瞬間に処理が始まってしまう」というプログラムをすると、上記のような「ボタン押しちゃったけど、やっぱやめた。今の無し」と言う操作が出来なくなります。 また、Ctrl+Aの判定時も、キーリピートにより「OnKeyDownが連続して発生し、OnKeyUpが発生しない」と言う状態がありますので注意してください。 もし「OnKeyDownのあとには必ずOnKeyUpがある筈」と言うプログラムをしたら酷い目に遭います。 「クリックした時に、Ctrlキーなども一緒に押されていたか判定する」とか「Ctrl+AやCtrl+Bを判定する」と言う場合は、以下のようにします。 #define BKEY_CTRL 0x01 #define BKEY_SHIFT 0x02 #define BKEY_ALT 0x04 #define BMOUSE_CTRL 0x08 #define BMOUSE_SHIFT 0x10 #define BMOUSE_ALT 0x20 #define BCTRL_A 0x40 #define BCTRL_B 0x80 //--------------------------------------------------------------------------- void __fastcall TForm1::Button1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { int f = ((TComponent *)(Sender))->Tag; if (Key == VK_SHIFT) f |= BKEY_SHIFT; if (Key == VK_CONTROL) f |= BKEY_CTRL; if (Key == VK_MENU) f |= BKEY_ALT; if ((Key == 'A') && (f & (BKEY_CTRL | BMOUSE_CTRL))) { if (f & BCTRL_A) { Label4->Caption = "Ctrl+Aが押され続けている"; } else { Label4->Caption = "Ctrl+Aが押された"; } f |= BCTRL_A; } if ((Key == 'B') && (f & (BKEY_CTRL | BMOUSE_CTRL))) { if (f & BCTRL_B) { Label4->Caption = "Ctrl+Bが押され続けている"; } else { Label4->Caption = "Ctrl+Bが押された"; } f |= BCTRL_B; } ((TComponent *)(Sender))->Tag = f; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1KeyUp(TObject *Sender, WORD &Key, TShiftState Shift) { int f = ((TComponent *)(Sender))->Tag; if (Key == VK_SHIFT) f &= ~BKEY_SHIFT; if (Key == VK_CONTROL) f &= ~BKEY_CTRL; if (Key == VK_MENU) f &= ~BKEY_ALT; if (Key == 'A') { if (f & BCTRL_A) { Label4->Caption = "Ctrl+Aが離された"; } f &= ~BCTRL_A; } if (Key == 'B') { if (f & BCTRL_B) { Label4->Caption = "Ctrl+Bが離された"; } f &= ~BCTRL_B; } ((TComponent *)(Sender))->Tag = f; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1MouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { int f = ((TComponent *)(Sender))->Tag; f &= ~(BMOUSE_CTRL | BMOUSE_SHIFT | BMOUSE_ALT); if (Shift.Contains(ssCtrl)) f |= BMOUSE_CTRL; if (Shift.Contains(ssShift)) f |= BMOUSE_SHIFT; if (Shift.Contains(ssAlt)) f |= BMOUSE_ALT; ((TComponent *)(Sender))->Tag = f; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1MouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { int f = ((TComponent *)(Sender))->Tag; f &= ~(BMOUSE_CTRL | BMOUSE_SHIFT | BMOUSE_ALT); ((TComponent *)(Sender))->Tag = f; } //--------------------------------------------------------------------------- void __fastcall TForm1::Button1Click(TObject *Sender) { int f = ((TComponent *)(Sender))->Tag; if (f & (BKEY_CTRL | BMOUSE_CTRL)) { Label1->Caption = "Ctrlキーを押されてクリック"; } else { Label1->Caption = "Ctrlキーを押されずクリック"; } if (f & (BKEY_SHIFT | BMOUSE_SHIFT)) { Label2->Caption = "Shiftキーを押されてクリック"; } else { Label2->Caption = "Shiftキーを押されずクリック"; } if (f & (BKEY_ALT | BMOUSE_ALT)) { Label3->Caption = "Altキーを押されてクリック"; } else { Label3->Caption = "Altキーを押されずクリック"; } } //--------------------------------------------------------------------------- この例では、フラグに「コンポーネントのTagプロパティ」を使用しているので、グローバル変数は不要です。 また、この例は、複数のボタンでイベントコードを共有出来ます。こうするとボタンコントロールごとにイベントを1つづつ個別に書く必要はないので「1ヶ所だけ直し忘れた」と言うミスを防げます。

CLMN
質問者

お礼

う~ん、ここまでしないとマズイですか? 単純ではなかったのですね。 レベルが高くてちょっとついて行けない状態です。 if (f & BCTRL_A) { これで「押され続けている」という判定になる理由が良く分かりませんでした。 Ctrlとボタンについての説明は分かりました。 工夫してみようと思います。 ありがとうございました。

関連する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; } } }