Neu: SDI-App: zentriert starten (nicht mehr dialogfeldbasiert)



  • Edit:

    Das Problem bei der dialogfeldbasierten Applikation hat sich erledigt; jetzt ist die Frage, wie das bei einem Doc/View-Programm (SDI) funktioniert (siehe weiter unten...)

    Hallo,

    ich möchte eine dialogbasierte MFC-App beim Start in der Mitte des Bildschirms anzeigen.
    Ich dachte, ich lese aus den Systemmetrics die Auflösung heraus und schiebe das Dialogfenster mit MoveWindow an die passende Stelle.

    Nur: an welcher Stelle soll ich dieses Verschieben einbauen??

    Probiere ich es in der OnInitDialog:

    BOOL CZentriertTestDlg::OnInitDialog()
    {
    	CDialog::OnInitDialog();
    
    	// Hinzufügen des Menübefehls "Info..." zum Systemmenü.
    
    	// IDM_ABOUTBOX muss sich im Bereich der Systembefehle befinden.
    	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
    	ASSERT(IDM_ABOUTBOX < 0xF000);
    
    	CMenu* pSysMenu = GetSystemMenu(FALSE);
    	if (pSysMenu != NULL)
    	{
    		CString strAboutMenu;
    		strAboutMenu.LoadString(IDS_ABOUTBOX);
    		if (!strAboutMenu.IsEmpty())
    		{	
    			pSysMenu->AppendMenu(MF_SEPARATOR);
    			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
    		}
    	}
    
    	// Symbol für dieses Dialogfeld festlegen. Wird automatisch erledigt
    	//  wenn das Hauptfenster der Anwendung kein Dialogfeld ist
    	SetIcon(m_hIcon, TRUE);			// Großes Symbol verwenden
    	SetIcon(m_hIcon, FALSE);		// Kleines Symbol verwenden
    
    	// ZU ERLEDIGEN: Hier zusätzliche Initialisierung einfügen
    
    	// BIS HIERHER: Assistenten-Gruschd, ab hier soll verschoben werden
    	LPRECT lpRect;
    	this->GetWindowRect(lpRect);
    	int Breite = lpRect->right-lpRect->left;
    	int Hoehe = lpRect->top-lpRect->bottom;
    	this->MoveWindow(0,0,Breite,Hoehe);
    
    	return TRUE;  // Geben Sie TRUE zurück, außer ein Steuerelement soll den Fokus erhalten
    }
    

    dann steigt das schon bei this->GetWindowRect(lpRect); aus.
    this hat aber schon einen Wert und ein m_hWnd, somit solte das Fenster an dieser Stelle doch schon existieren, oder?

    Wo liegt hier mein großer Denkfehler???

    Andreas



  • Sachen, die das Dialogfenster betreffen, funktionieren komischerweise in der OnInitDialog nicht.
    Ich kenne das von ShowWindow und habe da einen einfachen Workaround: Mach einen Timer mit Zeit 1, wo du dann die Position setzt und dann den Timer killst. 🙂



  • Danke, so klappts... 🙂 🙂
    (Warum auch immer...)

    Andreas



  • Nur mal ganz hypothetisch (ich hab's bisher noch nicht gebraucht, aber wer weiß...):
    Wo sollte man das in einer Doc/View-Anwendung unterbringen? In der CMainFrame-Klasse? Und in welchem Handler dort? So etwas wie InitDialog oder OnInitialUpdate scheint es ja nicht zu geben. Oder auch am Besten wie hier ber einen Timer? 😕 😕

    Danke,
    Andreas



  • PreCreateWindow ist der Platz. Über den Parameter kannst du so einiges einstellen. 🙂



  • PreCreateWindow also... nie gehört und bisher auch noch nie gebraucht, soweit ich weiß.
    Aber wenn ich das mal brauche, weiß ich jetzt jedenfalls Bescheid 🙂
    (falls nicht, wird mir hier ja jederzeit geholfen 😉 )

    Danke,
    Andreas



  • Das wird automatisch miterstellt und der Kommentar sagt dir schon einiges. 🙂



  • So, jetzt hab ich das doch mal probiert mit der PreCreateWindow:

    BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
    {
    	// TODO: Modify the Window class or styles here by modifying
    	//  the CREATESTRUCT cs
    	cs.style = WS_OVERLAPPED | WS_SYSMENU | WS_BORDER | WS_MINIMIZEBOX ;
    	cs.style &= ~(LONG) FWS_ADDTOTITLE;
    
    	// Zentrieren 
    	int BSBreite = GetSystemMetrics(SM_CXMAXTRACK);
    	int BSHoehe = GetSystemMetrics(SM_CYMAXTRACK);
    
    	// Fenster-Abmessungen ermitteln
    	int Breite = cs.cx;
    	int Hoehe = cs.cy;
    
    	int x1,y1;
    	x1=(BSBreite-Breite)/2;
    	y1=(BSHoehe-Hoehe)/2;
    
        cs.x = x1; 
        cs.y = y1;
    
    	return CFrameWnd::PreCreateWindow(cs);
    }
    

    Aber: Es klappt so nicht 😮

    Ich kann zwar einen Wert für die Position setzen (cs.x, cs.y), der dann auch übernommen wird.

    Aber zum Zentrieren brauche ich auch die Fensterbreite (cs.cx, cs.cy). Und die sind in der Funktion mit 0 initialisiert. Wird die Breite erst irgendwo später errechnet? Und kann ich die an dieser Stelle bereits ermitteln?

    Andreas



  • Schade, das weiß ich auch nicht.
    Bei mir ist die Breite fest vorgegeben, daher kann ich damit auch rechnen.


Anmelden zum Antworten