tagCANDY CGI VBレスキュー(花ちゃん)の Visual Basic 6.0用 掲示板 [ツリー表示へ]   [Home]
一括表示(VB6.0)
タイトル複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13059
投稿日: 2008/09/25(Thu) 17:44
投稿者ぼた
2つの画面(Form1とForm2)にCreatePopupMenu APIを使用しプルダウンメニューを作成したいと
考えております。まずはForm1に下記手順にて作成を行いました。

1.CreatePopupMenuを定義しメニューを作成
2.メニュー選択のイベントを取得するためにForm1をサブクラス化
    変更前の値 = SetWindowLong(Form1.hwnd, _
         GWL_WNDPROC, AddressOf ウインドウプロシージャ関数)
3.TrackPopupMenuを使用しメニューを表示
4.メニューが表示され項目をクリックするとウインドウプロシージャ関数が呼ばれ
 WM_COMMAND(メニュー項目が選択されたメッセージ)が来たら選択された項目を取得

と大雑把ですが普通の手順だと思います。
これをForm2にもまったく同じメニューを表示したいと思い以下の手順を追加しました。
1.Form2を開く時にForm1のサブクラス化を解除し、Form2をサブクラス化する
2.Form2を閉じるときに、Form2のサブクラス化を解除し、Form1をサブクラス化する
上記変更で、Form1でも2でも問題無く動作することができました。

しかし、ソース上から実行後、テストを行いVBの停止ボタンを押すとVBが終了してしまうのです。
停止ができる場合もありますが、その後実行するとほぼ100%落ちます。

いろいろ手順などを変えましたがメニュー選択時のメッセージをフックできない不具合が発生
しましうまくいきません。

手順のミスや、考え方のミス等ありましたらご教授いただきたいと思います。

以上 よろしくお願いします。

環境:Windows2000Pro(SP4) + VB6(SP6)

[ツリー表示へ]
タイトルRe: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13061
投稿日: 2008/09/25(Thu) 22:30
投稿者花ちゃん
> しかし、ソース上から実行後、テストを行いVBの停止ボタンを押すとVBが終了してしまうのです。

VBの停止ボタン とは、IDE 上の ■ のボタンの事なら、当然落ちてしまいます。
サブクラス化時は、Form の閉じるボタンで閉じる様にして下さい。
又は、サブクラス化を解除してから終了して下さい。
当然サブクラスしている部分ではデバッグもできません。

[ツリー表示へ]
タイトルRe^2: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13062
投稿日: 2008/09/26(Fri) 12:03
投稿者ぼた
>花ちゃんさん
コメント&ご指摘ありがとうございます。
ご指摘の通りIDEの■ボタンで終了した場合に落ちます。
■を押す前にサブクラス化を解除すればよいのですね。
サンプルを作り確認したところ確かにサブクラス化を解除した後に■を押せば問題なくなりました。

しかし、サブクラス化を解除した後にEndすると落ちるようです。
前回の重複となってしまいますが記述します。

サンプルの内容
Form1.ボタン1
@Form1をサブクラス化

Form1.Form2表示ボタン2
AForm1をサブクラス化解除
BForm2をサブクラス化

Form2.Form2閉じるボタン1
CForm2をサブクラス化解除
DForm1をサブクラス化

Form1.終了ボタン
EForm1をサブクラス化解除
FEnd ★ここでIDEごと落ちてしまいます。
 Form1の右上の×ボタン or IDEの■だとちゃんと終了してくれます。

へたにサブクラス化は使わないほうが無難ではないかと思えてきました。
申し訳ありませんが、なぜ「END」を実行した場合落ちてしまうのかを
ご教授ください。お願いします。

[ツリー表示へ]
タイトルRe^3: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13063
投稿日: 2008/09/26(Fri) 12:36
投稿者花ちゃん
> FEnd ★ここでIDEごと落ちてしまいます。

これって、コード中に End ステートメントを記述していると言う事ですか?

サブクラス化 に限らず、End ステートメントを実行したらそれ以降の処理は
なにも行われませんのでコード中には使用しないで下さい。
(使用中のメモリの解放等も行われない可能性がある)
Unload ステートメントを実行する事でメモリからアンロードします。
従って、終了は、Unload ステートメントでして下さい。

サブクラス化中は、プロシージャ内でもブレークポイントを設定する等デバッグ処理は
厳禁です。
又、当然ながらサブクラス化内で、プログラムミスを冒していると当然落ちてしまい、
場合によっては、パソコンを壊す事にもなりますので注意して下さい。

ここのサイト内・外の検索から、 サブクラス化とは をキーワードにWEB上を検索
して見て下さい。(私の回答は怪答の方だから)
又、同じく End ステートメント をキーに検索して見て下さい。

[ツリー表示へ]
タイトルRe: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13065
投稿日: 2008/09/26(Fri) 16:03
投稿者K.J.K.
> 3.TrackPopupMenuを使用しメニューを表示

ここで、フラグ値として
TPM_RETURNCMD Or TPM_NONOTIFY
を追加して(Or)おくわけには行かないのですか?
そうすれば、サブクラス化などの面倒なことをせずに済みそうですし。

[ツリー表示へ]
タイトルRe: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13066
投稿日: 2008/09/26(Fri) 18:45
投稿者ぼた
>花ちゃんさん、K.J.Kさん
ご教授ありがとうございます。
ちょっとWEB上で調査 & K.J.Kさんの案を考慮してみます。

とり急いでお礼と思いコメントさせていただきました。

[ツリー表示へ]
タイトルRe: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13067
投稿日: 2008/09/27(Sat) 01:52
投稿者Starfish
> 2つの画面(Form1とForm2)にCreatePopupMenu APIを使用しプルダウンメニューを作成したいと

 VBの機能ではだめなのですか?サブクラスどころか、WindowsAPIも直接使用しなくて
済みますが。

 例えば、Form1のメニューに、以下のメニューを作成する。
  キャプション:Popup(なんでも良い)
  名前    :mnuPopup
  表示    :チェックを外す。(Loadイベントで、非表示にしてもいいです)
 実際の、ポップアップメニューは、この下のレベルで作成しておく。

 Form1でポップアップメニューを表示したいときは、
  PopupMenu mnuPopup
 で、表示できます。

 Form2から、Form1のポップアップメニューを表示したいなら、
  PopupMenu Form1.mnuPopup
 です。

[ツリー表示へ]
タイトルRe^2: 複数画面へのCreatePopupMenuを使用したメニュー作成
記事No13069
投稿日: 2008/09/29(Mon) 10:16
投稿者ぼた
>Starfish さん
レスありがとうございます。
普通VB標準のメニュー機能で作りますが、業務上引き継いだプログラムがなぜか
APIで作ってあってそれを拡張する必要があるのです。
なぜVB標準で作らなかったのかは不明です。メッセージフックなんてデバックやり
辛いしAPIじゃないとできないこともやってないし、ただのかっこ付けと思って諦めました。

いろいろ調べましたが、これだという方法は見つかっておりません。
片方はVB標準のメニューを使うことも考えて進めたいと思います。

いろいろ検討していただきありがとうございます^^

[ツリー表示へ]