• 締切済み

VBA API WM_KEYDOWN

エクセル内のオブジェクトの移動を判定するため、マウスアップを検出しようと考えています。 GetAsyncKeyStateでできるのですが、エクセルが受け取るWM_KEYDOWNを受け取る方法はないのでしょうか? そもそもWindowsがイベント待ちで動いているのに、GetAsyncKeyStateだとループ処理で監視することになるので、すっきりしません。私だけでしょうか? ちなみに、新規に図形を作ったり、図形を移動したりしたときに処理したいですが、このイベントは準備されていないですよね?

みんなの回答

  • masnoske
  • ベストアンサー率35% (67/190)
回答No.1

アイデアだけで、うまくできるかどうか分かりませんが。。。 シェイプにマクロを割り当てておくと、クリックできることを利用します。 はじめにシェイプがシート上に配置されてる状態で SetMacro を実行します。 これで全てのシェイプに ShapeClick マクロが割り当てられます。 以降は、シェイプをクリックすると選択状態になります。 あとはマウスの位置に合わせてシェイプを擬似的に移動させる(笑) Public ClickObj As String ' オートシェイプにマクロを割り当てる Sub SetMacro() Dim shp As Shape For Each shp In ActiveSheet.Shapes shp.OnAction = "ShapeClick" Next Set shp = Nothing End Sub ' オートシェイプがクリックされたら選択状態にする Sub ShapeClick() Dim shp As Shape ClickObj = Application.Caller Set shp = ActiveSheet.Shapes(ClickObj) shp.Select End Sub 同じような事を考える人がいるのか。。。 https://blog.goo.ne.jp/end-u/e/e05cc38782bd685f5661c53bc93b1620

tanakanono
質問者

お礼

なかなか回答がつかない中、回答ありがとうございます。 しかし、ユーザーが図形を新規作成した際にイベントが発生しないので、図形作成後にセル選択などをしないと新規図形を検知できないです。。。 ループ処理でCPUが変わるか見てみましたが、sleep 50くらいにするとほとんど使用しないようです。無駄なループは翻訳してイベント待ちになっているのかもしれません。VBAは謎が多い言語(コンパイラ?)ですので。。

