Create children initially hidden

Volker Bartheld dr_versaeg at freenet.de
Mon Apr 2 03:13:25 PDT 2007


Hi Vadim!

> VB> > TL> a) Is it possible to create children initially hidden? 
> VB> >         MyWindow *win = new MyWindow; // default ctor! 
> VB> >         win->Hide(); 
> VB> >         win->Create(parent, id, ...);
> VB> One of my wxDialog-based classes does quite a lot of rendering/resizing
> VB> etc. in it's nondefault c'tor that shouldn't be shown to the user. So the
> VB> two-step creation is probably no option.

> You can perfectly well implement the ctor of your class using
> default ctor of the base class + call to Create() with an intervening call
> to Hide().

Probably, I still didn't get it. Here's the shortes version of my code
that reproduces the problem (for wxidleonceevthandler.cpp/h see below):

#include <wx/wx.h>
#include "wxidleonceevthandler.h"
class MyDialog : public wxDialog
{
public:
  MyDialog(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMINIMIZE_BOX, const wxString& name=wxT("dialogBox")) { Create(parent, id, title, pos, size, style, name); }
  ~MyDialog() { delete m_idleonce; }
  bool Create(wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos=wxDefaultPosition, const wxSize& size=wxDefaultSize, long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxMINIMIZE_BOX, const wxString& name=wxT("dialogBox"))
  {
    Hide();
    bool b=wxDialog::Create(NULL, wxID_ANY, title, pos);
    SetIcon(wxICON(tiny));
    SetSizer(new wxBoxSizer(wxVERTICAL));
    GetSizer()->Add(new wxButton(this, wxID_OK, _("&OK")), 0, wxALL, 5);
    GetSizer()->SetSizeHints(this);
    m_idleonce=new wxIdleOnceEvtHandler(this);
    return b;
  }
  void OnClose(wxCloseEvent &event)   { if(IsModal()) EndModal(0); else Destroy(); }
  void OnIdleOnce(wxIdleEvent&)
  {
    wxSleep(1); // MyDialog shown for one second - why? Should be hidden...
    Iconize();
  }
private:
  wxIdleOnceEvtHandler* m_idleonce;
  DECLARE_EVENT_TABLE()
};
BEGIN_EVENT_TABLE(MyDialog, wxDialog)
EVT_IDLE_ONCE(MyDialog::OnIdleOnce)
END_EVENT_TABLE()
class MyApp : public wxApp
{
public: 
  virtual bool OnInit()
  {
    if(!wxApp::OnInit()) return false;
    MyDialog TheDialog(NULL, wxID_ANY, _T("Test Dialog"));
    TheDialog.ShowModal();
    return false;
  }
};  
IMPLEMENT_APP(MyApp)

What happens is, that the dialog still flashes up for a short time
(between MyDialog::Create() and MyDialog::OnIdleOnce()) probably because of
the (mandatory?) call to wxDialog::Create(). Even though I *DID* a Hide()
prior to that. Then, it's minimized into the taskbar OK.

So it more or less boils down to one question: How can I create a modal
dialog, that starts minimized in the taskbar _without_ initially popping
up to the screen for a short time. I wasn't able to solve that and I'm not
sure how your advice helps me there.

I assume, you don't suggest calling the special c'tor of my class, there
calling the default c'tor of the base class and then calling Create() of
my class, entirely leaving out a call to Create() of the base class when
you're saying:

> You can perfectly well implement the ctor of your class using
> default ctor of the base class + call to Create() with an intervening call
> to Hide().

do you?

Sorry to bother you again.

Volker



<wxidleonceevthandler.h>
#ifndef WXIDLEONCEEVTHANDLER_INCLUDED
#define WXIDLEONCEEVTHANDLER_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <wx/window.h>
#include <wx/event.h>

#define EVT_IDLE_ONCE(func) wx__DECLARE_EVT0(wxEVT_IDLE_ONCE, wxIdleEventHandler(func))
extern wxEventType wxEVT_IDLE_ONCE;
class wxIdleOnceEvtHandler : public wxEvtHandler
{
public:
  wxIdleOnceEvtHandler::wxIdleOnceEvtHandler(wxEvtHandler* target);
  void wxIdleOnceEvtHandler::Stop(void);
  wxIdleOnceEvtHandler::~wxIdleOnceEvtHandler();
  bool wxIdleOnceEvtHandler::ProcessEvent(wxEvent& event);
private:
  wxEvtHandler* m_target;
};
#endif // #ifndef WXIDLEONCEEVTHANDLER_INCLUDED
</wxidleonceevthandler.h>

<wxidleonceevthandler.cpp>
#include <wx/window.h>
#include <wx/event.h>
#include "wxidleonceevthandler.h"

wxEventType wxEVT_IDLE_ONCE=wxNewEventType();
wxIdleOnceEvtHandler::wxIdleOnceEvtHandler(wxEvtHandler* target) : m_target(target), wxEvtHandler()
{
  if(wxIS_KIND_OF(m_target, wxWindow) && GetEvtHandlerEnabled()) ((wxWindow*)m_target)->PushEventHandler(this);   // push event handler into parent's list
}
void wxIdleOnceEvtHandler::Stop(void)
{
  if(wxIS_KIND_OF(m_target, wxWindow) && GetEvtHandlerEnabled()) ((wxWindow*)m_target)->RemoveEventHandler(this); // remove handler from parent's list
  SetEvtHandlerEnabled(false);
} // void wxIdleOnceEvtHandler::Stop(void)
wxIdleOnceEvtHandler::~wxIdleOnceEvtHandler() { Stop(); }
bool wxIdleOnceEvtHandler::ProcessEvent(wxEvent& event)                                 // event handle "hook"
{
  if(wxEVT_IDLE==event.GetEventType() && GetEvtHandlerEnabled())                        // is it the wxEVT_IDLE and it arrived for the first time (event handler still enabled)?
  {
    Stop();                                                                             // stop the handler
    wxEvent* temp=event.Clone();                                                        // duplicate the event
    temp->SetEventType(wxEVT_IDLE_ONCE);                                                // set correct event type
    wxPostEvent(m_target, *temp);                                                       // and reinsert it into parent's queue
    delete temp;
  } // if(wxEVT_IDLE==event.GetEventType() && GetEvtHandlerEnabled())
  return wxEvtHandler::ProcessEvent(event);
} // bool wxIdleOnceEvtHandler::ProcessEvent(wxEvent& event)
</wxidleonceevthandler.cpp>

-- 
mailto:  V B A R T H E L D at G M X dot D E






More information about the wx-users mailing list