- MFC相談室 mfc22d.dll
478 :デフォルトの名無しさん[]:2014/06/12(木) 09:18:24.66 ID:GvZA3DBS - MFCのソースはスパゲッティーだと思う人いますか?
ちなみに自分は思います。 シンプルなことを複雑に書いてしまっているので、ちょっとした機能向上 のために自前で何かを追加すると、アクティブ化やDocking, Floating関連、 CFrame,CView,CDocument関連の一部で妙な不具合が出てきます。
|
- MFC相談室 mfc22d.dll
479 :デフォルトの名無しさん[]:2014/06/12(木) 09:26:17.26 ID:GvZA3DBS - Document&View Architecture は、一つの CDocumentを複数のCViewで
表示する事が基本理念なのに、VC++6.0のMFCで用意されている関数は、 CFrame,CView,CDocumentを一括で作成する物だけで、既存の CDocumentを新しいCViewにリンクするような関数は無いようです。 メッセージ・ルーティングも、実装が複雑なせいか、Doc&View Architecute から離れて、単独の CView や CWnd などを持つと、 当たり前のことが当たり前に出来ないような事態になります。
|
- MFC相談室 mfc22d.dll
482 :デフォルトの名無しさん[]:2014/06/12(木) 10:00:12.19 ID:GvZA3DBS - VC++6.0でMFCのMDIアプリのプロジェクトを作成し、直後にビルド。
アプリに作成されたCViewの継承クラスに OnActivateView() の仮想関数を 追加。その中で: MyDebugPrintf( "OnActivateView(), bActv = %d, pAct=%08X, pDeact=%08X, this=%08X\n", bActivate, pActivateView, pDeactiveView, this ); と書く。この関数は、OutpurDebugString()にvspritnf()を使って、 書式付出力機能をつけた物。 デバッグを開始し、アプリのファイルメニューから新規作成を二度行い、 MDI Child Frame を二個作って、アクティブ化のテストを行う。 別アプリをアクティブ化して、このアプリのタイトルバーをクリックす ると、pAct==pDeact==this で上記の仮想関数三回呼び出されてくる。 bActvは、1,0,1 の順。で、三回とも、同じ this の値は同じ。つまり、 pAct==pDeact==this は、計9回同じ値が表示され、bActvだけが1,0,1。 別アプリをアクティブ化して、このアプリの中のMDI子ウィンドウをクリック した場合は、これが、4回となる。
|
- MFC相談室 mfc22d.dll
483 :デフォルトの名無しさん[]:2014/06/12(木) 10:11:18.90 ID:GvZA3DBS - >>481
なるほど。それはすみませんでした。 ちなみに、MSDN Library によれば: pView = new CMyView; pView->Create(NULL, NULL, AFX_WS_DEFAULT_VIEW, rectDefault, this, AFX_IDW_PANE_FIRST + 1, NULL); //pView->SetDlgCtrlID(AFX_IDW_PANE_FIRST); // ??? pView->ShowWindow(SW_SHOW); AddView( pView ); SetActiveView(pViewAdd); RecalcLayout(); とするとのことですが、CViewのCFrameWnd はどうなりますか? 自動作成ですか、自前で用意するのですか? CViewを追加するだけでこのように大量のコードが必要なのですか?
|
- MFC相談室 mfc22d.dll
484 :デフォルトの名無しさん[]:2014/06/12(木) 10:24:14.20 ID:GvZA3DBS - 誤字訂正:
誤:AddView( pView ); 正:pDocument->AddView( pView ); ただ、CDocument::AddView(CView *pView) より、 virtual CFrameWnd *CDocTemplate::CreateNewFrame( CDocument* pDoc, CFrameWnd* pOther ); の方が「まだまし」な関数です。なぜなら、後者は、ちゃんとCFrame を作成してくれるからです。 しかし、これが正しく動作するかは誰にも分かりませんが。
|
- MFC相談室 mfc22d.dll
486 :デフォルトの名無しさん[]:2014/06/12(木) 11:31:25.92 ID:GvZA3DBS - ちなみに、CDocument::AddView(CView *pView) が公開されていることで、
CViewは、どんなCFrameWndに入れても正しく動作するわけではないことは 実験的にはっきりしています。もちろん、一般のCWndに入れたらそれ以上 に駄目です。 MDIの場合、結露から言うと、CViewは、CMainFrm (<-- CMDIFrameWnd) に 入れるか MDI CLIENT WINDOW の子であるところの CMDIChildWnd に入れ ないと正しく動作しません。 それ以外のCFrameWndに入れた場合、メッセージルーティングがおかし くったり、アクティブ化が誤動作します。Docking<--->Floatingでは、 親であるところのCFrameWndの「すげ換え」が置きますが、CControlBar にCViewを入れたりすると、Floating化後に「二重アクティブCView現象」 が発生し、CMainFrmのメニューが(開こうとすると点滅して)開けなく なります。
|
- MFC相談室 mfc22d.dll
487 :デフォルトの名無しさん[]:2014/06/12(木) 11:45:23.41 ID:GvZA3DBS - >>485
釈迦に説法。 自分はIPA認定の天才プログラマを超えている。 その上でかなりMFCの経験をつみ、よく調べた上で書いている。 MFCはスパゲッティーで、ドキュメントに書かれている理念でさえ 満たせていない。ほぼデフォルトの状態でしか使えないと見た方がいい。 変えようとするとさまざまな不具合に遭遇し、MFCのソースを解析、 SPY++でメッセージの調査、テストアプリの製作が必要となり、 最終的にはMFCのソースを大量にコピーして修正する必要が有るか、 または、そうした方が楽。
|
- MFC相談室 mfc22d.dll
490 :デフォルトの名無しさん[]:2014/06/12(木) 12:00:25.93 ID:GvZA3DBS - >>488
実際書いてるし、これからもっと書くつもり。
|
- MFC相談室 mfc22d.dll
491 :デフォルトの名無しさん[]:2014/06/12(木) 12:04:03.31 ID:GvZA3DBS - >>488
「使いこなせない」わけじゃない。普通のプログラマなら、デフォルト 状態に毛の生えた状態でしかしようとしない。 自分の場合は、機能拡張を試みるので、機能拡張が全く出来ないよう ものが困るだけ。
|
- MFC相談室 mfc22d.dll
492 :デフォルトの名無しさん[]:2014/06/12(木) 12:10:17.33 ID:GvZA3DBS - >>486 の誤字訂正:
誤:ちなみに、CDocument::AddView(CView *pView) が公開されていることで、 CViewは、どんなCFrameWndに入れても正しく動作するわけではないことは 正:ちなみに、CDocument::AddView(CView *pView) が公開されているので 勘違いしそうですが、CView を、どんなCFrameWndに入れても正しく 動作するわけではありません。それは、
|
- MFC相談室 mfc22d.dll
493 :デフォルトの名無しさん[]:2014/06/12(木) 12:14:12.78 ID:GvZA3DBS - >>485
その理解もホントは間違い。 なぜなら、オブジェクト指向の理念からすると、公開されている 関数は、どのような使い方をしても正しく動作しなければならない から。 CView *pView を引数に持つ関数を公開するのなら、ありとあらゆる 方法で作成した CView でも絶対的に正常に動作しなければならない。 この理念の理解の仕方が、天才プログラマのオイラとMFCの設計者や あなたとの違いだ。
|
- MFC相談室 mfc22d.dll
494 :デフォルトの名無しさん[]:2014/06/12(木) 12:24:41.32 ID:GvZA3DBS - 公開さらたメンバ関数に、CView *pView を引数に持つ場合、本来、
次のようなことが守られて無ければならない。 ・pView = new CView した pView でも良い。 ・CDocTemplate などから間接的に作成したものでも良い。 ・既にどこかで使われている既存の CView でも良い。 ・CView は、Create() や CreateEx() などでウィンドウオブジェクト を作成する前でも後でも良い。 ・CView は、クラスの集合で公開されている方法を使ってそうなった なら、他のどんな種類のウィンドウの子であっても良い。 もし、一般の CWnd の子に成り得てしまうのなら、その場合でも 正常に動作しなければならない。 ・CView は、どんなスタイルや属性を持ってCreate()やCreateEx() されていても良い。 これが、C++ の基本的な理念。これが一つでも守られていなければ アウト。ただし、CView は、一般の CWnd ではなく、必ず CFrameWnd に入れる、程度の制約は、ドキュメント化されているならセーフ。
|
- MFC相談室 mfc22d.dll
499 :デフォルトの名無しさん[]:2014/06/12(木) 15:26:31.26 ID:GvZA3DBS - 少なくとも、.Net はもっと使いたくないですけどね。
|