Mehrere Fragen zu MDI
-
1, Es zeigt einen Designfehler auf, dass Du überhaupt aus dem View in den Frame hineingreifen willst. Was steht dort was Du benötigst.
2. Dein View kennt CMainFRame nicht weil Du den Header, in dem CMainFrame deklariert wird nicht included hat.
-
Ok, an das mit dem Header includen hab ich noch gar nicht gedacht !
Ich habe in meiner Toolbar 3 Buttons, und wenn im Childframe auf ein Button geklickt wird, dann soll abhängig vom geklickten Button in der Toolbar die 3 Buttons enabled, disabled werden.
Habe dazu On_Update_Command_UIs im View, nur springt von den dreien nur der erste an, ich will aber, dass alle 3 anspringen und darin dann den jeweiligen Button in der Toolbar disablen oder enablen.
So sieht das bei mir aus:
Die 3 HandlerON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDStart) ON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDPause) ON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDStop) ... void C...View::OnUpdateIDStart(CCmdUI *pCmdUI) { pCmdUI->Enable(showIDStart); } void C...View::OnUpdateIDPause(CCmdUI *pCmdUI) { pCmdUI->Enable(showIDPause); } void C...View::OnUpdateIDStop(CCmdUI *pCmdUI) { pCmdUI->Enable(showIDStop); }Die Variablen jeweils sind BOOL, werden wenn ein bestimmter Button geklickt wird, auf TRUE oder FALSE gesetzt, nur springt immer nur der erste Handler (OnUpdateIDStart) an, habe das durch setzen eines Breakpoints gemerkt.
Kann man überhaupt mehrere Buttons gleichzeitig in der Toolbar disablen ??
Habe sonst grad keine weitere Idee...
-
Und was glaubst Du soll das System machen wenn Du das hier machst:
ON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDStart) ON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDPause) ON_UPDATE_COMMAND_UI(ID_START, OnUpdateIDStop)DWIM willst Du?
Das System soll selbst wissen, wenn der Button ID_START heißt, dass Du beim ertsen, den ersten ID_START Button meinst, beim zweiten, den zweiten und beim dritten den dritten...
Am Besten hör auf zu Programmieren... Die Systeme sind noch nicht reif für das was Du denkst <duck&wech>
-
Oh, ok *schäm*
Man kann sagen, dass ich das total übersehen habe. Copy & Paste eben...
Natürlich erstmal vielen Dank für die Hilfe, aber
Martin Richter schrieb:
Am Besten hör auf zu Programmieren... Die Systeme sind noch nicht reif für das was Du denkst <duck&wech>
was soll das wieder heißen ?
-
Ich hab da gleich mal noch ne Frage.

Und zwar zum Thema neues Childframe erstellen:
Habe in der App-Klasse folgenden CodeCMultiDocTemplate* pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_...TYPE, RUNTIME_CLASS(C...Doc), RUNTIME_CLASS(CChildFrame), // Benutzerspezifischer MDI-Child-Rahmen RUNTIME_CLASS(C...View)); if (!pDocTemplate) return FALSE; AddDocTemplate(pDocTemplate); return TRUE;einfach in eine Funktion ausgelagert, rufe die natürlich am Anfang auf, ich will ja ein Childwindow am Anfang haben und ich rufe die Funktion später wieder auf, wenn ich die brauche.
Meine Frage: Erstellt es mir dadurch ein leeres Fenster oder eins, was genau wie das Erste, also wie in den Ressourcen definiert, ist ??Das würde mich mal noch interessieren...
-
Ich erwecke den Thread hier nochmal.

