ツールバーのフローティングイベント – プログラミング – Home

ツールバーのフローティングイベント
 
通知
すべてクリア

ツールバーのフローティングイベント


Peng
 Peng
(@Peng)
ゲスト
結合: 18年前
投稿: 17
Topic starter  

フローティング可能なツールバーが
「フローティング状態なった」「再びメインフレームにドッキングした」
「フローティング時に×が押された」などのイベントは、
なにかのメッセージでわかるものなのでしょうか?

あるダイアログベースのプロジェクトに
別途フレームウィンドウを表示できるか挑戦しています。

ドキュメント/ビューを使わないSDI形式のアプリケーションを一時的に作成し、
それらのMainFrame/ChildViewをダイアログベースのプロジェクトに移植し、

pMainFrame = new CMainFrame;
pMainFrame->LoadFrame(...);
pMainFrame->ShowWindow(SW_SHOW);
pMainFrame->UpdateWindow();

としてみたところ、一応はフレームウィンドウを表示できたのですが、
フレームウィンドウベースのアプリケーションのように
ツールバーなどのON_UPDATE_COMMAND_UIがうまくコールされなかったり、
フローティング時にフレームウィンドウが自動調整されなかったりと困っています。

MFCのソースを追いかけてみたところ、
このへんの処理はCWinThread::OnIdleをとおして
CFrameWnd::OnIdleUpdateCmdUIでやっているのかなと思ったのですが、
ダイアログベースではCWinThread::OnIdleが発生しないようなのです。
なにかひとつ処理が終わるたびに手動でフレームウィンドウから

SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);
m_wndToolBar.SendMessage(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, 0);

とやればとりあえずは更新されたのですが、
冒頭のようなイベントが発生した際にも
どうやらこれらの処理を入れなければいけないみたいなのです。

それとも、このような「フレームウィンドウをダイアログベースに追加」
するためのお決まりの方法はありますでしょうか。
よろしくお願いいたします。


引用解決済
トピックタグ
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

ダイアログベースのアプリケーションは、モーダルダイアログと
同じメッセージループの処理(CWnd::RunModalLoop)が実行されます
ので、そのような動作になります。

一番簡単な解決方法としては、メインのダイアログを「モードレス」
にしてみてはいかがでしょうか?


返信引用
Peng
 Peng
(@Peng)
ゲスト
結合: 18年前
投稿: 17
Topic starter  

> 一番簡単な解決方法としては、メインのダイアログを「モードレス」
> にしてみてはいかがでしょうか?

やはりそのようになってしまうのでしょうか。
たしかに、SDIプロジェクトに移植してみたところ、
フローティングツールバーなどは正常に表示されました。

将来的には、今回のフレームウィンドウは
今後のいろいろな自作アプリケーションに
プラグイン的に組み込めるようにしたいため、
できれば組み込み先のプロジェクトがダイアログベースでも
フレームウィンドウベースでも、
自前でCFrameWnd::OnIdleUpdateCmdUIをコールできればと思っているのですが…。


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

いや、ダイアログベースのままでも構わないので、「ダイアログを
モードレスにしてみれば?」と言っているのです。

BOOL CXXXApp::InitInstance()
{
// ..略..

CHogeDlg* dlg = new CHogeDlg;
m_pMainWnd = dlg;
dlg->Create(CXXXDlg::IDD);
dlg->ShowWindow(SW_SHOW);
dlg->UpdateWindow();

return TRUE;
}

void CHogeDlg::PostNcDestroy()
{
delete this;
}

これだけだと、フレームウィンドウにWM_IDLEUPDATECMDUIメッセージが
流れるかどうかはわかりませんが、少なくともOnIdleは呼ばれるでしょう。


返信引用
Kerry
 Kerry
(@Kerry)
ゲスト
結合: 20年前
投稿: 192
 

もしくは、ダイアログをモードレスにしたくない、ということであれば、
モーダルダイアログの場合は、アイドル時にWM_KICKIDLEメッセージが
送られるので、それをハンドルするのが良いかもしれません。

#include <afxpriv.h>

BEGIN_MESSAGE_MAP(CHogeDlg, CDialog)
ON_MESSAGE(WM_KICKIDLE, OnKickIdle)
END_MESSAGE_MAP()

LRESULT CHogeDlg::OnKickIdle(WPARAM wParam, LPARAM lParam)
{
// TODO:
return 0L;
}


返信引用
Peng
 Peng
(@Peng)
ゲスト
結合: 18年前
投稿: 17
Topic starter  

CWinThread::OnIdleをとおしてCFrameWnd::OnIdleUpdateCmdUIが
コールされているようなので、
ひょっとしたらフレームウィンドウ側を別スレッドにしてしまえば、
モーダルダイアログから作成されても独自のメッセージループが回って、
アドレスなどもそのまま共有できるのかなとも思ったのですが、
よくわかりませんでした…。

やはり、このフレームウィンドウを使いたい側がダイアログベースだったら、
自分をモードレス化したりOnKickIdleを使うなりして、
フレームウィンドウ側にアイドル状態を教えてやらなければいけないのですね。

ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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