1 名前:デフォルトの名無しさん mailto:sage [2008/04/04(金) 18:37:47 ] Microsoft Foundation Classライブラリ専用スレです。 前スレ ■MFC相談室 mfc18d.dll■ pc11.2ch.net/test/read.cgi/tech/1185917008/
708 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:06:13 ] >>706 処理中ダイアログって考えはなかったわ でも1ハンドラ内に>>691 の記述でモードレス中ダイアログを表示できたっけ?
709 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:07:10 ] >>703 表示/非表示じゃなくダイアログの作成/破棄な CDialog::Create()とCWnd::DestroyWindow() インスタンスの生成/破棄(new/delete)とも別だよ
710 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:20:51 ] >>708 PeekMessageでもはさむんじゃね?
711 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:48:54 ] >>709 事情は変わらんだろ。ダイアログ自身が管理していれば、利用者はそれを意識する必要はない。
712 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:52:27 ] 俺はそもそも モードレスとモーダルをいっしょのクラスで分岐させる無意味な汎用性と Createされてる状況でCreate関数を再び呼ぶ必要を考慮してるクラスの仕様のが 気持ち悪くていまの話題についていけないけどね
713 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 22:56:54 ] いっそのこと新しいC++向けのMS製フレームワークを提供してほしいわ .NETは相性悪すぎる せっかくDirect2DとDirectWriteもC++向けに提供するんだし、アプリケーションハンガリアンでエレガントなクラス群を是非
714 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:01:17 ] >>711 モードレスダイアログのサンプル書いてみてよ
715 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:03:47 ] >>714 CWaitDlg wait; wait.Create(this); // 処理 wait.DestroyWindow();
716 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:14:20 ] >>715 処理中ダイアログじゃなくてOKボタン押すまで表示されてるモードレスダイアログのサンプル書いてみてよ
717 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:15:52 ] >>716 意味がわかんない
718 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:18:19 ] >>716 CWaitDlg wait; wait.Create(this); while(1){ PeekMessage GetMessage TranslateMessage DispatchMessage if(ボタンが押されたら)break; //処理 } wait.DestroyWindow();
719 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:32:06 ] >>718 モードレスのサンプルになってないよ その用途ならモーダル使うのが普通じゃん
720 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:36:43 ] >>719 プログレスバーが表示できるじゃん 質問元が思いっきりそういう意図じゃん 普通だったらモードレスなんてつかわねぇよ 正直いってバグりやすいもん 大部分がこんな感じで済むんだよ
721 名前:706 mailto:sage [2008/11/29(土) 23:49:45 ] >>708 1ハンドラでの処理は考えてなかった。 てか忘れてた。 new/deleteの話いらないって話なんだから、1ハンドラだね。 そういうわけで、>>706 はなかったことに。 (>>710 の通りやればできそうだけど、確認したくないという事情によります) まったく持ってごめん。 反省した。 次は、、次も、、とり頭だからやってしまうかもしれん。
722 名前:デフォルトの名無しさん mailto:sage [2008/11/29(土) 23:58:54 ] >>718 を>>711 のようにするにはどうすればいいの?
723 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:00:13 ] >>722 何がやりたいのか具体的にいいたまへ
724 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:13:23 ] >>716 どっかのクラス { CWaitDlg m_wait; }; どっかのクラス::モーダレス表示するハンドラ() { wait.Create(AfxGetMainWnd()); } これで、親クラスが消滅するかダイアログの「×」ボタン「OK」または 「Cancel」ボタンがクリックされるまで表示されたままになる。 >>719 モードレスだが? >>722 スレッドを起こせばいい。
725 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:15:04 ] >>724 > wait.Create(AfxGetMainWnd()); ... 誤 m_wait.Create(AfxGetMainWnd()); ... 正
726 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:30:19 ] >>723 ダイアログ自身が管理する形で書かれていないので CWaitDlgが管理するようにしたいんだけど
727 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:38:36 ] >>724 m_wait.Create(AfxGetMainWnd());が2回呼ばれたらマズくない? m_wait.DestroyWindow();は必要ないの?
728 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:39:43 ] >>726 何を管理する?ちゃんと日本語で書けよバカSEよ。それとも低級な魔法 使い気取りか?
729 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 00:51:56 ] >>727 > m_wait.Create(AfxGetMainWnd());が2回呼ばれたらマズくない? 概念の説明だけでなく、エラー処理まで手取り足取り見なきゃならん のか? if(m_wait.m_hWnd=NULL) m_wait.Create(AfxGetMainWnd()); とでもしておけばいい。 > m_wait.DestroyWindow();は必要ないの? MFCの場合、明示的に呼ばなくても、m_waitのデストラクタ内で DestroyWindow()が呼び出される仕様。 CFile::Close()等も同様。
730 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 01:12:45 ] >>729 呼ばれなくね? とりあえず俺の環境では Warning: calling DestroyWindow in CDialog::~CDialog -- OnDestroy or PostNcDestroy in derived class will not be called. って警告がでちゃうよ
731 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 01:27:56 ] だよね。質問元の>>684 にもそう書いてあるし
732 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 02:18:51 ] >>730-731 MFCのソースも読めないし、トレースの仕方も知らんと恥を晒している ようだな。 まさに宝の持ち腐れ。 豚に真珠ってヤツだ。 その警告メッセージは、MFC(デバッグ版ライブラリ)が出している。 CDialog::~CDialog() { if (m_hWnd != NULL) { TRACE0("Warning: calling DestroyWindow in CDialog::~CDialog --\n"); TRACE0("\tOnDestroy or PostNcDestroy in derived class will not be called.\n"); DestroyWindow(); // ← ここで呼んでるだろうが、ボケ!!! } } ついでに、英語も理解できないおまえらに、低学歴の漏れが警告メッ セージの意味を解説してやると、 『テメェが忘れてるから、デストラクタ内(CDialog::~CDialog())で ケツ拭きでDestroyWindow()呼んでやるが、今からじゃ手遅れで派生 クラスのOnDestroy()やPostNcDestroy()は呼ばれねぇけど、間違っても Windowsのバグとか、ゲイツ様のせいにすんじゃねぇぞ、ゴルァ!』 ってこった。
733 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 02:49:47 ] そんなことは、皆了解済みの上で話していると思うのだがどうか。 わざわざトレース文が入っているようなお情け処理を、 正式な仕様として扱う勇気は俺には無いな。
734 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 05:34:25 ] >>688 >>716 今までの話を整理したらこうなった void CPropertyDialogSampleView::OnEditProperty() { m_propertyDlg.Show(); } CModelessDialogBase::~CModelessDialogBase() { if (CWnd::GetSafeHwnd() != NULL) CWnd::DestroyWindow(); } void CModelessDialogBase::Show(CWnd* pParentWnd = NULL) { if (CWnd::GetSafeHwnd() == NULL) CDialog::Create(GetTemplateID(), pParentWnd); CWnd::ShowWindow(SW_SHOW); CWnd::BringWindowToTop(); } void CModelessDialogBase::OnOK() { CWnd::ShowWindow(SW_HIDE); } void CModelessDialogBase::OnCancel() { CWnd::ShowWindow(SW_HIDE); }
735 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 07:02:30 ] >>733 でもそこなんでトレースいれるんだろうね 少なくとも俺の感覚としちゃそこでDestroyWindowを呼ぶのは当然の処理で 警告なんて出す意味がわからないんだけど
736 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 07:11:07 ] CreateとDestroyWindowが対だからじゃね? コンストラクタでCreateしないからデストラクタでもDestroyWindowしない方針
737 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 08:00:16 ] >>736 しろよな しない方針にすることでなにかいいことあるのか?って感じ Create関数のヘルプにもそんなこと書いてねーし DestroyWindow関数のヘルプには MFC側で呼んだり呼ばなかったりするからユーザー側でうまくやれよマジで とかかなりむかつく仕様だしで作った奴マジ嫌な感じだな
738 名前:732 mailto:sage [2008/11/30(日) 10:06:48 ] >>733 > そんなことは、皆了解済みの上で話していると思うのだがどうか。 理解したり、(実際に呼ばれていることを)知っていたら『呼ばれなくね?』 なんて発言は、マヂでありえなくね。(w C++の基本を理解し、警告メッセージの意味を正しく理解していれば、 > わざわざトレース文が入っているようなお情け処理を、 > 正式な仕様として扱う勇気は俺には無いな。 なんて発言も出てこないハズ。
739 名前:732 mailto:sage [2008/11/30(日) 10:08:09 ] >>735 CDialogクラスのデストラクタで呼び出しているので、(この時点では 派生クラスのメッセージマップや仮想関数テーブルを参照できない、 もしくは存在自体を知りえないため)派生クラスのOnDestroy()やPost NcDestroy()は呼ばれないだけ。 当然ながら、CDialog::OnDestroy() やCDialog::PostNcDestroy()の呼び出しは行われる。 派生クラスのOnDestroy()やPostNcDestroy()で独自の実装(例:閉じた 時のウィンドウサイズを取得してレジストリやINIファイルに保存する 等)を呼び出していなければ、デストラクタに処理を任せてもなんら 問題ない。 だからこそ「Error:」じゃなく、あくまで「Warning:」ってなってる。 CFileクラスのデストラクタや、CGdiObjectクラス(CPen,CBrush等の基本 クラス)のデストラクタでも同様のことをやっているけど、これらはメッセ ージループを廻す必要がないので、TRACE記述はない。
740 名前:732 mailto:sage [2008/11/30(日) 10:13:43 ] >>736-737 こういう文句を言う連中は、MFCはおろかC++の基本的な仕様(派生クラスと 基本クラスのコンストラクタ/デストラクタが呼び出される順序や、仮想 関数など)さえロクに理解していないんだろうナァ。 方針なんて関係ない。強いて言えばデザインパターンってやつか? コンストラクタでデフォルト値を代入してメンバ変数の初期化忘れを防ぐ とか、デストラクタでメモリやハンドルの解放忘れを防ぐというのは、 基本中の基本。 インスタンスの消滅で確実にウィンドウを破棄し、なおかつ派生クラス のOnDestroy()やPostNcDestroy()も呼び出されるようにしたければ、MFC 内部の実装に関係なく、派生クラスのオブジェクトが消滅するタイミング でDestroyWindow()を呼び出せばいいだけ。 すなわち、自分が作るCDialog派生クラスで、デストラクタ関数を定義し、 m_hWndが有効ならDestroyWindow()を呼び出してやればいい。 class CMyDialog : public CDialog { virtual ~CMyDialog(); }; CMyDialog::~CMyDialog() { if(m_hWnd!=NULL) DestroyWindow(); } ただそれだけのことだ。
741 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 10:14:42 ] >>738 俺とそいつは別人だ ちなみに「よばれてなくね?」は俺 >>739 警告の必要なくね?
742 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 10:18:33 ] >>740 でもヘルプでだってどういうときに DestroyWindowを呼ばなきゃいけないのか書いてないわけだし 当然MFCの中身の都合なんてこっちはしったこっちゃないわけで もし、自分でこういうもんを作るとしたら解放はフレームワークのほうで自動でやってほしいかな?
743 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 11:15:41 ] >>740 のコードがまずいというのもわかりにくいしな
744 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 15:54:00 ] 何この流れ どうせお互いまったく譲り合わないんだから、これ以上書いても無駄だよ
745 名前:デフォルトの名無しさん mailto:sage [2008/11/30(日) 18:51:38 ] Win7ってペイントとかワードパッドにリボン採用してるよな 今後作るソフトはリボンで作った方が惹きやすいのだろうか・・・2008SP1は持ってるが