home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / src / os2 / mdi.cpp < prev    next >
C/C++ Source or Header  |  2002-08-16  |  33KB  |  1,183 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        mdi.cpp
  3. // Purpose:     MDI classes
  4. // Author:      David Webster
  5. // Modified by:
  6. // Created:     10/10/99
  7. // RCS-ID:      $Id: MDI.CPP,v 1.15 2002/08/16 09:55:54 JS Exp $
  8. // Copyright:   (c) David Webster
  9. // Licence:     wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #ifndef WX_PRECOMP
  16.     #include "wx/setup.h"
  17.     #include "wx/frame.h"
  18.     #include "wx/menu.h"
  19.     #include "wx/app.h"
  20.     #include "wx/utils.h"
  21.     #include "wx/dialog.h"
  22.     #include "wx/statusbr.h"
  23.     #include "wx/settings.h"
  24.     #include "wx/intl.h"
  25.     #include "wx/log.h"
  26. #endif
  27.  
  28. #include "wx/mdi.h"
  29. #include "wx/os2/private.h"
  30.  
  31. #include <string.h>
  32.  
  33. // ---------------------------------------------------------------------------
  34. // global variables
  35. // ---------------------------------------------------------------------------
  36.  
  37. extern wxWindowList wxModelessWindows;      // from dialog.cpp
  38. extern wxMenu *wxCurrentPopupMenu;
  39.  
  40. extern wxWindow *wxWndHook;                 // from window.cpp
  41.  
  42. extern void wxAssociateWinWithHandle(HWND hWnd, wxWindow *win);
  43.  
  44. static HWND invalidHandle = 0;
  45.  
  46. // ---------------------------------------------------------------------------
  47. // constants
  48. // ---------------------------------------------------------------------------
  49.  
  50. static const int IDM_WINDOWTILE  = 4001;
  51. static const int IDM_WINDOWTILEHOR  = 4001;
  52. static const int IDM_WINDOWCASCADE = 4002;
  53. static const int IDM_WINDOWICONS = 4003;
  54. static const int IDM_WINDOWNEXT = 4004;
  55. static const int IDM_WINDOWTILEVERT = 4005;
  56. static const int IDM_WINDOWPREV = 4006;
  57.  
  58. // This range gives a maximum of 500 MDI children. Should be enough :-)
  59. static const int wxFIRST_MDI_CHILD = 4100;
  60. static const int wxLAST_MDI_CHILD = 4600;
  61.  
  62. // Status border dimensions
  63. static const int wxTHICK_LINE_BORDER = 3;
  64. static const int wxTHICK_LINE_WIDTH  = 1;
  65.  
  66. // ---------------------------------------------------------------------------
  67. // private functions
  68. // ---------------------------------------------------------------------------
  69.  
  70. // set the MDI menus (by sending the WM_MDISETMENU message) and update the menu
  71. // of the parent of win (which is supposed to be the MDI client window)
  72. static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow);
  73.  
  74. // insert the window menu (subMenu) into menu just before "Help" submenu or at
  75. // the very end if not found
  76. static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu);
  77.  
  78. // is this an id of an MDI child?
  79. inline bool IsMdiCommandId(int id)
  80. {
  81.     return (id >= wxFIRST_MDI_CHILD) && (id <= wxLAST_MDI_CHILD);
  82. }
  83.  
  84. // unpack the parameters of WM_MDIACTIVATE message
  85. static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
  86.                               WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact);
  87.  
  88. // return the HMENU of the MDI menu
  89. static inline HMENU GetMDIWindowMenu(wxMDIParentFrame *frame)
  90. {
  91.     wxMenu *menu = frame->GetWindowMenu();
  92.     return menu ? GetHmenuOf(menu) : 0;
  93. }
  94.  
  95. // ===========================================================================
  96. // implementation
  97. // ===========================================================================
  98.  
  99. // ---------------------------------------------------------------------------
  100. // wxWin macros
  101. // ---------------------------------------------------------------------------
  102.  
  103.     IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame)
  104.     IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame)
  105.     IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow)
  106.  
  107. BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame)
  108.     EVT_SIZE(wxMDIParentFrame::OnSize)
  109.     EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged)
  110. END_EVENT_TABLE()
  111.  
  112. BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow)
  113.     EVT_SCROLL(wxMDIClientWindow::OnScroll)
  114. END_EVENT_TABLE()
  115.  
  116. // ===========================================================================
  117. // wxMDIParentFrame: the frame which contains the client window which manages
  118. // the children
  119. // ===========================================================================
  120.  
  121. wxMDIParentFrame::wxMDIParentFrame()
  122. {
  123.     m_clientWindow = NULL;
  124.     m_currentChild = NULL;
  125.     m_windowMenu = 0;
  126.     m_parentFrameActive = TRUE;
  127. }
  128.  
  129. bool wxMDIParentFrame::Create(wxWindow *parent,
  130.                               wxWindowID id,
  131.                               const wxString& title,
  132.                               const wxPoint& pos,
  133.                               const wxSize& size,
  134.                               long style,
  135.                               const wxString& name)
  136. {
  137.   m_hDefaultIcon = (WXHICON) (wxSTD_MDIPARENTFRAME_ICON ? wxSTD_MDIPARENTFRAME_ICON : wxDEFAULT_MDIPARENTFRAME_ICON);
  138.  
  139.   m_clientWindow = NULL;
  140.   m_currentChild = NULL;
  141.   m_windowMenu = 0;
  142.   m_parentFrameActive = TRUE;
  143.  
  144.   if (!parent)
  145.     wxTopLevelWindows.Append(this);
  146.  
  147.   SetName(name);
  148.   wxWindowBase::Show(TRUE); // MDI child frame starts off shown
  149.   m_windowStyle = style;
  150.  
  151.   if (parent) parent->AddChild(this);
  152.  
  153.   if ( id > -1 )
  154.     m_windowId = id;
  155.   else
  156.     m_windowId = (int)NewControlId();
  157.  
  158.   int x = pos.x;
  159.   int y = pos.y;
  160.   int width = size.x;
  161.   int height = size.y;
  162.  
  163. // TODO:  m_windowMenu = (WXHMENU) ::LoadMenu(wxGetInstance(), wxT("wxWindowMenu"));
  164. /*
  165.   DWORD msflags = WS_OVERLAPPED;
  166.   if (style & wxMINIMIZE_BOX)
  167.     msflags |= WS_MINIMIZEBOX;
  168.   if (style & wxMAXIMIZE_BOX)
  169.     msflags |= WS_MAXIMIZEBOX;
  170.   if (style & wxTHICK_FRAME)
  171.     msflags |= WS_THICKFRAME;
  172.   if (style & wxSYSTEM_MENU)
  173.     msflags |= WS_SYSMENU;
  174.   if ((style & wxMINIMIZE) || (style & wxICONIZE))
  175.     msflags |= WS_MINIMIZE;
  176.   if (style & wxMAXIMIZE)
  177.     msflags |= WS_MAXIMIZE;
  178.   if (style & wxCAPTION)
  179.     msflags |= WS_CAPTION;
  180.  
  181.   if (style & wxCLIP_CHILDREN)
  182.     msflags |= WS_CLIPCHILDREN;
  183.  
  184.   wxWindow::MSWCreate(m_windowId, parent, wxMDIFrameClassName, this, title, x, y, width, height,
  185.          msflags);
  186. */
  187.   wxModelessWindows.Append(this);
  188.  
  189.   return TRUE;
  190. }
  191.  
  192. wxMDIParentFrame::~wxMDIParentFrame()
  193. {
  194.     DestroyChildren();
  195.  
  196. // TODO:    ::DestroyMenu((HMENU)m_windowMenu);
  197.     m_windowMenu = 0;
  198.  
  199.     if ( m_clientWindow )
  200.     {
  201.         if ( m_clientWindow->OS2GetOldWndProc() )
  202.             m_clientWindow->UnsubclassWin();
  203.  
  204.         m_clientWindow->SetHWND(0);
  205.         delete m_clientWindow;
  206.     }
  207. }
  208.  
  209. void wxMDIParentFrame::InternalSetMenuBar()
  210. {
  211.     // TODO:
  212. /*
  213.     HMENU subMenu = GetSubMenu((HMENU) m_windowMenu, 0);
  214.  
  215.     m_parentFrameActive = TRUE;
  216.  
  217.     InsertWindowMenu(GetClientWindow(), m_hMenu, subMenu);
  218. */
  219. }
  220.  
  221. void wxMDIParentFrame::OnSize(wxSizeEvent& event)
  222. {
  223.     // TODO:
  224. /*
  225.     if ( GetClientWindow() )
  226.     {
  227.         int width, height;
  228.         GetClientSize(&width, &height);
  229.  
  230.         GetClientWindow()->SetSize(0, 0, width, height);
  231.     }
  232. */
  233. }
  234.  
  235. // Returns the active MDI child window
  236. wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
  237. {
  238.     HWND hWnd = 0; // TODO: (HWND)::SendMessage(GetWinHwnd(GetClientWindow()),
  239. //                                    WM_MDIGETACTIVE, 0, 0L);
  240.     if ( hWnd == 0 )
  241.         return NULL;
  242.     else
  243.         return (wxMDIChildFrame *)wxFindWinFromHandle((WXHWND) hWnd);
  244. }
  245.  
  246. // Create the client window class (don't Create the window, just return a new
  247. // class)
  248. wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
  249. {
  250.     return new wxMDIClientWindow;
  251. }
  252.  
  253. // Responds to colour changes, and passes event on to children.
  254. void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
  255. {
  256.     if ( m_clientWindow )
  257.     {
  258.         m_clientWindow->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE));
  259.         m_clientWindow->Refresh();
  260.     }
  261.  
  262.     event.Skip();
  263. }
  264.  
  265. // ---------------------------------------------------------------------------
  266. // MDI operations
  267. // ---------------------------------------------------------------------------
  268.  
  269. void wxMDIParentFrame::Cascade()
  270. {
  271. // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDICASCADE, 0, 0);
  272. }
  273.  
  274. // TODO: add a direction argument (hor/vert)
  275. void wxMDIParentFrame::Tile()
  276. {
  277. // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDITILE, MDITILE_HORIZONTAL, 0);
  278. }
  279.  
  280. void wxMDIParentFrame::ArrangeIcons()
  281. {
  282. // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDIICONARRANGE, 0, 0);
  283. }
  284.  
  285. void wxMDIParentFrame::ActivateNext()
  286. {
  287. // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 0);
  288. }
  289.  
  290. void wxMDIParentFrame::ActivatePrevious()
  291. {
  292. // TODO:    ::SendMessage(GetWinHwnd(GetClientWindow()), WM_MDINEXT, 0, 1);
  293. }
  294.  
  295. // ---------------------------------------------------------------------------
  296. // the MDI parent frame window proc
  297. // ---------------------------------------------------------------------------
  298.  
  299. MRESULT wxMDIParentFrame::OS2WindowProc(WXUINT message,
  300.                                         WXWPARAM wParam,
  301.                                         WXLPARAM lParam)
  302. {
  303.     MRESULT rc = 0;
  304.     bool processed = FALSE;
  305.  
  306.     // TODO:
  307. /*
  308.     switch ( message )
  309.     {
  310.         case WM_ACTIVATE:
  311.             {
  312.                 WXWORD state, minimized;
  313.                 WXHWND hwnd;
  314.                 UnpackActivate(wParam, lParam, &state, &minimized, &hwnd);
  315.  
  316.                 processed = HandleActivate(state, minimized != 0, hwnd);
  317.             }
  318.             break;
  319.  
  320.         case WM_COMMAND:
  321.             {
  322.                 WXWORD id, cmd;
  323.                 WXHWND hwnd;
  324.                 UnpackCommand(wParam, lParam, &id, &hwnd, &cmd);
  325.  
  326.                 (void)HandleCommand(id, cmd, hwnd);
  327.  
  328.                 // even if the frame didn't process it, there is no need to try it
  329.                 // once again (i.e. call wxFrame::HandleCommand()) - we just dud it,
  330.                 // so pretend we processed the message anyhow
  331.                 processed = TRUE;
  332.             }
  333.  
  334.             // always pass this message DefFrameProc(), otherwise MDI menu
  335.             // commands (and sys commands - more surprizingly!) won't work
  336.             MSWDefWindowProc(message, wParam, lParam);
  337.             break;
  338.  
  339.         case WM_CREATE:
  340.             m_clientWindow = OnCreateClient();
  341.             // Uses own style for client style
  342.             if ( !m_clientWindow->CreateClient(this, GetWindowStyleFlag()) )
  343.             {
  344.                 wxLogMessage(_("Failed to create MDI parent frame."));
  345.  
  346.                 rc = -1;
  347.             }
  348.  
  349.             processed = TRUE;
  350.             break;
  351.  
  352.         case WM_ERASEBKGND:
  353.             processed = TRUE;
  354.  
  355.             // we erase background ourselves
  356.             rc = TRUE;
  357.             break;
  358.  
  359.         case WM_MENUSELECT:
  360.             {
  361.                 WXWORD item, flags;
  362.                 WXHMENU hmenu;
  363.                 UnpackMenuSelect(wParam, lParam, &item, &flags, &hmenu);
  364.  
  365.                 if ( m_parentFrameActive )
  366.                 {
  367.                     processed = HandleMenuSelect(item, flags, hmenu);
  368.                 }
  369.                 else if (m_currentChild)
  370.                 {
  371.                     processed = m_currentChild->
  372.                         HandleMenuSelect(item, flags, hmenu);
  373.                 }
  374.             }
  375.             break;
  376.  
  377.         case WM_SIZE:
  378.             // as we don't (usually) resize the MDI client to exactly fit the
  379.             // client area (we put it below the toolbar, above statusbar &c),
  380.             // we should not pass this one to DefFrameProc
  381.             break;
  382.     }
  383. */
  384.     if ( !processed )
  385.         rc = wxFrame::OS2WindowProc(message, wParam, lParam);
  386.  
  387.     return rc;
  388. }
  389.  
  390. bool wxMDIParentFrame::HandleActivate(int state, bool minimized, WXHWND activate)
  391. {
  392.     bool processed = FALSE;
  393.  
  394.     // TODO:
  395. /*
  396.     if ( wxWindow::HandleActivate(state, minimized, activate) )
  397.     {
  398.         // already processed
  399.         processed = TRUE;
  400.     }
  401.  
  402.     // If this window is an MDI parent, we must also send an OnActivate message
  403.     // to the current child.
  404.     if ( (m_currentChild != NULL) &&
  405.          ((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)) )
  406.     {
  407.         wxActivateEvent event(wxEVT_ACTIVATE, TRUE, m_currentChild->GetId());
  408.         event.SetEventObject( m_currentChild );
  409.         if ( m_currentChild->GetEventHandler()->ProcessEvent(event) )
  410.             processed = TRUE;
  411.     }
  412. */
  413.     return processed;
  414. }
  415.  
  416. bool wxMDIParentFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
  417. {
  418.     // In case it's e.g. a toolbar.
  419.     if ( hwnd )
  420.     {
  421.         wxWindow *win = wxFindWinFromHandle(hwnd);
  422.         if ( win )
  423.             return FALSE; // Need to get wxWindow for OS/2 up to date: win->OS2Command(cmd, id);
  424.     }
  425.  
  426.     // is it one of standard MDI commands?
  427.     WXWPARAM wParam = 0;
  428.     int msg = 0;
  429.  
  430.     // TODO:
  431. /*
  432.     switch ( id )
  433.     {
  434.         case IDM_WINDOWCASCADE:
  435.             msg = WM_MDICASCADE;
  436.             wParam = MDITILE_SKIPDISABLED;
  437.             break;
  438.  
  439.         case IDM_WINDOWTILEHOR:
  440.             wParam |= MDITILE_HORIZONTAL;
  441.             // fall through
  442.  
  443.         case IDM_WINDOWTILEVERT:
  444.             if ( !wParam )
  445.                 wParam = MDITILE_VERTICAL;
  446.             msg = WM_MDITILE;
  447.             wParam |= MDITILE_SKIPDISABLED;
  448.             break;
  449.  
  450.         case IDM_WINDOWICONS:
  451.             msg = WM_MDIICONARRANGE;
  452.             break;
  453.  
  454.         case IDM_WINDOWNEXT:
  455.             msg = WM_MDINEXT;
  456.             break;
  457.  
  458.         default:
  459.             msg = 0;
  460.     }
  461. */
  462.     if ( msg )
  463.     {
  464. // TODO:        ::SendMessage(GetWinHwnd(GetClientWindow()), msg, wParam, 0);
  465.  
  466.         return TRUE;
  467.     }
  468.  
  469.     // FIXME VZ: what does this test do??
  470.     if (id >= 0xF000)
  471.     {
  472.         return FALSE; // Get WndProc to call default proc
  473.     }
  474.  
  475.     if ( IsMdiCommandId(id) )
  476.     {
  477.         wxWindowList::Node* node = GetChildren().GetFirst();
  478.         while ( node )
  479.         {
  480.             wxWindow* child = node->GetData();
  481.             if ( child->GetHWND() )
  482.             {
  483.                 long childId = wxGetWindowId(child->GetHWND());
  484.                 if (childId == (long)id)
  485.                 {
  486. // TODO:                    ::SendMessage( GetWinHwnd(GetClientWindow()),
  487. //                                   WM_MDIACTIVATE,
  488. //                                   (WPARAM)child->GetHWND(), 0);
  489.                     return TRUE;
  490.                 }
  491.             }
  492.             node = node->GetNext();
  493.         }
  494.     }
  495.     else if ( m_parentFrameActive )
  496.     {
  497.         return ProcessCommand(id);
  498.     }
  499.     else if ( m_currentChild )
  500.     {
  501.         return m_currentChild->HandleCommand(id, cmd, hwnd);
  502.     }
  503.     else
  504.     {
  505.         // this shouldn't happen because it means that our messages are being
  506.         // lost (they're not sent to the parent frame nor to the children)
  507.         wxFAIL_MSG(wxT("MDI parent frame is not active, "
  508.                       "yet there is no active MDI child?"));
  509.     }
  510.  
  511.     return FALSE;
  512. }
  513.  
  514. MRESULT wxMDIParentFrame::OS2DefWindowProc(WXUINT message,
  515.                                            WXWPARAM wParam,
  516.                                            WXLPARAM lParam)
  517. {
  518.     WXHWND clientWnd;
  519.     if ( GetClientWindow() )
  520.         clientWnd = GetClientWindow()->GetHWND();
  521.     else
  522.         clientWnd = 0;
  523.  
  524. // TODO:    return DefFrameProc(GetHwnd(), (HWND)clientWnd, message, wParam, lParam);
  525.     return((MRESULT)0);
  526. }
  527.  
  528. bool wxMDIParentFrame::OS2TranslateMessage(WXMSG* msg)
  529. {
  530.     // TODO:
  531. /*
  532.     if ( m_currentChild && m_currentChild->GetHWND() &&
  533.          m_currentChild->OS2TranslateMessage(msg) )
  534.     {
  535.         return TRUE;
  536.     }
  537.  
  538.     if ( m_acceleratorTable.Translate(this, msg) )
  539.     {
  540.         return TRUE;
  541.     }
  542.  
  543.     if ( pMsg->message == WM_KEYDOWN || pMsg->message == WM_SYSKEYDOWN )
  544.     {
  545.         if ( ::TranslateMDISysAccel(GetWinHwnd(GetClientWindow()), pMsg))
  546.             return TRUE;
  547.     }
  548. */
  549.     return FALSE;
  550. }
  551.  
  552. // ===========================================================================
  553. // wxMDIChildFrame
  554. // ===========================================================================
  555.  
  556. wxMDIChildFrame::wxMDIChildFrame()
  557. {
  558. }
  559.  
  560. bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
  561.                              wxWindowID id,
  562.                              const wxString& title,
  563.                              const wxPoint& pos,
  564.                              const wxSize& size,
  565.                              long style,
  566.                              const wxString& name)
  567. {
  568.   m_hDefaultIcon = (WXHICON)(wxSTD_MDICHILDFRAME_ICON ? wxSTD_MDICHILDFRAME_ICON
  569.                                                       : wxDEFAULT_MDICHILDFRAME_ICON);
  570.  
  571.   SetName(name);
  572.  
  573.   if ( id > -1 )
  574.     m_windowId = id;
  575.   else
  576.     m_windowId = (int)NewControlId();
  577.  
  578.   if ( parent )
  579.   {
  580.       parent->AddChild(this);
  581.   }
  582.  
  583.   wxWndHook = this;
  584.  
  585.   int x = pos.x;
  586.   int y = pos.y;
  587.   int width = size.x;
  588.   int height = size.y;
  589.  
  590.     // TODO:
  591. /*
  592.   MDICREATESTRUCT mcs;
  593.  
  594.   mcs.szClass = wxMDIChildFrameClassName;
  595.   mcs.szTitle = title;
  596.   mcs.hOwner = wxGetInstance();
  597.   if (x > -1)
  598.       mcs.x = x;
  599.   else
  600.       mcs.x = CW_USEDEFAULT;
  601.  
  602.   if (y > -1)
  603.       mcs.y = y;
  604.   else
  605.       mcs.y = CW_USEDEFAULT;
  606.  
  607.   if (width > -1)
  608.       mcs.cx = width;
  609.   else
  610.       mcs.cx = CW_USEDEFAULT;
  611.  
  612.   if (height > -1)
  613.       mcs.cy = height;
  614.   else
  615.       mcs.cy = CW_USEDEFAULT;
  616.  
  617.   DWORD msflags = WS_OVERLAPPED | WS_CLIPCHILDREN;
  618.   if (style & wxMINIMIZE_BOX)
  619.     msflags |= WS_MINIMIZEBOX;
  620.   if (style & wxMAXIMIZE_BOX)
  621.     msflags |= WS_MAXIMIZEBOX;
  622.   if (style & wxTHICK_FRAME)
  623.     msflags |= WS_THICKFRAME;
  624.   if (style & wxSYSTEM_MENU)
  625.     msflags |= WS_SYSMENU;
  626.   if ((style & wxMINIMIZE) || (style & wxICONIZE))
  627.     msflags |= WS_MINIMIZE;
  628.   if (style & wxMAXIMIZE)
  629.     msflags |= WS_MAXIMIZE;
  630.   if (style & wxCAPTION)
  631.     msflags |= WS_CAPTION;
  632.  
  633.   mcs.style = msflags;
  634.  
  635.   mcs.lParam = 0;
  636. */
  637.   DWORD Return = 0; // SendMessage(GetWinHwnd(parent->GetClientWindow()),
  638. //                             WM_MDICREATE, 0, (LONG)(LPSTR)&mcs);
  639.   m_hWnd = (WXHWND)Return;
  640.  
  641.   wxWndHook = NULL;
  642.   wxAssociateWinWithHandle((HWND) GetHWND(), this);
  643.  
  644.   // VZ: what's this? an act of piracy?
  645.   //SetWindowLong(GetHwnd(), 0, (long)this);
  646.  
  647.   wxModelessWindows.Append(this);
  648.   return TRUE;
  649. }
  650.  
  651. wxMDIChildFrame::~wxMDIChildFrame()
  652. {
  653.     OS2DestroyWindow();
  654. }
  655.  
  656. // Set the client size (i.e. leave the calculation of borders etc.
  657. // to wxWindows)
  658. void wxMDIChildFrame::DoSetClientSize(int width, int height)
  659. {
  660.   HWND hWnd = GetHwnd();
  661.  
  662.     // TODO:
  663. /*
  664.   RECT rect;
  665.   ::GetClientRect(hWnd, &rect);
  666.  
  667.   RECT rect2;
  668.   GetWindowRect(hWnd, &rect2);
  669.  
  670.   // Find the difference between the entire window (title bar and all)
  671.   // and the client area; add this to the new client size to move the
  672.   // window
  673.   int actual_width = rect2.right - rect2.left - rect.right + width;
  674.   int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
  675.  
  676.   if (GetStatusBar())
  677.   {
  678.     int sx, sy;
  679.     GetStatusBar()->GetSize(&sx, &sy);
  680.     actual_height += sy;
  681.   }
  682.  
  683.   POINT point;
  684.   point.x = rect2.left;
  685.   point.y = rect2.top;
  686.  
  687.   // If there's an MDI parent, must subtract the parent's top left corner
  688.   // since MoveWindow moves relative to the parent
  689.   wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
  690.   ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
  691.  
  692.   MoveWindow(hWnd, point.x, point.y, actual_width, actual_height, (BOOL)TRUE);
  693.  
  694.   wxSizeEvent event(wxSize(width, height), m_windowId);
  695.   event.SetEventObject( this );
  696.   GetEventHandler()->ProcessEvent(event);
  697. */
  698. }
  699.  
  700. void wxMDIChildFrame::DoGetPosition(int *x, int *y) const
  701. {
  702.     // TODO:
  703. /*
  704.   RECT rect;
  705.   GetWindowRect(GetHwnd(), &rect);
  706.   POINT point;
  707.   point.x = rect.left;
  708.   point.y = rect.top;
  709.  
  710.   // Since we now have the absolute screen coords,
  711.   // if there's a parent we must subtract its top left corner
  712.   wxMDIParentFrame *mdiParent = (wxMDIParentFrame *)GetParent();
  713.   ::ScreenToClient((HWND) mdiParent->GetClientWindow()->GetHWND(), &point);
  714.  
  715.   *x = point.x;
  716.   *y = point.y;
  717. */
  718. }
  719.  
  720. void wxMDIChildFrame::InternalSetMenuBar()
  721. {
  722.     // TODO:
  723. /*
  724.  
  725.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  726.  
  727.     HMENU subMenu = GetSubMenu((HMENU)parent->GetWindowMenu(), 0);
  728.  
  729.     InsertWindowMenu(parent->GetClientWindow(), m_hMenu, subMenu);
  730.  
  731.     parent->m_parentFrameActive = FALSE;
  732. */
  733. }
  734.  
  735. // ---------------------------------------------------------------------------
  736. // MDI operations
  737. // ---------------------------------------------------------------------------
  738.  
  739. void wxMDIChildFrame::Maximize(bool maximize)
  740. {
  741.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  742.     // TODO:
  743. /*
  744.     if ( parent && parent->GetClientWindow() )
  745.     {
  746.         ::SendMessage(GetWinHwnd(parent->GetClientWindow()),
  747.                       maximize ? WM_MDIMAXIMIZE : WM_MDIRESTORE,
  748.                       (WPARAM)GetHwnd(), 0);
  749.     }
  750. */
  751. }
  752.  
  753. void wxMDIChildFrame::Restore()
  754. {
  755.     // TODO:
  756. /*
  757.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  758.     if ( parent && parent->GetClientWindow() )
  759.     {
  760.         ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIRESTORE,
  761.                       (WPARAM) GetHwnd(), 0);
  762.     }
  763. */
  764. }
  765.  
  766. void wxMDIChildFrame::Activate()
  767. {
  768.     // TODO:
  769. /*
  770.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  771.     if ( parent && parent->GetClientWindow() )
  772.     {
  773.         ::SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIACTIVATE,
  774.                       (WPARAM) GetHwnd(), 0);
  775.     }
  776. */
  777. }
  778.  
  779. // ---------------------------------------------------------------------------
  780. // MDI window proc and message handlers
  781. // ---------------------------------------------------------------------------
  782.  
  783. MRESULT wxMDIChildFrame::OS2WindowProc(WXUINT message,
  784.                                        WXWPARAM wParam,
  785.                                        WXLPARAM lParam)
  786. {
  787.     MRESULT rc = 0;
  788.     bool processed = FALSE;
  789.  
  790.     // TODO:
  791. /*
  792.     switch ( message )
  793.     {
  794.         case WM_COMMAND:
  795.             {
  796.                 WORD id, cmd;
  797.                 WXHWND hwnd;
  798.                 UnpackCommand((WXWPARAM)wParam, (WXLPARAM)lParam,
  799.                               &id, &hwnd, &cmd);
  800.  
  801.                 processed = HandleCommand(id, cmd, (WXHWND)hwnd);
  802.             }
  803.             break;
  804.  
  805.         case WM_GETMINMAXINFO:
  806.             // let the default window proc calculate the size of MDI children
  807.             // frames because it is based on the size of the MDI client window,
  808.             // not on the values specified in wxWindow m_min/max variables
  809.             return MSWDefWindowProc(message, wParam, lParam);
  810.  
  811.         case WM_MDIACTIVATE:
  812.             {
  813.                 WXWORD act;
  814.                 WXHWND hwndAct, hwndDeact;
  815.                 UnpackMDIActivate(wParam, lParam, &act, &hwndAct, &hwndDeact);
  816.  
  817.                 processed = HandleMDIActivate(act, hwndAct, hwndDeact);
  818.             }
  819.             // fall through
  820.  
  821.         case WM_MOVE:
  822.             // must pass WM_MOVE to DefMDIChildProc() to recalculate MDI client
  823.             // scrollbars if necessary
  824.  
  825.             // fall through
  826.  
  827.         case WM_SIZE:
  828.             // must pass WM_SIZE to DefMDIChildProc(), otherwise many weird
  829.             // things happen
  830.             MSWDefWindowProc(message, wParam, lParam);
  831.             break;
  832.  
  833.         case WM_SYSCOMMAND:
  834.             // DefMDIChildProc handles SC_{NEXT/PREV}WINDOW here, so pass it
  835.             // the message (the base class version does not)
  836.             return MSWDefWindowProc(message, wParam, lParam);
  837.  
  838.         case WM_WINDOWPOSCHANGING:
  839.             processed = HandleWindowPosChanging((LPWINDOWPOS)lParam);
  840.             break;
  841.     }
  842. */
  843.     if ( !processed )
  844.         rc = wxFrame::OS2WindowProc(message, wParam, lParam);
  845.  
  846.     return rc;
  847. }
  848.  
  849. bool wxMDIChildFrame::HandleSize(int x, int y, WXUINT id)
  850. {
  851.     HWND hwnd = GetHwnd();
  852.  
  853.     if ( !hwnd || hwnd == invalidHandle )
  854.     {
  855.         return FALSE;
  856.     }
  857.  
  858.     // TODO:
  859. /*
  860.     switch (id)
  861.     {
  862.         case SIZEFULLSCREEN:
  863.         case SIZENORMAL:
  864.             m_iconized = FALSE;
  865.             break;
  866.  
  867.         case SIZEICONIC:
  868.             m_iconized = TRUE;
  869.             break;
  870.     }
  871.  
  872.     if ( !m_iconized )
  873.     {
  874.         // forward WM_SIZE to status bar control
  875. #if wxUSE_NATIVE_STATUSBAR
  876.         if (m_frameStatusBar && m_frameStatusBar->IsKindOf(CLASSINFO(wxStatusBar95)))
  877.         {
  878.             wxSizeEvent event(wxSize(x, y), m_frameStatusBar->GetId());
  879.             event.SetEventObject( m_frameStatusBar );
  880.  
  881.             ((wxStatusBar95 *)m_frameStatusBar)->OnSize(event);
  882.         }
  883. #endif // wxUSE_NATIVE_STATUSBAR
  884.  
  885.         PositionStatusBar();
  886.         PositionToolBar();
  887.  
  888.         return wxWindow::HandleSize(x, y, id);
  889.     }
  890.     else
  891.     {
  892.         return FALSE;
  893.     }
  894. */
  895.     return TRUE;
  896. }
  897.  
  898. bool wxMDIChildFrame::HandleCommand(WXWORD id, WXWORD cmd, WXHWND hwnd)
  899. {
  900.     // In case it's e.g. a toolbar.
  901.     if ( hwnd )
  902.     {
  903.         wxWindow *win = wxFindWinFromHandle(hwnd);
  904. //        if (win)
  905. // Fix dependent stuff           return win->OS2Command(cmd, id);
  906.     }
  907.  
  908.     if (wxCurrentPopupMenu)
  909.     {
  910.         wxMenu *popupMenu = wxCurrentPopupMenu;
  911.         wxCurrentPopupMenu = NULL;
  912. // Fix dependent stuff        if (popupMenu->OS2Command(cmd, id))
  913. //            return TRUE;
  914.     }
  915.  
  916.     if (GetMenuBar() && GetMenuBar()->FindItem(id))
  917.     {
  918.         ProcessCommand(id);
  919.         return TRUE;
  920.     }
  921.     else
  922.         return FALSE;
  923.  
  924.     return TRUE;
  925. }
  926.  
  927. bool wxMDIChildFrame::HandleMDIActivate(long WXUNUSED(activate),
  928.                                         WXHWND hwndAct,
  929.                                         WXHWND hwndDeact)
  930. {
  931.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  932.  
  933.     HMENU menuToSet = 0;
  934.  
  935.     bool activated;
  936.  
  937.     if ( m_hWnd == hwndAct )
  938.     {
  939.         activated = TRUE;
  940.         parent->m_currentChild = this;
  941.  
  942.         HMENU child_menu = (HMENU)GetWinMenu();
  943.         if ( child_menu )
  944.         {
  945.             parent->m_parentFrameActive = FALSE;
  946.  
  947.             menuToSet = child_menu;
  948.         }
  949.     }
  950.     else if ( m_hWnd == hwndDeact )
  951.     {
  952.         wxASSERT_MSG( parent->m_currentChild == this,
  953.                       wxT("can't deactivate MDI child which wasn't active!") );
  954.  
  955.         activated = FALSE;
  956.         parent->m_currentChild = NULL;
  957.  
  958.         HMENU parent_menu = (HMENU)parent->GetWinMenu();
  959.         if ( parent_menu )
  960.         {
  961.             parent->m_parentFrameActive = TRUE;
  962.  
  963.             menuToSet = parent_menu;
  964.         }
  965.     }
  966.     else
  967.     {
  968.         // we have nothing to with it
  969.         return FALSE;
  970.     }
  971.  
  972.     if ( menuToSet )
  973.     {
  974.         HMENU subMenu = 0; // TODO: GetSubMenu((HMENU) parent->GetWindowMenu(), 0);
  975.  
  976.         MDISetMenu(parent->GetClientWindow(), menuToSet, subMenu);
  977.     }
  978.  
  979.     wxActivateEvent event(wxEVT_ACTIVATE, activated, m_windowId);
  980.     event.SetEventObject( this );
  981.  
  982.     return GetEventHandler()->ProcessEvent(event);
  983. }
  984.  
  985. bool wxMDIChildFrame::HandleWindowPosChanging(void *pos)
  986. {
  987. //    WINDOWPOS *lpPos = (WINDOWPOS *)pos;
  988.     return FALSE;
  989. }
  990.  
  991. // ---------------------------------------------------------------------------
  992. // MDI specific message translation/preprocessing
  993. // ---------------------------------------------------------------------------
  994.  
  995. MRESULT wxMDIChildFrame::OS2DefWindowProc(WXUINT message, WXWPARAM wParam, WXLPARAM lParam)
  996. {
  997.     // TODO
  998. /*
  999.     return DefMDIChildProc(GetHwnd(),
  1000.                            (UINT)message, (WPARAM)wParam, (LPARAM)lParam);
  1001. */
  1002.     return (MRESULT)0;
  1003. }
  1004.  
  1005. bool wxMDIChildFrame::OS2TranslateMessage(WXMSG* msg)
  1006. {
  1007. #if wxUSE_ACCEL
  1008.     return m_acceleratorTable.Translate(GetParent()->GetHWND(), msg);
  1009. #else
  1010.     return FALSE;
  1011. #endif  //wxUSE_ACCEL
  1012.  
  1013. }
  1014.  
  1015. // ---------------------------------------------------------------------------
  1016. // misc
  1017. // ---------------------------------------------------------------------------
  1018.  
  1019. void wxMDIChildFrame::OS2DestroyWindow()
  1020. {
  1021. // get wxWindow up to date    OS2DetachWindowMenu();
  1022.     invalidHandle = GetHwnd();
  1023.  
  1024.     wxMDIParentFrame *parent = (wxMDIParentFrame *)GetParent();
  1025.  
  1026.     // Must make sure this handle is invalidated (set to NULL) since all sorts
  1027.     // of things could happen after the child client is destroyed, but before
  1028.     // the wxFrame is destroyed.
  1029.  
  1030.     HWND oldHandle = (HWND)GetHWND();
  1031. // TODO:    SendMessage(GetWinHwnd(parent->GetClientWindow()), WM_MDIDESTROY,
  1032. //                (WPARAM)oldHandle, 0);
  1033.     invalidHandle = 0;
  1034.  
  1035.     if (m_hMenu)
  1036.     {
  1037. // TODO:        ::DestroyMenu((HMENU) m_hMenu);
  1038.         m_hMenu = 0;
  1039.     }
  1040.     m_hWnd = 0;
  1041. }
  1042.  
  1043. // Change the client window's extended style so we don't get a client edge
  1044. // style when a child is maximised (a double border looks silly.)
  1045. bool wxMDIChildFrame::ResetWindowStyle(void *vrect)
  1046. {
  1047.     return FALSE;
  1048. }
  1049.  
  1050. // ===========================================================================
  1051. // wxMDIClientWindow: the window of predefined (by Windows) class which
  1052. // contains the child frames
  1053. // ===========================================================================
  1054.  
  1055. bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style)
  1056. {
  1057.     m_backgroundColour = wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE);
  1058.  
  1059.     // TODO:
  1060. /*
  1061.     CLIENTCREATESTRUCT ccs;
  1062.     m_windowStyle = style;
  1063.     m_parent = parent;
  1064.  
  1065.     ccs.hWindowMenu = (HMENU)parent->GetWindowMenu();
  1066.     ccs.idFirstChild = wxFIRST_MDI_CHILD;
  1067.  
  1068.     DWORD msStyle = WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
  1069.     if ( style & wxHSCROLL )
  1070.         msStyle |= WS_HSCROLL;
  1071.     if ( style & wxVSCROLL )
  1072.         msStyle |= WS_VSCROLL;
  1073.  
  1074. #if defined(__WIN95__)
  1075.     DWORD exStyle = WS_EX_CLIENTEDGE;
  1076. #else
  1077.     DWORD exStyle = 0;
  1078. #endif
  1079.  
  1080.     wxWndHook = this;
  1081.     m_hWnd = (WXHWND)::CreateWindowEx
  1082.                        (
  1083.                         exStyle,
  1084.                         wxT("MDICLIENT"),
  1085.                         NULL,
  1086.                         msStyle,
  1087.                         0, 0, 0, 0,
  1088.                         GetWinHwnd(parent),
  1089.                         NULL,
  1090.                         wxGetInstance(),
  1091.                         (LPSTR)(LPCLIENTCREATESTRUCT)&ccs);
  1092.     if ( !m_hWnd )
  1093.     {
  1094.         wxLogLastError("CreateWindowEx(MDI client)");
  1095.  
  1096.         return FALSE;
  1097.     }
  1098.  
  1099.     SubclassWin(m_hWnd);
  1100.     wxWndHook = NULL;
  1101. */
  1102.     return TRUE;
  1103. }
  1104.  
  1105. // Explicitly call default scroll behaviour
  1106. void wxMDIClientWindow::OnScroll(wxScrollEvent& event)
  1107. {
  1108.     // Note: for client windows, the scroll position is not set in
  1109.     // WM_HSCROLL, WM_VSCROLL, so we can't easily determine what
  1110.     // scroll position we're at.
  1111.     // This makes it hard to paint patterns or bitmaps in the background,
  1112.     // and have the client area scrollable as well.
  1113.  
  1114.     if ( event.GetOrientation() == wxHORIZONTAL )
  1115.         m_scrollX = event.GetPosition(); // Always returns zero!
  1116.     else
  1117.         m_scrollY = event.GetPosition(); // Always returns zero!
  1118.  
  1119.     event.Skip();
  1120. }
  1121.  
  1122. // ---------------------------------------------------------------------------
  1123. // non member functions
  1124. // ---------------------------------------------------------------------------
  1125.  
  1126. static void MDISetMenu(wxWindow *win, HMENU hmenuFrame, HMENU hmenuWindow)
  1127. {
  1128.     // TODO:
  1129. /*
  1130.     ::SendMessage(GetWinHwnd(win), WM_MDISETMENU,
  1131.                   (WPARAM)hmenuFrame, (LPARAM)hmenuWindow);
  1132.     // update menu bar of the parent window
  1133.     wxWindow *parent = win->GetParent();
  1134.     wxCHECK_RET( parent, wxT("MDI client without parent frame? weird...") );
  1135.  
  1136.     ::DrawMenuBar(GetWinHwnd(parent));
  1137. */
  1138. }
  1139.  
  1140. static void InsertWindowMenu(wxWindow *win, WXHMENU menu, HMENU subMenu)
  1141. {
  1142. /*
  1143.     // Try to insert Window menu in front of Help, otherwise append it.
  1144.     HMENU hmenu = (HMENU)menu;
  1145.     int N = GetMenuItemCount(hmenu);
  1146.     bool success = FALSE;
  1147.     for ( int i = 0; i < N; i++ )
  1148.     {
  1149.         wxChar buf[256];
  1150.         int chars = GetMenuString(hmenu, i, buf, WXSIZEOF(buf), MF_BYPOSITION);
  1151.         if ( chars == 0 )
  1152.         {
  1153.             wxLogLastError(wxT("GetMenuString"));
  1154.  
  1155.             continue;
  1156.         }
  1157.  
  1158.         if ( wxStripMenuCodes(wxString(buf)).IsSameAs(wxT("Help")) )
  1159.         {
  1160.             success = TRUE;
  1161.             ::InsertMenu(hmenu, i, MF_BYPOSITION | MF_POPUP | MF_STRING,
  1162.                          (UINT)subMenu, wxT("&Window"));
  1163.             break;
  1164.         }
  1165.     }
  1166.  
  1167.     if ( !success )
  1168.     {
  1169.         ::AppendMenu(hmenu, MF_POPUP, (UINT)subMenu, wxT("&Window"));
  1170.     }
  1171.     MDISetMenu(win, hmenu, subMenu);
  1172. */
  1173. }
  1174.  
  1175. static void UnpackMDIActivate(WXWPARAM wParam, WXLPARAM lParam,
  1176.                               WXWORD *activate, WXHWND *hwndAct, WXHWND *hwndDeact)
  1177. {
  1178.     *activate = TRUE;
  1179.     *hwndAct = (WXHWND)lParam;
  1180.     *hwndDeact = (WXHWND)wParam;
  1181. }
  1182.  
  1183.