関連するQ&A

  • WM_KEYDOWN が拾えない(EditBox関連)

    メインとなるウィンドウ(親)のクライアント領域に子ウィンドウを貼り付けそこにデータを表示させています。内容的にはエクセルのような表形式になっていてセルを選択でき、方向キーで選択を移動できます。 移動は子ウィンドウでWM_KEYDOWNが拾えなかったので親ウィンドウでWM_KEYDONWを子ウィンドウにSendMessageして子ウィンドウで処理させています。このやり方に少々疑問も感じますがとりあえずここまでは期待通りに動いてくれています。 ここからが問題なのですが、データを修正する時に子ウィンドウにEditBox(孫)を作成し直接入力できるようにしましたが、入力が終わりエディットボックスを破棄した後、以前のように方向キーでの移動が出来なくなってしまいました。親ウィンドウでWM_KEYDOWNを拾えていないようです。でも、最小化などにより一度親ウィンドウがフォーカスを失うと再び正常に戻ります。 EditBoxはサブクラス化してリターンキーで閉じるようになってます。 良い解決方法がありましたらお願いします。 環境:VC++6.0(SDK) WindowsMe

  • VBA オブジェクトのマウスアップ

    エクセルで図形を移動したら余分な操作なくセルにフィットさせたいです。 オブジェクトでマウスアップイベントが使えたらいいのですが、無いようです。 いい方法はないでしょうか? 中途半端な案 1.枠線に合わせるを強制する。  →挿入や移動でセルに合わない時もあるのでNG?(そもそもなぜ合わないの?) 2.図形移動後、別の図形かセルが選択されるのに期待  →すべてのオブジェクトにonactionを設定   セルchangeイベントとオブジェクトonactionを使う。 3.フォームを全画面表示、透明化、フォームのマウスアップイベントを使う  →考えただけでも難易度が高すぎ。

  • C# イベント処理について

    GUIなどの処理はイベントというのを使っていますが、イベントの実際の内部処理は一体どんな仕組みで動いているのでしょうか。  単純に無限ループをして状態が変化しているかチェックしているのでしょうか。 例えばボタンが2つあり、マウスが上に来たらボタンの色を反転させるイベントは、マウスと2つのボタンの当たり判定を監視し、繰り返す。という感じなのでしょうか。 (ということはボタンの数やボタン自体のイベントが増えれば負荷も増えてしまう?)

  • WM_NCLBUTTONUPについて

    タイトルバー上でのマウスボタンのアップを検出したいので、 WM_NCLBUTTONUPメッセージを拾うために、単純に以下のようなコードを書きました。 が、このコードではうまくWM_NCLBUTTONUPメッセージを拾えません。 ウィンドウを最大化しているときは問題なくメッセージを拾えるのですが、 それ以外の時(縮小表示)はメッセージを拾えません。 ただ、WM_NCLBUTTONDOWNは正しく拾うことができました。 ウィンドウが縮小表示になっている時にWM_NCLBUTTONUPを取得する場合には何か特殊な処理が必要なんでしょうか? ご存知の方がいらっしゃったら、よろしくお願いします。 // ウィンドウプロシージャ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_NCLBUTTONUP: MessageBox(hWnd, "UP", "LBUTTON", MB_OK); return 0; case WM_DESTROY: // ウインドウが破棄されたときの処理 PostQuitMessage(0); return 0; default: // デフォルトの処理 return DefWindowProc(hWnd, message, wParam, lParam); } }

  • VBAのイベント処理について

    VBAのイベント処理について お世話になってます。現在、VBAでアプリケーションを作成しています。 1つのフォームに4つのテキストボックスと1つのボタンが配置されており、それぞれイベントが設定されています。 その中のテキストボックスに関するイベントなのですが、1つのテキストボックスに対してKeyPress、KeyDown、MouseUp、AfterUpdate、以上4つのイベントを作成します。 フォームに配置されている4つのテキストボックスすべてに、上記で示したイベントを作成する必要がありますが、各イベントにおける処理の内容はオブジェクト名が違うだけで全く同じです。 ひとつひとつイベントを作成していけば、処理目的は満たせそうですが、ソースがかなり長くなってしまいます。ひとつのオブジェクトに対してこれらの処理をひとまとめにする様な記述方法はありませんでしょうか?考え方だけでも教えていただければ幸いです。 質問が長くなってしまい申し訳ありません。回答宜しくお願い致します。

  • ダイアログプログラムでEnterキーを検出するには?

    おせわになります。 開発環境はWindowsXP、VisualC++.NET、SDK開発です。 ダイアログ上のテキストボックスでエンターキーが入力されたら、 値を取り込むというプログラムを考えています。 ただ、WM_KEYDOWNではENTERが検出できないで困っています。 WM_SYSKEYでもENTERを押してもOKボタンが押されてしまいます。 過去のログを見ますとTranslateMessageでフックするというような 記述がありますが、具体的なコードは無いでしょうか? メイン関数内のループでMSGを処理するのではと思っていますが 思うような動作が出来ません。

  • キーボード処理 SDK

    クライアントがサーバを操るツールを作っています。 何をしたいか↓ ・クライアントはサーバの画面上でメモ帳を開き「日本語」入力をする。 (クライアントからサーバの画面上で「(0~9)(a~z)」は打てます。) □サーバ側 case WM_KEYDOWN: //押されたときの処理   //送られてきたキーイベントの実行   keybd_event(cmsg.wParam,cmsg.wParam,0,0);   break; case WM_KEYUP: //離されたときの処理:解放処理   keybd_event(cmsg.wParam,cmsg.wParam,KEYEVENTF_KEYUP,0);   break; □クライアント //キーボード処理 case WM_KEYDOWN: 環境 WindowsXP MicrosoftVisualC++ SDK お願いします。

  • VBAのExitイベントについて

    VBA(Excel)についてご質問します。 フォームにて、IDというオブジェクト名のテキストボックス、 Private Sub ID_Exit(ByVal Cancel As MSForms.ReturnBoolean) という関数(Exitイベント)を用意しました。 IDにフォーカスがある状態で、フォーカスを移動しようとすると、この関数が必ず実行されるかと思います。 そのとき、特定のボタン(例えばキャンセルボタン)がクリックされたためにフォーカスが移動したときは、この関数の処理を実行したくない。もしくはこの関数内で特定のボタンがクリックされたこと(そのためにフォーカスが移動したこと)を検出して、処理をスキップしたいです。 どうすれば実現できますでしょうか? よろしくお願いします。

  • エクセルVBA ヒントを下さい

    バージョンはエクセル2000です。 セルの値を判定し条件分岐する、というありふれた処理です。 A1を判定⇒A2を判定・・・のようにオフセットなり変数を使うなりで 次のセルをアクティブにしていっているのですが、 当然セルの数だけ処理時間は増えていきます。 アクティブセル範囲がA1:Z1000みたいなかんじであったとして、 これをRangeオブジェクトとして定義し一気にその中身を処理する (セルの値が1ならば0にする、のような)ことは出来るのでしょうか。 配列を使えばいいのかとも一瞬思ったのですが、それでも一つ一つ処理することに変わりはなさそうだし・・。 何かヒントをいただければと思います。

  • excel vba 名前付きセルが存在しないとき

    あるワークシートのセルに、"_1", "_2","_3","_10"のように名前をつけています。 "_8"が見つからなかったら、ループで番号を上げていき、"_10"にたどりつくようにしたいんですが、"_8"というセルが見つからなかった時の判定方法がわかりません。 On error ではない処理を使いたいのですが、 If Range("_8") = Empty Then では実行時エラー1004 "アプリケーション定義またはオブジェクト定義のエラーです" と出ます。 Rangeオブジェクトがemptyになるわけではないんでしょうか? よい方法があれば、教えてください。

専門家に質問してみよう