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 >
C/C++ Source or Header  |  1993-04-18  |  37KB  |  1,536 lines

  1. /*
  2.  * File:     wx_frame.cc
  3.  * Purpose:  wxFrame implementation
  4.  *
  5.  *                       wxWindows 1.40
  6.  * Copyright (c) 1993 Artificial Intelligence Applications Institute,
  7.  *                   The University of Edinburgh
  8.  *
  9.  *                     Author: Julian Smart
  10.  *                       Date: 18-4-93
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose is hereby granted without fee, provided
  14.  * that the above copyright notice, author statement and this permission
  15.  * notice appear in all copies of this software and related documentation.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, EXPRESS,
  18.  * IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
  19.  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL THE ARTIFICIAL INTELLIGENCE APPLICATIONS INSTITUTE OR THE
  22.  * UNIVERSITY OF EDINBURGH BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR
  23.  * CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER RESULTING FROM
  24.  * LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE POSSIBILITY OF
  25.  * DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
  26.  * THE USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <windows.h>
  30. #include <iostream.h>
  31.  
  32. #include "common.h"
  33. #include "wx_frame.h"
  34. #include "wx_gdi.h"
  35. #include "wx_event.h"
  36. #include "wx_main.h"
  37. #include "wx_utils.h"
  38. #include "wx_privt.h"
  39.  
  40. #ifdef wx_motif
  41. #include <Xm/BulletinB.h>
  42. #include <Xm/Form.h>
  43. #include <Xm/Frame.h>
  44. #include <Xm/MainW.h>
  45. #include <Xm/Label.h>
  46. #include <Xm/Protocols.h>
  47. void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
  48. #endif
  49.  
  50. #ifdef wx_xview
  51. extern "C" int xv_window_loop(Frame);
  52. extern "C" int xv_window_return(int);
  53. Notify_value wxFrameInterposer(Frame x_frame, Event *x_event, Notify_arg arg,
  54.                                Notify_event_type type);
  55. Notify_value
  56. wxFrameCloseInterposer(Notify_client client, Destroy_status status);
  57. #endif
  58.  
  59. #ifdef wx_msw
  60. extern wxList wxModelessWindows;
  61.  
  62. wxPen *wxStatusGreyPen = NULL;
  63. wxPen *wxStatusWhitePen = NULL;
  64.  
  65. #define IDM_WINDOWTILE  4001
  66. #define IDM_WINDOWCASCADE 4002
  67. #define IDM_WINDOWICONS 4003
  68. #define IDM_WINDOWNEXT 4004
  69. #define wxFIRST_MDI_CHILD 4100
  70.  
  71. // Status border dimensions
  72. #define         wxTHICK_LINE_BORDER 4
  73. #define         wxTHICK_LINE_WIDTH  2
  74. #endif
  75.  
  76. #ifdef wx_motif
  77. Bool wxTopLevelUsed = FALSE;
  78. #endif
  79.  
  80. wxFrame::wxFrame(wxFrame *Parent, char *title, int x, int y,
  81.                  int width, int height, int type)
  82. {
  83.   frame_type = type;
  84.   wx_menu_bar = NULL;
  85.   status_line_exists = FALSE;
  86.   icon = NULL;
  87.   modal_showing = FALSE;
  88.   if (Parent) Parent->AddChild(this);
  89.   window_parent = Parent;
  90. #ifdef wx_motif
  91.   statusTextWidget = 0;
  92.   statusLineWidget = 0;
  93.  
  94.   if (wxTopLevelUsed)
  95.     frameShell = XtAppCreateShell(NULL, "Shell", topLevelShellWidgetClass, XtDisplay(wxTheApp->topLevel), NULL, 0);
  96.   else
  97.   {
  98.     frameShell = wxTheApp->topLevel;
  99.   }
  100.  
  101.   XtVaSetValues(frameShell, 
  102.                  // Allows menu to resize
  103.                  XmNallowShellResize, True,
  104.                  XmNdeleteResponse, XmDO_NOTHING,
  105.                  XmNmappedWhenManaged, False,
  106.                  NULL);
  107.  
  108.   if (title)
  109.     XtVaSetValues(frameShell, 
  110.                   XmNtitle, title,
  111.                   NULL);
  112.  
  113.   menuBarWidget = NULL;
  114.   statusLineWidget = NULL;
  115.  
  116.   frameWidget = XtVaCreateManagedWidget("main_window",
  117.                     xmMainWindowWidgetClass, frameShell,
  118.                     XmNresizePolicy, XmRESIZE_NONE,
  119.                     NULL);
  120.  
  121.   workArea = XtVaCreateManagedWidget("form",
  122.                     xmFormWidgetClass, frameWidget,
  123.                     XmNresizePolicy, XmRESIZE_NONE,
  124.                     NULL);
  125.  
  126.   XtVaSetValues(frameWidget,
  127.     XmNworkWindow, workArea,
  128.     NULL);
  129.  
  130.   wxWidgetHashTable->Put((long)workArea, this);
  131.  
  132.   XtOverrideTranslations(workArea,
  133.               XtParseTranslationTable("<Configure>: resize()"));
  134.  
  135.   if (x > -1)
  136.   {
  137.     XtVaSetValues(frameShell, XmNx, x, NULL);
  138.   }
  139.   if (y > -1)
  140.   {
  141.     XtVaSetValues(frameShell, XmNy, y, NULL);
  142.   }
  143.   if (width > -1)
  144.   {
  145.     XtVaSetValues(frameShell, XmNwidth, width, NULL);
  146.   }
  147.   if (height > -1)
  148.   {
  149.     XtVaSetValues(frameShell, XmNheight, height, NULL);
  150.   }
  151.  
  152.   handle = (char *)frameWidget;
  153.  
  154.   XtRealizeWidget(frameShell);
  155.   wxTopLevelUsed = TRUE;
  156.  
  157.   // Intercept CLOSE messages from the window manager
  158.   Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay(frameShell), "WM_DELETE_WINDOW", False);
  159.   XmAddWMProtocolCallback(frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (XtPointer)this);
  160.  
  161.   PreResize();
  162.   OnSize(width, height);
  163. #endif
  164. #ifdef wx_xview
  165.   Frame parent;
  166.   if (Parent == (wxFrame *)NULL)
  167.     {
  168.       parent = (Frame)NULL;
  169.     }
  170.   else
  171.     {
  172.       parent = (Frame)(Parent->GetHandle());
  173.     };
  174.  
  175.   Frame frame = (Frame) xv_create(parent, FRAME, FRAME_LABEL, title,
  176.                               WIN_CLIENT_DATA, (char *)this,
  177.                               XV_SHOW, FALSE,
  178.                               NULL);
  179.  
  180.   if (x > -1)
  181.     xv_set(frame, XV_X, x, NULL);
  182.  
  183.   if (y > -1)
  184.     xv_set(frame, XV_Y, y, NULL);
  185.  
  186.   if (width > -1)
  187.     xv_set(frame, XV_WIDTH, width, NULL);
  188.  
  189.   if (height > -1)
  190.     xv_set(frame, XV_HEIGHT, height, NULL);
  191.  
  192.   handle = (char *)frame;
  193.  
  194.   menu_bar_panel = NULL;
  195.   y_offset = 0;
  196.  
  197.   // Have to do this interposition to receive frame resize events
  198.   (void)notify_interpose_event_func(frame, (Notify_func)wxFrameInterposer, NOTIFY_SAFE);
  199.   (void)notify_interpose_destroy_func(frame, (Notify_func)wxFrameCloseInterposer);
  200. #endif
  201.  
  202. #ifdef wx_msw
  203.   status_window = NULL;
  204.   wx_iconized = FALSE;
  205.   wxWnd *cparent = NULL;
  206.   if (Parent)
  207.     cparent = (wxWnd *)Parent->handle;
  208.  
  209.   DWORD msflags = WS_OVERLAPPEDWINDOW;
  210.  
  211.   switch (type)
  212.   {
  213.     case wxMDI_PARENT:
  214.       wxWinType = wxTYPE_XWND;
  215.       handle = (char *)new wxMDIFrame(NULL, this, title, x, y, width, height);
  216.       break;
  217.     case wxMDI_CHILD:
  218.       wxWinType = wxTYPE_MDICHILD;
  219.       handle = (char *)new wxMDIChild((wxMDIFrame *)cparent, this, title, x, y, width, height);
  220.       break;
  221.     default:
  222.     case wxSDI:
  223.       wxWinType = wxTYPE_XWND;
  224.       handle = (char *)new wxFrameWnd(cparent, "wxFrameClass", this, title,
  225.                    x, y, width, height, msflags);
  226.       break;
  227.   }
  228.  
  229.   wxModelessWindows.Append(this);
  230. #endif
  231. }
  232.  
  233. // For ~wxFrame, see wx_item.cc
  234.  
  235. #ifdef wx_motif
  236. void wxFrame::PreResize(void)
  237. {
  238. //  cout << "Motif frame PreResize\n";
  239. }
  240. #endif
  241.  
  242.  
  243. // Default resizing behaviour - if only ONE subwindow,
  244. // resize to client rectangle size
  245. void wxFrame::OnSize(int x, int y)
  246. {
  247. #ifdef wx_motif
  248. //  cout << "wxFrame::OnSize\n";
  249. #endif
  250.   if (children->Number() == 1 && frame_type != wxMDI_PARENT)
  251.   {
  252.     wxWindow *child = (wxWindow *)children->First()->Data();
  253.     int client_x, client_y;
  254.     GetClientSize(&client_x, &client_y);
  255.     child->SetSize(0, 0, client_x, client_y);
  256.   }
  257. }
  258.  
  259. // Get size *available for subwindows* i.e. excluding menu bar etc.
  260. // For XView, this is the same as GetSize
  261. void wxFrame::GetClientSize(int *x, int *y)
  262. {
  263. #ifdef wx_motif
  264.   Dimension xx, yy;
  265.   XtVaGetValues(workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
  266.  
  267.   if (status_line_exists)
  268.   {
  269.     Dimension ys;
  270.     XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
  271.     yy -= ys;
  272.   }
  273.  
  274.   *x = xx; *y = yy;
  275. #endif
  276. #ifdef wx_xview
  277.   Frame x_frame = (Frame)handle;
  278.  
  279.   *x = (int)xv_get(x_frame, XV_WIDTH);
  280.   *y = (int)xv_get(x_frame, XV_HEIGHT) - y_offset;
  281. #endif
  282. #ifdef wx_msw
  283.   wxWnd *wnd = (wxWnd *)handle;
  284.   RECT rect;
  285.   GetClientRect(wnd->handle, &rect);
  286.   if (status_window)
  287.     rect.bottom -= status_window->height;
  288.  
  289.   *x = rect.right;
  290.   *y = rect.bottom;
  291. #endif
  292. }
  293.  
  294. // Set the client size (i.e. leave the calculation of borders etc.
  295. // to wxWindows)
  296. void wxFrame::SetClientSize(int width, int height)
  297. {
  298. #ifdef wx_motif
  299.   // Calculate how large the new main window should be
  300.   // by finding the difference between the client area and the
  301.   // main window area, and adding on to the new client area
  302.   Dimension current_frame_width, current_frame_height;
  303.   Dimension current_form_width, current_form_height;
  304.   XtVaGetValues(frameWidget, XmNwidth, ¤t_frame_width, XmNheight, ¤t_frame_height, NULL);
  305.   XtVaGetValues(workArea, XmNwidth, ¤t_form_width, XmNheight, ¤t_form_height, NULL);
  306.   int diffX = current_frame_width - current_form_width;
  307.   int diffY = current_frame_height - current_form_height;
  308.  
  309.   if (width > -1)
  310.     XtVaSetValues(frameWidget, XmNwidth, width + diffX, NULL);
  311.   if (height > -1)
  312.   {
  313.     int real_height = height + diffY;
  314.     if (status_line_exists)
  315.     {
  316.       Dimension ys;
  317.       XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL);
  318.       real_height += ys;
  319.     }
  320.  
  321.     XtVaSetValues(frameWidget, XmNheight, real_height, NULL);
  322.   }
  323.   OnSize(width, height);
  324. #endif
  325. #ifdef wx_xview
  326.   Frame x_frame = (Frame)handle;
  327.  
  328.   (void)xv_set(x_frame, XV_WIDTH, width, XV_HEIGHT, height + y_offset, NULL);
  329. #endif
  330. #ifdef wx_msw
  331.   wxWnd *wnd = (wxWnd *)handle;
  332.   RECT rect;
  333.   GetClientRect(wnd->handle, &rect);
  334.  
  335.   RECT rect2;
  336.   GetWindowRect(wnd->handle, &rect2);
  337.  
  338.   // Find the difference between the entire window (title bar and all)
  339.   // and the client area; add this to the new client size to move the
  340.   // window
  341.   int actual_width = rect2.right - rect2.left - rect.right + width;
  342.   int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
  343.  
  344.   if (status_window)
  345.     actual_height += status_window->height;
  346.  
  347.   MoveWindow(wnd->handle, rect2.left, rect2.top, actual_width, actual_height, TRUE);
  348.   OnSize(actual_width, actual_height);
  349. #endif
  350. }
  351.  
  352. void wxFrame::GetSize(int *width, int *height)
  353. {
  354. #ifdef wx_motif
  355.   Dimension xx, yy;
  356.   XtVaGetValues(frameWidget, XmNwidth, &xx, XmNheight, &yy, NULL);
  357.   *width = xx; *height = yy;
  358. #endif
  359. #ifdef wx_xview
  360.   Xv_opaque x_win = (Xv_opaque)handle;
  361.  
  362.   *width = (int)xv_get(x_win, XV_WIDTH);
  363.   *height = (int)xv_get(x_win, XV_HEIGHT);
  364. #endif
  365. #ifdef wx_msw
  366.   wxWnd *wnd = (wxWnd *)handle;
  367.   RECT rect;
  368.   GetWindowRect(wnd->handle, &rect);
  369.   *width = rect.right - rect.left;
  370.   *height = rect.bottom - rect.top;
  371. #endif
  372. }
  373.  
  374. void wxFrame::GetPosition(int *x, int *y)
  375. {
  376. #ifdef wx_motif
  377.   Widget widget = (Widget)handle;
  378.   Dimension xx, yy;
  379.   XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
  380.   *x = xx; *y = yy;
  381. #endif
  382. #ifdef wx_xview
  383.   Xv_opaque x_win = (Xv_opaque)handle;
  384.  
  385.   *x = (int)xv_get(x_win, XV_X);
  386.   *y = (int)xv_get(x_win, XV_Y);
  387. #endif
  388. #ifdef wx_msw
  389.   wxWnd *wnd = (wxWnd *)handle;
  390.   wxWindow *parent = GetParent();
  391.  
  392.   RECT rect;
  393.   GetWindowRect(wnd->handle, &rect);
  394.   POINT point;
  395.   point.x = rect.left;
  396.   point.y = rect.top;
  397.  
  398.   // Since we now have the absolute screen coords,
  399.   // if there's a parent we must subtract its top left corner
  400.   if (parent)
  401.   {
  402.     wxWnd *cparent = (wxWnd *)(parent->handle);
  403.     ScreenToClient(wnd->handle, &point);
  404.   }
  405.   *x = point.x;
  406.   *y = point.y;
  407.  
  408. #endif
  409. }
  410.  
  411. void wxFrame::SetSize(int x, int y, int width, int height)
  412. {
  413. #ifdef wx_motif
  414.   if (x > -1)
  415.     XtVaSetValues(frameShell, XmNx, x, NULL);
  416.   if (y > -1)
  417.     XtVaSetValues(frameShell, XmNy, y, NULL);
  418.   if (width > -1)
  419.     XtVaSetValues(frameWidget, XmNwidth, width, NULL);
  420.   if (height > -1)
  421.     XtVaSetValues(frameWidget, XmNheight, height, NULL);
  422.   OnSize(width, height);
  423. #endif
  424. #ifdef wx_xview
  425.   Xv_opaque x_win = (Xv_opaque)handle;
  426.  
  427.   (void)xv_set(x_win, XV_X, x, XV_Y, y, XV_WIDTH, width, XV_HEIGHT, height, NULL);
  428. #endif
  429. #ifdef wx_msw
  430.   int currentX, currentY;
  431.   GetPosition(¤tX, ¤tY);
  432.   if (x == -1)
  433.     x = currentX;
  434.   if (y == -1)
  435.     y = currentY;
  436.  
  437.   wxWnd *wnd = (wxWnd *)handle;
  438.   if (wnd)
  439.     MoveWindow(wnd->handle, x, y, width, height, TRUE);
  440.   OnSize(width, height);
  441. #endif
  442. }
  443.  
  444. void wxFrame::Show(Bool show)
  445. {
  446. #ifdef wx_motif
  447.   if (show)
  448.   {
  449.     XtMapWidget(frameShell);
  450.     XRaiseWindow(XtDisplay(frameShell), XtWindow(frameShell));
  451.   }
  452.   else
  453.     XtUnmapWidget(frameShell);
  454. #endif
  455. #ifdef wx_xview
  456.   Xv_opaque window = (Xv_opaque)handle;
  457.   xv_set(window, XV_SHOW, show, NULL);
  458. #endif
  459. #ifdef wx_msw
  460.   wxWnd *wnd = (wxWnd *)handle;
  461.   int cshow;
  462.   if (show)
  463.     cshow = SW_SHOW;
  464.   else
  465.     cshow = SW_HIDE;
  466.   ShowWindow(wnd->handle, cshow);
  467.   if (show)
  468.     BringWindowToTop(wnd->handle);
  469. #endif
  470. }
  471.  
  472. // Default activation behaviour - set the focus for the first child
  473. // window
  474. void wxFrame::OnActivate(Bool flag)
  475. {
  476.   if (flag && GetChildren() && (GetChildren()->Number() > 0))
  477.   {
  478.     wxWindow *child = (wxWindow *)GetChildren()->First()->Data();
  479.     child->SetFocus();
  480.   }
  481. }
  482.  
  483. wxMenuBar *wxFrame::GetMenuBar(void)
  484. {
  485.   return wx_menu_bar;
  486. }
  487.  
  488. #ifdef wx_xview
  489. Notify_value wxFrameInterposer(Frame x_frame, Event *x_event, Notify_arg arg,
  490.                                Notify_event_type type)
  491. {
  492.   wxFrame *frame = (wxFrame *)xv_get(x_frame, WIN_CLIENT_DATA);
  493.  
  494. //  cout << event_action(x_event) << "\n";
  495.  
  496.   if (frame && event_action(x_event) == WIN_RESIZE)
  497.     {
  498. //      cout << "Frame resized\n";
  499.         int width, height;
  500.         frame->GetSize(&width, &height);
  501.  
  502.         frame->OnSize(width, height);
  503.  
  504.        return notify_next_event_func(x_frame, (long unsigned int)x_event, arg, type);
  505.     }
  506.   else return notify_next_event_func(x_frame, (long unsigned int)x_event, arg, type);
  507. }
  508.  
  509. Notify_value
  510. wxFrameCloseInterposer(Notify_client client, Destroy_status status)
  511. {
  512.   wxFrame *frame = (wxFrame *)xv_get(client, WIN_CLIENT_DATA);
  513.  
  514.   if (status == DESTROY_CHECKING)
  515.   {
  516.     if (frame)
  517.     {
  518.       Bool answer = frame->OnClose();
  519.       if (!answer)
  520.         notify_veto_destroy(client);
  521.     }
  522.   }
  523.   else if (status == DESTROY_CLEANUP)
  524.   {
  525.     // Should we destroy the wxFrame or wot?
  526.     // Try to delete the wxFrame without allowing the Frame
  527.     // to be deleted, since this will be done by XView
  528.  
  529.     if (frame)
  530.     {
  531.       frame->Show(FALSE);
  532.       frame->handle = NULL;
  533.       delete frame;
  534.       if (frame == wxTheApp->wx_frame)
  535.         wxTheApp->wx_frame = NULL;
  536.     }
  537.     return notify_next_destroy_func(client, status);
  538.   }
  539.   else if (status == DESTROY_SAVE_YOURSELF)
  540.   {
  541.     // Do nothing - this is an Open Look specific feature
  542.   }
  543.   else  if (status == DESTROY_PROCESS_DEATH)
  544.   { 
  545.     if (!wxTheApp->death_processed)
  546.     {
  547.       wxTheApp->OnExit();
  548.       wxTheApp->death_processed = TRUE;
  549.     }
  550.   };
  551.   return NOTIFY_DONE;
  552. }
  553.  
  554. #endif
  555.  
  556. #ifdef wx_motif
  557. void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs)
  558. {
  559.   wxFrame *frame = (wxFrame *)client_data;
  560.   if (frame->OnClose())
  561.     delete frame;
  562. }
  563. #endif
  564.  
  565. void wxFrame::Iconize(Bool iconize)
  566. {
  567.   if (!iconize)
  568.     Show(TRUE);
  569. #ifdef wx_motif
  570.   XtVaSetValues(frameShell, XmNiconic, iconize, NULL);
  571. #endif
  572. #ifdef wx_xview
  573.   Xv_opaque window = (Xv_opaque)handle;
  574.   xv_set(window, FRAME_CLOSED, iconize, NULL);
  575. #endif
  576. #ifdef wx_msw
  577.   wxWnd *wnd = (wxWnd *)handle;
  578.   int cshow;
  579.   if (iconize)
  580.     cshow = SW_MINIMIZE;
  581.   else
  582.     cshow = SW_RESTORE;
  583.   ShowWindow(wnd->handle, cshow);
  584.   wx_iconized = iconize;
  585. #endif
  586. }
  587.  
  588. Bool wxFrame::Iconized(void)
  589. {
  590. #ifdef wx_motif
  591.   Bool iconic;
  592.   XtVaGetValues(frameShell, XmNiconic, &iconic, NULL);
  593.   return iconic;
  594. #endif
  595. #ifdef wx_xview
  596.   Xv_opaque window = (Xv_opaque)handle;
  597.   return xv_get(window, FRAME_CLOSED);
  598. #endif
  599. #ifdef wx_msw
  600.   wxWnd *wnd = (wxWnd *)handle;
  601.   return wx_iconized;
  602. #endif
  603. }
  604.  
  605.  
  606. void wxFrame::SetTitle(char *title)
  607. {
  608. #ifdef wx_motif
  609.   if (title)
  610.     XtVaSetValues(frameShell, 
  611.                   XmNtitle, title,
  612.                   XmNiconName, title,
  613.                   NULL);
  614. #endif
  615. #ifdef wx_xview
  616.   Frame xframe = (Frame)handle;
  617.   xv_set(xframe, FRAME_LABEL, title, NULL);
  618.   if (icon)
  619.   {
  620.     xv_set(icon->x_icon, XV_LABEL, title, NULL);
  621.     xv_set(xframe, FRAME_ICON, icon->x_icon, NULL);
  622.   }
  623. #endif
  624. #ifdef wx_msw
  625.   wxWnd *wnd = (wxWnd *)handle;
  626.   SetWindowText(wnd->handle, title);
  627. #endif
  628. }
  629.  
  630. void wxFrame::SetIcon(wxIcon *wx_icon)
  631. {
  632. /*
  633.   if (icon)
  634.     delete icon;
  635. */
  636.   icon = wx_icon;
  637. #ifdef wx_motif
  638.   if (!wx_icon->x_pixmap)
  639.     return;
  640.  
  641.   XtVaSetValues(frameShell, XmNiconPixmap, wx_icon->x_pixmap, NULL);
  642.  
  643.   // The following isn't necessary and doesn't even work (P.587 of Heller)
  644. /*
  645.   Display *dpy = XtDisplay(wxTheApp->topLevel);
  646.   Window window, root;
  647.   XtVaGetValues(frameShell, XmNiconWindow, &window, NULL);
  648.   if (!window)
  649.   {
  650.     int x, y;
  651.     unsigned int width, height, border_width, depth;
  652.     if (!XGetGeometry(dpy, wx_icon->x_pixmap, &root, &x, &y, &width, &height, &border_width,
  653.                       &depth) ||
  654.         !(window = XCreateSimpleWindow(dpy, root, 0, 0, width, height, (unsigned)0, 
  655.           CopyFromParent, CopyFromParent)))
  656.     {
  657.       XtVaSetValues(frameShell, XmNiconPixmap, wx_icon->x_pixmap, NULL);
  658.       return;
  659.     }
  660.     XSetWindowBackgroundPixmap(dpy, window, wx_icon->x_pixmap);
  661.     XClearWindow(dpy, window);
  662.   }
  663. */
  664. #endif
  665. #ifdef wx_xview
  666.   Frame xframe = (Frame)handle;
  667.   char *label = (char *)xv_get(xframe, FRAME_LABEL);
  668.   xv_set(wx_icon->x_icon, XV_LABEL, label, NULL);
  669.   xv_set(xframe, FRAME_ICON, wx_icon->x_icon, NULL);
  670. #endif
  671. #ifdef wx_msw
  672.   switch (frame_type)
  673.   {
  674.     case wxMDI_PARENT:
  675.     {
  676.       wxMDIFrame *wnd = (wxMDIFrame *)handle;
  677.       wnd->icon = wx_icon->ms_icon;
  678.       break;
  679.     }
  680.     case wxMDI_CHILD:
  681.     {
  682.       wxMDIChild *wnd = (wxMDIChild *)handle;
  683.       wnd->icon = wx_icon->ms_icon;
  684.       break;
  685.     }
  686.     default:
  687.     case wxSDI:
  688.     {
  689.       wxFrameWnd *wnd = (wxFrameWnd *)handle;
  690.       wnd->icon = wx_icon->ms_icon;
  691.       break;
  692.     }
  693.   }
  694. #endif
  695. }
  696.  
  697.  
  698. void wxFrame::CreateStatusLine(void)
  699. {
  700.   if (status_line_exists)
  701.     return;
  702.  
  703.   status_line_exists = TRUE;
  704.  
  705. #ifdef wx_motif
  706.   statusLineWidget = XtVaCreateManagedWidget("status_line",
  707.       xmFrameWidgetClass,      workArea,
  708.       XmNshadowType,           XmSHADOW_IN,
  709.       XmNbottomAttachment,     XmATTACH_FORM,
  710.       XmNleftAttachment,       XmATTACH_FORM,
  711.       XmNrightAttachment,      XmATTACH_FORM,
  712.       NULL);
  713.  
  714.   statusTextWidget = XtVaCreateManagedWidget("status_text",
  715.       xmLabelWidgetClass,      statusLineWidget,
  716.       XmNalignment,            XmALIGNMENT_BEGINNING,
  717.       NULL);
  718.   XtRealizeWidget(statusLineWidget);
  719.   XtRealizeWidget(statusTextWidget);
  720.  
  721.   SetStatusText("");
  722. #endif
  723. #ifdef wx_xview
  724.   Frame xframe = (Frame)handle;
  725.   xv_set(xframe, FRAME_SHOW_FOOTER, TRUE, NULL);
  726. #endif
  727. #ifdef wx_msw
  728.   wxFrameWnd *cframe = (wxFrameWnd *)handle;
  729.  
  730.   TEXTMETRIC tm;
  731.   HDC dc = GetDC(cframe->handle);
  732.   GetTextMetrics(dc, &tm);
  733.   ReleaseDC(cframe->handle, dc);
  734.   int char_height = tm.tmHeight + tm.tmExternalLeading;
  735.   int status_window_height =
  736.      (int)((char_height * 3.0/2.0) + 2*wxTHICK_LINE_BORDER);
  737.  
  738.   if (!wxStatusGreyPen)
  739.   {
  740.     wxStatusGreyPen = new wxPen("DIM GREY", wxTHICK_LINE_WIDTH, wxSOLID);
  741.     wxStatusWhitePen = new wxPen("WHITE", wxTHICK_LINE_WIDTH, wxSOLID);
  742.   }
  743.  
  744.   status_window = new wxStatusWnd(cframe, status_window_height);
  745.   PositionStatusWindow();
  746. #endif
  747. }
  748.  
  749. void wxFrame::SetStatusText(char *text)
  750. {
  751.   if (!status_line_exists)
  752.     return;
  753. #ifdef wx_motif
  754.   if (!text) text = " ";
  755.   sprintf(wxBuffer, " %s", text);
  756.   XmString str = XmStringCreateSimple(wxBuffer);
  757.   XtVaSetValues(statusTextWidget,
  758.                   XmNlabelString, str,
  759.                   NULL);
  760.   XmStringFree(str);
  761. #endif
  762. #ifdef wx_xview
  763.   Frame xframe = (Frame)handle;
  764.   xv_set(xframe, FRAME_LEFT_FOOTER, text, NULL);
  765. #endif
  766. #ifdef wx_msw
  767.   if (status_window->status_text)
  768.     delete status_window->status_text;
  769.  
  770.   if (text)
  771.     status_window->status_text = copystring(text);
  772.   else status_window->status_text = NULL;
  773.  
  774.   HDC dc = GetDC(status_window->handle);
  775.  
  776.   RECT rect;
  777.   GetClientRect(status_window->handle, &rect );
  778.  
  779.   int width = rect.right;
  780.   int height = rect.bottom;
  781.  
  782.   SetBkMode(dc, TRANSPARENT);
  783.  
  784.   ::SetTextColor(dc, ::GetSysColor( COLOR_WINDOWTEXT ) );
  785.  
  786.   TEXTMETRIC tm;
  787.   GetTextMetrics(dc, &tm);
  788.   int cy = tm.tmHeight + tm.tmExternalLeading;
  789.   int y = (int)((rect.bottom - cy)/2);
  790.  
  791.   rect.left += wxTHICK_LINE_BORDER + 1;
  792.   rect.top += wxTHICK_LINE_BORDER + 1;
  793.   rect.right -= (wxTHICK_LINE_BORDER + 1);
  794.   rect.bottom -= (wxTHICK_LINE_BORDER + 1);
  795.   FillRect(dc, &rect, status_window->light_grey_brush);
  796.  
  797.   IntersectClipRect(dc, wxTHICK_LINE_BORDER + 3, y-1,
  798.                             width - wxTHICK_LINE_BORDER - 1, height);
  799.  
  800.   if (status_window->status_text)
  801.     TextOut(dc, wxTHICK_LINE_BORDER + 4, y,
  802.                 status_window->status_text, strlen(status_window->status_text));
  803.  
  804.   SelectClipRgn(dc, NULL);
  805.   ReleaseDC(status_window->handle, dc);
  806. #endif
  807. }
  808.  
  809. Bool wxFrame::StatusLineExists(void)
  810. {
  811.   return status_line_exists;
  812. }
  813.  
  814. #ifdef wx_msw
  815. void wxFrame::PositionStatusWindow(void)
  816. {
  817.   wxFrameWnd *cframe = (wxFrameWnd *)handle;
  818.   RECT rect;
  819.   GetClientRect(cframe->handle, &rect);
  820.   int cwidth = rect.right;
  821.   int cheight = rect.bottom;
  822.   MoveWindow(status_window->handle, 0, cheight - status_window->height,
  823.                             cwidth, status_window->height, TRUE);
  824. }
  825. #endif
  826.  
  827. void wxFrame::LoadAccelerators(char *table)
  828. {
  829. #ifdef wx_msw
  830.   wxFrameWnd *cframe = (wxFrameWnd *)handle;
  831.   cframe->accelerator_table = ::LoadAccelerators(wxhInstance, table);
  832. #endif
  833. }
  834.  
  835. void wxFrame::Fit(void)
  836. {
  837. #ifdef wx_motif
  838.   int maxX = 0;
  839.   int maxY = 0;
  840.   wxNode *node = GetChildren()->First();
  841.   while (node)
  842.   {
  843.     wxWindow *win = (wxWindow *)node->Data();
  844.     int x, y, w, h;
  845.     win->GetPosition(&x, &y);
  846.     win->GetSize(&w, &h);
  847.     if ((x + w) > maxX)
  848.       maxX = x + w;
  849.     if ((y + h) > maxY)
  850.       maxY = y + h;
  851.     node = node->Next();
  852.   }
  853.   SetClientSize(maxX, maxY);
  854. #endif
  855. #ifdef wx_xview
  856.   Frame xframe = (Frame)handle;
  857.   window_fit(xframe);
  858. #endif
  859. #ifdef wx_msw
  860.   // Work out max. size
  861.   wxNode *node = children->First();
  862.   int max_width = 0;
  863.   int max_height = 0;
  864.   while (node)
  865.   {
  866.     wxWindow *win = (wxWindow *)node->Data();
  867.     int width, height;
  868.     int x, y;
  869.     win->GetSize(&width, &height);
  870.     win->GetPosition(&x, &y);
  871.  
  872.     if ((x + width) > max_width)
  873.       max_width = x + width;
  874.     if ((y + height) > max_height)
  875.       max_height = y + height;
  876.     node = node->Next();
  877.   }
  878.   SetClientSize(max_width, max_height);
  879. #endif
  880. }
  881.  
  882. void wxFrame::Centre(int direction)
  883. {
  884.   int display_width, display_height, width, height, x, y;
  885.   wxDisplaySize(&display_width, &display_height);
  886.  
  887.   GetSize(&width, &height);
  888.   GetPosition(&x, &y);
  889.  
  890.   if (direction == wxBOTH || direction == wxHORIZONTAL)
  891.     x = (int)((display_width - width)/2);
  892.   if (direction == wxBOTH || direction == wxVERTICAL)
  893.     y = (int)((display_height - height)/2);
  894.  
  895.   SetSize(x, y, width, height);
  896. }
  897.  
  898.  
  899.  
  900. #ifdef wx_msw
  901.  
  902. /*
  903.  * Windows 3 specific windows
  904.  *
  905.  */
  906.  
  907. wxStatusWnd::wxStatusWnd(wxFrameWnd *parent, int the_height)
  908. {
  909.   status_text = NULL;
  910.   height = the_height;
  911.   light_grey_brush = GetStockObject(LTGRAY_BRUSH);
  912.  
  913.   Create(parent, "wxPanelClass", NULL, NULL, 0, 0, 100, 100, WS_CHILD);
  914.   ShowWindow(handle, SW_SHOW);
  915. }
  916.  
  917. wxStatusWnd::~wxStatusWnd(void)
  918. {
  919.   if (status_text)
  920.     delete status_text;
  921. }
  922.  
  923. BOOL wxStatusWnd::OnPaint()
  924. {
  925.   RECT rect;
  926.   if (GetUpdateRect(handle, &rect, FALSE))
  927.   {
  928.     PAINTSTRUCT ps;
  929.     // Hold a pointer to the dc so long as the OnPaint() message
  930.     // is being processed
  931.     cdc = BeginPaint(handle, &ps);
  932.  
  933.     ::GetClientRect(handle, &rect);
  934.  
  935.     int width = rect.right;
  936.     int height = rect.bottom;
  937.  
  938.     ::SetBkMode(cdc, TRANSPARENT);
  939.     ::FillRect(cdc, &rect, light_grey_brush);
  940.  
  941.     HBRUSH old_brush = ::SelectObject(cdc, wxGREY_BRUSH->cbrush);
  942.  
  943.     // Draw border
  944.     // Have grey background, plus 3-d border -
  945.     // One black rectangle.
  946.     // Inside this, left and top sides - dark grey. Bottom and right -
  947.     // white.
  948.  
  949.     // Right and bottom white lines
  950.     HPEN old_pen = SelectObject(cdc, wxStatusWhitePen->cpen);
  951.     MoveToEx(cdc, width-wxTHICK_LINE_BORDER,
  952.                   wxTHICK_LINE_BORDER, NULL);
  953.     LineTo(cdc, width-wxTHICK_LINE_BORDER,
  954.                 height-wxTHICK_LINE_BORDER);
  955.     LineTo(cdc, wxTHICK_LINE_BORDER,
  956.               height-wxTHICK_LINE_BORDER);
  957.  
  958.     // Left and top grey lines
  959.     SelectObject(cdc, wxStatusGreyPen->cpen);
  960.     LineTo(cdc, wxTHICK_LINE_BORDER, wxTHICK_LINE_BORDER);
  961.     LineTo(cdc, width-wxTHICK_LINE_BORDER, wxTHICK_LINE_BORDER);
  962.  
  963.     SetTextColor(cdc, ::GetSysColor( COLOR_WINDOWTEXT ) );
  964.  
  965.     TEXTMETRIC tm;
  966.     ::GetTextMetrics(cdc, &tm);
  967.     int cy = tm.tmHeight + tm.tmExternalLeading;
  968.     int y = (int)((rect.bottom - cy)/2);
  969.  
  970.     ::IntersectClipRect(cdc, wxTHICK_LINE_BORDER + 3, y-1,
  971.                             rect.right - wxTHICK_LINE_BORDER - 1, rect.bottom);
  972.  
  973.     if (status_text)
  974.       ::TextOut(cdc, wxTHICK_LINE_BORDER + 4, y,
  975.                   status_text, strlen(status_text));
  976.  
  977.     ::SelectClipRgn(cdc, NULL);
  978.     SelectObject(cdc, old_pen);
  979.     SelectObject(cdc, old_brush);
  980.  
  981.     EndPaint(handle, &ps);
  982.     cdc = NULL;
  983.     return 0;
  984.   }
  985.   return 1;
  986. }
  987.  
  988.  
  989. /*
  990.  * Frame window
  991.  *
  992.  */
  993.  
  994. wxFrameWnd::wxFrameWnd(wxWnd *parent, char *wclass, wxWindow *wx_win, char *title,
  995.                    int x, int y, int width, int height, DWORD style)
  996. {
  997.   icon = NULL;
  998.   iconized = FALSE;
  999.   Create(parent, "wxFrameClass", wx_win, title, x, y, width, height,
  1000.          style);
  1001. }
  1002.  
  1003. wxFrameWnd::~wxFrameWnd(void)
  1004. {
  1005. }
  1006.  
  1007. BOOL wxFrameWnd::OnPaint(void)
  1008. {
  1009.   RECT rect;
  1010.   if (GetUpdateRect(handle, &rect, FALSE))
  1011.   {
  1012.     PAINTSTRUCT ps;
  1013.     // Hold a pointer to the dc so long as the OnPaint() message
  1014.     // is being processed
  1015.     cdc = BeginPaint(handle, &ps);
  1016.  
  1017.     if (iconized)
  1018.     {
  1019.       HICON the_icon = icon;
  1020.       if (the_icon == 0)
  1021.         the_icon = wxSTD_FRAME_ICON;
  1022.  
  1023.       if (the_icon)
  1024.       {
  1025.         RECT rect;
  1026.         GetClientRect(handle, &rect);
  1027.         int icon_width = 32;
  1028.         int icon_height = 32;
  1029.         int icon_x = (int)((rect.right - icon_width)/2);
  1030.         int icon_y = (int)((rect.bottom - icon_height)/2);
  1031.         DrawIcon(cdc, icon_x, icon_y, the_icon);
  1032.       }
  1033.     }
  1034.  
  1035.     if (!iconized && wx_window)
  1036.       wx_window->OnPaint();
  1037.  
  1038.     EndPaint(handle, &ps);
  1039.     cdc = NULL;
  1040.     return 0;
  1041.   }
  1042.   return 1;
  1043. }
  1044.  
  1045. void wxFrameWnd::OnSize(int x, int y, UINT id)
  1046. {
  1047.   switch (id)
  1048.   {
  1049.     case SIZEFULLSCREEN:
  1050.     case SIZENORMAL:
  1051.       iconized = FALSE;
  1052.     break;
  1053.     case SIZEICONIC:
  1054.       iconized = TRUE;
  1055.     break;
  1056.   }
  1057.  
  1058.  if (!iconized)
  1059.  {
  1060.   wxFrame *frame = (wxFrame *)wx_window;
  1061.   if (frame && frame->status_window)
  1062.     frame->PositionStatusWindow();
  1063.  
  1064.   if (wx_window && wx_window->handle)
  1065.     wx_window->OnSize(x, y);
  1066.  }
  1067. }
  1068.  
  1069. BOOL wxFrameWnd::OnClose(void)
  1070. {
  1071.   if (wx_window)
  1072.   {
  1073.     if (wx_window->OnClose())
  1074.     {
  1075.       delete wx_window;
  1076.       return TRUE;
  1077.     } else return FALSE;
  1078.   }
  1079.   return FALSE;
  1080. }
  1081.  
  1082. BOOL wxFrameWnd::OnCommand(WORD id, WORD cmd, HWND control)
  1083. {
  1084.   if (cmd == 0)
  1085.   {
  1086.     wx_window->OnMenuCommand(id);
  1087.     return TRUE;
  1088.   }
  1089.   else
  1090.     return FALSE;
  1091. }
  1092.  
  1093. void wxFrameWnd::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
  1094. {
  1095.   wxFrame *frame = (wxFrame *)wx_window;
  1096.   if (nFlags == -1 && hSysMenu == NULL)
  1097.     frame->OnMenuSelect(-1);
  1098.   else if (nFlags != MF_SEPARATOR)
  1099.     frame->OnMenuSelect(nItem);
  1100. }
  1101.  
  1102. /*
  1103.  * Windows MDI stuff
  1104.  */
  1105.  
  1106. wxMDIFrame::wxMDIFrame(wxWnd *parent, wxWindow *wx_win, char *title,
  1107.                    int x, int y, int width, int height)
  1108. {
  1109.   icon = NULL;
  1110.   iconized = FALSE;
  1111.   parent_frame_active = TRUE;
  1112.   current_child = NULL;
  1113.  
  1114.   window_menu = ::LoadMenu(wxhInstance, "wxDefaultMenu");
  1115.  
  1116.   Create(parent, "wxMDIFrameClass", wx_win, title, x, y, width, height,
  1117.          WS_OVERLAPPEDWINDOW);
  1118. }
  1119.  
  1120. wxMDIFrame::~wxMDIFrame(void)
  1121. {
  1122.   DestroyMenu(window_menu);
  1123. }
  1124.  
  1125. void wxMDIFrame::OnCreate(LPCREATESTRUCT cs)
  1126. {
  1127.   CLIENTCREATESTRUCT ccs;
  1128.     
  1129.   ccs.hWindowMenu = window_menu;
  1130.   ccs.idFirstChild = wxFIRST_MDI_CHILD;
  1131.  
  1132.   client_hwnd = ::CreateWindowEx(0, "mdiclient", NULL,
  1133.                 WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN, 0, 0, 0, 0, handle, NULL,
  1134.                 wxhInstance, (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
  1135. }
  1136.  
  1137. BOOL wxMDIFrame::OnPaint(void)
  1138. {
  1139.   (void)DefWindowProc(last_msg, last_wparam, last_lparam);
  1140.   RECT rect;
  1141.   if (GetUpdateRect(handle, &rect, FALSE))
  1142.   {
  1143.     PAINTSTRUCT ps;
  1144.     // Hold a pointer to the dc so long as the OnPaint() message
  1145.     // is being processed
  1146.     cdc = BeginPaint(handle, &ps);
  1147.  
  1148.     if (iconized)
  1149.     {
  1150.       HICON the_icon = icon;
  1151.       if (the_icon == 0)
  1152.         the_icon = wxSTD_FRAME_ICON;
  1153.  
  1154.       if (the_icon)
  1155.       {
  1156.         RECT rect;
  1157.         GetClientRect(handle, &rect);
  1158.         int icon_width = 32;
  1159.         int icon_height = 32;
  1160.         int icon_x = (int)((rect.right - icon_width)/2);
  1161.         int icon_y = (int)((rect.bottom - icon_height)/2);
  1162.         DrawIcon(cdc, icon_x, icon_y, the_icon);
  1163.       }
  1164.     }
  1165.  
  1166.     if (!iconized && wx_window)
  1167.       wx_window->OnPaint();
  1168.  
  1169.     EndPaint(handle, &ps);
  1170.     cdc = NULL;
  1171.     return 0;
  1172.   }
  1173.   return 1;
  1174. }
  1175.  
  1176. void wxMDIFrame::OnSize(int x, int y, UINT id)
  1177. {
  1178.   switch (id)
  1179.   {
  1180.     case SIZEFULLSCREEN:
  1181.     case SIZENORMAL:
  1182.       iconized = FALSE;
  1183.     break;
  1184.     case SIZEICONIC:
  1185.       iconized = TRUE;
  1186.     break;
  1187.   }
  1188.  
  1189.  if (!iconized)
  1190.  {
  1191.   wxFrame *frame = (wxFrame *)wx_window;
  1192.  
  1193.   if (frame && frame->status_window)
  1194.   {
  1195.     RECT rect;
  1196.     GetClientRect(handle, &rect);
  1197.     int cwidth = rect.right;
  1198.     int cheight = rect.bottom;
  1199.  
  1200.     MoveWindow(client_hwnd, 0, 0,
  1201.                cwidth, cheight - frame->status_window->height,
  1202.                TRUE);
  1203.  
  1204.     frame->PositionStatusWindow();
  1205.   }
  1206.   else (void)DefWindowProc(last_msg, last_wparam, last_lparam);
  1207.  
  1208.   if (wx_window && wx_window->handle)
  1209.     wx_window->OnSize(x, y);
  1210.   }
  1211. }
  1212.  
  1213. BOOL wxMDIFrame::OnClose(void)
  1214. {
  1215.   if (wx_window)
  1216.   {
  1217.     if (wx_window->OnClose())
  1218.     {
  1219.       delete wx_window;
  1220.       return TRUE;
  1221.     } else return FALSE;
  1222.   }
  1223.   return FALSE;
  1224. }
  1225.  
  1226. BOOL wxMDIFrame::OnCommand(WORD id, WORD cmd, HWND control)
  1227. {
  1228.   if (cmd == 0)
  1229.   {
  1230.     switch (id)
  1231.     {
  1232.       case IDM_WINDOWCASCADE:
  1233.         SendMessage(client_hwnd, WM_MDICASCADE, MDITILE_SKIPDISABLED, 0);
  1234.         return TRUE;
  1235.         break;
  1236.       case IDM_WINDOWTILE:
  1237.         SendMessage(client_hwnd, WM_MDITILE, MDITILE_HORIZONTAL, 0);
  1238.         return TRUE;
  1239.         break;
  1240.       case IDM_WINDOWICONS:
  1241.         SendMessage(client_hwnd, WM_MDIICONARRANGE, 0, 0);
  1242.         return TRUE;
  1243.         break;
  1244.       case IDM_WINDOWNEXT:
  1245.         SendMessage(client_hwnd, WM_MDINEXT, current_child->handle, 0);
  1246.         return TRUE;
  1247.         break;
  1248.       default:
  1249.         break;
  1250.      }
  1251.  
  1252.     if (parent_frame_active && id < wxFIRST_MDI_CHILD)
  1253.     {
  1254.       wx_window->OnMenuCommand(id);
  1255.       return TRUE;
  1256.     }
  1257.     else if (current_child && id < wxFIRST_MDI_CHILD)
  1258.     {
  1259.       return current_child->OnCommand(id, cmd, control);
  1260.     }
  1261.  }
  1262.  return DefWindowProc(last_msg, last_wparam, last_lparam);
  1263. }
  1264.  
  1265. void wxMDIFrame::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
  1266. {
  1267.   if (parent_frame_active)
  1268.   {
  1269.     wxFrame *frame = (wxFrame *)wx_window;
  1270.     if (nFlags == -1 && hSysMenu == NULL)
  1271.       frame->OnMenuSelect(-1);
  1272.     else if (nFlags != MF_SEPARATOR)
  1273.       frame->OnMenuSelect(nItem);
  1274.   }
  1275.   else if (current_child)
  1276.   {
  1277.     current_child->OnMenuSelect(nItem, nFlags, hSysMenu);
  1278.   }
  1279. }
  1280.  
  1281. long wxMDIFrame::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam)
  1282. {
  1283.   return DefFrameProc(handle, client_hwnd, message, wParam, lParam);
  1284. }
  1285.  
  1286. BOOL wxMDIFrame::ProcessMessage(MSG* pMsg)
  1287. {
  1288.   if (current_child != NULL && current_child->ProcessMessage(pMsg))
  1289.      return TRUE;
  1290.     
  1291.   if (accelerator_table != NULL &&
  1292.           ::TranslateAccelerator(handle, accelerator_table, pMsg))
  1293.     return TRUE;
  1294.     
  1295.   if (pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN)
  1296.   {
  1297.     if (::TranslateMDISysAccel(client_hwnd, pMsg))
  1298.       return TRUE;
  1299.   }
  1300.  
  1301.   return FALSE;
  1302. }
  1303.  
  1304. BOOL wxMDIFrame::OnEraseBkgnd(HDC pDC)
  1305. {
  1306.   return TRUE;
  1307. }
  1308.  
  1309. extern wxWnd *wxWndHook;
  1310. extern wxList *wxWinHandleList;
  1311. wxMDIChild::wxMDIChild(wxMDIFrame *parent, wxWindow *wx_win, char *title,
  1312.                    int x, int y, int width, int height)
  1313. {
  1314.   icon = NULL;
  1315.   iconized = FALSE;
  1316.   wx_window = wx_win;
  1317.   active = FALSE;
  1318.   is_dialog = FALSE;
  1319.  
  1320.   HWND hParent = NULL;
  1321.   if (parent)
  1322.     hParent = parent->handle;
  1323.  
  1324.   wxWndHook = this;
  1325.  
  1326.   MDICREATESTRUCT mcs;
  1327.     
  1328.   mcs.szClass = "wxMDIChildFrameClass";
  1329.   mcs.szTitle = title;
  1330.   mcs.hOwner = wxhInstance;
  1331.   if (x > -1) mcs.x = x;
  1332.   else mcs.x = CW_USEDEFAULT;
  1333.  
  1334.   if (y > -1) mcs.y = y;
  1335.   else mcs.y = CW_USEDEFAULT;
  1336.  
  1337.   if (width > -1) mcs.cx = width;
  1338.   else mcs.cx = CW_USEDEFAULT;
  1339.  
  1340.   if (height > -1) mcs.cy = height;
  1341.   else mcs.cy = CW_USEDEFAULT;
  1342.  
  1343.   mcs.style = WS_OVERLAPPEDWINDOW;
  1344.   mcs.lParam = 0;
  1345.  
  1346.   DWORD Return = SendMessage(parent->client_hwnd,
  1347.         WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
  1348.  
  1349.   handle = (HWND)LOWORD(Return);
  1350.  
  1351.   wxWndHook = NULL;
  1352.   wxWinHandleList->Append((long)handle, this);
  1353.  
  1354.   SetWindowLong(handle, 0, (long)this);
  1355. }
  1356.  
  1357.  
  1358. BOOL wxMDIChild::OnPaint(void)
  1359. {
  1360.   (void)DefWindowProc(last_msg, last_wparam, last_lparam);
  1361.  
  1362.   RECT rect;
  1363.   if (GetUpdateRect(handle, &rect, FALSE))
  1364.   {
  1365.     PAINTSTRUCT ps;
  1366.     // Hold a pointer to the dc so long as the OnPaint() message
  1367.     // is being processed
  1368.     cdc = BeginPaint(handle, &ps);
  1369.  
  1370.     if (iconized)
  1371.     {
  1372.       HICON the_icon = icon;
  1373.       if (the_icon == 0)
  1374.         the_icon = wxSTD_FRAME_ICON;
  1375.  
  1376.       if (the_icon)
  1377.       {
  1378.         RECT rect;
  1379.         GetClientRect(handle, &rect);
  1380.         int icon_width = 32;
  1381.         int icon_height = 32;
  1382.         int icon_x = (int)((rect.right - icon_width)/2);
  1383.         int icon_y = (int)((rect.bottom - icon_height)/2);
  1384.         DrawIcon(cdc, icon_x, icon_y, the_icon);
  1385.       }
  1386.     }
  1387.  
  1388.     if (!iconized && wx_window)
  1389.       wx_window->OnPaint();
  1390.  
  1391.     EndPaint(handle, &ps);
  1392.     cdc = NULL;
  1393.     return 0;
  1394.   }
  1395.   return 1;
  1396. }
  1397.  
  1398. void wxMDIChild::OnSize(int x, int y, UINT id)
  1399. {
  1400.   (void)DefWindowProc(last_msg, last_wparam, last_lparam);
  1401.   switch (id)
  1402.   {
  1403.     case SIZEFULLSCREEN:
  1404.     case SIZENORMAL:
  1405.       iconized = FALSE;
  1406.     break;
  1407.     case SIZEICONIC:
  1408.       iconized = TRUE;
  1409.     break;
  1410.   }
  1411.  
  1412.  if (!iconized)
  1413.  {
  1414.   wxFrame *frame = (wxFrame *)wx_window;
  1415.   if (frame && frame->status_window)
  1416.     frame->PositionStatusWindow();
  1417.  
  1418.   if (wx_window && wx_window->handle)
  1419.     wx_window->OnSize(x, y);
  1420.  }
  1421. }
  1422.  
  1423. BOOL wxMDIChild::OnClose(void)
  1424. {
  1425.   if (wx_window)
  1426.   {
  1427.     if (wx_window->OnClose())
  1428.     {
  1429.       delete wx_window;
  1430.       return TRUE;
  1431.     } else return FALSE;
  1432.   }
  1433.   return FALSE;
  1434. }
  1435.  
  1436. BOOL wxMDIChild::OnCommand(WORD id, WORD cmd, HWND control)
  1437. {
  1438.   (void)DefWindowProc(last_msg, last_wparam, last_lparam);
  1439.   if (cmd == 0)
  1440.   {
  1441.     wx_window->OnMenuCommand(id);
  1442.     return TRUE;
  1443.   }
  1444.   else
  1445.     return FALSE;
  1446. }
  1447.  
  1448. void wxMDIChild::OnMenuSelect(WORD nItem, WORD nFlags, HMENU hSysMenu)
  1449. {
  1450.   wxFrame *frame = (wxFrame *)wx_window;
  1451.   if (nFlags == -1 && hSysMenu == NULL)
  1452.     frame->OnMenuSelect(-1);
  1453.   else if (nFlags != MF_SEPARATOR)
  1454.     frame->OnMenuSelect(nItem);
  1455. }
  1456.  
  1457. long wxMDIChild::DefWindowProc(UINT message, UINT wParam, LONG lParam)
  1458. {
  1459.   return DefMDIChildProc(handle, message, wParam, lParam);
  1460. }
  1461.  
  1462. BOOL wxMDIChild::ProcessMessage(MSG *msg)
  1463. {
  1464.   if (accelerator_table)
  1465.   {
  1466.     wxFrame *parent = (wxFrame *)wx_window->GetParent();
  1467.     HWND parent_hwnd = ((wxWnd *)parent->handle)->handle;
  1468.     return ::TranslateAccelerator(parent_hwnd, accelerator_table, msg);
  1469.   }
  1470.   return FALSE;
  1471. }
  1472.  
  1473. BOOL wxMDIChild::OnMDIActivate(BOOL bActivate, HWND,
  1474.                                                 HWND)
  1475. {
  1476.   wxFrame *parent = (wxFrame *)wx_window->GetParent();
  1477.   wxFrame *child = (wxFrame *)wx_window;
  1478.   HMENU parent_menu = parent->GetWinMenu();
  1479.   HMENU child_menu = child->GetWinMenu();
  1480.   wxMDIFrame *cparent = (wxMDIFrame *)parent->handle;
  1481.   if (bActivate)
  1482.   {
  1483.     active = TRUE;
  1484.     cparent->current_child = this;
  1485.     if (child_menu)
  1486.     {
  1487.       cparent->parent_frame_active = FALSE;
  1488. #ifdef WIN32
  1489.       ::SendMessage(cparent->client_hwnd, WM_MDISETMENU, child_menu,
  1490.                   GetSubMenu(cparent->window_menu, 0));
  1491. #else
  1492.       ::SendMessage(cparent->client_hwnd, WM_MDISETMENU, 0,
  1493.                   MAKELONG(child_menu, GetSubMenu(cparent->window_menu, 0)));
  1494. #endif
  1495.  
  1496.       ::DrawMenuBar(cparent->handle);
  1497.     }
  1498.   }
  1499.   else
  1500.   {
  1501.     if (cparent->current_child == this)
  1502.       cparent->current_child = NULL;
  1503.  
  1504.     active = FALSE;
  1505.     if (parent_menu)
  1506.     {
  1507.       cparent->parent_frame_active = TRUE;
  1508. #ifdef WIN32
  1509.       ::SendMessage(cparent->client_hwnd, WM_MDISETMENU, parent_menu,
  1510.                    GetSubMenu(cparent->window_menu, 0));
  1511. #else
  1512.       ::SendMessage(cparent->client_hwnd, WM_MDISETMENU, 0,
  1513.                   MAKELONG(parent_menu, GetSubMenu(cparent->window_menu, 0)));
  1514. #endif
  1515.  
  1516.       ::DrawMenuBar(cparent->handle);
  1517.     }
  1518.   }
  1519.   wx_window->OnActivate(bActivate);
  1520.   return 0;
  1521. }
  1522.  
  1523. wxMDIChild::~wxMDIChild(void)
  1524. {
  1525. }
  1526.  
  1527. void wxMDIChild::DestroyWindow(void)
  1528. {
  1529.   wxFrame *parent = (wxFrame *)wx_window->GetParent();
  1530.   wxMDIFrame *cparent = (wxMDIFrame *)parent->handle;
  1531.   SendMessage(cparent->client_hwnd, WM_MDIDESTROY, (HWND)handle, 0);
  1532. }
  1533.  
  1534. #endif
  1535.  
  1536.