Ich will, wenn bestimmte Bedingungen zutreffen, in meiner App-Klasse eine Funktion aufrufen, die dann ein neues Childframe erzeugt, dass eben genauso aussieht wie das jetzige, also dasselbe Doc verwendet.
Mein Problem ist, ich weiß nicht, wie diese Funktion aussehen soll, so ist sie bis jetzt bei mir:
BOOL C...App::CreateFrame(C...Doc *pDoc) { CMultiDocTemplate *pDocTemplate; pDocTemplate = new CMultiDocTemplate(IDR_...TYPE, RUNTIME_CLASS(C...Doc), RUNTIME_CLASS(CChildFrame), // Benutzerspezifischer MDI-Child-Rahmen RUNTIME_CLASS(C...View)); if (!pDocTemplate) return false; AddDocTemplate(pDocTemplate); CFrameWnd *pFrame; pFrame = pDocTemplate->CreateNewFrame(pDoc, NULL); // hier gibts ne Assert... pFrame->InitialUpdateFrame(pDoc, TRUE); return true; }Und ich rufe die Funktion in meiner Doc-Klasse über theApp.CreateNewFrame(this) auf, die Pointer sind alle gültig, das steht mal fest.
/ should be a normal window ASSERT(::IsWindow(m_hWnd)); // should also be in the permanent or temporary handle map CHandleMap* pMap = afxMapHWND(); ASSERT(pMap != NULL); // hier bleibt er stehen CObject* p=NULL;Trotzdem gibts die Assert !
Oder kann man das über ID_FILE_NEW irgendwie realisieren ??
Verstehe das nicht...
-
Hab dazu jetzt nen anderen Ansatz, ich rufe, wenn ich es brauche, diese Funktion in der App-Klasse aus der Doc-Klasse:
if (!AppStart) { if (AfxMessageBox("Dadurch werden die selben Daten in ein neues Logfile geschrieben.\r\nFortsetzen ?", MB_OKCANCEL | MB_ICONEXCLAMATION | MB_DEFBUTTON1, 0) == IDOK) { CWinApp::OnFileNew(); return; } else return; } else { CWinApp::OnFileNew(); AppStart = false; }AppStart wird im Ctor der App-Klasse auf true gesetzt und dann ja auf false. Ich will diese Funktion später wieder aufrufen, nur knallt es dann bei mir bei CWinApp::OnFileNew().
Der CallStack:> mfc80d.dll!AfxAssertValidObject(const CObject * pOb=0x00000000, const char * lpszFileName=0x5aad7178, int nLine=499) Line 78 C++ mfc80d.dll!CMDIChildWnd::Create(const char * lpszClassName=0x0020d128, const char * lpszWindowName=0x01aebf28, unsigned long dwStyle=1087340544, const tagRECT & rect={...}, ... mfc80d.dll!CMDIChildWnd::LoadFrame(unsigned int nIDResource=129, unsigned long dwDefaultStyle=1087340544, CWnd * pParentWnd=0x00000000, CCreateContext * pContext=0x02c2fa08) Line 618 + 0x3b bytes C++ mfc80d.dll!CDocTemplate::CreateNewFrame(CDocument * pDoc=0x01aed7a0, CFrameWnd * pOther=0x00000000) Line 277 + 0x22 bytes C++ mfc80d.dll!CMultiDocTemplate::OpenDocumentFile(const char * lpszPathName=0x00000000, int bMakeVisible=1) Line 121 + 0x13 bytes C++ mfc80d.dll!CDocManager::OnFileNew() Line 848 C++ mfc80d.dll!CWinApp::OnFileNew() Line 22 C++ ....exe!C...App::OnNew() Line 196 + 0x8 bytesUnd dann bleibt er da stehen:
if (pOb == NULL) { TRACE(traceAppMsg, 0, "ASSERT_VALID fails with NULL pointer.\n"); if (AfxAssertFailedLine(lpszFileName, nLine)) AfxDebugBreak(); // hier steht er dann... return; // quick escape }Kann mir jemand was dazu sagen ??
-
Du hast keinen gültigen CWinApp Zeiger!
Wie rufst Du die Methode den auf?
Spezielle Deine Methode....exe!C...App::OnNew() Line 196 + 0x8 byteshier ist relevant.
-
Ach so, ok.
Ich rufe die über theApp.OnNew() auf, also über das App-Objekt !
EDIT:
überC...App* pApp = dynamic_cast<C...App*>(AfxGetApp()); ASSERT(pApp); pApp->OnNew();Passiert das Gleiche !
EDIT2:
Hängt es vielleicht damit zusammen, dass ich diese Funktion aus meiner Doc-Klasse aus aufrufe ??
-
Habe es immer noch nicht, weiß nicht, wie ich einen gültigen CWinApp-Pointer kriegen kann.
Über den direkten Aufruf kriegt man ja "cannot access protected member..." als Compiler-Error !
-
Ich mach hier nochmal ein push !
Habs immer noch nicht hinbekommen, hier schon im Forum ohne Ende gesucht, gegoogelt, aber bis jetzt hat keine Lösung funktioniert !
Hat da noch jemand nen Vorschlag, hab langsam die Schn**** voll, verstehe es nicht !
Nochmal ein Danke von mir.

-
Ich will, wenn bestimmte Bedingungen zutreffen, in meiner App-Klasse eine Funktion aufrufen, die dann ein neues Childframe erzeugt, dass eben genauso aussieht wie das jetzige, also dasselbe Doc verwendet.
Wirklich das bestehende CDocument? Wenn ja, kannst du lediglich eine neue View innerhalb des Childframe erzeugen. Suche hierzu in der Hilfe nach "AddView()".
Wenn Du aber für alle "Ereignisse" einen neuen ChildFrame anlegen willst, dann musst Du die Aktion im Mainframe abfangen, und ein komplett neues Document/View Paar innerhalb des Mainframe erzeugen (das ist dann ein MDI).
Gruß, Gio
-
Ich hab es soeben hingekriegt, mache das (vllt nicht ganz sauber) per Postmessage aus meiner Doc an MainFrame und gebe dort als WParam ID_FILE_NEW an und Message ist WM_COMMAND.
So funktioniert es wie es soll !
Aber trotzdem danke für deine Hilfe !!
