sizers and a menu bar

Daniel C. Bastos dbast0s at yahoo.com.br
Sun Jun 17 13:49:20 PDT 2007


In article <my0EfD.A.iUQ.SXZdGB at brage.sunsite.dk>,
Vadim Zeitlin wrote:

> On Sun, 17 Jun 2007 12:43:48 -0400 "Daniel C. Bastos" <dbast0s at yahoo.com.br> wrote:
> 
> DCB> I built a chess board, and I wanted the window (the main frame) to have
> DCB> the same dimensions as the board. The board is painted on a panel. The
> DCB> panel constructor sets the dimensions. When I run the application, I can
> DCB> see that the frame did get the size of the panel; and, as I wanted, you
> DCB> cannot resize the frame to something less than the size of the
> DCB> panel. However, if I add a menu bar, then the initial frame size is a
> DCB> little less than the panel size. Now ``little less'' seems to be exactly
> DCB> the height of the menu bar.
> ...
> DCB> Frame::Frame(wxFrame *fr, const wxChar* title)
> DCB>   : wxFrame(fr, wxID_ANY, title)
> DCB> {
> DCB>   // define size of pieces, and board dimensions
> DCB>   pxSquare = 44; nWid = nHei = 8; 
> DCB> 
> DCB>   // define pen width for board painting
> DCB>   penWidth = 1;
> DCB> 
> DCB>   // create the panel
> DCB>   pan = new Panel(this, 0, 0, szSquare() * dimWid(), szSquare() * dimHei());
> DCB> 
> DCB>   #if USE_STATUS_BAR
> DCB>   CreateStatusBar(1); SetStatusText(wxT("Pinky is ready."));
> DCB>   #endif
> DCB> 
> DCB>   // let's put a sizer on this frame and attach the panel to it
> DCB>   wxBoxSizer* topSizer = new wxBoxSizer(wxVERTICAL);
> DCB>   
> DCB>   // take the exact size of the panel
> DCB>   topSizer->Add(pan, 0, 0, 0);
> DCB> 
> DCB>   // attach this sizer to the frame
> DCB>   SetSizer(topSizer);
> DCB> 
> DCB>   // fit the frame to the panel
> DCB>   topSizer->Fit(this);
> DCB> 
> DCB>   // dont get smaller than the panel
> DCB>   topSizer->SetSizeHints(this);
> DCB> }
> 
>  I don't see where is the menu created here but I suspect that you do it
> after SetSizeHints() call. You need to create all non-client controls
> (menus, tool and status bars) before calling SetSizeHints() which calls
> wxWindow::SetClientSize() -- if you add a menu afterwards, the client size
> will be reduced by the menu height as the total window size will never be
> changed unless you do it explicitly.

You suspect right. I was creating the menu in OnInit() which
instantiated the Frame before the menu. I got it to work
now. Thanks a lot, Vadim. 

But I only made it on my second attempt. I first tried creating the menu
right after the status bar, but actually I need to create the panel
after both of them. I'm not sure why the order matters in this
case. Just to make things clear, I'll show exactly what I tried.

I tried:

Frame::Frame(wxFrame *fr, const wxChar* title)
  : wxFrame(fr, wxID_ANY, title)
{
  // size of a square; dimentions of the board
  pxSquare = 44; nWid = nHei = 8; 

  // the width of a pen to paint borders of squares
  penWidth = 1;

  // create the panel
  pan = new Panel(this, 0, 0, szSquare() * dimWid(), szSquare() * dimHei());

  #if USE_STATUS_BAR
  CreateStatusBar(1); SetStatusText(wxT("Pinky is ready."));
  #endif

  #if USE_MENU
  wxMenu *filemenu = new wxMenu;
  wxMenu *helpmenu = new wxMenu;
  helpmenu->Append(wxID_ABOUT, wxT("&About...\tF1"), 
                   wxT("Show about dialog"));

  filemenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"), 
                   wxT("End this program"));

  wxMenuBar *menubar = new wxMenuBar();
  menubar->Append(filemenu, wxT("&File"));
  menubar->Append(helpmenu, wxT("&Help"));
  SetMenuBar(menubar);
  #endif

  // let's put a sizer on this frame and attach the panel to it
  wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL);
  
  // take the exact size of the panel
  sizerPanel->Add(pan, 1, 0, 0); 

  // attach this sizer to the frame
  SetSizer(sizerPanel);

  // fit the frame to the panel
  sizerPanel->Fit(this); 

  // dont get smaller than the panel
  sizerPanel->SetSizeHints(this);
}

This doesn't work. The panel doesn't get the right size. Then I tried:

Frame::Frame(wxFrame *fr, const wxChar* title)
  : wxFrame(fr, wxID_ANY, title)
{
  // size of a square; dimentions of the board
  pxSquare = 44; nWid = nHei = 8; 

  // the width of a pen to paint borders of squares
  penWidth = 1;

  #if USE_STATUS_BAR
  CreateStatusBar(1); SetStatusText(wxT("Pinky is ready."));
  #endif

  #if USE_MENU
  wxMenu *filemenu = new wxMenu;
  wxMenu *helpmenu = new wxMenu;
  helpmenu->Append(wxID_ABOUT, wxT("&About...\tF1"), 
                   wxT("Show about dialog"));

  filemenu->Append(wxID_EXIT, wxT("E&xit\tAlt-X"), 
                   wxT("End this program"));

  wxMenuBar *menubar = new wxMenuBar();
  menubar->Append(filemenu, wxT("&File"));
  menubar->Append(helpmenu, wxT("&Help"));
  SetMenuBar(menubar);
  #endif

  // create the panel
  pan = new Panel(this, 0, 0, szSquare() * dimWid(), szSquare() * dimHei());

  // let's put a sizer on this frame and attach the panel to it
  wxBoxSizer* sizerPanel = new wxBoxSizer(wxVERTICAL);
  
  // take the exact size of the panel
  sizerPanel->Add(pan, 1, 0, 0); 

  // attach this sizer to the frame
  SetSizer(sizerPanel);

  // fit the frame to the panel
  sizerPanel->Fit(this); 

  // dont get smaller than the panel
  sizerPanel->SetSizeHints(this);
}

This works.






More information about the wx-users mailing list