Tengo que crear un diálogo basado en la aplicación, en lugar de los antiguos CFormView tipo de diseño. Pero CDialog produce fija el tamaño de los cuadros de diálogo. ¿Cómo puedo crear un diálogo basado en aplicaciones con tamaño variable de los diálogos?

  • La pregunta no tiene nada que ver con C++. Por lo tanto, he quitado la etiqueta.
  • Tal vez tire una Win32 etiqueta en esto, el archivo RC cosas es básico Win32 y ni siquiera MFC específicos.
  • El RC cosas no pueden ser MFC-específico, pero el título especifica MFC, CDialog (especificado en la pregunta) es una clase MFC (véase el MSVS ayuda), y algunas buenas respuestas requieren una considerable interacción con métodos MFC – así que era lo correcto al dejar que estar de pie. Como en C++, MSVS genera código C++ para MFC, pero lo hace para cualquier otro idioma? Si no, [C++] no era del todo irrelevante—, pero redundante, por lo que justo dos.
  • Derecho a dejar que lo soporte, el MFC etiqueta? He sugerido (modo posible de años, ¿por qué incluso metiendo en esto ahora?) la adición de una win32/winapi etiqueta, no para quitar el MFC etiqueta.
  • Sí, el derecho a dejar la etiqueta de soporte. Me respondió porque no tuvo «ni siquiera MFC específicos» para referirse a la totalidad de la pregunta. No creo que la edad de los comentarios de los asuntos. Mi comentario era para nadie pensando acerca de la pregunta+comentarios+etiquetas a medida para usted, espero que no se han puesto de salida.
InformationsquelleAutor | 2008-09-26

