Click here to Skip to main content
15,889,462 members
Articles / Desktop Programming / MFC
Tip/Trick

Change GUI control position with dialog re-size

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
28 Jun 2012CPOL2 min read 27.4K   6   2
Change GUI control position with dialog re-size

Introduction

I think many of us had faced an issue that GUI controls were missing actual positions while re-sizing. This could be a serious problem while working with products; which are indented to run on different resolutions. This may happened because of two reasons;

  1. Re-sizing of the GUI at runtime
  2. Accidental modifications to the resource file.

We can solve this issue by using relative positions for controls. So normally the next question should be How to implement? I think many of the programmers have their on way to solve this issue. Here I am trying to present my idea. I do not argue that this is the only method, your suggestions are always welcome.  

Using the Code

Below is the figure of my dialog, first image is from resource editor and second one is the expected GUI.  

Image 1

Fig 1: From Resource Editor

Image 2

Fig 2: Expected GUI

For implementing this first of all you need to have a detail specification about your GUI; like its initial position, controls initial and relative position. I implemented the below logic according to my requirement; you can apply your own logic. 

C++
// Main Window Initial X and Y Positions 
const int MAIN_WINDOW_START_X = 100;
const int MAIN_WINDOW_START_Y = 100;

// Main Window Initial Width and Height 
const int MAIN_WINDOW_WIDTH     = 800;
const int MAIN_WINDOW_HEIGHT    = 800;

// Edit control Initial X and Y Positions relative to Main window 
const int EDIT_START_X = 20;
const int EDIT_START_Y = 30;

// Edit control width and height  factor relative to Main window 
const float EDIT_WIDTH_F     = 0.7;
const float EDIT_HEIGHT_F   = 0.8;

// All other controls X Position =  middle position between Edit control and window end
// All other controls Y Position =  Spacd in 50 unit intervels fromEdit control bottom 
// All other controls Width and Height factor relative to distance between Main window and edi// t control.
const float CONTROL_WIDTH_F     = 0.3;
const float CONTROL_HEIGHT_F   = 0.5;
const int CONTROL_INTER   = 50;

Next I am going to add a function to resize my controls according to my specifications 

C++
void CPositionsDlg::ArrangeControls( int cX, int cY )
{
    // Calculating Edit control width and height
    int nEditBoxW =  EDIT_WIDTH_F * cX;
    int nEditBoxH   = EDIT_HEIGHT_F * cY;
    // Setting Edit Control Positions
    ::SetWindowPos(  GetDlgItem( IDC_EDIT1 )->m_hWnd, HWND_TOP ,
                                    EDIT_START_X , EDIT_START_Y, nEditBoxW, nEditBoxH, NULL );

    // Distance between Edit control and Window right
    int nDist =  ( cX - nEditBoxW );
    int nMiddle = nEditBoxW + nDist / 2;

    int nControlWidth =  nDist * CONTROL_WIDTH_F;
    int nControlHeight = nControlWidth * CONTROL_HEIGHT_F;
    int nControlXpos =nMiddle - ( nControlWidth / 2 );
    int nControlYpos =nEditBoxH - ( nControlHeight / 2 );

    // Cancel button
    ::SetWindowPos(  GetDlgItem( IDCANCEL )->m_hWnd, HWND_TOP ,
                                    nControlXpos , nControlYpos, nControlWidth,
                                    nControlHeight, NULL );

    // Ok button
    nControlYpos -= CONTROL_INTER;
   ::SetWindowPos(  GetDlgItem( IDOK )->m_hWnd, HWND_TOP ,
                                    nControlXpos , nControlYpos, nControlWidth,
                                    nControlHeight, NULL );

    // Radio button
    nControlYpos -= CONTROL_INTER;
   ::SetWindowPos(  GetDlgItem( IDC_RADIO1 )->m_hWnd, HWND_TOP ,
                                    nControlXpos , nControlYpos, nControlWidth,
                                    nControlHeight, NULL );

    // Combo Box
    nControlYpos -= CONTROL_INTER;
   ::SetWindowPos(  GetDlgItem( IDC_COMBO1 )->m_hWnd, HWND_TOP ,
                                    nControlXpos , nControlYpos, nControlWidth,
                                    nControlHeight, NULL );

}

The above function and its calculations may be different with different requirements, I have just shown one sample.

The next thing is to set the main window position, the best place for this operations is OnInitDialog() method.

C++
BOOL CPositionsDlg::OnInitDialog()
{
.......................
  // TODO: Add extra initialization here
  SetWindowPos( NULL, 100, 100, 800, 800, NULL );

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

Now we have our control position calculation code and Main window, next we need to place our ArrangeControls() method. The best place is ON_WM_SIZE message handler, you need to do a little bit more to implement this. Because this function should be called during main window creation and our controls were not created at that time. This may cause crash in our application. So we include one checking, IsWindowVisible() to verify if our main window exists or not.

C++
void CPositionsDlg::OnSize(UINT nType, int cx, int cy)
{
    CDialogEx::OnSize(nType, cx, cy);
    if( ::IsWindowVisible( this->m_hWnd )) 
    {
        ArrangeControls( cx, cy);
    }
}

Now it is almost ok but there exists one more issue, i.e our ArrangeControls() is never been called because of the IsWindowVisible() checking. If we try to re-size the GUI, the ArrangeControls() method handle the re-sizing. So for setting controls on proper positions during initialization we need to call ArrangeControls() from ON_WM_SHOWWINDOW message handler.

C++
void CPositionsDlg::OnShowWindow(BOOL bShow, UINT nStatus)
{
    CDialogEx::OnShowWindow(bShow, nStatus);
    ArrangeControls( MAIN_WINDOW_WIDTH, MAIN_WINDOW_HEIGHT );
}

Now everything is ready for our purpose; you can enjoy freedom of resizing. 

History

Version 2

  • June-02-2012: Updated the entire document for including more detail.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
India India
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy 2 suggestions. Pin
SoMad24-Jun-12 16:00
professionalSoMad24-Jun-12 16:00 
GeneralRe: My 2 suggestions. Pin
Binu MD24-Jun-12 23:10
Binu MD24-Jun-12 23:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.