Resize moving Window?



  • Hallo alle zusammen,
    ich habe follgendes Problem.

    Ich habe einen CDialog dessen Größe ich im Verlauf des Programmdurchlaufes verändere möchte. (Modaler Dialog)

    Das Problem tritt auf, wenn ich in dem Moment noch einen Drag auf den Dialog habe.
    D.h. wenn der Benutzer den Dialog zieht (verschiebt).

    Nach dem resize des Dialoges ist alles in Ordnung, biss ich die Linke maustaste wider
    los lasse, oder den Dialog weiter ziehe (verschiebe). Der Dialog bekommt dann seine Ausgangsgröße.

    Was habe ich alles versucht:
    Ich habe ReleasCaption() ausgeführt vor dem resize. Das hat zur Folge, dass
    ich den drag des Fensters verliere.

    Na gut (habe ich mir gedacht), dann setze ich die Caption wieder (SetCapture). Siehe da, der Dialog ist wider im Dragmodus. Lasse ich in diesem Moment die linke Maustaste los, bleibt der Dialog in seiner neuen Größe. Bewege ich jedoch die Maus habe ich wider die Ausgangsgröße.

    Hat vielleicht jemand von euch eine Idee.

    Ich hatte mir z.B. überlegt den Style des Fenster zu ändern, dass kein resizen möglich ist.



  • hast du OnSize oder aehnliche mit eigenen code ueberladen ? wenn ja zeig mal



  • Hir ist der Code meines Testprogramms mit dem ich das Problem nachgestellt habe.

    Ich habe eine Lösung gefunden. (die mir nicht gefällt) Der Schlüssel ist
    OnWindowPosChanging(WINDOWPOS* lpwndpos).

    An dieser Stelle kann ich die Fenster Size manipulieren.
    Das Manko ist dabei
    Man muss selber differenzieren ob ich im WindowDrag-Modus bin
    (mit hilfe von OnEnterSizeMove & OnExitSizeMove)
    Man muss die Größe des Fensters speichern (WINDOWPOS eignet sich gut dazu)
    Man muss differenzeiren ob man selber die Fenstergröße endert oder ob das
    User Interface (die Maus) das Fenster Verschiebt.
    Man muss die Fensterpositionierung so Anpassen, dass die Maus auch noch auf
    dem Titel des Fensters sitzt(und am besten in der mitte)

    Das Tolle ist nämlich. Ich ändere die Größe des Fensters und MS-WIN
    ruft beim Ziehen mit der Maus OnWindowPosChanging auf, aber mit
    WINDOWPOS welches noch die alten Größenangaben besitzt.

    CTestDlgDlg::CTestDlgDlg(CWnd* pParent /=NULL/)
    : CDialog(CTestDlgDlg::IDD, pParent)
    {
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    }

    void CTestDlgDlg::DoDataExchange(CDataExchange* pDX)
    {
    CDialog::DoDataExchange(pDX);
    }

    BEGIN_MESSAGE_MAP(CTestDlgDlg, CDialog)
    ON_WM_SYSCOMMAND()
    ON_WM_PAINT()
    ON_WM_QUERYDRAGICON()
    ON_WM_WINDOWPOSCHANGING()
    ON_MESSAGE( WM_ENTERSIZEMOVE, OnEnterSizeMove)
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()

    // CTestDlgDlg message handlers

    BOOL CTestDlgDlg::OnInitDialog()
    {
    CDialog::OnInitDialog();

    // Add "About..." menu item to system menu.

    // IDM_ABOUTBOX must be in the system command range.
    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);
    }
    }

    // Set the icon for this dialog. The framework does this automatically
    // when the application's main window is not a dialog
    SetIcon(m_hIcon, TRUE); // Set big icon
    SetIcon(m_hIcon, FALSE); // Set small icon

    // TODO: Add extra initialization here

    return TRUE; // return TRUE unless you set the focus to a control
    }

    void CTestDlgDlg::OnSysCommand(UINT nID, LPARAM lParam)
    {
    if ((nID & 0xFFF0) == IDM_ABOUTBOX)
    {
    CAboutDlg dlgAbout;
    dlgAbout.DoModal();
    }
    else
    {
    CDialog::OnSysCommand(nID, lParam);
    }
    }

    // If you add a minimize button to your dialog, you will need the code below
    // to draw the icon. For MFC applications using the document/view model,
    // this is automatically done for you by the framework.

    void CTestDlgDlg::OnPaint()
    {
    if (IsIconic())
    {
    CPaintDC dc(this); // device context for painting

    SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

    // Center icon in client rectangle
    int cxIcon = GetSystemMetrics(SM_CXICON);
    int cyIcon = GetSystemMetrics(SM_CYICON);
    CRect rect;
    GetClientRect(&rect);
    int x = (rect.Width() - cxIcon + 1) / 2;
    int y = (rect.Height() - cyIcon + 1) / 2;

    // Draw the icon
    dc.DrawIcon(x, y, m_hIcon);
    }
    else
    {
    CDialog::OnPaint();
    }
    }

    // The system calls this function to obtain the cursor to display while the user drags
    // the minimized window.
    HCURSOR CTestDlgDlg::OnQueryDragIcon()
    {
    return static_cast<HCURSOR>(m_hIcon);
    }

    LRESULT CTestDlgDlg::OnEnterSizeMove( WPARAM wparam, LPARAM lparam)
    {
    SetWindowPos(NULL, 100, 100, 50, 50, SWP_NOZORDER );

    return (LRESULT)0;
    }


  • Mod

    Könntest Du vielleicht einfach mal erklären was passieren soll?
    Ich werdeaus dem Sinn dieses Stückes Code in keiner Weise schlau.
    Warum sollte sich beim Verschieben die Größe eines Fensters ändern?
    Und warum setzt Du das Fenster sofort in diesem Moment auf die Koordinaten 0,0?

    Wäre die Behandlung über WM_MOVING/WM_SIZEING nicht korrekter.

    Aber ohne zu wissen was Du willst ist das Stochern im Nebel!



  • Den Quellcode den du oben siehst ist ein neues MFC Projekt in das ich
    den Fehlerfall nachgestellt habe. Ich weis das es in diesem Kontext nicht
    sinnvoll ist, aber irgendwie muss ich den Fehler nachstellen. Somit kann jemand der mir Helfen will, das Problem leicht nachvollziehen indem er ein MFC Projekt anlegt und meine Änderungen übernimmt.

    Noch mahl um das Problem zu verdeutlichen.
    Wenn ich die Maus nehme und anfange das Fenster zu ziehen und just in diesem
    Moment wird die Fenstergröße verändert, dann bekommt die WindowsRoutine (die für das verschieben des realen Fensters verantwortlich ist ) nicht mit, dass sich die WINDOWSINFO geändert hat. D.h. Die WindowsRoutine führt OnWindowPosChanging mit den altern Größenparametern aus.

    Was ich erreichen wollte, ist das der Benutzer das Fenster verschiebt und dieses einfach nur dabei resized werden kann, ohne den Drag auf das Fenster oder die neue Größe zu verlieren, Damit der Benutzer das vergrößerte Fenster an der gleichen Stelle an der er das Fenster gepackt hat weiter schieben kann.

    Ich habe das Problem gelöst. Wie schon Erläutert mit OnWindowPosChanging nur, dass man noch eine Differenz mit einberechnen muss, denn die Stelle an der das Fenster gezogen wird ist nicht immer gleich der Position des Mouscursors.


Anmelden zum Antworten