7 Comentarios

  1. 22

    En la RC archivo de recursos si el diálogo tiene este estilo similar a este que va a ser de tamaño fijo:

    IDD_DIALOG_DIALOG DIALOGEX 0, 0, 320, 201
    STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU

    Si el diálogo tiene este estilo va a ser considerable:

    IDD_DIALOG_DIALOG DIALOGEX 0, 0, 320, 201
    STYLE WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME

    Con estos considerable opciones de marco de la ventana para volver considerable, pero todavía tendrá que hacer un montón de trabajo en el manejo de la WM_SIZE mensaje para gestionar el tamaño de un posicionamiento de los controles en el cuadro de diálogo.

    • Yo no recomienda editar .rc archivos directamente, mientras que el formato parece sencillo suficiente el analizador es muy quisquillosos. Además, ya que usted está utilizando MFC, es seguro asumir que usted también está usando Visual Studio. En el que caso de que usted simplemente debe abrir el cuadro de diálogo de recursos en Visual Studio, y bajo el cuadro de diálogo propiedades de elegir «cambiar de tamaño» para la «Frontera» de la propiedad.
  2. 22

    Además de establecer el estilo de WS_THICKFRAME, es probable que usted también desea tener un sistema para mover y cambiar el tamaño de los controles de un cuadro de diálogo como el cuadro de diálogo cambia de tamaño. Para mi propio uso personal, he creado una clase base para reemplazar CDialog que tiene esta capacidad. Se derivan de esta clase y en su InitDialog llamada a la función de la AutoMove función para cada niño de control para definir cuánto se debe mover y cuánto se debe cambiar el tamaño con relación a la matriz de diálogo. El tamaño del cuadro de diálogo en el archivo de recursos se utiliza como un tamaño mínimo.

    BaseDialog.h:

    #if !defined(AFX_BASEDIALOG_H__DF4DE489_4474_4759_A14E_EB3FF0CDFBDA__INCLUDED_)
    #define AFX_BASEDIALOG_H__DF4DE489_4474_4759_A14E_EB3FF0CDFBDA__INCLUDED_
    
    #if _MSC_VER > 1000
    #pragma once
    #endif //_MSC_VER > 1000
    
    #include <vector>
    
    class CBaseDialog : public CDialog
    {
    //Construction
    public:
        CBaseDialog(UINT nIDTemplate, CWnd* pParent = NULL);   //standard constructor
    
        void AutoMove(int iID, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct);
    
    //Overrides
        //ClassWizard generated virtual function overrides
        //{{AFX_VIRTUAL(CBaseDialog)
    protected:
        //}}AFX_VIRTUAL
    
    protected:
        //{{AFX_MSG(CBaseDialog)
        virtual BOOL OnInitDialog();
        afx_msg void OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI);
        afx_msg void OnSize(UINT nType, int cx, int cy);
        //}}AFX_MSG
        DECLARE_MESSAGE_MAP()
    
    public:
        bool            m_bShowGripper;         //ignored if not WS_THICKFRAME
    
    private:
        struct SMovingChild
        {
            HWND        m_hWnd;
            double      m_dXMoveFrac;
            double      m_dYMoveFrac;
            double      m_dXSizeFrac;
            double      m_dYSizeFrac;
            CRect       m_rcInitial;
        };
        typedef std::vector<SMovingChild>   MovingChildren;
    
        MovingChildren  m_MovingChildren;
        CSize           m_szInitial;
        CSize           m_szMinimum;
        HWND            m_hGripper;
    };
    
    //{{AFX_INSERT_LOCATION}}
    //Microsoft Visual C++ will insert additional declarations immediately before the previous line.
    
    #endif //!defined(AFX_BASEDIALOG_H__DF4DE489_4474_4759_A14E_EB3FF0CDFBDA__INCLUDED_)

    BaseDialog.cpp:

    #include "stdafx.h"
    #include "BaseDialog.h"
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
    #endif
    CBaseDialog::CBaseDialog(UINT nIDTemplate, CWnd* pParent /*=NULL*/)
    : CDialog(nIDTemplate, pParent),
    m_bShowGripper(true),
    m_szMinimum(0, 0),
    m_hGripper(NULL)
    {
    }
    BEGIN_MESSAGE_MAP(CBaseDialog, CDialog)
    //{{AFX_MSG_MAP(CBaseDialog)
    ON_WM_GETMINMAXINFO()
    ON_WM_SIZE()
    //}}AFX_MSG_MAP
    END_MESSAGE_MAP()
    void CBaseDialog::AutoMove(int iID, double dXMovePct, double dYMovePct, double dXSizePct, double dYSizePct)
    {
    ASSERT((dXMovePct + dXSizePct) <= 100.0);   //can't use more than 100% of the resize for the child
    ASSERT((dYMovePct + dYSizePct) <= 100.0);   //can't use more than 100% of the resize for the child
    SMovingChild s;
    GetDlgItem(iID, &s.m_hWnd);
    ASSERT(s.m_hWnd != NULL);
    s.m_dXMoveFrac = dXMovePct / 100.0;
    s.m_dYMoveFrac = dYMovePct / 100.0;
    s.m_dXSizeFrac = dXSizePct / 100.0;
    s.m_dYSizeFrac = dYSizePct / 100.0;
    ::GetWindowRect(s.m_hWnd, &s.m_rcInitial);
    ScreenToClient(s.m_rcInitial);
    m_MovingChildren.push_back(s);
    }
    BOOL CBaseDialog::OnInitDialog()
    {
    CDialog::OnInitDialog();
    //use the initial dialog size as the default minimum
    if ((m_szMinimum.cx == 0) && (m_szMinimum.cy == 0))
    {
    CRect rcWindow;
    GetWindowRect(rcWindow);
    m_szMinimum = rcWindow.Size();
    }
    //keep the initial size of the client area as a baseline for moving/sizing controls
    CRect rcClient;
    GetClientRect(rcClient);
    m_szInitial = rcClient.Size();
    //create a gripper in the bottom-right corner
    if (m_bShowGripper && ((GetStyle() & WS_THICKFRAME) != 0))
    {
    SMovingChild s;
    s.m_rcInitial.SetRect(-GetSystemMetrics(SM_CXVSCROLL), -GetSystemMetrics(SM_CYHSCROLL), 0, 0);
    s.m_rcInitial.OffsetRect(rcClient.BottomRight());
    m_hGripper = CreateWindow(_T("Scrollbar"), _T("size"), WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP,
    s.m_rcInitial.left, s.m_rcInitial.top, s.m_rcInitial.Width(), s.m_rcInitial.Height(),
    m_hWnd, NULL, AfxGetInstanceHandle(), NULL);
    ASSERT(m_hGripper != NULL);
    if (m_hGripper != NULL)
    {
    s.m_hWnd = m_hGripper;
    s.m_dXMoveFrac = 1.0;
    s.m_dYMoveFrac = 1.0;
    s.m_dXSizeFrac = 0.0;
    s.m_dYSizeFrac = 0.0;
    m_MovingChildren.push_back(s);
    //put the gripper first in the z-order so it paints first and doesn't obscure other controls
    ::SetWindowPos(m_hGripper, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_SHOWWINDOW);
    }
    }
    return TRUE;  //return TRUE  unless you set the focus to a control
    }
    void CBaseDialog::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI) 
    {
    CDialog::OnGetMinMaxInfo(lpMMI);
    if (lpMMI->ptMinTrackSize.x < m_szMinimum.cx)
    lpMMI->ptMinTrackSize.x = m_szMinimum.cx;
    if (lpMMI->ptMinTrackSize.y < m_szMinimum.cy)
    lpMMI->ptMinTrackSize.y = m_szMinimum.cy;
    }
    void CBaseDialog::OnSize(UINT nType, int cx, int cy) 
    {
    CDialog::OnSize(nType, cx, cy);
    int iXDelta = cx - m_szInitial.cx;
    int iYDelta = cy - m_szInitial.cy;
    HDWP hDefer = NULL;
    for (MovingChildren::iterator p = m_MovingChildren.begin();  p != m_MovingChildren.end();  ++p)
    {
    if (p->m_hWnd != NULL)
    {
    CRect rcNew(p->m_rcInitial);
    rcNew.OffsetRect(int(iXDelta * p->m_dXMoveFrac), int(iYDelta * p->m_dYMoveFrac));
    rcNew.right += int(iXDelta * p->m_dXSizeFrac);
    rcNew.bottom += int(iYDelta * p->m_dYSizeFrac);
    if (hDefer == NULL)
    hDefer = BeginDeferWindowPos(m_MovingChildren.size());
    UINT uFlags = SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER;
    if ((p->m_dXSizeFrac != 0.0) || (p->m_dYSizeFrac != 0.0))
    uFlags |= SWP_NOCOPYBITS;
    DeferWindowPos(hDefer, p->m_hWnd, NULL, rcNew.left, rcNew.top, rcNew.Width(), rcNew.Height(), uFlags);
    }
    }
    if (hDefer != NULL)
    EndDeferWindowPos(hDefer);
    if (m_hGripper != NULL)
    ::ShowWindow(m_hGripper, (nType == SIZE_MAXIMIZED) ? SW_HIDE : SW_SHOW);
    }
  3. 4

    Si el uso de una plantilla de cuadro de diálogo, a continuación, abra el cuadro de diálogo plantilla en el editor de recursos y establecer los Estilo propiedad Emergente y la Frontera propiedad cambio de tamaño de. Estoy bastante seguro de que esto va a hacer lo mismo jussij dijo y establecer el WS_POPUP y WS_THICKFRAME estilos. Para establecer estos dinámicamente, a continuación, reemplace la función PreCreateWindow y agregue el siguiente:

    cs.style |= WS_POPUP | WS_THICKFRAME;
    • flounder.com/getminmaxinfo.htm tiene un ejemplo visual de cambio de la Frontera mediante el cuadro de diálogo Propiedades (en el comienzo de la página).
  4. 2

    Desde Visual Studio 2015, puede utilizar MFC Dinámica de Diálogo Diseño, pero parece que no hay manera de restringir el cuadro de diálogo tamaño al tamaño mínimo (todavía sólo el viejo camino por manejo de WM_GETMINMAXINFO).

    Diseño dinámico se puede hacer:

    • en tiempo de diseño en el editor de recursos por seleccionar el control y ajuste de la Movimiento Tipo y Tamaño Tipo propiedades (este emite nueva AFX_DIALOG_LAYOUT de sección .archivo rc);
    • o mediante programación utilizando el CMFCDynamicLayout clase.

    Documentación: Diseño Dinámico

  5. 0

    He probado muchos MFC diseño de bibliotecas y este es uno de los mejores: http://www.codeproject.com/KB/dialog/layoutmgr.aspx. Echa un vistazo a los comentarios, no para algunas correcciones de errores y mejoras (descargo de responsabilidad: algunos de ellos por mí 😉 ). Al usar esta biblioteca, al establecer el correcto cambiar el tamaño de las banderas en tu ventana, serán tratados para usted.

  6. 0

    Tengo algunas blog de instrucciones sobre cómo crear un muy minimalista re-considerable en el cuadro de diálogo en el MFC.

    Se trata básicamente de una aplicación de Paulo Messina publicación en CodeProject
    pero con tanto extrañas cosas eliminado como sea posible, para ayudar a clarificar cómo hacerlo mejor.

    Es bastante sencillo de implementar una vez que has tenido un poco de práctica: el importante bits son:

    yo. asegúrese de tener su CodeProject bibliotecas, etc tirado en el proyecto y todo se compila correctamente.

    ii. hacer la inicialización adicionales dentro de la OnInitDialog método: hacer la pinza visible, establezca el número máximo de dilog tamaño, añadir puntos de ancla en el cuadro de diálogo de control de los artículos que usted desea para ‘estirar’ etc.

    iii. Reemplazar el uso de CDialog con CResizableDialog en los puntos correspondientes: en el cuadro de diálogo definición de clase, constructor, DoDataExchange, BEGIN_MESSAGE_MAP, OnInitDialog etc.

Dejar respuesta

Please enter your comment!
Please enter your name here