CMDIFrameWndExの仕様なのでしょうか? – プログラミング – Home

CMDIFrameWndExの仕様なの...
 
通知
すべてクリア

[解決済] CMDIFrameWndExの仕様なのでしょうか?

固定ページ 1 / 3

hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

VisualStudio2008にてMDIアプリケーションを作成して、ビューを開き最大化にした状態
でビューを閉じるとMDI枠のヘッコミ?クライアントエッジ的な表示がなくなるんです。
最大化させないで閉じるとなくならない。
これはCMDIFrameWndExを使うときは仕方ないのでしょうか?
CMDIFrameWndExを使わないとこの症状は起きません
何か回避策があれば、お手数ですが教えていただけませんか?
ちなみに2010でも同じ症状がでるんです…


引用未解決
トピックタグ
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

自分しては「バグ」の判定ですね。
Spy++で見ればすぐにわかりますが、その操作をするとMDIClient
の WS_EX_CLIENTEDGE スタイルが外れてしまいます(笑)。
以後、復活することはありません。はっきりいってまぬけです。
自分でコードすれば WS_EX_CLIENTEDGE スタイルを付け直すことも
できますが、面倒なのでやってません。

直接は関係ありませんが、メニューバーのメニューのショートカットキー
の表示(ex. ファイル(F))の(F)の部分のアンダースコアも表示されませんよね
(しくしく)。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

もとい。アンダーラインですねorz。


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

バグですか…
CMDIFrameWndExのm_hWndMDIClientをサブクラス化できないのも、やっぱりバグなんでし
ょうかね、ちょっとがっかりですね
それともやり方が悪いんでしょうかね


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

CMFCCaptionBarの画像を割り当てないと(SetBitmap)しないとXボタンがなくなっちゃう
のもバグっぽいですね
RecalcLayoutをオーバーライドしてコチョコチョしないと具合悪いですね
Visual2010で改善されなかったぽいですし, 改善されないということは仕様ということ
ですかね

あ、解決ということで、ありがとうございます


返信引用
えーと
 えーと
(@えーと)
ゲスト
結合: 19年前
投稿: 54
 

RecalcLayout()を操作する必要はありません。
バグって言えばバグですよね。

原因は
CMDIChildWnd::UpdateClientEdge()です。
子MDIが閉じる時にこの関数が呼ばれますが、この関数は子MDI
が最大化する場合に、WS_EX_CLIENTEDGEを外し、それ以外では
付けます。

ただし、閉じる時には対応できていないので外れた状態のままになります。

このことから、最大化を外してあげれば解決します。

# 子MDIが複数ある場合+最大化の場合はその必要はありません。

子MDI(CMDIChildWnd(Ex))のWM_CLOSEを処理し、以下のようにすれば解決します。
必要であれば、WS_EX_CLIENTEDGEが付いていない時の条件も加えても良いと思います。

void CHogeChildFrame::OnClose()
{
CMDIFrameWnd* pFrameWnd = dynamic_cast<CMDIFrameWnd *>( AfxGetMainWnd() );
ASSERT_VALID(pFrameWnd);
if( (GetStyle() & WS_MAXIMIZE) &&
( ::GetWindow( ::GetWindow( pFrameWnd->m_hWndMDIClient, GW_CHILD ),
GW_HWNDNEXT ) == NULL )){
ModifyStyle( WS_MAXIMIZE | WS_VISIBLE, 0, 0 );
}
__super::OnClose();
}

参考まで


返信引用
えーと
 えーと
(@えーと)
ゲスト
結合: 19年前
投稿: 54
 

追記。

> 仲澤@失業者さん

>自分でコードすれば WS_EX_CLIENTEDGE スタイルを付け直すことも
>できますが、面倒なのでやってません。
この処理を閉じる時にModifyStyleEx()で付けてあげても、
結局CMDIChildWnd::UpdateClientEdge()が呼ばれて外されてしまいます。(T.T)


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

本件について、あまり真剣に考えるつもりはないのですが、
まぁ、暇つぶしにやってみると。

