[cbuilder:40112] ポップアップメニューが閉じられた事を知るには

70 views
Skip to first unread message

Mifuji

unread,
Aug 10, 2009, 6:12:04 AM8/10/09
to cbui...@sfdata.ne.jp
こんにちわ、三藤です。

ポップアップメニューをプロパティに持った、TGraphicControlから
派生したボタンコンポーネントを作成しています。

このボタンはクリックされるとプロパティに割り当てられた
PopupMenuをボタンのすぐ下に表示させます。

MouseDown時にボタンの状態を押下に変えてPaintメソッドで
ボタンが押下された状態を描画しています。
MouseUp時に同じく押上状態に戻してPaintしているのですが、
MouseDown時にPopupMenu->Popupを実行すると、
MouseUpイベントが発生しないようでマウスが押下された状態の
描画のままになってしまいました。

しかし、動き的にはポップアップが閉じるまで押下状態を描画
したいと思っているので、ポップアップが閉じた時にボタンを
押上状態に戻すことができれば理想の動きになります。

そこで、ポップアップが閉じた事を知る方法がないかを質問
させていただきたく思うのですが、どなたかアドバイスを
いただけませんでしょうか。

よろしくお願いします。


S.Yamazakj

unread,
Aug 10, 2009, 10:38:54 AM8/10/09
to cbui...@sfdata.ne.jp
三藤さん

 山崎です。
 あまりお力にはなれないのですが、
昔、必要があって似たようなUIを作った時には、
TStringGridを配置した Form を用意して(フォームの BorderStyle は bsNone、
グリッドの Align は alClient)、カスタムコントロールを押下時に
表示してメニューの代用品に使うという実装をしました。

①カスタムコントロールをオーナーとしてグリッド配置フォームを
 生成する。初期状態ではフォームを非表示にする。
②オーナーコントロールの MouseDown でグリッド配置フォームを表示し、
 フォーカスをフォームにセットする。
 オーナーコントロールは、押下状態に表示する。
③グリッドのOnClick(メニュー項目選択)、ないしフォームのOnExit
 (別コントロールにフォーカス移動)をオーナーコントロールでキャッチして、
 フォームを非表示にする。
 オーナーコントロールは、解放状態に表示する。

 以上のような感じです。
 VCL のバージョンは4くらいだったかと記憶。

 今、C++Builder6で改めて見てみても、PopupMenu には、OnPopup
(ポップアップの表示)イベントしかないですね。
 不本意かと思いますが、こんなところで手が打てればいかがでしょうか。

========================
 2009年_8月10日    
     山 崎 創 介 
========================

* Original message *********************************

Mifuji

unread,
Aug 11, 2009, 3:17:42 AM8/11/09
to cbui...@sfdata.ne.jp
山崎さん

三藤です、アドバイスありがとうございます。

TGraphicControlから派生しているため、
フォーカスの有無を調べる手段をどうしようか迷いました。
考えた末、解決策が見当たらなかったので、
結果的に以下のような手順を踏んでみました。

1.
OnMouseDownイベントでボタンの状態を押下にして
Invalidateで再描画。
その後メニューをPopupで表示。

2.
OnMouseDown内でPopupするとOnMouseUpが発生しない。
Popupで表示されたメニューが閉じられるまで次の処理に
移行しないようなのでPopup後にPerformを使って
MouseUpを強制的に発行すればメニューが閉じた時に
ボタン押上状態にできる。

3.
OnMouseUpイベントでボタンの状態を押上に戻し、
Invalidateで再描画。

これでボタンが押されたらボタン押下状態となり、
メニューが表示され、メニューが閉じた時にボタンも
押上状態となりました。

ただ、今メニューが表示されている状態かどうかの判断が
できないので、ボタン押下状態(メニュー表示中)に再度
ボタンが押された時にメニューを閉じるという動作は
実現できませんでした。

IE8の「ページ(P)」「ツール(O)」ボタンのような動きまで
あと少しなのですが・・。


S.Yamazakj

unread,
Aug 11, 2009, 11:24:49 AM8/11/09
to cbui...@sfdata.ne.jp
三藤さん

> IE8の「ページ(P)」「ツール(O)」ボタンのような動きまで
> あと少しなのですが・・。

 目指しているものが分かった気が。(^-^;

 ToolButton の DropdownMenu プロパティでは行けませんか?

 まず、フォームに PopupMenu を配置して、必要なメニューを作成。
 次に、フォームに ToolBar を配置して必要な数の ToolButton を作成し、
ToolButton の DropdownMenu プロパティに、用意した PopupMenu を
設定します。
 そこそこの動作は実現しそうです。

 ツールバーでしか使えないのが残念ですけど。
 あと、角が丸くならないのも難点になりますか?

 Vclのソースコード ComCtrls.pas は、カスタムコントロール作成の
参考になりそうです。

========================
 2009年_8月11日    
     山 崎 創 介 
sou38.y...@nifty.com
========================

Mifuji

unread,
Aug 11, 2009, 11:18:28 PM8/11/09
to cbui...@sfdata.ne.jp
山崎さん

こんにちわ、三藤です。

>  目指しているものが分かった気が。(^-^;
>  ToolButton の DropdownMenu プロパティでは行けませんか?

部分部分のパーツの話をするよりも、最終的にどんなものが
出来ればよいのかという事を書くべきでしたね^^;

当初はTToolButtonも検討したのですが、以下の点があるので
少し思い描いているものと違っていたのです。

・メニューを表示させるトリガとして使いたい(どこを押してもメニュー表示)
・エディットボックスや他のボタンと並べて配置したい
 
TToolButtonだとボタン右端の部分を押さないとメニューが
表示されないのでちょっと目的と異なっていました。
また、山崎さんもおっしゃる通りTToolBarが必要なので、
他のコントロールに並べて配置が難しいです。

ボタンを押した時にメニューを表示させるようにプログラムを書く事も
できますが、機能として多く使われそうな話だったので、
コンポーネント化してアプリ開発時は極力コード量を減らせるように
考えたんですね。

もう少し具体的な理想を書くと、ボタンを押すとTCheckListBoxみたいな
チェックつきの一覧が出て、再度メニューボタンを押すか、
他のコントロールの場所を押せばメニューが閉じるような形に
できればさらに良いのですけど(一度に複数選択される事も多いので、
選ぶたびにメニューを閉じたくないので)。

いろいろアドバイスを受けていながら「こうではない」みたいな話に
いつもなってしまって申し訳ないです・・。
でも参考になる部分も多くComCtrls.pasなんかはかなり熟読しました。
わかる部分もありますが、追っても結果的に謎なところも多く、
習得は難しいですね^^;


Reply all
Reply to author
Forward
0 new messages