home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
WXWIN140.ZIP
/
SRC
/
WX_FRAME.CC
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-18
|
37KB
|
1,536 lines
/*
* File: wx_frame.cc
* Purpose: wxFrame implementation
*
* wxWindows 1.40
* Copyright (c) 1993 Artificial Intelligence Applications Institute,
* The University of Edinburgh
*
* Author: Julian Smart
* Date: 18-4-93
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice, author statement and this permission
* notice appear in all copies of this software and related documentation.
*
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
* IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
*
* IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
* UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
* DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <windows.h>
#include <iostream.h>
#include "common.h"
#include "wx_frame.h"
#include "wx_gdi.h"
#include "wx_event.h"
#include "wx_main.h"
#include "wx_utils.h"
#include "wx_privt.h"
#ifdef wx_motif
#include <Xm/BulletinB.h>
#include <Xm/Form.h>
#include <Xm/Frame.h>
#include <Xm/MainW.h>
#include <Xm/Label.h>
#include <Xm/Protocols.h>
void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
#endif
#ifdef wx_xview
extern "C" int xv_window_loop(Frame);
extern "C" int xv_window_return(int);
Notify_value wxFrameInterposer(Frame x_frame, Event *x_event, Notify_arg arg,
Notify_event_type type);
Notify_value
wxFrameCloseInterposer(Notify_client client, Destroy_status status);
#endif
#ifdef wx_msw
extern wxList wxModelessWindows;
wxPen *wxStatusGreyPen = NULL;
wxPen *wxStatusWhitePen = NULL;
#define IDM_WINDOWTILE 4001
#define IDM_WINDOWCASCADE 4002
#define IDM_WINDOWICONS 4003
#define IDM_WINDOWNEXT 4004
#define wxFIRST_MDI_CHILD 4100
// Status border dimensions
#define wxTHICK_LINE_BORDER 4
#define wxTHICK_LINE_WIDTH 2
#endif
#ifdef wx_motif
Bool wxTopLevelUsed = FALSE;
#endif
wxFrame::wxFrame(wxFrame *Parent, char *title, int x, int y,
int width, int height, int type)
{
frame_type = type;
wx_menu_bar = NULL;
status_line_exists = FALSE;
icon = NULL;
modal_showing = FALSE;
if (Parent) Parent->AddChild(this);
window_parent = Parent;
#ifdef wx_motif
statusTextWidget = 0;
statusLineWidget = 0;
if (wxTopLevelUsed)
frameShell = XtAppCreateShell(NULL, "Shell", topLevelShellWidgetClass, XtDisplay(wxTheApp->topLevel), NULL, 0);
else
{
frameShell = wxTheApp->topLevel;
}
XtVaSetValues(frameShell,
// Allows menu to resize
XmNallowShellResize, True,
XmNdeleteResponse, XmDO_NOTHING,
XmNmappedWhenManaged, False,
NULL);
if (title)
XtVaSetValues(frameShell,
XmNtitle, title,
NULL);
menuBarWidget = NULL;
statusLineWidget = NULL;
frameWidget = XtVaCreateManagedWidget("main_window",
xmMainWindowWidgetClass, frameShell,
XmNresizePolicy, XmRESIZE_NONE,
NULL);
workArea = XtVaCreateManagedWidget("form",
xmFormWidgetClass, frameWidget,
XmNresizePolicy, XmRESIZE_NONE,
NULL);
XtVaSetValues(frameWidget,
XmNworkWindow, workArea,
NULL);
wxWidgetHashTable->Put((long)workArea, this);
XtOverrideTranslations(workArea,
XtParseTranslationTable("<Configure>: resize()"));
if (x > -1)
{
XtVaSetValues(frameShell, XmNx, x, NULL);
}
if (y > -1)
{
XtVaSetValues(frameShell, XmNy, y, NULL);
}
if (width > -1)
{
XtVaSetValues(frameShell, XmNwidth, width, NULL);
}
if (height > -1)
{
XtVaSetValues(frameShell, XmNheight, height, NULL);
}
handle = (char *)frameWidget;
XtRealizeWidget(frameShell);
wxTopLevelUsed = TRUE;
// Intercept CLOSE messages from the window manager
Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(frameShell), "WM_DELETE_WINDOW", False);
XmAddWMProtocolCallback(frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (XtPointer)this);
PreResize();
OnSize(width, height);
#endif
#ifdef wx_xview
Frame parent;
if (Parent == (wxFrame *)NULL)
{
parent = (Frame)NULL;
}
else
{
parent = (Frame)(Parent->GetHandle());
};
Frame frame = (Frame) xv_create(parent, FRAME, FRAME_LABEL, title,
WIN_CLIENT_DATA, (char *)this,
XV_SHOW, FALSE,
NULL);
if (x > -1)
xv_set(frame, XV_X, x, NULL);
if (y > -1)
xv_set(frame, XV_Y, y, NULL);
if (width > -1)
xv_set(frame, XV_WIDTH, width, NULL);
if (height > -1)
xv_set(frame, XV_HEIGHT, height, NULL);
handle = (char *)frame;
menu_bar_panel = NULL;
y_offset = 0;
// Have to do this interposition to receive frame resize events
(void)notify_interpose_event_func(frame, (Notify_func)wxFrameInterposer, NOTIFY_SAFE);
(void)notify_interpose_destroy_func(frame, (Notify_func)wxFrameCloseInterposer);
#endif
#ifdef wx_msw
status_window = NULL;
wx_iconized = FALSE;
wxWnd *cparent = NULL;
if (Parent)
cparent = (wxWnd *)Parent->handle;
DWORD msflags = WS_OVERLAPPEDWINDOW;
switch (type)
{
case wxMDI_PARENT:
wxWinType = wxTYPE_XWND;
handle = (char *)new wxMDIFrame(NULL, this, title, x, y, width, height);
break;
case wxMDI_CHILD:
wxWinType = wxTYPE_MDICHILD;
handle = (char *)new wxMDIChild((wxMDIFrame *)cparent, this, title, x, y, width, height);
break;
default:
case wxSDI:
wxWinType = wxTYPE_XWND;
handle = (char *)new wxFrameWnd(cparent, "wxFrameClass", this, title,
x, y, width, height, msflags);
break;
}
wxModelessWindows.Append(this);
#endif
}
// For ~wxFrame, see wx_item.cc
#ifdef wx_motif
void wxFrame::PreResize(void)
{
// cout << "Motif frame PreResize\n";
}
#endif
// Default resizing behaviour - if only ONE subwindow,
// resize to client rectangle size
void wxFrame::OnSize(int x, int y)
{
#ifdef wx_motif
// cout << "wxFrame::OnSize\n";
#endif
if (children->Number() == 1 && frame_type != wxMDI_PARENT)
{
wxWindow *child = (wxWindow *)children->First()->Data();
int client_x, client_y;
GetClientSize(&client_x, &client_y);
child->SetSize(0, 0, client_x, client_y);
}
}
// Get size *available for subwindows* i.e. excluding menu bar etc.
// For XView, this is the same as GetSize
void wxFrame::GetClientSize(int *x, int *y)
{
#ifdef wx_motif
Dimension xx, yy;
XtVaGetValues(workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
if (status_line_exists)
{
Dimension ys;
XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
yy -= ys;
}
*x = xx; *y = yy;
#endif
#ifdef wx_xview
Frame x_frame = (Frame)handle;
*x = (int)xv_get(x_frame, XV_WIDTH);
*y = (int)xv_get(x_frame, XV_HEIGHT) - y_offset;
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
RECT rect;
GetClientRect(wnd->handle, &rect);
if (status_window)
rect.bottom -= status_window->height;
*x = rect.right;
*y = rect.bottom;
#endif
}
// Set the client size (i.e. leave the calculation of borders etc.
// to wxWindows)
void wxFrame::SetClientSize(int width, int height)
{
#ifdef wx_motif
// Calculate how large the new main window should be
// by finding the difference between the client area and the
// main window area, and adding on to the new client area
Dimension current_frame_width, current_frame_height;
Dimension current_form_width, current_form_height;
XtVaGetValues(frameWidget, XmNwidth, ¤t_frame_width, XmNheight, ¤t_frame_height, NULL);
XtVaGetValues(workArea, XmNwidth, ¤t_form_width, XmNheight, ¤t_form_height, NULL);
int diffX = current_frame_width - current_form_width;
int diffY = current_frame_height - current_form_height;
if (width > -1)
XtVaSetValues(frameWidget, XmNwidth, width + diffX, NULL);
if (height > -1)
{
int real_height = height + diffY;
if (status_line_exists)
{
Dimension ys;
XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
real_height += ys;
}
XtVaSetValues(frameWidget, XmNheight, real_height, NULL);
}
OnSize(width, height);
#endif
#ifdef wx_xview
Frame x_frame = (Frame)handle;
(void)xv_set(x_frame, XV_WIDTH, width, XV_HEIGHT, height + y_offset, NULL);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
RECT rect;
GetClientRect(wnd->handle, &rect);
RECT rect2;
GetWindowRect(wnd->handle, &rect2);
// Find the difference between the entire window (title bar and all)
// and the client area; add this to the new client size to move the
// window
int actual_width = rect2.right - rect2.left - rect.right + width;
int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
if (status_window)
actual_height += status_window->height;
MoveWindow(wnd->handle, rect2.left, rect2.top, actual_width, actual_height, TRUE);
OnSize(actual_width, actual_height);
#endif
}
void wxFrame::GetSize(int *width, int *height)
{
#ifdef wx_motif
Dimension xx, yy;
XtVaGetValues(frameWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
*width = xx; *height = yy;
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*width = (int)xv_get(x_win, XV_WIDTH);
*height = (int)xv_get(x_win, XV_HEIGHT);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
RECT rect;
GetWindowRect(wnd->handle, &rect);
*width = rect.right - rect.left;
*height = rect.bottom - rect.top;
#endif
}
void wxFrame::GetPosition(int *x, int *y)
{
#ifdef wx_motif
Widget widget = (Widget)handle;
Dimension xx, yy;
XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
*x = xx; *y = yy;
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
*x = (int)xv_get(x_win, XV_X);
*y = (int)xv_get(x_win, XV_Y);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
wxWindow *parent = GetParent();
RECT rect;
GetWindowRect(wnd->handle, &rect);
POINT point;
point.x = rect.left;
point.y = rect.top;
// Since we now have the absolute screen coords,
// if there's a parent we must subtract its top left corner
if (parent)
{
wxWnd *cparent = (wxWnd *)(parent->handle);
ScreenToClient(wnd->handle, &point);
}
*x = point.x;
*y = point.y;
#endif
}
void wxFrame::SetSize(int x, int y, int width, int height)
{
#ifdef wx_motif
if (x > -1)
XtVaSetValues(frameShell, XmNx, x, NULL);
if (y > -1)
XtVaSetValues(frameShell, XmNy, y, NULL);
if (width > -1)
XtVaSetValues(frameWidget, XmNwidth, width, NULL);
if (height > -1)
XtVaSetValues(frameWidget, XmNheight, height, NULL);
OnSize(width, height);
#endif
#ifdef wx_xview
Xv_opaque x_win = (Xv_opaque)handle;
(void)xv_set(x_win, XV_X, x, XV_Y, y, XV_WIDTH, width, XV_HEIGHT, height, NULL);
#endif
#ifdef wx_msw
int currentX, currentY;
GetPosition(¤tX, ¤tY);
if (x == -1)
x = currentX;
if (y == -1)
y = currentY;
wxWnd *wnd = (wxWnd *)handle;
if (wnd)
MoveWindow(wnd->handle, x, y, width, height, TRUE);
OnSize(width, height);
#endif
}
void wxFrame::Show(Bool show)
{
#ifdef wx_motif
if (show)
{
XtMapWidget(frameShell);
XRaiseWindow(XtDisplay(frameShell), XtWindow(frameShell));
}
else
XtUnmapWidget(frameShell);
#endif
#ifdef wx_xview
Xv_opaque window = (Xv_opaque)handle;
xv_set(window, XV_SHOW, show, NULL);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
int cshow;
if (show)
cshow = SW_SHOW;
else
cshow = SW_HIDE;
ShowWindow(wnd->handle, cshow);
if (show)
BringWindowToTop(wnd->handle);
#endif
}
// Default activation behaviour - set the focus for the first child
// window
void wxFrame::OnActivate(Bool flag)
{
if (flag && GetChildren() && (GetChildren()->Number() > 0))
{
wxWindow *child = (wxWindow *)GetChildren()->First()->Data();
child->SetFocus();
}
}
wxMenuBar *wxFrame::GetMenuBar(void)
{
return wx_menu_bar;
}
#ifdef wx_xview
Notify_value wxFrameInterposer(Frame x_frame, Event *x_event, Notify_arg arg,
Notify_event_type type)
{
wxFrame *frame = (wxFrame *)xv_get(x_frame, WIN_CLIENT_DATA);
// cout << event_action(x_event) << "\n";
if (frame && event_action(x_event) == WIN_RESIZE)
{
// cout << "Frame resized\n";
int width, height;
frame->GetSize(&width, &height);
frame->OnSize(width, height);
return notify_next_event_func(x_frame, (long unsigned int)x_event, arg, type);
}
else return notify_next_event_func(x_frame, (long unsigned int)x_event, arg, type);
}
Notify_value
wxFrameCloseInterposer(Notify_client client, Destroy_status status)
{
wxFrame *frame = (wxFrame *)xv_get(client, WIN_CLIENT_DATA);
if (status == DESTROY_CHECKING)
{
if (frame)
{
Bool answer = frame->OnClose();
if (!answer)
notify_veto_destroy(client);
}
}
else if (status == DESTROY_CLEANUP)
{
// Should we destroy the wxFrame or wot?
// Try to delete the wxFrame without allowing the Frame
// to be deleted, since this will be done by XView
if (frame)
{
frame->Show(FALSE);
frame->handle = NULL;
delete frame;
if (frame == wxTheApp->wx_frame)
wxTheApp->wx_frame = NULL;
}
return notify_next_destroy_func(client, status);
}
else if (status == DESTROY_SAVE_YOURSELF)
{
// Do nothing - this is an Open Look specific feature
}
else if (status == DESTROY_PROCESS_DEATH)
{
if (!wxTheApp->death_processed)
{
wxTheApp->OnExit();
wxTheApp->death_processed = TRUE;
}
};
return NOTIFY_DONE;
}
#endif
#ifdef wx_motif
void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
{
wxFrame *frame = (wxFrame *)client_data;
if (frame->OnClose())
delete frame;
}
#endif
void wxFrame::Iconize(Bool iconize)
{
if (!iconize)
Show(TRUE);
#ifdef wx_motif
XtVaSetValues(frameShell, XmNiconic, iconize, NULL);
#endif
#ifdef wx_xview
Xv_opaque window = (Xv_opaque)handle;
xv_set(window, FRAME_CLOSED, iconize, NULL);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
int cshow;
if (iconize)
cshow = SW_MINIMIZE;
else
cshow = SW_RESTORE;
ShowWindow(wnd->handle, cshow);
wx_iconized = iconize;
#endif
}
Bool wxFrame::Iconized(void)
{
#ifdef wx_motif
Bool iconic;
XtVaGetValues(frameShell, XmNiconic, &iconic, NULL);
return iconic;
#endif
#ifdef wx_xview
Xv_opaque window = (Xv_opaque)handle;
return xv_get(window, FRAME_CLOSED);
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
return wx_iconized;
#endif
}
void wxFrame::SetTitle(char *title)
{
#ifdef wx_motif
if (title)
XtVaSetValues(frameShell,
XmNtitle, title,
XmNiconName, title,
NULL);
#endif
#ifdef wx_xview
Frame xframe = (Frame)handle;
xv_set(xframe, FRAME_LABEL, title, NULL);
if (icon)
{
xv_set(icon->x_icon, XV_LABEL, title, NULL);
xv_set(xframe, FRAME_ICON, icon->x_icon, NULL);
}
#endif
#ifdef wx_msw
wxWnd *wnd = (wxWnd *)handle;
SetWindowText(wnd->handle, title);
#endif
}
void wxFrame::SetIcon(wxIcon *wx_icon)
{
/*
if (icon)
delete icon;
*/
icon = wx_icon;
#ifdef wx_motif
if (!wx_icon->x_pixmap)
return;
XtVaSetValues(frameShell, XmNiconPixmap, wx_icon->x_pixmap, NULL);
// The following isn't necessary and doesn't even work (P.587 of Heller)
/*
Display *dpy = XtDisplay(wxTheApp->topLevel);
Window window, root;
XtVaGetValues(frameShell, XmNiconWindow, &window, NULL);
if (!window)
{
int x, y;
unsigned int width, height, border_width, depth;
if (!XGetGeometry(dpy, wx_icon->x_pixmap, &root, &x, &y, &width, &height, &border_width,
&depth) ||
!(window = XCreateSimpleWindow(dpy, root, 0, 0, width, height, (unsigned)0,
CopyFromParent, CopyFromParent)))
{
XtVaSetValues(frameShell, XmNiconPixmap, wx_icon->x_pixmap, NULL);
return;
}
XSetWindowBackgroundPixmap(dpy, window, wx_icon->x_pixmap);
XClearWindow(dpy, window);
}
*/
#endif
#ifdef wx_xview
Frame xframe = (Frame)handle;
char *label = (char *)xv_get(xframe, FRAME_LABEL);
xv_set(wx_icon->x_icon, XV_LABEL, label, NULL);
xv_set(xframe, FRAME_ICON, wx_icon->x_icon, NULL);
#endif
#ifdef wx_msw
switch (frame_type)
{
case wxMDI_PARENT:
{
wxMDIFrame *wnd = (wxMDIFrame *)handle;
wnd->icon = wx_icon->ms_icon;
break;
}
case wxMDI_CHILD:
{
wxMDIChild *wnd = (wxMDIChild *)handle;
wnd->icon = wx_icon->ms_icon;
break;
}
default:
case wxSDI:
{
wxFrameWnd *wnd = (wxFrameWnd *)handle;
wnd->icon = wx_icon->ms_icon;
break;
}
}
#endif
}
void wxFrame::CreateStatusLine(void)
{
if (status_line_exists)
return;
status_line_exists = TRUE;
#ifdef wx_motif
statusLineWidget = XtVaCreateManagedWidget("status_line",
xmFrameWidgetClass, workArea,
XmNshadowType, XmSHADOW_IN,
XmNbottomAttachment, XmATTACH_FORM,
XmNleftAttachment, XmATTACH_FORM,
XmNrightAttachment, XmATTACH_FORM,
NULL);
statusTextWidget = XtVaCreateManagedWidget("status_text",
xmLabelWidgetClass, statusLineWidget,
XmNalignment, XmALIGNMENT_BEGINNING,
NULL);
XtRealizeWidget(statusLineWidget);
XtRealizeWidget(statusTextWidget);
SetStatusText("");
#endif
#ifdef wx_xview
Frame xframe = (Frame)handle;
xv_set(xframe, FRAME_SHOW_FOOTER, TRUE, NULL);
#endif
#ifdef wx_msw
wxFrameWnd *cframe = (wxFrameWnd *)handle;
TEXTMETRIC tm;
HDC dc = GetDC(cframe->handle);
GetTextMetrics(dc, &tm);
ReleaseDC(cframe->handle, dc);
int char_height = tm.tmHeight + tm.tmExternalLeading;
int status_window_height =
(int)((char_height * 3.0/2.0) + 2*wxTHICK_LINE_BORDER);
if (!wxStatusGreyPen)
{
wxStatusGreyPen = new wxPen("DIM GREY", wxTHICK_LINE_WIDTH, wxSOLID);
wxStatusWhitePen = new wxPen("WHITE", wxTHICK_LINE_WIDTH, wxSOLID);
}
status_window = new wxStatusWnd(cframe, status_window_height);
PositionStatusWindow();
#endif
}
void wxFrame::SetStatusText(char *text)
{
if (!status_line_exists)
return;
#ifdef wx_motif
if (!text) text = " ";
sprintf(wxBuffer, " %s", text);
XmString str = XmStringCreateSimple(wxBuffer);
XtVaSetValues(statusTextWidget,
XmNlabelString, str,
NULL);
XmStringFree(str);
#endif
#ifdef wx_xview
Frame xframe = (Frame)handle;
xv_set(xframe, FRAME_LEFT_FOOTER, text, NULL);
#endif
#ifdef wx_msw
if (status_window->status_text)
delete status_window->status_text;
if (text)
status_window->status_text = copystring(text);
else status_window->status_text = NULL;
HDC dc = GetDC(status_window->handle);
RECT rect;
GetClientRect(status_window->handle, &rect );
int width = rect.right;
int height = rect.bottom;
SetBkMode(dc, TRANSPARENT);
::SetTextColor(dc, ::GetSysColor( COLOR_WINDOWTEXT ) );
TEXTMETRIC tm;
GetTextMetrics(dc, &tm);
int cy = tm.tmHeight + tm.tmExternalLeading;
int y = (int)((rect.bottom - cy)/2);
rect.left += wxTHICK_LINE_BORDER + 1;
rect.top += wxTHICK_LINE_BORDER + 1;
rect.right -= (wxTHICK_LINE_BORDER + 1);
rect.bottom -= (wxTHICK_LINE_BORDER + 1);
FillRect(dc, &rect, status_window->light_grey_brush);
IntersectClipRect(dc, wxTHICK_LINE_BORDER + 3, y-1,
width - wxTHICK_LINE_BORDER - 1, height);
if (status_window->status_text)
TextOut(dc, wxTHICK_LINE_BORDER + 4, y,
status_window->status_text, strlen(status_window->status_text));
SelectClipRgn(dc, NULL);
ReleaseDC(status_window->handle, dc);
#endif
}
Bool wxFrame::StatusLineExists(void)
{
return status_line_exists;
}
#ifdef wx_msw
void wxFrame::PositionStatusWindow(void)
{
wxFrameWnd *cframe = (wxFrameWnd *)handle;
RECT rect;
GetClientRect(cframe->handle, &rect);
int cwidth = rect.right;
int cheight = rect.bottom;
MoveWindow(status_window->handle, 0, cheight - status_window->height,
cwidth, status_window->height, TRUE);
}
#endif
void wxFrame::LoadAccelerators(char *table)
{
#ifdef wx_msw
wxFrameWnd *cframe = (wxFrameWnd *)handle;
cframe->accelerator_table = ::LoadAccelerators(wxhInstance, table);
#endif
}
void wxFrame::Fit(void)
{
#ifdef wx_motif
int maxX = 0;
int maxY = 0;
wxNode *node = GetChildren()->First();
while (node)
{
wxWindow *win = (wxWindow *)node->Data();
int x, y, w, h;
win->GetPosition(&x, &y);
win->GetSize(&w, &h);
if ((x + w) > maxX)
maxX = x + w;
if ((y + h) > maxY)
maxY = y + h;
node = node->Next();
}
SetClientSize(maxX, maxY);
#endif
#ifdef wx_xview
Frame xframe = (Frame)handle;
window_fit(xframe);
#endif
#ifdef wx_msw
// Work out max. size
wxNode *node = children->First();
int max_width = 0;
int max_height = 0;
while (node)
{
wxWindow *win = (wxWindow *)node->Data();
int width, height;
int x, y;
win->GetSize(&width, &height);
win->GetPosition(&x, &y);
if ((x + width) > max_width)
max_width = x + width;
if ((y + height) > max_height)
max_height = y + height;
node = node->Next();
}
SetClientSize(max_width, max_height);
#endif
}
void wxFrame::Centre(int direction)
{
int display_width, display_height, width, height, x, y;
wxDisplaySize(&display_width, &display_height);
GetSize(&width, &height);
GetPosition(&x, &y);
if (direction == wxBOTH || direction == wxHORIZONTAL)
x = (int)((display_width - width)/2);
if (direction == wxBOTH || direction == wxVERTICAL)
y = (int)((display_height - height)/2);
SetSize(x, y, width, height);
}
#ifdef wx_msw
/*
* Windows 3 specific windows
*
*/
wxStatusWnd::wxStatusWnd(wxFrameWnd *parent, int the_height)
{
status_text = NULL;
height = the_height;
light_grey_brush = GetStockObject(LTGRAY_BRUSH);
Create(parent, "wxPanelClass", NULL, NULL, 0, 0, 100, 100, WS_CHILD);
ShowWindow(handle, SW_SHOW);
}
wxStatusWnd::~wxStatusWnd(void)
{
if (status_text)
delete status_text;
}
BOOL wxStatusWnd::OnPaint()
{
RECT rect;
if (GetUpdateRect(handle, &rect, FALSE))
{
PAINTSTRUCT ps;
// Hold a pointer to the dc so long as the OnPaint() message
// is being processed
cdc = BeginPaint(handle, &ps);
::GetClientRect(handle, &rect);
int width = rect.right;
int height = rect.bottom;
::SetBkMode(cdc, TRANSPARENT);
::FillRect(cdc, &rect, light_grey_brush);
HBRUSH old_brush = ::SelectObject(cdc, wxGREY_BRUSH->cbrush);
// Draw border
// Have grey background, plus 3-d border -
// One black rectangle.
// Inside this, left and top sides - dark grey. Bottom and right -
// white.
// Right and bottom white lines
HPEN old_pen = SelectObject(cdc, wxStatusWhitePen->cpen);
MoveToEx(cdc, width-wxTHICK_LINE_BORDER,
wxTHICK_LINE_BORDER, NULL);
LineTo(cdc, width-wxTHICK_LINE_BORDER,
height-wxTHICK_LINE_BORDER);
LineTo(cdc, wxTHICK_LINE_BORDER,
height-wxTHICK_LINE_BORDER);
// Left and top grey lines
SelectObject(cdc, wxStatusGreyPen->cpen);
LineTo(cdc, wxTHICK_LINE_BORDER, wxTHICK_LINE_BORDER);
LineTo(cdc, width-wxTHICK_LINE_BORDER, wxTHICK_LINE_BORDER);
SetTextColor(cdc, ::GetSysColor( COLOR_WINDOWTEXT ) );
TEXTMETRIC tm;
::GetTextMetrics(cdc, &tm);
int cy = tm.tmHeight + tm.tmExternalLeading;
int y = (int)((rect.bottom - cy)/2);
::IntersectClipRect(cdc, wxTHICK_LINE_BORDER + 3, y-1,
rect.right - wxTHICK_LINE_BORDER - 1, rect.bottom);
if (status_text)
::TextOut(cdc, wxTHICK_LINE_BORDER + 4, y,
status_text, strlen(status_text));
::SelectClipRgn(cdc, NULL);
SelectObject(cdc, old_pen);
SelectObject(cdc, old_brush);
EndPaint(handle, &ps);
cdc = NULL;
return 0;
}
return 1;
}
/*
* Frame window
*
*/
wxFrameWnd::wxFrameWnd(wxWnd *parent, char *wclass, wxWindow *wx_win, char *title,
int x, int y, int width, int height, DWORD style)
{
icon = NULL;
iconized = FALSE;
Create(parent, "wxFrameClass", wx_win, title, x, y, width, height,
style);
}
wxFrameWnd::~wxFrameWnd(void)
{
}
BOOL wxFrameWnd::OnPaint(void)
{
RECT rect;
if (GetUpdateRect(handle, &rect, FALSE))
{
PAINTSTRUCT ps;
// Hold a pointer to the dc so long as the OnPaint() message
// is being processed
cdc = BeginPaint(handle, &ps);
if (iconized)
{
HICON the_icon = icon;
if (the_icon == 0)
the_icon = wxSTD_FRAME_ICON;
if (the_icon)
{
RECT rect;
GetClientRect(handle, &rect);
int icon_width = 32;
int icon_height = 32;
int icon_x = (int)((rect.right - icon_width)/2);
int icon_y = (int)((rect.bottom - icon_height)/2);
DrawIcon(cdc, icon_x, icon_y, the_icon);
}
}
if (!iconized && wx_window)
wx_window->OnPaint();
EndPaint(handle, &ps);
cdc = NULL;
return 0;
}
return 1;
}
void wxFrameWnd::OnSize(int x, int y, UINT id)
{
switch (id)
{
case SIZEFULLSCREEN:
case SIZENORMAL:
iconized = FALSE;
break;
case SIZEICONIC:
iconized = TRUE;
break;
}
if (!iconized)
{
wxFrame *frame = (wxFrame *)wx_window;
if (frame && frame->status_window)
frame->PositionStatusWindow();
if (wx_window && wx_window->handle)
wx_window->OnSize(x, y);
}
}
BOOL wxFrameWnd::OnClose(void)
{
if (wx_window)
{
if (wx_window->OnClose())
{
delete wx_window;
return TRUE;
} else return FALSE;
}
return FALSE;
}
BOOL wxFrameWnd::OnCommand(WORD id, WORD cmd, HWND control)
{
if (cmd == 0)
{
wx_window->OnMenuCommand(id);
return TRUE;
}
else
return FALSE;
}
void wxFrameWnd::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
{
wxFrame *frame = (wxFrame *)wx_window;
if (nFlags == -1 && hSysMenu == NULL)
frame->OnMenuSelect(-1);
else if (nFlags != MF_SEPARATOR)
frame->OnMenuSelect(nItem);
}
/*
* Windows MDI stuff
*/
wxMDIFrame::wxMDIFrame(wxWnd *parent, wxWindow *wx_win, char *title,
int x, int y, int width, int height)
{
icon = NULL;
iconized = FALSE;
parent_frame_active = TRUE;
current_child = NULL;
window_menu = ::LoadMenu(wxhInstance, "wxDefaultMenu");
Create(parent, "wxMDIFrameClass", wx_win, title, x, y, width, height,
WS_OVERLAPPEDWINDOW);
}
wxMDIFrame::~wxMDIFrame(void)
{
DestroyMenu(window_menu);
}
void wxMDIFrame::OnCreate(LPCREATESTRUCT cs)
{
CLIENTCREATESTRUCT ccs;
ccs.hWindowMenu = window_menu;
ccs.idFirstChild = wxFIRST_MDI_CHILD;
client_hwnd = ::CreateWindowEx(0, "mdiclient", NULL,
WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 0, 0, 0, 0, handle, NULL,
wxhInstance, (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
}
BOOL wxMDIFrame::OnPaint(void)
{
(void)DefWindowProc(last_msg, last_wparam, last_lparam);
RECT rect;
if (GetUpdateRect(handle, &rect, FALSE))
{
PAINTSTRUCT ps;
// Hold a pointer to the dc so long as the OnPaint() message
// is being processed
cdc = BeginPaint(handle, &ps);
if (iconized)
{
HICON the_icon = icon;
if (the_icon == 0)
the_icon = wxSTD_FRAME_ICON;
if (the_icon)
{
RECT rect;
GetClientRect(handle, &rect);
int icon_width = 32;
int icon_height = 32;
int icon_x = (int)((rect.right - icon_width)/2);
int icon_y = (int)((rect.bottom - icon_height)/2);
DrawIcon(cdc, icon_x, icon_y, the_icon);
}
}
if (!iconized && wx_window)
wx_window->OnPaint();
EndPaint(handle, &ps);
cdc = NULL;
return 0;
}
return 1;
}
void wxMDIFrame::OnSize(int x, int y, UINT id)
{
switch (id)
{
case SIZEFULLSCREEN:
case SIZENORMAL:
iconized = FALSE;
break;
case SIZEICONIC:
iconized = TRUE;
break;
}
if (!iconized)
{
wxFrame *frame = (wxFrame *)wx_window;
if (frame && frame->status_window)
{
RECT rect;
GetClientRect(handle, &rect);
int cwidth = rect.right;
int cheight = rect.bottom;
MoveWindow(client_hwnd, 0, 0,
cwidth, cheight - frame->status_window->height,
TRUE);
frame->PositionStatusWindow();
}
else (void)DefWindowProc(last_msg, last_wparam, last_lparam);
if (wx_window && wx_window->handle)
wx_window->OnSize(x, y);
}
}
BOOL wxMDIFrame::OnClose(void)
{
if (wx_window)
{
if (wx_window->OnClose())
{
delete wx_window;
return TRUE;
} else return FALSE;
}
return FALSE;
}
BOOL wxMDIFrame::OnCommand(WORD id, WORD cmd, HWND control)
{
if (cmd == 0)
{
switch (id)
{
case IDM_WINDOWCASCADE:
SendMessage(client_hwnd, WM_MDICASCADE, MDITILE_SKIPDISABLED, 0);
return TRUE;
break;
case IDM_WINDOWTILE:
SendMessage(client_hwnd, WM_MDITILE, MDITILE_HORIZONTAL, 0);
return TRUE;
break;
case IDM_WINDOWICONS:
SendMessage(client_hwnd, WM_MDIICONARRANGE, 0, 0);
return TRUE;
break;
case IDM_WINDOWNEXT:
SendMessage(client_hwnd, WM_MDINEXT, current_child->handle, 0);
return TRUE;
break;
default:
break;
}
if (parent_frame_active && id < wxFIRST_MDI_CHILD)
{
wx_window->OnMenuCommand(id);
return TRUE;
}
else if (current_child && id < wxFIRST_MDI_CHILD)
{
return current_child->OnCommand(id, cmd, control);
}
}
return DefWindowProc(last_msg, last_wparam, last_lparam);
}
void wxMDIFrame::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
{
if (parent_frame_active)
{
wxFrame *frame = (wxFrame *)wx_window;
if (nFlags == -1 && hSysMenu == NULL)
frame->OnMenuSelect(-1);
else if (nFlags != MF_SEPARATOR)
frame->OnMenuSelect(nItem);
}
else if (current_child)
{
current_child->OnMenuSelect(nItem, nFlags, hSysMenu);
}
}
long wxMDIFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
return DefFrameProc(handle, client_hwnd, message, wParam, lParam);
}
BOOL wxMDIFrame::ProcessMessage(MSG* pMsg)
{
if (current_child != NULL && current_child->ProcessMessage(pMsg))
return TRUE;
if (accelerator_table != NULL &&
::TranslateAccelerator(handle, accelerator_table, pMsg))
return TRUE;
if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
{
if (::TranslateMDISysAccel(client_hwnd, pMsg))
return TRUE;
}
return FALSE;
}
BOOL wxMDIFrame::OnEraseBkgnd(HDC pDC)
{
return TRUE;
}
extern wxWnd *wxWndHook;
extern wxList *wxWinHandleList;
wxMDIChild::wxMDIChild(wxMDIFrame *parent, wxWindow *wx_win, char *title,
int x, int y, int width, int height)
{
icon = NULL;
iconized = FALSE;
wx_window = wx_win;
active = FALSE;
is_dialog = FALSE;
HWND hParent = NULL;
if (parent)
hParent = parent->handle;
wxWndHook = this;
MDICREATESTRUCT mcs;
mcs.szClass = "wxMDIChildFrameClass";
mcs.szTitle = title;
mcs.hOwner = wxhInstance;
if (x > -1) mcs.x = x;
else mcs.x = CW_USEDEFAULT;
if (y > -1) mcs.y = y;
else mcs.y = CW_USEDEFAULT;
if (width > -1) mcs.cx = width;
else mcs.cx = CW_USEDEFAULT;
if (height > -1) mcs.cy = height;
else mcs.cy = CW_USEDEFAULT;
mcs.style = WS_OVERLAPPEDWINDOW;
mcs.lParam = 0;
DWORD Return = SendMessage(parent->client_hwnd,
WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
handle = (HWND)LOWORD(Return);
wxWndHook = NULL;
wxWinHandleList->Append((long)handle, this);
SetWindowLong(handle, 0, (long)this);
}
BOOL wxMDIChild::OnPaint(void)
{
(void)DefWindowProc(last_msg, last_wparam, last_lparam);
RECT rect;
if (GetUpdateRect(handle, &rect, FALSE))
{
PAINTSTRUCT ps;
// Hold a pointer to the dc so long as the OnPaint() message
// is being processed
cdc = BeginPaint(handle, &ps);
if (iconized)
{
HICON the_icon = icon;
if (the_icon == 0)
the_icon = wxSTD_FRAME_ICON;
if (the_icon)
{
RECT rect;
GetClientRect(handle, &rect);
int icon_width = 32;
int icon_height = 32;
int icon_x = (int)((rect.right - icon_width)/2);
int icon_y = (int)((rect.bottom - icon_height)/2);
DrawIcon(cdc, icon_x, icon_y, the_icon);
}
}
if (!iconized && wx_window)
wx_window->OnPaint();
EndPaint(handle, &ps);
cdc = NULL;
return 0;
}
return 1;
}
void wxMDIChild::OnSize(int x, int y, UINT id)
{
(void)DefWindowProc(last_msg, last_wparam, last_lparam);
switch (id)
{
case SIZEFULLSCREEN:
case SIZENORMAL:
iconized = FALSE;
break;
case SIZEICONIC:
iconized = TRUE;
break;
}
if (!iconized)
{
wxFrame *frame = (wxFrame *)wx_window;
if (frame && frame->status_window)
frame->PositionStatusWindow();
if (wx_window && wx_window->handle)
wx_window->OnSize(x, y);
}
}
BOOL wxMDIChild::OnClose(void)
{
if (wx_window)
{
if (wx_window->OnClose())
{
delete wx_window;
return TRUE;
} else return FALSE;
}
return FALSE;
}
BOOL wxMDIChild::OnCommand(WORD id, WORD cmd, HWND control)
{
(void)DefWindowProc(last_msg, last_wparam, last_lparam);
if (cmd == 0)
{
wx_window->OnMenuCommand(id);
return TRUE;
}
else
return FALSE;
}
void wxMDIChild::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
{
wxFrame *frame = (wxFrame *)wx_window;
if (nFlags == -1 && hSysMenu == NULL)
frame->OnMenuSelect(-1);
else if (nFlags != MF_SEPARATOR)
frame->OnMenuSelect(nItem);
}
long wxMDIChild::DefWindowProc(UINT message, UINT wParam, LONG lParam)
{
return DefMDIChildProc(handle, message, wParam, lParam);
}
BOOL wxMDIChild::ProcessMessage(MSG *msg)
{
if (accelerator_table)
{
wxFrame *parent = (wxFrame *)wx_window->GetParent();
HWND parent_hwnd = ((wxWnd *)parent->handle)->handle;
return ::TranslateAccelerator(parent_hwnd, accelerator_table, msg);
}
return FALSE;
}
BOOL wxMDIChild::OnMDIActivate(BOOL bActivate, HWND,
HWND)
{
wxFrame *parent = (wxFrame *)wx_window->GetParent();
wxFrame *child = (wxFrame *)wx_window;
HMENU parent_menu = parent->GetWinMenu();
HMENU child_menu = child->GetWinMenu();
wxMDIFrame *cparent = (wxMDIFrame *)parent->handle;
if (bActivate)
{
active = TRUE;
cparent->current_child = this;
if (child_menu)
{
cparent->parent_frame_active = FALSE;
#ifdef WIN32
::SendMessage(cparent->client_hwnd, WM_MDISETMENU, child_menu,
GetSubMenu(cparent->window_menu, 0));
#else
::SendMessage(cparent->client_hwnd, WM_MDISETMENU, 0,
MAKELONG(child_menu, GetSubMenu(cparent->window_menu, 0)));
#endif
::DrawMenuBar(cparent->handle);
}
}
else
{
if (cparent->current_child == this)
cparent->current_child = NULL;
active = FALSE;
if (parent_menu)
{
cparent->parent_frame_active = TRUE;
#ifdef WIN32
::SendMessage(cparent->client_hwnd, WM_MDISETMENU, parent_menu,
GetSubMenu(cparent->window_menu, 0));
#else
::SendMessage(cparent->client_hwnd, WM_MDISETMENU, 0,
MAKELONG(parent_menu, GetSubMenu(cparent->window_menu, 0)));
#endif
::DrawMenuBar(cparent->handle);
}
}
wx_window->OnActivate(bActivate);
return 0;
}
wxMDIChild::~wxMDIChild(void)
{
}
void wxMDIChild::DestroyWindow(void)
{
wxFrame *parent = (wxFrame *)wx_window->GetParent();
wxMDIFrame *cparent = (wxMDIFrame *)parent->handle;
SendMessage(cparent->client_hwnd, WM_MDIDESTROY, (HWND)handle, 0);
}
#endif