home *** CD-ROM | disk | FTP | other *** search
/ Borland Programmer's Resource / Borland_Programmers_Resource_CD_1995.iso / code / wxwin140 / src / wx_win.cc < prev   
Encoding:
C/C++ Source or Header  |  1995-05-19  |  42.0 KB  |  1,901 lines

  1. /*
  2.  * File:     wx_win.cc
  3.  * Purpose:  wxWindow class 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_win.h"
  34. #include "wx_main.h"
  35. #include "wx_utils.h"
  36. #include "wx_privt.h"
  37.  
  38. #ifdef wx_xview
  39. // Intercept focus events
  40. extern "C" int win_set_kbd_focus(Xv_Window, XID);
  41. #endif
  42.  
  43. #ifdef wx_msw
  44. // Find an item given the MS Windows id
  45. wxWindow *wxWindow::FindItem(int id)
  46. {
  47.   if (!children)
  48.     return NULL;
  49.   wxNode *current = children->First();
  50.   wxWindow *the_item = NULL;
  51.  
  52.   while (current)
  53.   {
  54.     wxWindow *item = (wxWindow *)current->Data();
  55.     if (item->windows_id == id)
  56.     {
  57.       the_item = item;
  58.       break;
  59.     }
  60.     else
  61.       current = current->Next();
  62.   }
  63.   return the_item;
  64. }
  65.  
  66. // Default command handler
  67. BOOL wxWindow::Command(UINT param)
  68. {
  69.   return FALSE;
  70. }
  71.  
  72. void wxWindow::PreDelete(HDC dc)
  73. {
  74. }
  75. #endif
  76.  
  77. // Constructor
  78. wxWindow::wxWindow(void)
  79. {
  80.   wx_client_data = NULL;
  81.   window_parent = NULL;
  82.   font = NULL;
  83.   handle = NULL;
  84.   callback = 0;
  85.   wx_cursor = wxSTANDARD_CURSOR;
  86.   children = new wxList;
  87. #ifdef wx_motif
  88.   wxType = 0;
  89. #endif
  90. }
  91.  
  92. // Destructor
  93. wxWindow::~wxWindow(void)
  94. {
  95.   if (window_parent)
  96.     window_parent->RemoveChild(this);
  97.  
  98. #ifdef wx_motif
  99.   if (handle)
  100.   {
  101.     DestroyChildren();
  102.  
  103.     wxWidgetHashTable->Delete((long)handle);
  104.     Widget w = (Widget)handle;
  105.     XtDestroyWidget(w);
  106.  
  107.     PostDestroyChildren();
  108.  
  109.   }
  110. #endif
  111. #ifdef wx_xview
  112.   if (handle)
  113.   {
  114.     // Reset client data
  115.     xv_set((Xv_opaque)handle, WIN_CLIENT_DATA, NULL, NULL);
  116.     DestroyChildren();
  117.     xv_destroy_safe((Xv_opaque)handle);
  118.   }
  119. #endif
  120. #ifdef wx_msw
  121.   DestroyChildren();
  122.   switch (wxWinType)
  123.   {
  124.     case wxTYPE_XWND:
  125.     {
  126.       if (handle)
  127.       {
  128.         wxWnd *wnd = (wxWnd *)handle;
  129.         HDC dc = GetDC(wnd->handle);
  130.         PreDelete(dc);
  131.         ReleaseDC(wnd->handle, dc);
  132.  
  133.         wnd->DestroyWindow();
  134.         delete wnd;
  135.         handle = NULL;
  136.       }
  137.       break;
  138.     }
  139.     case wxTYPE_HWND:
  140.     {
  141.       DestroyWindow((HWND)ms_handle);
  142.       handle = NULL;
  143.       break;
  144.     }
  145.     default:
  146.       break;
  147.     }
  148. #endif
  149.  
  150.   delete children;
  151.   children = NULL;
  152. }
  153.  
  154. char *wxWindow::GetHandle(void)
  155. {
  156.   return handle;
  157. }
  158.  
  159. void wxWindow::SetFocus(void)
  160. {
  161. #ifdef wx_motif
  162.   XmProcessTraversal((Widget)handle, XmTRAVERSE_CURRENT);
  163.   XmProcessTraversal((Widget)handle, XmTRAVERSE_CURRENT);
  164. #endif
  165. #ifdef wx_xview
  166.   Xv_opaque win = (Xv_opaque)handle;
  167.   win_set_kbd_focus(win, xv_get(win, XV_XID));
  168. #endif
  169. #ifdef wx_msw
  170.   switch (wxWinType)
  171.   {
  172.     case wxTYPE_XWND:
  173.     {
  174.       if (handle != NULL)
  175.       {
  176.         wxWnd *wnd = (wxWnd *)handle;
  177.         ::SetFocus(wnd->handle);
  178.       }
  179.       break;
  180.     }
  181.     case wxTYPE_HWND:
  182.     {
  183.       if (ms_handle != NULL)
  184.         ::SetFocus((HWND)ms_handle);
  185.       break;
  186.     }
  187.     default:
  188.       break;
  189.   }
  190. #endif
  191. }
  192.  
  193. void wxWindow::OnPaint(void)
  194. {
  195. }
  196.  
  197. void wxWindow::OnSize(int width, int height)
  198. {
  199. }
  200.  
  201. void wxWindow::OnEvent(wxEvent& event)
  202. {
  203. }
  204.  
  205. void wxWindow::OnChar(int ch)
  206. {
  207. }
  208.  
  209. Bool wxWindow::OnClose(void)
  210. {
  211.   return FALSE;
  212. }
  213.  
  214. void wxWindow::OnActivate(Bool active)
  215. {
  216. }
  217.  
  218. // Get total size
  219. void wxWindow::GetSize(int *x, int *y)
  220. {
  221. #ifdef wx_motif
  222.   Widget widget = (Widget)handle;
  223.   Dimension xx, yy;
  224.   XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
  225.   *x = xx; *y = yy;
  226. #endif
  227. #ifdef wx_xview
  228.   Xv_opaque x_win = (Xv_opaque)handle;
  229.  
  230.   *x = (int)xv_get(x_win, XV_WIDTH);
  231.   *y = (int)xv_get(x_win, XV_HEIGHT);
  232. #endif
  233. #ifdef wx_msw
  234.   wxWnd *wnd = (wxWnd *)handle;
  235.   RECT rect;
  236.   GetWindowRect(wnd->handle, &rect);
  237.   *x = rect.right - rect.left;
  238.   *y = rect.bottom - rect.top;
  239. #endif
  240. }
  241.  
  242. void wxWindow::GetPosition(int *x, int *y)
  243. {
  244. #ifdef wx_motif
  245.   Widget widget = (Widget)handle;
  246.   Dimension xx, yy;
  247.   XtVaGetValues(widget, XmNx, &xx, XmNy, &yy, NULL);
  248.   *x = xx; *y = yy;
  249. #endif
  250. #ifdef wx_xview
  251.   Xv_opaque x_win = (Xv_opaque)handle;
  252.  
  253.   *x = (int)xv_get(x_win, XV_X);
  254.   *y = (int)xv_get(x_win, XV_Y);
  255. #endif
  256. #ifdef wx_msw
  257.   wxWnd *wnd = (wxWnd *)handle;
  258.   wxWindow *parent = GetParent();
  259.  
  260.   RECT rect;
  261.   GetWindowRect(wnd->handle, &rect);
  262.  
  263.   // Since we now have the absolute screen coords,
  264.   // if there's a parent we must subtract its top left corner
  265.   POINT point;
  266.   point.x = rect.left;
  267.   point.y = rect.top;
  268.   if (parent)
  269.   {
  270.     wxWnd *cparent = (wxWnd *)(parent->handle);
  271.     ScreenToClient(cparent->handle, &point);
  272.   }
  273.   *x = point.x;
  274.   *y = point.y;
  275.  
  276. #endif
  277. }
  278.  
  279. wxCursor *wxWindow::SetCursor(wxCursor *cursor)
  280. {
  281.   wxCursor *old_cursor = wx_cursor;
  282.   wx_cursor = cursor;
  283. #ifdef wx_motif
  284.   if (cursor && cursor->x_cursor)
  285.   {
  286.     Widget w = (Widget)handle;
  287.     Window win = XtWindow(w);
  288.     Display *dpy = XtDisplay(wxTheApp->topLevel);
  289.     XDefineCursor(dpy, win, cursor->x_cursor);
  290.   }
  291. #endif
  292. #ifdef wx_xview
  293.   Xv_opaque x_win = (Xv_opaque)handle;
  294.   Xv_Window win = xv_get(x_win, CANVAS_NTH_PAINT_WINDOW, 0);
  295.   if (cursor && cursor->x_cursor)
  296.   {
  297.     if (cursor->use_raw_x_cursor)
  298.     {
  299.       Xv_Screen screen = xv_get(xview_server, SERVER_NTH_SCREEN, 0);
  300.       Xv_Window root_window = xv_get(screen, XV_ROOT);
  301.       Display *dpy = (Display *)xv_get(root_window, XV_DISPLAY);
  302.       Window win2 = xv_get(win, XV_XID);
  303.  
  304.       XDefineCursor(dpy, win2, cursor->x_cursor);
  305.     }
  306.     else
  307.       xv_set(win, WIN_CURSOR, cursor->x_cursor, NULL);
  308.   }
  309.  
  310. #endif
  311. #ifdef wx_msw
  312.   if (wx_cursor)
  313.     ::SetCursor(wx_cursor->ms_cursor);
  314. #endif
  315.   return old_cursor;
  316. }
  317.  
  318. // Get size *available for subwindows* i.e. excluding menu bar etc.
  319. // For XView, this is the same as GetSize
  320. void wxWindow::GetClientSize(int *x, int *y)
  321. {
  322. #ifdef wx_motif
  323.   Widget widget = (Widget)handle;
  324.   Dimension xx, yy;
  325.   XtVaGetValues(widget, XmNwidth, &xx, XmNheight, &yy, NULL);
  326.   *x = xx; *y = yy;
  327. #endif
  328. #ifdef wx_xview
  329.   Xv_opaque x_win = (Xv_opaque)handle;
  330.  
  331.   *x = (int)xv_get(x_win, XV_WIDTH);
  332.   *y = (int)xv_get(x_win, XV_HEIGHT);
  333. #endif
  334. #ifdef wx_msw
  335.   wxWnd *wnd = (wxWnd *)handle;
  336.   RECT rect;
  337.   GetClientRect(wnd->handle, &rect);
  338.   *x = rect.right;
  339.   *y = rect.bottom;
  340. #endif
  341. }
  342.  
  343. void wxWindow::SetSize(int x, int y, int width, int height)
  344. {
  345. #ifdef wx_motif
  346.   Widget widget = (Widget)handle;
  347.  
  348.   if (x > -1)
  349.     XtVaSetValues(widget, XmNx, x, NULL);
  350.   if (y > -1)
  351.     XtVaSetValues(widget, XmNy, y, NULL);
  352.   if (width > -1)
  353.     XtVaSetValues(widget, XmNwidth, width, NULL);
  354.   if (height > -1)
  355.     XtVaSetValues(widget, XmNheight, height, NULL);
  356.   OnSize(width, height);
  357. #endif
  358. #ifdef wx_xview
  359.   Xv_opaque x_win = (Xv_opaque)handle;
  360.  
  361.   (void)xv_set(x_win, XV_X, x, XV_Y, y, XV_WIDTH, width, XV_HEIGHT, height, NULL);
  362.   OnSize(width, height);
  363. #endif
  364. #ifdef wx_msw
  365.   int currentX, currentY;
  366.   GetPosition(¤tX, ¤tY);
  367.   if (x == -1)
  368.     x = currentX;
  369.   if (y == -1)
  370.     y = currentY;
  371.  
  372.   wxWnd *wnd = (wxWnd *)handle;
  373.   if (wnd)
  374.     MoveWindow(wnd->handle, x, y, width, height, TRUE);
  375.   OnSize(width, height);
  376. #endif
  377. }
  378.  
  379. void wxWindow::SetClientSize(int width, int height)
  380. {
  381. #ifdef wx_motif
  382.   Widget widget = (Widget)handle;
  383.  
  384.     XtVaSetValues(widget, XmNwidth, width, NULL);
  385.   if (height > -1)
  386.     XtVaSetValues(widget, XmNheight, height, NULL);
  387.   OnSize(width, height);
  388. #endif
  389. #ifdef wx_xview
  390.   Xv_opaque x_win = (Xv_opaque)handle;
  391.  
  392.   (void)xv_set(x_win, XV_WIDTH, width, XV_HEIGHT, height, NULL);
  393. #endif
  394. #ifdef wx_msw
  395.   wxWindow *parent = GetParent();
  396.   wxWnd *wnd = (wxWnd *)handle;
  397.   RECT rect;
  398.   GetClientRect(wnd->handle, &rect);
  399.  
  400.   RECT rect2;
  401.   GetWindowRect(wnd->handle, &rect2);
  402.  
  403.   // Find the difference between the entire window (title bar and all)
  404.   // and the client area; add this to the new client size to move the
  405.   // window
  406.   int actual_width = rect2.right - rect2.left - rect.right + width;
  407.   int actual_height = rect2.bottom - rect2.top - rect.bottom + height;
  408.  
  409.   // If there's a parent, must subtract the parent's top left corner
  410.   // since MoveWindow moves relative to the parent
  411.  
  412.   POINT point;
  413.   point.x = rect2.left;
  414.   point.y = rect2.top;
  415.   if (parent)
  416.   {
  417.     wxWnd *cparent = (wxWnd *)(parent->handle);
  418.     ScreenToClient(cparent->handle, &point);
  419.   }
  420.  
  421.   MoveWindow(wnd->handle, point.x, point.y, actual_width, actual_height, TRUE);
  422.   OnSize(actual_width, actual_height);
  423. #endif
  424. }
  425.  
  426. // General callback setting
  427. void wxWindow::Callback(wxFunction Function)
  428. {
  429.   if (Function)
  430.     callback = Function;
  431. }
  432.  
  433. // Client data handling (any window, item etc.)
  434. void wxWindow::SetClientData(char *data)
  435. {
  436.   wx_client_data = data;
  437. }
  438.  
  439. char *wxWindow::GetClientData(void)
  440. {
  441.   return wx_client_data;
  442. }
  443.  
  444. void wxWindow::Show(Bool show)
  445. {
  446. #ifdef wx_motif
  447. #endif
  448. #ifdef wx_xview
  449.   Xv_opaque window = (Xv_opaque)handle;
  450.   xv_set(window, XV_SHOW, show, NULL);
  451. #endif
  452. #ifdef wx_msw
  453.   wxWnd *wnd = (wxWnd *)handle;
  454.   int cshow;
  455.   if (show)
  456.     cshow = SW_SHOW;
  457.   else
  458.     cshow = SW_HIDE;
  459.   ShowWindow(wnd->handle, cshow);
  460.   if (show)
  461.     BringWindowToTop(wnd->handle);
  462. #endif
  463. }
  464.  
  465. wxWindow *wxWindow::GetParent(void)
  466. {
  467.   return window_parent;
  468. }
  469.  
  470. wxWindow *wxWindow::GetGrandParent(void)
  471. {
  472.   if (window_parent)
  473.     return window_parent->window_parent;
  474.   else return NULL;
  475. }
  476.  
  477. void wxWindow::AddChild(wxObject *child)
  478. {
  479.   children->Append(child);
  480. }
  481.  
  482. void wxWindow::RemoveChild(wxObject *child)
  483. {
  484.   if (children)
  485.     children->DeleteObject(child);
  486. }
  487.  
  488. void wxWindow::DestroyChildren(void)
  489. {
  490.   if (children)
  491.   {
  492.     wxNode *node = children->First();
  493.     while (node)
  494.     {
  495.       wxWindow *child = (wxWindow *)node->Data();
  496.       child->DestroyChildren();
  497.       delete child;
  498.       node = children->First();
  499.     }
  500.   }
  501. }
  502.  
  503. // Default menu command handler
  504. void wxWindow::OnMenuCommand(int Id)
  505. {
  506. }
  507.  
  508. // Default handler for OnMenuSelect
  509. void wxWindow::OnMenuSelect(int Id)
  510. {
  511. }
  512.  
  513. void wxWindow::SetTitle(char *title)
  514. {
  515. }
  516.  
  517. int wxWindow::GetTextFamily(void)
  518. {
  519. #ifdef wx_motif
  520.   return 0;
  521. #endif
  522. #ifdef wx_xview
  523.   Xv_Font the_font;
  524.  
  525.   if (!(font && font->x_font))
  526.   {
  527.     Xv_opaque thing = (Xv_opaque)handle;
  528.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  529.   }
  530.   else the_font = font->x_font;
  531.  
  532.  
  533.   char *family = (char *)xv_get(the_font, FONT_FAMILY);
  534.   int wx_family;
  535.  
  536.   if (strcmp(family, FONT_FAMILY_LUCIDA) == 0)
  537.     wx_family = wxDECORATIVE;
  538.   else if (strcmp(family, FONT_FAMILY_ROMAN) == 0)
  539.     wx_family = wxROMAN;
  540.   else if (strcmp(family, FONT_FAMILY_HELVETICA) == 0)
  541.     wx_family = wxSWISS;
  542.  else if (strcmp(family, FONT_FAMILY_COUR) == 0)
  543.     wx_family = wxMODERN;
  544.   else
  545.     wx_family = wxDEFAULT;
  546.  
  547.   return wx_family;
  548. #endif
  549. #ifdef wx_msw
  550.   TEXTMETRIC lpTextMetric;
  551.   wxWnd *wnd = (wxWnd *)handle;
  552.   HDC dc = GetDC(wnd->handle);
  553.  
  554.   GetTextMetrics(dc, &lpTextMetric);
  555.   ReleaseDC(wnd->handle, dc);
  556.   int family;
  557.   switch (lpTextMetric.tmPitchAndFamily & 0xF0)
  558.   {
  559.     case FF_DECORATIVE:
  560.       family = wxDECORATIVE;
  561.       break;
  562.     case FF_MODERN:
  563.       family = wxMODERN;
  564.       break;
  565.     case FF_ROMAN:
  566.       family = wxROMAN;
  567.       break;
  568.     case FF_SWISS:
  569.       family = wxSWISS;
  570.       break;
  571.     default:
  572.     case FF_DONTCARE:
  573.       family = wxDEFAULT;
  574.   }
  575.   return family;
  576. #endif
  577. }
  578.  
  579. int wxWindow::GetTextStyle(void)
  580. {
  581. #ifdef wx_motif
  582.   return 0;
  583. #endif
  584. #ifdef wx_xview
  585.   Xv_Font the_font;
  586.  
  587.   if (!(font && font->x_font))
  588.   {
  589.     Xv_opaque thing = (Xv_opaque)handle;
  590.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  591.   }
  592.   else the_font = font->x_font;
  593.  
  594.   char *style = (char *)xv_get(the_font, FONT_STYLE);
  595.   int wx_style;
  596.  
  597.   if (strcmp(style, FONT_STYLE_NORMAL) == 0)
  598.     wx_style = wxNORMAL;
  599.   else if (strcmp(style, FONT_STYLE_BOLD) == 0)
  600.     wx_style = wxNORMAL;
  601.   else if (strcmp(style, FONT_STYLE_ITALIC) == 0)
  602.     wx_style = wxITALIC;
  603.   else if (strcmp(style, FONT_STYLE_BOLD_ITALIC) == 0)
  604.     wx_style = wxITALIC;
  605.   else if (strcmp(style, FONT_STYLE_OBLIQUE) == 0)
  606.     wx_style = wxSLANT;
  607.   else if (strcmp(style, FONT_STYLE_BOLD_OBLIQUE) == 0)
  608.     wx_style = wxSLANT;
  609.   else wx_style = wxDEFAULT;
  610.  
  611.   return wx_style;
  612. #endif
  613. #ifdef wx_msw
  614.   TEXTMETRIC lpTextMetric;
  615.   wxWnd *wnd = (wxWnd *)handle;
  616.   HDC dc = GetDC(wnd->handle);
  617.  
  618.   GetTextMetrics(dc, &lpTextMetric);
  619.   ReleaseDC(wnd->handle, dc);
  620.   int wx_style;
  621.   if (lpTextMetric.tmItalic)
  622.     wx_style = wxITALIC;
  623.   else wx_style = wxNORMAL;
  624.  
  625.   return wx_style;
  626. #endif
  627. }
  628.  
  629. int wxWindow::GetTextWeight(void)
  630. {
  631. #ifdef wx_motif
  632.   return 0;
  633. #endif
  634. #ifdef wx_xview
  635.   Xv_Font the_font;
  636.  
  637.   if (!(font && font->x_font))
  638.   {
  639.     Xv_opaque thing = (Xv_opaque)handle;
  640.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  641.   }
  642.   else the_font = font->x_font;
  643.  
  644.   char *style = (char *)xv_get(the_font, FONT_STYLE);
  645.   int wx_weight;
  646.  
  647.   if (strcmp(style, FONT_STYLE_NORMAL) == 0)
  648.     wx_weight = wxNORMAL;
  649.   else if (strcmp(style, FONT_STYLE_BOLD) == 0)
  650.     wx_weight = wxBOLD;
  651.   else if (strcmp(style, FONT_STYLE_ITALIC) == 0)
  652.     wx_weight = wxNORMAL;
  653.   else if (strcmp(style, FONT_STYLE_BOLD_ITALIC) == 0)
  654.     wx_weight = wxBOLD;
  655.   else if (strcmp(style, FONT_STYLE_OBLIQUE) == 0)
  656.     wx_weight = wxNORMAL;
  657.   else if (strcmp(style, FONT_STYLE_BOLD_OBLIQUE) == 0)
  658.     wx_weight = wxBOLD;
  659.   else wx_weight = wxNORMAL;
  660.  
  661.   return wx_weight;
  662. #endif
  663. #ifdef wx_msw
  664.   TEXTMETRIC lpTextMetric;
  665.   wxWnd *wnd = (wxWnd *)handle;
  666.   HDC dc = GetDC(wnd->handle);
  667.  
  668.   GetTextMetrics(dc, &lpTextMetric);
  669.   ReleaseDC(wnd->handle, dc);
  670.   int wx_weight;
  671.   int cweight = lpTextMetric.tmWeight;
  672.   if (cweight > 0 && cweight < 350)
  673.     wx_weight = wxLIGHT;  // light
  674.   else if (cweight >= 350 && cweight < 500)
  675.     wx_weight = wxNORMAL; // normal
  676.   else if (cweight >= 500)
  677.     wx_weight = wxBOLD; // bold
  678.   else wx_weight = wxNORMAL;
  679.  
  680.   return wx_weight;
  681. #endif
  682. }
  683.  
  684. float wxWindow::GetTextHeight(void)
  685. {
  686. #ifdef wx_motif
  687.   return 0.0;
  688. #endif
  689. #ifdef wx_xview
  690.   Xv_Font the_font;
  691.  
  692.   if (!(font && font->x_font))
  693.   {
  694.     Xv_opaque thing = (Xv_opaque)handle;
  695.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  696.   }
  697.   else the_font = font->x_font;
  698.  
  699.   return (float)xv_get(the_font, FONT_DEFAULT_CHAR_HEIGHT);
  700. #endif
  701. #ifdef wx_msw
  702.   TEXTMETRIC lpTextMetric;
  703.   wxWnd *wnd = (wxWnd *)handle;
  704.   HDC dc = GetDC(wnd->handle);
  705.  
  706.   GetTextMetrics(dc, &lpTextMetric);
  707.   ReleaseDC(wnd->handle, dc);
  708.  
  709.   return (float)lpTextMetric.tmHeight;
  710. #endif
  711. }
  712.  
  713. float wxWindow::GetTextWidth(void)
  714. {
  715. #ifdef wx_motif
  716.   return 0.0;
  717. #endif
  718. #ifdef wx_xview
  719.   Xv_Font the_font;
  720.  
  721.   if (!(font && font->x_font))
  722.   {
  723.     Xv_opaque thing = (Xv_opaque)handle;
  724.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  725.   }
  726.   else the_font = font->x_font;
  727.  
  728.   return (float)xv_get(the_font, FONT_DEFAULT_CHAR_WIDTH);
  729. #endif
  730. #ifdef wx_msw
  731.   TEXTMETRIC lpTextMetric;
  732.   wxWnd *wnd = (wxWnd *)handle;
  733.   HDC dc = GetDC(wnd->handle);
  734.  
  735.   GetTextMetrics(dc, &lpTextMetric);
  736.   ReleaseDC(wnd->handle, dc);
  737.  
  738.   return (float)lpTextMetric.tmAveCharWidth;
  739. #endif
  740. }
  741.  
  742. void wxWindow::GetTextExtent(char *string, float *x, float *y)
  743. {
  744. #ifdef wx_motif
  745.   *x = 0; *y = 0;
  746. #endif
  747. #ifdef wx_xview
  748.   Xv_Font the_font;
  749.  
  750.   if (!(font && font->x_font))
  751.   {
  752.     Xv_opaque thing = (Xv_opaque)handle;
  753.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  754.   }
  755.   else the_font = font->x_font;
  756.  
  757.   Font_string_dims dims;
  758.  
  759.   (void)xv_get(the_font, FONT_STRING_DIMS, string, &dims);
  760.   *x = (float)dims.width;
  761.   *y = (float)dims.height;
  762. #endif
  763. #ifdef wx_msw
  764.   wxWnd *wnd = (wxWnd *)handle;
  765.   HDC dc = GetDC(wnd->handle);
  766.  
  767.   SIZE sizeRect;
  768.   GetTextExtentPoint(dc, string, strlen(string), &sizeRect);
  769.  
  770.   ReleaseDC(wnd->handle, dc);
  771.  
  772.   *x = (float)sizeRect.cx;
  773.   *y = (float)sizeRect.cy;
  774.  
  775. #endif
  776. }
  777.  
  778. // Return the number of chars that this pixel dimension represents
  779. int wxWindow::XChar(int pixels)
  780. {
  781. #ifdef wx_motif
  782.   return 0;
  783. #endif
  784. #ifdef wx_xview
  785.   Xv_Font the_font;
  786.  
  787.   if (!(font && font->x_font))
  788.   {
  789.     Xv_opaque thing = (Xv_opaque)handle;
  790.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  791.   }
  792.   else the_font = font->x_font;
  793.  
  794.   return (int)(pixels/((int)xv_get(the_font, FONT_DEFAULT_CHAR_WIDTH)));
  795. #endif
  796. #ifdef wx_msw
  797.   wxWnd *wnd = (wxWnd *)handle;
  798.   int x, y;
  799.   wxGetCharSize(wnd->handle, &x, &y);
  800.   return (int)(pixels/x);
  801. #endif
  802. }
  803.  
  804. int wxWindow::YChar(int pixels)
  805. {
  806. #ifdef wx_motif
  807.   return 0;
  808. #endif
  809. #ifdef wx_xview
  810.   Xv_Font the_font;
  811.  
  812.   if (!(font && font->x_font))
  813.   {
  814.     Xv_opaque thing = (Xv_opaque)handle;
  815.     the_font = (Xv_Font)xv_get(thing, XV_FONT);
  816.   }
  817.   else the_font = font->x_font;
  818.  
  819.   return (int)(pixels/((int)xv_get(the_font, FONT_DEFAULT_CHAR_HEIGHT)));
  820. #endif
  821. #ifdef wx_msw
  822.   wxWnd *wnd = (wxWnd *)handle;
  823.   int x, y;
  824.   wxGetCharSize(wnd->handle, &x, &y);
  825.   return (int)(pixels/y);
  826. #endif
  827. }
  828.  
  829. // Fit window to contents
  830. void wxWindow::Fit(void)
  831. {
  832. }
  833.  
  834. // Centre on panel/screen
  835. void wxWindow::Centre(int direction)
  836. {
  837. }
  838.  
  839. #ifdef wx_motif
  840. void wxWindow::PreResize(void)
  841. {
  842. }
  843. #endif
  844.  
  845. #ifdef wx_motif
  846. // All widgets should have this as their resize proc.
  847. // OnSize sent to wxWindow via client data.
  848. void wxWidgetResizeProc(Widget w, XConfigureEvent *event, String args[], int *num_args)
  849. {
  850. //  cout << "Motif widget resize: " << (long)w << "\n";
  851.   wxWindow *win = (wxWindow *)wxWidgetHashTable->Get((long)w);
  852.   if (!win)
  853.     return;
  854.  
  855.   int width, height;
  856.   win->GetSize(&width, &height);
  857.   win->PreResize();
  858.   win->OnSize(width, height);
  859. }
  860. #endif
  861.  
  862. #ifdef wx_msw
  863. // Hook for new window just as it's being created,
  864. // when the window isn't yet associated with the handle
  865. wxWnd *wxWndHook = NULL;
  866.  
  867. // Main Windows 3 window proc
  868. LONG FAR PASCAL _export
  869.   wxWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  870. {
  871.   wxWnd *wnd = (wxWnd *)GetWindowLong(hWnd, 0);
  872.   if (!wnd)
  873.   {
  874.     if (wxWndHook)
  875.     {
  876.       wnd = wxWndHook;
  877.       wnd->handle = hWnd;
  878.     }
  879.     else wnd = wxFindWinFromHandle(hWnd);
  880.   }
  881.  
  882.   if (wnd)
  883.   {
  884.     wnd->last_msg = message;
  885.     wnd->last_wparam = wParam;
  886.     wnd->last_lparam = lParam;
  887.  
  888.     if (message == WM_SETFONT)
  889.       return 0;
  890.     else if (message == WM_INITDIALOG)
  891.       return TRUE;
  892.   }
  893.  
  894.   switch (message)
  895.   {
  896.         case WM_ACTIVATE:
  897.         {
  898.             WORD state = LOWORD(wParam);
  899. #ifdef WIN32
  900.             WORD minimized = HIWORD(wParam);
  901.             HWND hwnd = (HWND)lParam;
  902. #else
  903.             WORD minimized = LOWORD(lParam);
  904.             HWND hwnd = (HWND)HIWORD(lParam);
  905. #endif
  906.             if (!wnd->OnActivate(state, minimized, hwnd))
  907.               return wnd->DefWindowProc(message, wParam, lParam );
  908.             break;
  909.         }
  910.         case WM_SETFOCUS:
  911.         {
  912.             HWND hwnd = (HWND)wParam;
  913.             if (!wnd->OnSetFocus(hwnd))
  914.               return wnd->DefWindowProc(message, wParam, lParam );
  915.             break;
  916.         }
  917.         case WM_KILLFOCUS:
  918.         {
  919.             HWND hwnd = (HWND)lParam;
  920.             if (!wnd->OnKillFocus(hwnd))
  921.               return wnd->DefWindowProc(message, wParam, lParam );
  922.             break;
  923.         }
  924.     case WM_CREATE:
  925.             if (wnd)
  926.               wnd->OnCreate((LPCREATESTRUCT)lParam);
  927.             return 0;
  928.         break;
  929.  
  930.     case WM_PAINT:
  931.             return (long)wnd->OnPaint();
  932.             break;
  933.  
  934.         case WM_SIZE:
  935.         {
  936.             if (wnd)
  937.             {
  938.               int width = LOWORD(lParam);
  939.               int height = HIWORD(lParam);
  940.               wnd->OnSize(width, height, wParam);
  941.             }
  942.             else return DefWindowProc( hWnd, message, wParam, lParam );
  943.             break;
  944.         }
  945.  
  946.         case WM_RBUTTONDOWN:
  947.         {
  948.             int x = LOWORD(lParam);
  949.             int y = HIWORD(lParam);
  950.             wnd->OnRButtonDown(x, y, wParam);
  951.             break;
  952.         }
  953.         case WM_RBUTTONUP:
  954.         {
  955.             int x = LOWORD(lParam);
  956.             int y = HIWORD(lParam);
  957.             wnd->OnRButtonUp(x, y, wParam);
  958.             break;
  959.         }
  960.         case WM_LBUTTONDOWN:
  961.         {
  962.             int x = LOWORD(lParam);
  963.             int y = HIWORD(lParam);
  964.             wnd->OnLButtonDown(x, y, wParam);
  965.             break;
  966.         }
  967.         case WM_LBUTTONUP:
  968.         {
  969.             int x = LOWORD(lParam);
  970.             int y = HIWORD(lParam);
  971.             wnd->OnLButtonUp(x, y, wParam);
  972.             break;
  973.         }
  974.         case WM_MOUSEMOVE:
  975.         {
  976.             int x = LOWORD(lParam);
  977.             int y = HIWORD(lParam);
  978.             wnd->OnMouseMove(x, y, wParam);
  979.             break;
  980.         }
  981.         case WM_DESTROY:
  982.             if (wnd)
  983.             {
  984.               if (wnd->OnDestroy())
  985.                 return 0;
  986.               else return wnd->DefWindowProc(message, wParam, lParam );
  987.             }
  988.             else return DefWindowProc( hWnd, message, wParam, lParam );
  989.             break;
  990. /*
  991.         case WM_SYSCOMMAND:
  992.             break;
  993. */
  994.         case WM_COMMAND:
  995.     {
  996.             WORD id = LOWORD(wParam);
  997.             HWND hwnd = (HWND)(UINT)lParam;
  998. #ifdef WIN32
  999.             WORD cmd = HIWORD(wParam);
  1000. #else
  1001.             WORD cmd = HIWORD(lParam);
  1002. #endif
  1003.             if (!wnd->OnCommand(id, cmd, hwnd))
  1004.               return wnd->DefWindowProc(message, wParam, lParam );
  1005.             break;
  1006.      }
  1007.         case WM_MENUSELECT:
  1008.         {
  1009.             WORD id = LOWORD(wParam);
  1010. #ifdef WIN32
  1011.             WORD flags = HIWORD(wParam);
  1012.             HMENU sysmenu = (HMENU)lParam;
  1013. #else
  1014.             WORD flags = LOWORD(lParam);
  1015.             HMENU sysmenu = (HMENU)HIWORD(lParam);
  1016. #endif
  1017.             wnd->OnMenuSelect(wParam, flags, sysmenu);
  1018.             break;
  1019.         }
  1020.         case WM_KEYDOWN:
  1021.             break;
  1022.         case WM_CHAR:
  1023.             wnd->OnChar(wParam);
  1024.             break;
  1025.         case WM_HSCROLL:
  1026.         {
  1027.             WORD code = LOWORD(wParam);
  1028. #ifdef WIN32
  1029.             WORD pos = HIWORD(wParam);
  1030.             HWND control = (HWND)lParam;
  1031. #else
  1032.             WORD pos = LOWORD(lParam);
  1033.             HWND control = (HWND)HIWORD(lParam);
  1034. #endif
  1035.             wnd->OnHScroll(code, pos, control);
  1036.             break;
  1037.         }
  1038.         case WM_VSCROLL:
  1039.         {
  1040.             WORD code = LOWORD(wParam);
  1041. #ifdef WIN32
  1042.             WORD pos = HIWORD(wParam);
  1043.             HWND control = (HWND)lParam;
  1044. #else
  1045.             WORD pos = LOWORD(lParam);
  1046.             HWND control = (HWND)HIWORD(lParam);
  1047. #endif
  1048.             wnd->OnVScroll(code, pos, control);
  1049.             break;
  1050.         }
  1051. #ifdef WIN32
  1052.         case WM_CTLCOLORBTN:
  1053.     {
  1054.           int nCtlColor = CTLCOLOR_BTN;
  1055.           HWND control = (HWND)LOWORD(lParam);
  1056.           HDC pDC = (HDC)HIWORD(wParam);
  1057.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1058.           break;
  1059.     }
  1060.         case WM_CTLCOLORDLG:
  1061.     {
  1062.           int nCtlColor = CTLCOLOR_DLG;
  1063.           HWND control = (HWND)LOWORD(lParam);
  1064.           HDC pDC = (HDC)HIWORD(wParam);
  1065.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1066.           break;
  1067.     }
  1068.         case WM_CTLCOLORLISTBOX:
  1069.     {
  1070.           int nCtlColor = CTLCOLOR_LISTBOX;
  1071.           HWND control = (HWND)LOWORD(lParam);
  1072.           HDC pDC = (HDC)HIWORD(wParam);
  1073.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1074.           break;
  1075.     }
  1076.         case WM_CTLCOLORMSGBOX:
  1077.     {
  1078.           int nCtlColor = CTLCOLOR_MSGBOX;
  1079.           HWND control = (HWND)LOWORD(lParam);
  1080.           HDC pDC = (HDC)HIWORD(wParam);
  1081.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1082.           break;
  1083.     }
  1084.         case WM_CTLCOLORSCROLLBAR:
  1085.     {
  1086.           int nCtlColor = CTLCOLOR_SCROLLBAR;
  1087.           HWND control = (HWND)LOWORD(lParam);
  1088.           HDC pDC = (HDC)HIWORD(wParam);
  1089.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1090.           break;
  1091.     }
  1092.         case WM_CTLCOLORSTATIC:
  1093.     {
  1094.           int nCtlColor = CTLCOLOR_STATIC;
  1095.           HWND control = (HWND)LOWORD(lParam);
  1096.           HDC pDC = (HDC)HIWORD(wParam);
  1097.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1098.           break;
  1099.     }
  1100.         case WM_CTLCOLOREDIT:
  1101.     {
  1102.           int nCtlColor = CTLCOLOR_EDIT;
  1103.           HWND control = (HWND)LOWORD(lParam);
  1104.           HDC pDC = (HDC)HIWORD(wParam);
  1105.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1106.           break;
  1107.     }
  1108. #else
  1109.         case WM_CTLCOLOR:
  1110.         {
  1111.           HWND control = (HWND)LOWORD(lParam);
  1112.           int nCtlColor = (int)HIWORD(lParam);
  1113.           HDC pDC = (HDC)wParam;
  1114.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1115.           break;
  1116.         }
  1117. #endif
  1118.         case WM_ERASEBKGND:
  1119.         {
  1120.             if (!wnd->OnEraseBkgnd((HDC)wParam))
  1121.               return wnd->DefWindowProc(message, wParam, lParam );
  1122.             else return 1;
  1123.             break;
  1124.         }
  1125.         case WM_MDIACTIVATE:
  1126.         {
  1127. #ifdef WIN32
  1128.             // Is this right???
  1129.             HWND hWndActivate = (HWND)LOWORD(wParam);
  1130.             HWND hWndDeactivate = (HWND)LOWORD(lParam);
  1131.             BOOL activate = (hWndActivate == hWnd);
  1132.             return wnd->OnMDIActivate(activate, hWndActivate, hWndDeactivate);
  1133. #else
  1134.             return wnd->OnMDIActivate((BOOL)wParam, (HWND)LOWORD(lParam),
  1135.                                                (HWND)HIWORD(lParam));
  1136. #endif
  1137.         }
  1138.         case WM_CLOSE:
  1139.         {
  1140.             if (wnd->OnClose())
  1141.               return 0L;
  1142.             else
  1143.               return 1L;
  1144.             break;
  1145.         }
  1146.  
  1147.         default:
  1148.             if (wnd)
  1149.               return wnd->DefWindowProc(message, wParam, lParam );
  1150.             else return DefWindowProc( hWnd, message, wParam, lParam );
  1151.     }
  1152.     return 0;
  1153. }
  1154.  
  1155. // Dialog window proc
  1156. LONG FAR PASCAL _export
  1157.   wxDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  1158. {
  1159.   wxWnd *wnd = wxFindWinFromHandle(hWnd);
  1160.  
  1161.   if (!wnd && wxWndHook)
  1162.   {
  1163.     wnd = wxWndHook;
  1164.     wnd->handle = hWnd;
  1165.   }
  1166.  
  1167.   if (wnd)
  1168.   {
  1169.     wnd->last_msg = message;
  1170.     wnd->last_wparam = wParam;
  1171.     wnd->last_lparam = lParam;
  1172.   }
  1173.  
  1174.   if (message == WM_SETFONT)
  1175.     return 0;
  1176.   else if (message == WM_INITDIALOG)
  1177.     return TRUE;
  1178.  
  1179.   switch (message)
  1180.   {
  1181.         case WM_ACTIVATE:
  1182.         {
  1183.             WORD state = LOWORD(wParam);
  1184. #ifdef WIN32
  1185.             WORD minimized = HIWORD(wParam);
  1186.             HWND hwnd = (HWND)lParam;
  1187. #else
  1188.             WORD minimized = LOWORD(lParam);
  1189.             HWND hwnd = (HWND)HIWORD(lParam);
  1190. #endif
  1191.             if (!wnd->OnActivate(state, minimized, hwnd))
  1192.               return wnd->DefWindowProc(message, wParam, lParam );
  1193.             break;
  1194.      }
  1195.  
  1196.         case WM_SETFOCUS:
  1197.         {
  1198.             HWND hwnd = (HWND)wParam;
  1199.             if (!wnd->OnSetFocus(hwnd))
  1200.               return wnd->DefWindowProc(message, wParam, lParam );
  1201.             break;
  1202.         }
  1203.         case WM_KILLFOCUS:
  1204.         {
  1205.             HWND hwnd = (HWND)lParam;
  1206.             if (!wnd->OnKillFocus(hwnd))
  1207.               return wnd->DefWindowProc(message, wParam, lParam );
  1208.             break;
  1209.         }
  1210.  
  1211.         case WM_CREATE:
  1212.             if (wnd)
  1213.               wnd->OnCreate((LPCREATESTRUCT)lParam);
  1214.             return 0;
  1215.         break;
  1216.  
  1217.         case WM_SIZE:
  1218.         {
  1219.             if (wnd)
  1220.             {
  1221.               int width = LOWORD(lParam);
  1222.               int height = HIWORD(lParam);
  1223.               wnd->OnSize(width, height, wParam);
  1224.             }
  1225.             else return FALSE;
  1226.             break;
  1227.         }
  1228. /*
  1229.         case WM_DESTROY:
  1230.             if (wnd)
  1231.             {
  1232.               if (wnd->OnDestroy())
  1233.                 return 0;
  1234.             }
  1235.             return FALSE;
  1236.             break;
  1237. */
  1238.         case WM_COMMAND:
  1239.     {
  1240.             WORD id = LOWORD(wParam);
  1241.             HWND hwnd = (HWND)(UINT)lParam;
  1242. #ifdef WIN32
  1243.             WORD cmd = HIWORD(wParam);
  1244. #else
  1245.             WORD cmd = HIWORD(lParam);
  1246. #endif
  1247.             if (!wnd->OnCommand(id, cmd, hwnd))
  1248.               return wnd->DefWindowProc(message, wParam, lParam );
  1249.             break;
  1250.     }
  1251.         case WM_HSCROLL:
  1252.         {
  1253.             WORD code = LOWORD(wParam);
  1254. #ifdef WIN32
  1255.             WORD pos = HIWORD(wParam);
  1256.             HWND control = (HWND)lParam;
  1257. #else
  1258.             WORD pos = LOWORD(lParam);
  1259.             HWND control = (HWND)HIWORD(lParam);
  1260. #endif
  1261.             wnd->OnHScroll(code, pos, control);
  1262.             break;
  1263.         }
  1264.         case WM_VSCROLL:
  1265.         {
  1266.             WORD code = LOWORD(wParam);
  1267. #ifdef WIN32
  1268.             WORD pos = HIWORD(wParam);
  1269.             HWND control = (HWND)lParam;
  1270. #else
  1271.             WORD pos = LOWORD(lParam);
  1272.             HWND control = (HWND)HIWORD(lParam);
  1273. #endif
  1274.             wnd->OnVScroll(code, pos, control);
  1275.             break;
  1276.         }
  1277. #ifdef WIN32
  1278.         case WM_CTLCOLORBTN:
  1279.     {
  1280.           int nCtlColor = CTLCOLOR_BTN;
  1281.           HWND control = (HWND)LOWORD(lParam);
  1282.           HDC pDC = (HDC)HIWORD(wParam);
  1283.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1284.           break;
  1285.     }
  1286.         case WM_CTLCOLORDLG:
  1287.     {
  1288.           int nCtlColor = CTLCOLOR_DLG;
  1289.           HWND control = (HWND)LOWORD(lParam);
  1290.           HDC pDC = (HDC)HIWORD(wParam);
  1291.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1292.           break;
  1293.     }
  1294.         case WM_CTLCOLORLISTBOX:
  1295.     {
  1296.           int nCtlColor = CTLCOLOR_LISTBOX;
  1297.           HWND control = (HWND)LOWORD(lParam);
  1298.           HDC pDC = (HDC)HIWORD(wParam);
  1299.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1300.           break;
  1301.     }
  1302.         case WM_CTLCOLORMSGBOX:
  1303.     {
  1304.           int nCtlColor = CTLCOLOR_MSGBOX;
  1305.           HWND control = (HWND)LOWORD(lParam);
  1306.           HDC pDC = (HDC)HIWORD(wParam);
  1307.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1308.           break;
  1309.     }
  1310.         case WM_CTLCOLORSCROLLBAR:
  1311.     {
  1312.           int nCtlColor = CTLCOLOR_SCROLLBAR;
  1313.           HWND control = (HWND)LOWORD(lParam);
  1314.           HDC pDC = (HDC)HIWORD(wParam);
  1315.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1316.           break;
  1317.     }
  1318.         case WM_CTLCOLORSTATIC:
  1319.     {
  1320.           int nCtlColor = CTLCOLOR_STATIC;
  1321.           HWND control = (HWND)LOWORD(lParam);
  1322.           HDC pDC = (HDC)HIWORD(wParam);
  1323.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1324.           break;
  1325.     }
  1326.         case WM_CTLCOLOREDIT:
  1327.     {
  1328.           int nCtlColor = CTLCOLOR_EDIT;
  1329.           HWND control = (HWND)LOWORD(lParam);
  1330.           HDC pDC = (HDC)HIWORD(wParam);
  1331.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1332.           break;
  1333.     }
  1334. #else
  1335.         case WM_CTLCOLOR:
  1336.         {
  1337.           HWND control = (HWND)LOWORD(lParam);
  1338.           int nCtlColor = (int)HIWORD(lParam);
  1339.           HDC pDC = (HDC)wParam;
  1340.           return (DWORD)wnd->OnCtlColor(pDC, control, nCtlColor);
  1341.           break;
  1342.         }
  1343. #endif
  1344.         case WM_ERASEBKGND:
  1345.         {
  1346.             return wnd->OnEraseBkgnd((HDC)wParam);
  1347.             break;
  1348.         }
  1349.         case WM_CLOSE:
  1350.         {
  1351.             return !wnd->OnClose();
  1352.             break;
  1353.         }
  1354.         default:
  1355.           return FALSE;
  1356.     }
  1357.     return FALSE;
  1358. }
  1359.  
  1360. wxList *wxWinHandleList = NULL;
  1361. wxWnd *wxFindWinFromHandle(HWND hWnd)
  1362. {
  1363.   wxNode *node = wxWinHandleList->Find((long)hWnd);
  1364.   if (!node)
  1365.     return NULL;
  1366.   return (wxWnd *)node->Data();
  1367. }
  1368.  
  1369. /* wxWnd class used to implement all Windows 3 windows
  1370.  */
  1371. wxWnd::wxWnd(void)
  1372.  
  1373. {
  1374.   x_scrolling_enabled = TRUE;
  1375.   y_scrolling_enabled = TRUE;
  1376.   last_msg = 0;
  1377.   last_wparam = 0;
  1378.   last_lparam = 0;
  1379.   accelerator_table = NULL;
  1380.  
  1381.   xscroll_pixels_per_line = 0;
  1382.   yscroll_pixels_per_line = 0;
  1383.   xscroll_lines = 0;
  1384.   yscroll_lines = 0;
  1385.   xscroll_lines_per_page = 0;
  1386.   yscroll_lines_per_page = 0;
  1387.   xscroll_position = 0;
  1388.   yscroll_position = 0;
  1389.   background_brush = GetStockObject( LTGRAY_BRUSH );
  1390.   last_x_pos = -1.0;
  1391.   last_y_pos = -1.0;
  1392.   last_event = -1;
  1393.   is_canvas = FALSE;
  1394.   cdc = NULL;
  1395. }
  1396.  
  1397. wxWnd::~wxWnd(void)
  1398. {
  1399.   wxWinHandleList->DeleteObject(this);
  1400. }
  1401.  
  1402. // Default destroyer - override if you destroy it in some other way
  1403. // (e.g. with MDI child windows)
  1404. void wxWnd::DestroyWindow(void)
  1405. {
  1406.   ::DestroyWindow(handle);
  1407.   SetWindowLong(handle, 0, (long)0);
  1408.   handle = NULL;
  1409. }
  1410.  
  1411. void wxWnd::Create(wxWnd *parent, char *wclass, wxWindow *wx_win, char *title,
  1412.                     int x, int y, int width, int height,
  1413.                     DWORD style, char *dialog_template)
  1414. {
  1415.   wx_window = wx_win;
  1416.   is_dialog = (dialog_template != NULL);
  1417.   int x1 = 0;
  1418.   int y1 = 0;
  1419.   int x2 = 100;
  1420.   int y2 = 100;
  1421.  
  1422.   // Find parent's size, if it exists, to set up a possible default
  1423.   // panel size the size of the parent window
  1424.   RECT parent_rect;
  1425.   if (parent)
  1426.   {
  1427.     GetWindowRect(parent->handle, &parent_rect);
  1428.  
  1429.     // Convert from screen coordinates to parent coordinates
  1430.     x2 = parent_rect.right - parent_rect.left;
  1431.     y2 = parent_rect.bottom - parent_rect.top;
  1432.   }
  1433.  
  1434.   if (x > -1) x1 = x;
  1435.   if (y > -1) y1 = y;
  1436.   if (width > -1) x2 = x1 + width;
  1437.   if (height > -1) y2 = y1 + height;
  1438.  
  1439.   HWND hParent = NULL;
  1440.   if (parent)
  1441.     hParent = parent->handle;
  1442.  
  1443.   wxWndHook = this;
  1444.  
  1445.   if (is_dialog)
  1446.   {
  1447.     // MakeProcInstance doesn't seem to be needed in C7. Is it needed for
  1448.     // other compilers???
  1449. //    DLGPROC dlgproc = (DLGPROC)MakeProcInstance(wxWndProc, wxhInstance);
  1450.  
  1451.     handle = ::CreateDialog(wxhInstance, dialog_template, hParent,
  1452.                             (DLGPROC)wxDlgProc);
  1453.     MoveWindow(handle, x1, y1, x2 - x1, y2 - y1, FALSE);
  1454.   }
  1455.   else
  1456.     handle = CreateWindow(wclass,
  1457.                 title,
  1458.                 style,
  1459.                 x1, y1,
  1460.                 x2 - x1, y2 - y1,
  1461.                 hParent, NULL, wxhInstance,
  1462.                 NULL);
  1463.  
  1464.   wxWndHook = NULL;
  1465.   wxWinHandleList->Append((long)handle, this);
  1466.  
  1467.   // Can't do this for dialogs!!!!
  1468.   if (!is_dialog) SetWindowLong(handle, 0, (long)this);
  1469. }
  1470.  
  1471. void wxWnd::OnCreate(LPCREATESTRUCT cs)
  1472. {
  1473. }
  1474.  
  1475. BOOL wxWnd::OnPaint(void)
  1476. {
  1477.   return 1;
  1478. }
  1479.  
  1480. BOOL wxWnd::OnClose(void)
  1481. {
  1482.   return FALSE;
  1483. }
  1484.  
  1485. BOOL wxWnd::OnDestroy(void)
  1486. {
  1487.   return FALSE;
  1488. }
  1489.  
  1490. void wxWnd::OnSize(int x, int y, UINT flag)
  1491. {
  1492. }
  1493.  
  1494. // Deal with child commands from buttons etc.
  1495.  
  1496. BOOL wxWnd::OnCommand(WORD id, WORD cmd, HWND control)
  1497. {
  1498.   return FALSE;
  1499. }
  1500.  
  1501. void wxWnd::OnMenuSelect(WORD item, WORD flags, HMENU sysmenu)
  1502. {
  1503. }
  1504.  
  1505. BOOL wxWnd::OnActivate(BOOL state, BOOL minimized, HWND activate)
  1506. {
  1507.   if (wx_window)
  1508.   {
  1509.     wx_window->OnActivate(((state == WA_ACTIVE) || (state == WA_CLICKACTIVE)));
  1510.     return TRUE;
  1511.   }
  1512.   else return FALSE;
  1513. }
  1514.  
  1515. BOOL wxWnd::OnSetFocus(HWND hwnd)
  1516. {
  1517.   if (wx_window)
  1518.   {
  1519.     wx_window->OnSetFocus();
  1520.     return TRUE;
  1521.   }
  1522.   else return FALSE;
  1523. }
  1524.  
  1525. BOOL wxWnd::OnKillFocus(HWND hwnd)
  1526. {
  1527.   if (wx_window)
  1528.   {
  1529.     wx_window->OnKillFocus();
  1530.     return TRUE;
  1531.   }
  1532.   else return FALSE;
  1533. }
  1534.  
  1535. void wxWnd::OnVScroll(WORD code, WORD pos, HWND control)
  1536. {
  1537. }
  1538.  
  1539. void wxWnd::OnHScroll(WORD code, WORD pos, HWND control)
  1540. {
  1541. }
  1542.  
  1543. void wxWnd::CalcScrolledPosition(int x, int y, int *xx, int *yy)
  1544. {
  1545.   *xx = x - xscroll_position * xscroll_pixels_per_line;
  1546.   *yy = y - yscroll_position * yscroll_pixels_per_line;
  1547. }
  1548.  
  1549. void wxWnd::CalcUnscrolledPosition(int x, int y, float *xx, float *yy)
  1550. {
  1551.   *xx = (float)(x + xscroll_position * xscroll_pixels_per_line);
  1552.   *yy = (float)(y + yscroll_position * yscroll_pixels_per_line);
  1553. }
  1554.  
  1555. HBRUSH wxWnd::OnCtlColor(HDC pDC, HWND pWnd, UINT nCtlColor)
  1556. {
  1557.   if ((nCtlColor == CTLCOLOR_STATIC || nCtlColor == CTLCOLOR_BTN) && background_brush)
  1558.   {
  1559.     SetBkColor(pDC, RGB(200, 200, 200));
  1560.     return background_brush;
  1561.   }
  1562.   else return NULL;
  1563. }
  1564.  
  1565. BOOL wxWnd::OnEraseBkgnd(HDC pDC)
  1566. {
  1567.   return FALSE;
  1568. }
  1569.  
  1570. void wxWnd::OnLButtonDown(int x, int y, UINT flags)
  1571. {
  1572. }
  1573.  
  1574. void wxWnd::OnLButtonUp(int x, int y, UINT flags)
  1575. {
  1576. }
  1577.  
  1578. void wxWnd::OnRButtonDown(int x, int y, UINT flags)
  1579. {
  1580. }
  1581.  
  1582. void wxWnd::OnRButtonUp(int x, int y, UINT flags)
  1583. {
  1584. }
  1585.  
  1586. void wxWnd::OnMouseMove(int x, int y, UINT flags)
  1587. {
  1588. }
  1589.  
  1590. void wxWnd::OnChar(WORD wParam)
  1591. {
  1592. }
  1593.  
  1594. LONG wxWnd::DefWindowProc(UINT nMsg, WPARAM wParam, LPARAM lParam)
  1595. {
  1596.   return ::DefWindowProc(handle, nMsg, wParam, lParam);
  1597. }
  1598.  
  1599. BOOL wxWnd::ProcessMessage(MSG* pMsg)
  1600. {
  1601.   return FALSE;
  1602. }
  1603.  
  1604. BOOL wxWnd::OnMDIActivate(BOOL flag, HWND activate, HWND deactivate)
  1605. {
  1606.   return 1;
  1607. }
  1608.  
  1609. /*
  1610.  * Subwindow - used for panels and canvases
  1611.  *
  1612.  */
  1613.  
  1614. wxSubWnd::wxSubWnd(wxWnd *parent, char *wclass, wxWindow *wx_win,
  1615.                            int x, int y, int width, int height,
  1616.                            DWORD style, char *dialog_template)
  1617.  
  1618. {
  1619.   Create(parent, wclass, wx_win, NULL, x, y, width, height, style, dialog_template);
  1620. }
  1621.  
  1622. wxSubWnd::~wxSubWnd(void)
  1623. {
  1624. }
  1625.  
  1626.  
  1627. BOOL wxSubWnd::OnPaint(void)
  1628. {
  1629.   RECT rect;
  1630.   if (GetUpdateRect(handle, &rect, FALSE))
  1631.   {
  1632.     PAINTSTRUCT ps;
  1633.     // Hold a pointer to the dc so long as the OnPaint() message
  1634.     // is being processed
  1635.     cdc = BeginPaint(handle, &ps);
  1636.     if (wx_window)
  1637.       wx_window->OnPaint();
  1638.  
  1639.     cdc = NULL;
  1640.     EndPaint(handle, &ps);
  1641.     return 0;
  1642.   }
  1643.   return 1;
  1644. }
  1645.  
  1646. void wxSubWnd::OnSize(int x, int y, UINT flag)
  1647. {
  1648.   // Store DC for duration of size message
  1649.   cdc = GetDC(handle);
  1650.   if (wx_window)
  1651.     wx_window->OnSize(x, y);
  1652.  
  1653.   ReleaseDC(handle, cdc);
  1654.   cdc = NULL;
  1655. }
  1656.  
  1657.  
  1658.  
  1659. // Deal with child commands from buttons etc.
  1660. BOOL wxSubWnd::OnCommand(WORD id, WORD cmd, HWND control)
  1661. {
  1662.   wxWindow *item = wx_window->FindItem(id);
  1663.   if (item)
  1664.   {
  1665.     Bool value = item->Command(cmd);
  1666.     return value;
  1667.   }
  1668.   else
  1669.     return FALSE;
  1670. }
  1671.  
  1672. void wxSubWnd::OnLButtonDown(int x, int y, UINT flags)
  1673. {
  1674.   wxEvent event;
  1675.   float px = (float)x;
  1676.   float py = (float)y;
  1677.  
  1678.   DeviceToLogical(&px, &py);
  1679.  
  1680.   CalcUnscrolledPosition((int)px, (int)py, &event.x, &event.y);
  1681.  
  1682.   event.event = wxLEFTDOWN;
  1683.   event.flags = flags;
  1684.  
  1685.   last_x_pos = event.x; last_y_pos = event.y; last_event = wxLEFTDOWN;
  1686.   if (wx_window) wx_window->OnEvent(event);
  1687. }
  1688.  
  1689. void wxSubWnd::OnLButtonUp(int x, int y, UINT flags)
  1690. {
  1691.   wxEvent event;
  1692.   float px = (float)x;
  1693.   float py = (float)y;
  1694.  
  1695.   DeviceToLogical(&px, &py);
  1696.  
  1697.   CalcUnscrolledPosition((int)px, (int)py, &event.x, &event.y);
  1698.  
  1699.   event.event = wxLEFTUP;
  1700.   event.flags = flags;
  1701.   last_x_pos = event.x; last_y_pos = event.y; last_event = wxLEFTUP;
  1702.   if (wx_window) wx_window->OnEvent(event);
  1703. }
  1704.  
  1705. void wxSubWnd::OnRButtonDown(int x, int y, UINT flags)
  1706. {
  1707.   wxEvent event;
  1708.   float px = (float)x;
  1709.   float py = (float)y;
  1710.  
  1711.   DeviceToLogical(&px, &py);
  1712.  
  1713.   CalcUnscrolledPosition((int)px, (int)py, &event.x, &event.y);
  1714.  
  1715.   event.event = wxRIGHTDOWN;
  1716.   event.flags = flags;
  1717.  
  1718.   last_x_pos = event.x; last_y_pos = event.y; last_event = wxRIGHTDOWN;
  1719.   if (wx_window) wx_window->OnEvent(event);
  1720. }
  1721.  
  1722. void wxSubWnd::OnRButtonUp(int x, int y, UINT flags)
  1723. {
  1724.   wxEvent event;
  1725.   float px = (float)x;
  1726.   float py = (float)y;
  1727.  
  1728.   DeviceToLogical(&px, &py);
  1729.  
  1730.   CalcUnscrolledPosition((int)px, (int)py, &event.x, &event.y);
  1731.  
  1732.   event.event = wxRIGHTUP;
  1733.   event.flags = flags;
  1734.   last_x_pos = event.x; last_y_pos = event.y; last_event = wxRIGHTUP;
  1735.   if (wx_window) wx_window->OnEvent(event);
  1736. }
  1737.  
  1738. void wxSubWnd::OnMouseMove(int x, int y, UINT flags)
  1739. {
  1740.   // Set cursor
  1741.   if (wx_window->wx_cursor)
  1742.     ::SetCursor(wx_window->wx_cursor->ms_cursor);
  1743.  
  1744.   wxEvent event;
  1745.   float px = (float)x;
  1746.   float py = (float)y;
  1747.  
  1748.   DeviceToLogical(&px, &py);
  1749.  
  1750.   CalcUnscrolledPosition((int)px, (int)py, &event.x, &event.y);
  1751.  
  1752.   event.event = wxMOVE;
  1753.   event.flags = flags;
  1754.  
  1755.   // Window gets a click down message followed by a mouse move
  1756.   // message even if position isn't changed!  We want to discard
  1757.   // the trailing move event if x and y are the same.
  1758.   if ((last_event == wxRIGHTDOWN || last_event == wxLEFTDOWN) &&
  1759.       (last_x_pos == event.x && last_y_pos == event.y))
  1760.   {
  1761.     last_x_pos = event.x; last_y_pos = event.y;
  1762.     last_event = wxMOVE;
  1763.     return;
  1764.   }
  1765.  
  1766.   last_event = wxMOVE;
  1767.   last_x_pos = event.x; last_y_pos = event.y;
  1768.   if (wx_window) wx_window->OnEvent(event);
  1769. }
  1770.  
  1771. void wxSubWnd::OnChar(WORD wParam)
  1772. {
  1773.   if (wx_window) wx_window->OnChar((int)wParam);
  1774. }
  1775.  
  1776. void wxSubWnd::OnVScroll(WORD wParam, WORD pos, HWND control)
  1777. {
  1778.     short nScrollInc;
  1779.     
  1780.     switch ( wParam )
  1781.     {
  1782.         case SB_TOP:
  1783.                         nScrollInc = -yscroll_position;
  1784.             break;
  1785.  
  1786.         case SB_BOTTOM:
  1787.                         nScrollInc = yscroll_lines - yscroll_position;
  1788.             break;
  1789.             
  1790.         case SB_LINEUP:
  1791.             nScrollInc = -1;
  1792.             break;
  1793.  
  1794.         case SB_LINEDOWN:
  1795.             nScrollInc = 1;
  1796.             break;
  1797.  
  1798.         case SB_PAGEUP:
  1799.                         nScrollInc = min(-1, -yscroll_lines_per_page);
  1800.             break;
  1801.  
  1802.         case SB_PAGEDOWN:
  1803.                         nScrollInc = max(1, yscroll_lines_per_page);
  1804.             break;
  1805.  
  1806.         case SB_THUMBTRACK:
  1807.                         nScrollInc = pos - yscroll_position;
  1808.             break;
  1809.  
  1810.         default:
  1811.             nScrollInc = 0;
  1812.     }
  1813.  
  1814.         int w, h;
  1815.         RECT rect;
  1816.         GetWindowRect(handle, &rect);
  1817.         w = rect.right - rect.left;
  1818.         h = rect.bottom - rect.top;
  1819.  
  1820.         int nVscrollMax = max(0, (int)(yscroll_lines + 2 -  h/yscroll_pixels_per_line));
  1821.         if ( nScrollInc = max( -yscroll_position,
  1822.                         min( nScrollInc, nVscrollMax - yscroll_position ) ) )
  1823.     {
  1824.           yscroll_position += nScrollInc;
  1825.  
  1826.           if (y_scrolling_enabled)
  1827.             ScrollWindow(handle, 0, -yscroll_pixels_per_line * nScrollInc, NULL, NULL );
  1828.           else
  1829.             InvalidateRect(handle, NULL, FALSE);
  1830.           SetScrollPos(handle, SB_VERT, yscroll_position, TRUE );
  1831.     }
  1832. }
  1833.  
  1834. void wxSubWnd::OnHScroll( WORD wParam, WORD pos, HWND control)
  1835. {
  1836.   if (control)
  1837.   {
  1838.     wxSliderEvent(control, wParam, pos);
  1839.   }
  1840.   else
  1841.   {
  1842.     int nScrollInc;
  1843.     switch ( wParam )
  1844.     {
  1845.         case SB_LINEUP:
  1846.             nScrollInc = -1;
  1847.             break;
  1848.  
  1849.         case SB_LINEDOWN:
  1850.             nScrollInc = 1;
  1851.             break;
  1852.  
  1853.         case SB_PAGEUP:
  1854.                         nScrollInc = -xscroll_lines_per_page;
  1855.             break;
  1856.  
  1857.         case SB_PAGEDOWN:
  1858.                         nScrollInc = xscroll_lines_per_page;
  1859.             break;
  1860.  
  1861.                 case SB_THUMBTRACK:
  1862.                         nScrollInc = pos - xscroll_position;
  1863.             break;
  1864.  
  1865.         default:
  1866.             nScrollInc = 0;
  1867.     }
  1868.         int w, h;
  1869.         RECT rect;
  1870.         GetWindowRect(handle, &rect);
  1871.         w = rect.right - rect.left;
  1872.         h = rect.bottom - rect.top;
  1873.         int nMaxWidth = xscroll_lines*xscroll_pixels_per_line;
  1874.         int nHscrollMax = max(0, (int)(2 + (nMaxWidth - w)/xscroll_pixels_per_line));
  1875.  
  1876.         if ( nScrollInc = max( -xscroll_position,
  1877.                          min( nScrollInc, nHscrollMax - xscroll_position ) ) )
  1878.     {
  1879.           xscroll_position += nScrollInc;
  1880.           if (x_scrolling_enabled)
  1881.             ScrollWindow(handle, -xscroll_pixels_per_line * nScrollInc, 0, NULL, NULL );
  1882.           else
  1883.             InvalidateRect(handle, NULL, FALSE);
  1884.           SetScrollPos(handle, SB_HORZ, xscroll_position, TRUE );
  1885.     }
  1886.   }
  1887. }
  1888.  
  1889. void wxGetCharSize(HWND wnd, int *x, int *y)
  1890. {
  1891.   TEXTMETRIC tm;
  1892.   HDC dc = GetDC(wnd);
  1893.   GetTextMetrics(dc, &tm);
  1894.   ReleaseDC(wnd, dc);
  1895.   *x = tm.tmAveCharWidth;
  1896.   *y = tm.tmHeight + tm.tmExternalLeading;
  1897. }
  1898.  
  1899. #endif
  1900.  
  1901.