まず、適当なタイミングのメッセージがわからなかったので、
メインフレームのWM_PAINTのコードに下記のコード

BOOL res =::EnumChildWindows( m_hWndMDIClient, EnumFunc, ( LPARAM)0);
if( res == FALSE){
LONG_PTR Style =::GetWindowLongPtr( m_hWndMDIClient, GWL_EXSTYLE);
if( 0 ==( Style & WS_EX_CLIENTEDGE)){
CRect rc;
GetClientRect( &rc);
Style |= WS_EX_CLIENTEDGE;
::SetWindowLongPtr( m_hWndMDIClient, GWL_EXSTYLE, Style);
::SetWindowPos( m_hWndMDIClient, NULL, 0, 0, rc.Width(), rc.Height(),
SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE);
::RedrawWindow( m_hWndMDIClient, NULL, NULL,
RDW_ERASE | RDW_FRAME | RDW_UPDATENOW);
}
}
をつっこんでやると、なんとかなりますよね(vv;)。
まぁ、正確なタイミングがわかったら、自分も対応したいとおもいます。


返信引用
仲澤@失業者
(@uncle_kei)
Prominent Member
結合: 5年前
投稿: 828
 

ちなみにEnumのコールバックは
BOOL CALLBACK EnumFunc(
HWND hwnd, LPARAM lParam)
{return FALSE;}
でよしっと。


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

色々考えてくださってありがとうございます
えっと,少々強引ですが CMainFrame(:CMDIFrameWndEx)の中で
GetWindowLongにて現在のExスタイルを取得してWS_EX_CLIENTEDGEとのアンドが0
ならばModifyStyleExで足すという処理をOnTimer内でポーリング的に実行させたのです
がダメでした
m_wndClientArea(:CMDIClientAreaWnd)という子がCMDIFrameWnd内のm_hWndMDIClientを
サブクラス(SubclassWindow)していて,この子が悪さをしているっぽいです
m_wndClientAreaをサブクラスかすれば何とかなりそうですけど,m_hWndMDIClientをサブ
クラス化しているm_wndClientAreaをサブクラス化させる方法は知りません,というかそ
んな方法はないのでは?
ダミーでドッカブルペインをクリエイトさせて追加させて,そして常に非表示とすると
OKなんですが…


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

仲澤@失業者さんの方法だと確かにできますね
TimerでできないのはWM_PAINT時に毎回WS_EX_CLIENTEDGEをはずしにきているんですか
ね?
やな感じですね
xxxEx系の新しいクラスはおかしなとこいっぱいですね


返信引用
hirocco
 hirocco
(@hirocco)
ゲスト
結合: 14年前
投稿: 138
Topic starter  

ごめんなさいウソでしたTimerでもできます
スタイル変更後,SetWindowPos忘れてました...


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

バグや改善提案についてはぜひこちらにフィードバックしてください。

https://connect.microsoft.com/VisualStudioJapan/Feedback

> メニューバーのメニューのショートカットキーの表示(ex. ファイル(F))の(F)の部分
> のアンダースコアも表示されませんよね(しくしく)。

それは最近の Windows の共通仕様では? OS は何でしょうか。


返信引用
えーと
 えーと
(@えーと)
ゲスト
結合: 19年前
投稿: 54
 

aetosさん

>> メニューバーのメニューのショートカットキーの表示(ex. ファイル(F))の(F)の部分
>> のアンダースコアも表示されませんよね(しくしく)。

>それは最近の Windows の共通仕様では? OS は何でしょうか。

http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+201007/10070007.txt
これのことです。


返信引用
aetos
(@aetos)
Noble Member
結合: 5年前
投稿: 1480
 

> これのことです。

MFC のソースまでは追いかけていませんが、Windows Server 2008 R2 x64 + VS2010
Ultimate で試したところ、メニューを縦にしても下線は表示されませんでした。

また、同環境にて、本題である

> MDI枠のヘッコミ?クライアントエッジ的な表示がなくなるんです。

の方も再現できません。


返信引用
固定ページ 1 / 3

返信する

投稿者名

投稿者メールアドレス

タイトル *

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