ツールヒントの表示方法 – プログラミング – Home

ツールヒントの表示方法
 
通知
すべてクリア

[解決済] ツールヒントの表示方法


める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

ダイアログベースのアプリを作成してますが、
ツールチップ(ヒント?)の出し方で悩んでます。

親ダイアログ(A)の中にタブコントロールとボタン2つがあり、
タブコントロールには、子ダイアログ(B)を貼り付けてます。

AのOninitDialog()にてこんなソースを書いてみました。
-----------------------------------------------
m_ToolTip.Create(this, TTS_ALWAYSTIP);
m_ToolTip.SetMaxTipWidth(350);
m_ToolTip.SetDelayTime(TTDT_AUTOPOP, 5000); // 表示中の時間(10Sec)
m_ToolTip.SetDelayTime(TTDT_INITIAL, 200); // 表示迄の時間(200ms)
m_ToolTip.AddTool(m_pTabCtrl, 画面切替);
m_ToolTip.AddTool(GetDlgItem(IDC_BTN_FILEOUT), 出力);
m_ToolTip.AddTool(GetDlgItem(IDC_BTN_QUIT), 終了);
m_pTabCtrl->SetToolTips(&m_ToolTip);
-----------------------------------------------
実行するとタブ部分は「画面切替」と表示されますが
ボタンは何も表示されません。
Bのダイアログの各コントロールにも同様の方法で
ツールチップを設定したのですが表示されません。
何故でしょうか?

また上記を調べている最中に「OnNotifyを使う方法」を見つけましたが、
AのダイアログのOnNotifyで、B上のコントロールのツールチップも
一緒に制御出来るのでしょうか?

宜しくお願い致します。

環境はVC6/MFC/Win2Kです。


引用未解決
トピックタグ
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

半分自己レスです。

>Bのダイアログの各コントロールにも同様の方法で
>ツールチップを設定したのですが表示されません。
>何故でしょうか?
PreTranslateMessage()で「m_ToolTip.RelayEvent(pMsg);」を
宣言していませんでした。

半分解決なのですが、この方法だとA・Bそれぞれに、ToolTipの
オブジェクトを作って管理しないとならないので、作り的に宜しくない
と思います。

今後CとかDとかダイアログが増える場合もあるので、OnNotifyと
StringTableで一元管理する方法を取りたいと思っているので、
ご指南頂けるとありがたいです。

宜しくお願い致します。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> 今後CとかDとかダイアログが増える場合もあるので、OnNotifyと
> StringTableで一元管理する方法を取りたいと思っているので、
> ご指南頂けるとありがたいです。

MSDN には、かなり詳しいやり方が載っていますが、
どこが分からないのでしょうか。


返信引用
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

すみません。Windowsのメッセージの仕組みが
イマイチよく分かっていないので・・・。

B(子ウィンドウ)上で、コントロールにカーソルを当てると、
BのOnNotifyが呼ばれますよね?
その情報をAのOnNotifyに与えてやればいいのかな?と
思っているのですが・・・。

ここの過去ログ
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200211/02110109.txt
で、
---------------------------
NMHDR* pNMHDR = (NMHDR*)lParam;
if (pNMHDR->code == TTN_NEEDTEXT)
GetParentFrame()->SendMessage(WM_NOTIFY, wParam, lParam);
return CFormView::OnNotify(wParam, lParam, pResult);
---------------------------
こういった回答あったので試してみたのですがAのOnNotifyで異常終了します。
これが正しい手法なのかわからないので原因は特定してませんが、
CFormViewではなくてCDialogなのでまた扱いが違うのかな?と・・・。
MSDN読みながら試行錯誤はしているのですが。申し訳ありません。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 


見つけた「OnNotifyを使う方法」とは、これのではないのでしょうか?

「CFrameWnd から派生していないウィンドウのツール ヒント」
http://www.microsoft.com/japan/msdn/library/ja/vccore/html/_core_tool_tips.asp

別にメッセージの仕組みがイマイチ分かってなくても、
書いてある通りに実践するだけだと思います。


返信引用
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

度々すみません。
↑のリンクの通りにしてやってますが詰まりました。
以下MSDNの名称のまま書きます。

