#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
#ifndef WX_PRECOMP
-#include "wx/setup.h"
-#include "wx/frame.h"
-#include "wx/menu.h"
-#include "wx/app.h"
-#include "wx/utils.h"
-#include "wx/dialog.h"
-#include "wx/settings.h"
-#include "wx/dcclient.h"
-#endif
+ #include "wx/setup.h"
+ #include "wx/frame.h"
+ #include "wx/menu.h"
+ #include "wx/app.h"
+ #include "wx/utils.h"
+ #include "wx/dialog.h"
+ #include "wx/settings.h"
+ #include "wx/dcclient.h"
+#endif // WX_PRECOMP
#include "wx/msw/private.h"
#include "wx/statusbr.h"
+#include "wx/toolbar.h"
#include "wx/menuitem.h"
#ifdef LoadAccelerators
#undef LoadAccelerators
#endif
-#if USE_NATIVE_STATUSBAR
-#include <wx/msw/statbr95.h>
+#if wxUSE_NATIVE_STATUSBAR
+ #include <wx/msw/statbr95.h>
#endif
extern wxList wxModelessWindows;
-extern wxList wxPendingDelete;
+extern wxList WXDLLEXPORT wxPendingDelete;
extern char wxFrameClassName[];
+extern wxMenu *wxCurrentPopupMenu;
#if !USE_SHARED_LIBRARY
BEGIN_EVENT_TABLE(wxFrame, wxWindow)
IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
#endif
-#if USE_NATIVE_STATUSBAR
-bool wxFrame::m_useNativeStatusBar = TRUE;
+#if wxUSE_NATIVE_STATUSBAR
+ bool wxFrame::m_useNativeStatusBar = TRUE;
#else
-bool wxFrame::m_useNativeStatusBar = FALSE;
+ bool wxFrame::m_useNativeStatusBar = FALSE;
#endif
-wxFrame::wxFrame(void)
+wxFrame::wxFrame()
{
+ m_frameToolBar = NULL ;
m_frameMenuBar = NULL;
m_frameStatusBar = NULL;
long style,
const wxString& name)
{
+#if wxUSE_TOOLTIPS
+ m_hwndToolTip = 0;
+#endif
+
if (!parent)
wxTopLevelWindows.Append(this);
// m_modalShowing = FALSE;
m_windowStyle = style;
m_frameMenuBar = NULL;
+ m_frameToolBar = NULL ;
m_frameStatusBar = NULL;
SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
int height = size.y;
m_iconized = FALSE;
- MSWCreate(m_windowId, (wxWindow *)parent, wxFrameClassName, this, (char *)(const char *)title,
- x, y, width, height, style);
+
+ // we pass NULL as parent to MSWCreate because frames with parents behave
+ // very strangely under Win95 shell
+ MSWCreate(m_windowId, NULL, wxFrameClassName, this, title,
+ x, y, width, height, style);
wxModelessWindows.Append(this);
return TRUE;
}
-wxFrame::~wxFrame(void)
+wxFrame::~wxFrame()
{
m_isBeingDeleted = TRUE;
wxTopLevelWindows.DeleteObject(this);
::BringWindowToTop((HWND) GetParent()->GetHWND());
}
-WXHMENU wxFrame::GetWinMenu(void) const
+WXHMENU wxFrame::GetWinMenu() const
{
return m_hMenu;
}
-// Get size *available for subwindows* i.e. excluding menu bar etc.
-// For XView, this is the same as GetSize
+// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
void wxFrame::GetClientSize(int *x, int *y) const
{
RECT rect;
- GetClientRect((HWND) GetHWND(), &rect);
+ ::GetClientRect((HWND) GetHWND(), &rect);
- if ( m_frameStatusBar )
+ if ( GetStatusBar() )
{
- int statusX, statusY;
- m_frameStatusBar->GetClientSize(&statusX, &statusY);
- rect.bottom -= statusY;
+ int statusX, statusY;
+ GetStatusBar()->GetClientSize(&statusX, &statusY);
+ rect.bottom -= statusY;
}
+
+ wxPoint pt(GetClientAreaOrigin());
+ rect.bottom -= pt.y;
+ rect.right -= pt.x;
+
*x = rect.right;
*y = rect.bottom;
}
// Set the client size (i.e. leave the calculation of borders etc.
// to wxWindows)
-void wxFrame::SetClientSize(int width, int height)
+void wxFrame::DoSetClientSize(int width, int height)
{
HWND hWnd = (HWND) GetHWND();
RECT rect;
- GetClientRect(hWnd, &rect);
+ ::GetClientRect(hWnd, &rect);
RECT rect2;
GetWindowRect(hWnd, &rect2);
int actual_width = rect2.right - rect2.left - rect.right + width;
int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
- if ( m_frameStatusBar )
+ if ( GetStatusBar() )
{
- int statusX, statusY;
- m_frameStatusBar->GetClientSize(&statusX, &statusY);
- actual_height += statusY;
+ int statusX, statusY;
+ GetStatusBar()->GetClientSize(&statusX, &statusY);
+ actual_height += statusY;
}
+ wxPoint pt(GetClientAreaOrigin());
+ actual_width += pt.y;
+ actual_height += pt.x;
+
POINT point;
point.x = rect2.left;
point.y = rect2.top;
*y = point.y;
}
-void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags)
+void wxFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags)
{
int currentX, currentY;
int x1 = x;
m_iconized = FALSE;
}
-bool wxFrame::IsIconized(void) const
+bool wxFrame::IsIconized() const
{
((wxFrame *)this)->m_iconized = (::IsIconic((HWND) GetHWND()) != 0);
return m_iconized;
}
+// Is it maximized?
+bool wxFrame::IsMaximized() const
+{
+ return (::IsZoomed((HWND) GetHWND()) != 0) ;
+}
+
void wxFrame::SetTitle(const wxString& title)
{
SetWindowText((HWND) GetHWND(), (const char *)title);
}
-wxString wxFrame::GetTitle(void) const
+wxString wxFrame::GetTitle() const
{
GetWindowText((HWND) GetHWND(), wxBuffer, 1000);
return wxString(wxBuffer);
#endif
}
-wxStatusBar *wxFrame::OnCreateStatusBar(int number)
+wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id,
+ const wxString& name)
{
wxStatusBar *statusBar = NULL;
-#if USE_NATIVE_STATUSBAR
+#if wxUSE_NATIVE_STATUSBAR
if (UsesNativeStatusBar())
{
- statusBar = new wxStatusBar95(this);
+ statusBar = new wxStatusBar95(this, id, style);
}
else
#endif
{
- statusBar = new wxStatusBar(this, -1, wxPoint(0, 0), wxSize(100, 20));
+ statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20),
+ style, name);
// Set the height according to the font and the border size
wxClientDC dc(statusBar);
- dc.SetFont(* statusBar->GetFont());
+ dc.SetFont(statusBar->GetFont());
long x, y;
dc.GetTextExtent("X", &x, &y);
return statusBar;
}
-bool wxFrame::CreateStatusBar(int number)
+wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id,
+ const wxString& name)
{
// VZ: calling CreateStatusBar twice is an error - why anyone would do it?
wxCHECK_MSG( m_frameStatusBar == NULL, FALSE,
"recreating status bar in wxFrame" );
- m_frameStatusBar = OnCreateStatusBar(number);
+ m_frameStatusBar = OnCreateStatusBar(number, style, id,
+ name);
if ( m_frameStatusBar )
{
PositionStatusBar();
- return TRUE;
+ return m_frameStatusBar;
}
else
- return FALSE;
+ return NULL;
}
void wxFrame::SetStatusText(const wxString& text, int number)
m_frameStatusBar->SetStatusText(text, number);
}
-void wxFrame::SetStatusWidths(int n, int *widths_field)
+void wxFrame::SetStatusWidths(int n, const int widths_field[])
{
wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" );
PositionStatusBar();
}
-void wxFrame::PositionStatusBar(void)
+void wxFrame::PositionStatusBar()
{
// native status bar positions itself
if (m_frameStatusBar
-#if USE_NATIVE_STATUSBAR
+#if wxUSE_NATIVE_STATUSBAR
&& !m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95))
#endif
)
GetClientSize(&w, &h);
int sw, sh;
m_frameStatusBar->GetSize(&sw, &sh);
+
+ // Since we wish the status bar to be directly under the client area,
+ // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
m_frameStatusBar->SetSize(0, h, w, sh);
}
}
menu_bar->m_menuBarFrame = this;
}
+#if 0
bool wxFrame::LoadAccelerators(const wxString& table)
{
m_acceleratorTable = (WXHANDLE)
return (m_acceleratorTable != (WXHANDLE) NULL);
}
+#endif
-void wxFrame::Fit(void)
+void wxFrame::Fit()
{
// Work out max. size
- wxNode *node = GetChildren()->First();
+ wxNode *node = GetChildren().First();
int max_width = 0;
int max_height = 0;
while (node)
{
wxSysColourChangedEvent event2;
event2.SetEventObject( m_frameStatusBar );
- m_frameStatusBar->ProcessEvent(event2);
+ m_frameStatusBar->GetEventHandler()->ProcessEvent(event2);
}
// Propagate the event to the non-top-level children
// Keep this in wxFrame because it saves recoding this function
// in wxTinyFrame
-#if USE_ITSY_BITSY
+#if wxUSE_ITSY_BITSY
if (style & wxTINY_CAPTION_VERT)
msflags |= IBS_VERTCAPTION;
if (style & wxTINY_CAPTION_HORIZ)
WXDWORD extendedStyle = MakeExtendedStyle(style);
+#if !defined(__WIN16__) && !defined(__SC__)
+ if (style & wxFRAME_TOOL_WINDOW)
+ extendedStyle |= WS_EX_TOOLWINDOW;
+#endif
+
if (style & wxSTAY_ON_TOP)
extendedStyle |= WS_EX_TOPMOST;
::PostMessage((HWND) GetHWND(), WM_SIZE, SIZE_RESTORED, MAKELPARAM(width, height));
}
-bool wxFrame::MSWOnPaint(void)
+bool wxFrame::MSWOnPaint()
{
-#if DEBUG > 1
- wxDebugMsg("wxFrameWnd::OnPaint %d\n", handle);
-#endif
RECT rect;
if (GetUpdateRect((HWND) GetHWND(), &rect, FALSE))
{
if (m_iconized)
{
HICON the_icon;
- if (m_icon.Ok())
- the_icon = (HICON) m_icon.GetHICON();
- if (the_icon == 0)
+ if (m_icon.Ok())
+ the_icon = (HICON) m_icon.GetHICON();
+ else
the_icon = (HICON) m_defaultIcon;
PAINTSTRUCT ps;
HDC cdc = BeginPaint((HWND) GetHWND(), &ps);
// Erase background before painting or we get white background
- this->MSWDefWindowProc(WM_ICONERASEBKGND,(WORD)ps.hdc,0L);
+ this->MSWDefWindowProc(WM_ICONERASEBKGND,(WORD)(LONG) ps.hdc,0L);
if (the_icon)
{
RECT rect;
- GetClientRect((HWND) GetHWND(), &rect);
+ ::GetClientRect((HWND) GetHWND(), &rect);
int icon_width = 32;
int icon_height = 32;
int icon_x = (int)((rect.right - icon_width)/2);
return 1;
}
-WXHICON wxFrame::MSWOnQueryDragIcon(void)
+WXHICON wxFrame::MSWOnQueryDragIcon()
{
if (m_icon.Ok() && (m_icon.GetHICON() != 0))
return m_icon.GetHICON();
void wxFrame::MSWOnSize(int x, int y, WXUINT id)
{
-#if DEBUG > 1
- wxDebugMsg("wxFrameWnd::OnSize %d\n", m_hWnd);
-#endif
switch (id)
{
- case SIZEFULLSCREEN:
case SIZENORMAL:
+ // only do it it if we were iconized before, otherwise resizing the
+ // parent frame has a curious side effect of bringing it under it's
+ // children
+ if ( !m_iconized )
+ break;
+
+ // restore all child frames too
+ IconizeChildFrames(FALSE);
+
+ // fall through
+
+ case SIZEFULLSCREEN:
m_iconized = FALSE;
- break;
+ break;
+
case SIZEICONIC:
+ // iconize all child frames too
+ IconizeChildFrames(TRUE);
+
m_iconized = TRUE;
- break;
+ break;
}
if (!m_iconized)
{
// forward WM_SIZE to status bar control
-#if USE_NATIVE_STATUSBAR
+#if wxUSE_NATIVE_STATUSBAR
if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
{
wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
#endif
PositionStatusBar();
+ PositionToolBar();
+
wxSizeEvent event(wxSize(x, y), m_windowId);
event.SetEventObject( this );
if (!GetEventHandler()->ProcessEvent(event))
}
}
-bool wxFrame::MSWOnClose(void)
+bool wxFrame::MSWOnClose()
{
-#if DEBUG > 1
- wxDebugMsg("wxFrameWnd::OnClose %d\n", handle);
-#endif
return Close();
}
bool wxFrame::MSWOnCommand(WXWORD id, WXWORD cmd, WXHWND control)
{
-#if DEBUG > 1
- wxDebugMsg("wxFrameWnd::OnCommand %d\n", handle);
-#endif
if (cmd == 0 || cmd == 1 ) // Can be either a menu command or an accelerator.
{
// In case it's e.g. a toolbar.
if (win)
return win->MSWCommand(cmd, id);
+ if (wxCurrentPopupMenu)
+ {
+ wxMenu *popupMenu = wxCurrentPopupMenu;
+ wxCurrentPopupMenu = NULL;
+ if (popupMenu->MSWCommand(cmd, id))
+ return TRUE;
+ }
+
if (GetMenuBar() && GetMenuBar()->FindItemForId(id))
{
ProcessCommand(id);
bool wxFrame::MSWProcessMessage(WXMSG* pMsg)
{
- if (m_acceleratorTable != 0 &&
- ::TranslateAccelerator((HWND) GetHWND(), (HANDLE) m_acceleratorTable, (MSG *)pMsg))
+ return FALSE;
+}
+
+bool wxFrame::MSWTranslateMessage(WXMSG* pMsg)
+{
+ if (m_acceleratorTable.Ok() &&
+ ::TranslateAccelerator((HWND) GetHWND(), (HACCEL) m_acceleratorTable.GetHACCEL(), (MSG *)pMsg))
return TRUE;
return FALSE;
// resize to client rectangle size
void wxFrame::OnSize(wxSizeEvent& event)
{
- // Search for a child which is a subwindow, not another frame.
+ // if we're using constraints - do use them
+ #if wxUSE_CONSTRAINTS
+ if ( GetAutoLayout() ) {
+ Layout();
+ return;
+ }
+ #endif
+
+ // do we have _exactly_ one child?
wxWindow *child = NULL;
- // Count the number of _subwindow_ children
- int noChildren = 0;
- for(wxNode *node = GetChildren()->First(); node; node = node->Next())
+ for ( wxNode *node = GetChildren().First(); node; node = node->Next() )
{
wxWindow *win = (wxWindow *)node->Data();
- if (!win->IsKindOf(CLASSINFO(wxFrame)) && !win->IsKindOf(CLASSINFO(wxDialog))
- && (win != GetStatusBar()))
+ if ( !win->IsKindOf(CLASSINFO(wxFrame)) &&
+ !win->IsKindOf(CLASSINFO(wxDialog)) &&
+ (win != GetStatusBar()) &&
+ (win != GetToolBar()) )
{
+ if ( child )
+ return; // it's our second subwindow - nothing to do
child = win;
- noChildren ++;
}
}
- // If not one child, call the Layout function if compiled in
- if (!child || (noChildren > 1)
-#if USE_CONSTRAINTS
- || GetAutoLayout()
-#endif
- )
- {
-#if USE_CONSTRAINTS
- if (GetAutoLayout())
- Layout();
-#endif
- return;
- }
-
- if (child)
- {
- int client_x, client_y;
+ if ( child ) {
+ // we have exactly one child - set it's size to fill the whole frame
+ int clientW, clientH;
+ GetClientSize(&clientW, &clientH);
-#if DEBUG > 1
- wxDebugMsg("wxFrame::OnSize: about to set the child's size.\n");
-#endif
+ int x = 0;
+ int y = 0;
- GetClientSize(&client_x, &client_y);
- child->SetSize(0, 0, client_x, client_y);
+ child->SetSize(x, y, clientW, clientH);
}
-
}
// Default activation behaviour - set the focus for the first child
// subwindow found.
void wxFrame::OnActivate(wxActivateEvent& event)
{
- for(wxNode *node = GetChildren()->First(); node; node = node->Next())
+ for(wxNode *node = GetChildren().First(); node; node = node->Next())
{
// Find a child that's a subwindow, but not a dialog box.
wxWindow *child = (wxWindow *)node->Data();
if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
!child->IsKindOf(CLASSINFO(wxDialog)))
{
-#if DEBUG > 1
- wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n");
-#endif
child->SetFocus();
return;
}
}
}
-// The default implementation for the close window event - calls
-// OnClose for backward compatibility.
-
+// The default implementation for the close window event.
void wxFrame::OnCloseWindow(wxCloseEvent& event)
{
- // Compatibility
- if ( GetEventHandler()->OnClose() || event.GetForce())
- {
- this->Destroy();
- }
+ this->Destroy();
}
// Destroy the window (delayed, if a managed window)
-bool wxFrame::Destroy(void)
+bool wxFrame::Destroy()
{
if (!wxPendingDelete.Member(this))
wxPendingDelete.Append(this);
{
if (GetStatusBar())
{
- if (event.GetMenuId() == -1)
- SetStatusText("");
- else
+ int menuId = event.GetMenuId();
+ if ( menuId != -1 )
{
wxMenuBar *menuBar = GetMenuBar();
if (menuBar)
{
- wxString helpString(menuBar->GetHelpString(event.GetMenuId()));
- if (helpString != "")
- SetStatusText(helpString);
+ // set status text even if the string is empty - this will at
+ // least remove the string from the item which was previously
+ // selected
+ SetStatusText(menuBar->GetHelpString(menuId));
}
}
}
}
-wxMenuBar *wxFrame::GetMenuBar(void) const
+wxMenuBar *wxFrame::GetMenuBar() const
{
return m_frameMenuBar;
}
void wxFrame::ProcessCommand(int id)
{
- wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, id);
+ wxCommandEvent commandEvent(wxEVT_COMMAND_MENU_SELECTED, id);
commandEvent.SetInt( id );
commandEvent.SetEventObject( this );
GetEventHandler()->ProcessEvent(commandEvent);
}
-void wxFrame::OnIdle(wxIdleEvent& event)
+// Checks if there is a toolbar, and returns the first free client position
+wxPoint wxFrame::GetClientAreaOrigin() const
{
- DoMenuUpdates();
+ wxPoint pt(0, 0);
+ if (GetToolBar())
+ {
+ int w, h;
+ GetToolBar()->GetSize(& w, & h);
+
+ if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
+ {
+ pt.x += w;
+ }
+ else
+ {
+ pt.y += h;
+ }
+ }
+ return pt;
}
-// Query app for menu item updates (called from OnIdle)
-void wxFrame::DoMenuUpdates(void)
+void wxFrame::ScreenToClient(int *x, int *y) const
{
- wxMenuBar* bar = GetMenuBar();
- if (!bar)
- return;
+ wxWindow::ScreenToClient(x, y);
+
+ // We may be faking the client origin.
+ // So a window that's really at (0, 30) may appear
+ // (to wxWin apps) to be at (0, 0).
+ wxPoint pt(GetClientAreaOrigin());
+ *x -= pt.x;
+ *y -= pt.y;
+}
- int i;
- for (i = 0; i < bar->m_menuCount; i++)
- {
- wxMenu* menu = bar->m_menus[i];
+void wxFrame::ClientToScreen(int *x, int *y) const
+{
+ // We may be faking the client origin.
+ // So a window that's really at (0, 30) may appear
+ // (to wxWin apps) to be at (0, 0).
+ wxPoint pt1(GetClientAreaOrigin());
+ *x += pt1.x;
+ *y += pt1.y;
+
+ wxWindow::ClientToScreen(x, y);
+}
- DoMenuUpdates(menu);
- }
+wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name)
+{
+ wxCHECK_MSG( m_frameToolBar == NULL, FALSE,
+ "recreating toolbar in wxFrame" );
+
+ wxToolBar* toolBar = OnCreateToolBar(style, id, name);
+ if (toolBar)
+ {
+ SetToolBar(toolBar);
+ PositionToolBar();
+ return toolBar;
+ }
+ else
+ {
+ return NULL;
+ }
}
-void wxFrame::DoMenuUpdates(wxMenu* menu)
+wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name)
{
- wxNode* node = menu->m_menuItems.First();
- while (node)
- {
- wxMenuItem* item = (wxMenuItem*) node->Data();
- if ( !item->IsSeparator() )
+ return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name);
+}
+
+void wxFrame::PositionToolBar()
+{
+ RECT rect;
+ ::GetClientRect((HWND) GetHWND(), &rect);
+
+ if ( GetStatusBar() )
{
- wxWindowID id = item->GetId();
- wxUpdateUIEvent event(id);
- event.SetEventObject( this );
+ int statusX, statusY;
+ GetStatusBar()->GetClientSize(&statusX, &statusY);
+ rect.bottom -= statusY;
+ }
- if (GetEventHandler()->ProcessEvent(event))
- {
- if (event.GetSetText())
- menu->SetLabel(id, event.GetText());
- if (event.GetSetChecked())
- menu->Check(id, event.GetChecked());
- if (event.GetSetEnabled())
- menu->Enable(id, event.GetEnabled());
- }
+ if (GetToolBar())
+ {
+ int tw, th;
+ GetToolBar()->GetSize(& tw, & th);
+
+ if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
+ {
+ // Use the 'real' MSW position
+ GetToolBar()->SetSize(0, 0, tw, rect.bottom, wxSIZE_NO_ADJUSTMENTS);
+ }
+ else
+ {
+ // Use the 'real' MSW position
+ GetToolBar()->SetSize(0, 0, rect.right, th, wxSIZE_NO_ADJUSTMENTS);
+ }
+ }
+}
- if (item->GetSubMenu())
- DoMenuUpdates(item->GetSubMenu());
+// propagate our state change to all child frames
+void wxFrame::IconizeChildFrames(bool bIconize)
+{
+ for ( wxNode *node = GetChildren().First(); node; node = node->Next() ) {
+ wxWindow *win = (wxWindow *)node->Data();
+ if ( win->IsKindOf(CLASSINFO(wxFrame)) ) {
+ ((wxFrame *)win)->Iconize(bIconize);
}
- node = node->Next();
}
}
+