1.BのOninitDialog()で、EnableToolTips(TRUE)を記述。
2.Aのメッセージマップに「ON_NOTIFY_EX( TTN_NEEDTEXT, 0, memberFxn )」を宣言。
3.Aに「memberFxn( UINT id, NMHDR * pTTTStruct, LRESULT * pResult )」を追加。

ここで詰まるのが、実行時にBのコントロール上にマウスを置いた場合に
BのOnNotifyが呼ばれますが、ここからSendMessageでTTN_NEEDTEXTを通知してやれば
AのmemberFxnが呼ばれるのでしょうか?

B→Aへの通知方法が知りたいです。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

>BのOnNotifyが呼ばれますが、ここからSendMessageでTTN_NEEDTEXTを通知してやれば
>AのmemberFxnが呼ばれるのでしょうか?

呼ばれますけど、
ON_NOTIFY_EX も memberFxn も B に追加するのではだめなのですか?


返信引用
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

>ON_NOTIFY_EX も memberFxn も B に追加するのではだめなのですか?

ですから「一元で管理」したいのです。
全てのダイアログ(今はBしかありませんが・・・)の
ツールチップを親ウィンドウであるAで管理したいのです。

BのOnNotifyからSendMessageで引数をどのように送ってやれば
良いのかわかりません。以下BのOnNotifyです。
--------------------------------------------------
BOOL CxxxxDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
NMHDR* pNMHDR = (NMHDR*)lParam;

if (pNMHDR->code == TTN_NEEDTEXT)
g_pMainDlg->memberFxn(0, pNMHDR, pResult);

return CDialog::OnNotify(wParam, lParam, pResult);
}
--------------------------------------------------
memberFxnを直接呼び出してしまっているのですが・・・。
これだとAに記述した「ON_NOTIFY_EX( TTN_NEEDTEXT, 0, memberFxn)」が
全く意味ありませんよね・・・。これは正しいやり方なのでしょうか・・・?

本来なら、SendMessage(TTN_NEEDTEXT, ????, ????)と呼ぶのが
正しい(?)と思う(思い込んでる)のですが。

ひとまず「動き」はしますが、正しくなかったりお行儀が悪いソースは
書きたくないので、セオリーとしてはどうすれば良いのかを知りたいです。
しつこくて申し訳ありません。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

g_pMainDlg->SendMessage(WM_NOTIFY, wParam, lParam);
ではないかと思います。


返信引用
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

おはようございます。

>g_pMainDlg->SendMessage(WM_NOTIFY, wParam, lParam);
でやってみましたが・・・動きました。何故なんでしょう?
ここが、私のイマイチわからない部分なんですが、

AにWM_NOTIFYを送ると、AのOnNotifyに行くのではないのですか?
メッセージマップに記述した「ON_NOTIFY_EX(・・・・,memberFxn)」が
memberFxnに飛ばしているのだとは思っていますが、

引数も謎です。memberFxn()の宣言はこうなってます。
「memberFxn(UINT id, NMHDR * pNMHDR, LRESULT * pResult)」

一応本題から外れてしまうので、解決としますが、
このあたりを、もう少ししっかり勉強したいと思ってます。
MSDNも読んでいるのですがまだ読みこなすには難しいです。

メッセージ関係で参考になるサイトってご存知ですか?
宜しくお願いします。


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> AにWM_NOTIFYを送ると、AのOnNotifyに行くのではないのですか?

その通りです。

で、OnNotify() の標準の処理が、
「メッセージマップ内の ON_NOTIFY* を順番に見ていって、
通知コード(この場合 TTN_NEEDTEXT)に対応するハンドラ探し出し、
呼び出す」
というものなので、定義したハンドラ(memberFxn)が呼び出されます。

この時、WPARAMとLPARAMを、そのメッセージに適した型に
変換してくれます。


返信引用
める
 める
(@める)
ゲスト
結合: 21年前
投稿: 62
Topic starter  

>「メッセージマップ内の ON_NOTIFY* を順番に見ていって、
なるほど。少しわかりました。

長々とお付き合い頂いて感謝しています。
ありがとうございました。m(__)mもっと精進します。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました