home *** CD-ROM | disk | FTP | other *** search
/ World of Shareware - Software Farm 2 / wosw_2.zip / wosw_2 / CPROG / WXWIN140.ZIP / SRC / WX_MAIN.CC < prev    next >
C/C++ Source or Header  |  1993-04-18  |  13KB  |  528 lines

  1. /*
  2.  * File:     wx_main.cc
  3.  * Purpose:  wxApp 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. #include <string.h>
  32.  
  33. #include "common.h"
  34. #include "wx_frame.h"
  35. #include "wx_main.h"
  36. #include "wx_utils.h"
  37. #include "wx_gdi.h"
  38. #include "wx_dc.h"
  39. #include "wx_dialg.h"
  40. #include "wx_privt.h"
  41.  
  42. wxApp *wxTheApp = NULL;
  43.  
  44. #ifdef wx_motif
  45. #include <Xm/Xm.h>
  46. wxHashTable *wxWidgetHashTable = NULL;
  47. #endif
  48.  
  49. #ifdef wx_msw
  50. HANDLE wxhInstance = 0;
  51. extern wxList *wxWinHandleList;
  52. char *wxFrameClassName = "wxFrameClass";
  53. char *wxMDIFrameClassName = "wxMDIFrameClass";
  54. char *wxMDIChildFrameClassName = "wxMDIChildFrameClass";
  55. char *wxPanelClassName = "wxPanelClass";
  56. char *wxCanvasClassName = "wxCanvasClass";
  57. HICON wxSTD_FRAME_ICON = NULL;
  58. HICON wxSTD_MDICHILDFRAME_ICON = NULL;
  59. LONG FAR PASCAL _export
  60.   wxWndProc(HWND hWnd, UINT message, UINT wParam, LONG lParam);
  61. #endif
  62.  
  63. void wxCleanUp(void);
  64.  
  65. #ifdef wx_xview
  66. Xv_Server xview_server;
  67. #endif
  68.  
  69. #ifdef wx_x
  70. main(int argc, char *argv[])
  71. {
  72.   if (!wxTheApp)
  73.   {
  74.     cerr << "wxWindows error: You have to define an instance of wxApp!\n";
  75.     _exit(0);
  76.   }
  77. #ifdef wx_xview
  78.   xview_server = xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
  79. #endif
  80. #ifdef wx_motif
  81.   wxTheApp->topLevel = XtVaAppInitialize(&wxTheApp->appContext, "wxApp",
  82.                          NULL, 0, &argc, argv, NULL, NULL);
  83.  
  84.   // Add general resize proc
  85.   XtActionsRec rec;
  86.   rec.string = "resize";
  87.   rec.proc = (XtActionProc)wxWidgetResizeProc;
  88.   XtAppAddActions(wxTheApp->appContext, &rec, 1);
  89.   wxWidgetHashTable = new wxHashTable(wxKEY_INTEGER);
  90. #endif
  91.   wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
  92.   wxTheColourDatabase->Initialize();
  93.  
  94.   wxInitializeStockObjects();
  95.  
  96.   wxTheApp->argc = argc;
  97.   wxTheApp->argv = argv;
  98.  
  99.   wxTheApp->wx_frame = wxTheApp->OnInit();
  100.  
  101.   // In XView, must ALWAYS have a main window.
  102.   if (wxTheApp->wx_frame)
  103.     wxTheApp->MainLoop();
  104.  
  105.   wxCleanUp();
  106.   return wxTheApp->OnExit();
  107. }
  108. #endif
  109.  
  110. #ifdef wx_msw
  111. void wxInitialize(HANDLE hInstance)
  112. {
  113.   wxSTD_FRAME_ICON = LoadIcon(hInstance, "wxSTD_FRAME");
  114.   wxSTD_MDICHILDFRAME_ICON = LoadIcon(hInstance, "wxSTD_MDICHILDFRAME");
  115.  
  116.   // Register the frame window class.
  117.   WNDCLASS wndclass;   // Structure used to register Windows class.
  118.  
  119.   wndclass.style         = CS_HREDRAW | CS_VREDRAW;
  120.   wndclass.lpfnWndProc   = wxWndProc;
  121.   wndclass.cbClsExtra    = 0;
  122.   wndclass.cbWndExtra    = 4;
  123.   wndclass.hInstance     = hInstance;
  124.   wndclass.hIcon         = wxSTD_FRAME_ICON;
  125.   wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
  126.   wndclass.hbrBackground = GetStockObject( WHITE_BRUSH );
  127.   wndclass.lpszMenuName  = NULL;
  128.   wndclass.lpszClassName = wxFrameClassName;
  129.   RegisterClass( &wndclass );
  130.  
  131.   // Register the MDI frame window class.
  132.   WNDCLASS wndclass1;   // Structure used to register Windows class.
  133.  
  134.   wndclass1.style         = CS_HREDRAW | CS_VREDRAW;
  135.   wndclass1.lpfnWndProc   = wxWndProc;
  136.   wndclass1.cbClsExtra    = 0;
  137.   wndclass1.cbWndExtra    = 4;
  138.   wndclass1.hInstance     = hInstance;
  139.   wndclass1.hIcon         = wxSTD_FRAME_ICON;
  140.   wndclass1.hCursor       = LoadCursor( NULL, IDC_ARROW );
  141.   wndclass1.hbrBackground = NULL;
  142.   wndclass1.lpszMenuName  = NULL;
  143.   wndclass1.lpszClassName = wxMDIFrameClassName;
  144.   RegisterClass( &wndclass1 );
  145.  
  146.   // Register the MDI child frame window class.
  147.   WNDCLASS wndclass4;   // Structure used to register Windows class.
  148.  
  149.   wndclass4.style         = CS_HREDRAW | CS_VREDRAW;
  150.   wndclass4.lpfnWndProc   = wxWndProc;
  151.   wndclass4.cbClsExtra    = 0;
  152.   wndclass4.cbWndExtra    = 4;
  153.   wndclass4.hInstance     = hInstance;
  154.   wndclass4.hIcon         = wxSTD_MDICHILDFRAME_ICON;
  155.   wndclass4.hCursor       = LoadCursor( NULL, IDC_ARROW );
  156.   wndclass4.hbrBackground = NULL;
  157.   wndclass4.lpszMenuName  = NULL;
  158.   wndclass4.lpszClassName = wxMDIChildFrameClassName;
  159.   RegisterClass( &wndclass4 );
  160.  
  161.   // Register the panel window class.
  162.   WNDCLASS wndclass2;   // Structure used to register Windows class.
  163.   memset(&wndclass2, 0, sizeof(WNDCLASS));   // start with NULL defaults
  164.   // Use CS_OWNDC to avoid messing about restoring the context
  165.   // for every graphic operation.
  166.   wndclass2.style         = CS_HREDRAW | CS_VREDRAW;
  167.   wndclass2.lpfnWndProc   = wxWndProc;
  168.   wndclass2.cbClsExtra    = 0;
  169.   wndclass2.cbWndExtra    = 4;
  170.   wndclass2.hInstance     = hInstance;
  171.   wndclass2.hIcon         = NULL;
  172.   wndclass2.hCursor       = NULL;
  173.   wndclass2.hbrBackground = GetStockObject( LTGRAY_BRUSH );
  174.   wndclass2.lpszMenuName  = NULL;
  175.   wndclass2.lpszClassName = wxPanelClassName;
  176.   RegisterClass( &wndclass2 );
  177.  
  178.   // Register the canvas and textsubwindow class name
  179.   WNDCLASS wndclass3;   // Structure used to register Windows class.
  180.   memset(&wndclass3, 0, sizeof(WNDCLASS));   // start with NULL defaults
  181.   // Use CS_OWNDC to avoid messing about restoring the context
  182.   // for every graphic operation.
  183.   wndclass3.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
  184.   wndclass3.lpfnWndProc   = wxWndProc;
  185.   wndclass3.cbClsExtra    = 0;
  186.   wndclass3.cbWndExtra    = 4;
  187.   wndclass3.hInstance     = hInstance;
  188.   wndclass3.hIcon         = NULL;
  189.   wndclass3.hCursor       = NULL;
  190.   wndclass3.hbrBackground = NULL;
  191.   wndclass3.lpszMenuName  = NULL;
  192.   wndclass3.lpszClassName = wxCanvasClassName;
  193.   RegisterClass( &wndclass3);
  194.  
  195.   wxWinHandleList = new wxList(wxKEY_INTEGER);
  196.   wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
  197.   wxTheColourDatabase->Initialize();
  198.   wxInitializeStockObjects();
  199. }
  200.  
  201. #endif
  202.  
  203. // Cleans up any wxWindows internal structures left lying around
  204. void wxCleanUp(void)
  205. {
  206. #ifdef wx_msw
  207.   if (wxSTD_FRAME_ICON)
  208.     DestroyIcon(wxSTD_FRAME_ICON);
  209.   if (wxSTD_MDICHILDFRAME_ICON)
  210.     DestroyIcon(wxSTD_MDICHILDFRAME_ICON);
  211. #endif
  212.  
  213.   // Destroy all GDI lists, etc.
  214.   delete wxTheBrushList;
  215.   delete wxThePenList;
  216.   delete wxTheIconList;
  217.   delete wxTheFontList;
  218.   delete wxTheBitmapList;
  219.  
  220.   delete wxTheColourDatabase;
  221.  
  222. #ifdef wx_xview
  223.   delete wxFontPool;
  224. #endif
  225. }
  226.  
  227. #ifdef wx_msw
  228.  
  229. #ifndef _WINDLL
  230.  
  231. // Main windows entry point
  232. int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR m_lpCmdLine,
  233.                     int nCmdShow )
  234. {
  235.   wxhInstance = hInstance;
  236.   wxInitialize(hInstance);
  237.  
  238.   // Split command line into tokens, as in usual main(argc, argv)
  239.   // form
  240.   char **command = new char*[50];
  241.   int count = 0;
  242.   char *token = 0;
  243.   char *buf = new char[500]; // Hangs around until end of app. in case
  244.                              // user carries pointers to the tokens
  245.  
  246.   Bool flag = TRUE;
  247.   int i = 0;
  248.   buf[0] = 0;
  249.  
  250. #ifndef _WINDLL // m_lpCmdLine isn't accessible from a DLL,
  251.                 // (it seems to crash anyhow)
  252.   while (flag)
  253.   {
  254.     if (m_lpCmdLine[i] == 0)
  255.     {
  256.       buf[i] = 0;
  257.       flag = FALSE;
  258.     }
  259.     else
  260.     {
  261.       buf[i] = m_lpCmdLine[i];
  262.       i ++;
  263.     }
  264.   }
  265. #endif
  266.  
  267.   // Get application name
  268.   char name[200];
  269.   ::GetModuleFileName(hInstance, name, 199);
  270.   command[count] = copystring(name);
  271.   count ++;
  272.  
  273.   token = strtok(buf, " ");
  274.   if (token)
  275.   {
  276.     command[count] = token;
  277.     count ++;
  278.  
  279.     while (token != NULL)
  280.     {
  281.       token = strtok(NULL, " ");
  282.       if (token)
  283.       {
  284.         command[count] = token;
  285.         count ++;
  286.       }
  287.     }
  288.   }
  289.  
  290.   if (!wxTheApp)
  291.   {
  292.     wxMessageBox("wxWindows error: You have to define an instance of wxApp!\n");
  293.     return 0;
  294.   }
  295.  
  296.  
  297.   wxTheApp->argc = count;
  298.   wxTheApp->argv = command;
  299.   wxTheApp->hInstance = hInstance;
  300.  
  301.   wxTheApp->wx_frame = wxTheApp->OnInit();
  302.   if (wxTheApp->wx_frame && wxTheApp->wx_frame->handle)
  303.     wxTheApp->wx_frame->Show(TRUE);
  304.  
  305.   return wxTheApp->MainLoop();
  306. }
  307.  
  308. #endif // not _WINDLL
  309.  
  310. #ifdef _WINDLL
  311. extern "C"
  312. int FAR PASCAL LibMain(HINSTANCE hInstance,
  313.     WORD wDataSegment, WORD wHeapSize, LPSTR lpszCmdLine)
  314. {
  315.   wxInitialize(hInstance);
  316.  
  317.   wxTheApp->argc = 0;
  318.   wxTheApp->argv = NULL;
  319.   wxTheApp->hInstance = hInstance;
  320.  
  321.   wxTheApp->wx_frame = wxTheApp->OnInit();
  322.   if (wxTheApp->wx_frame && wxTheApp->wx_frame->handle)
  323.     wxTheApp->wx_frame->Show(TRUE);
  324.  
  325.   return 1;
  326. }
  327. #endif // _WINDLL
  328.  
  329.  
  330. #endif // wx_msw
  331.  
  332. wxApp::wxApp(void)
  333. {
  334.   wx_frame = NULL;
  335.   wxTheApp = this;
  336.   death_processed = FALSE;
  337. }
  338.  
  339. wxApp::~wxApp(void)
  340. {
  341. }
  342.  
  343. Bool wxApp::Initialized(void)
  344. {
  345. #ifndef _WINDLL
  346.   if (wx_frame)
  347.     return TRUE;
  348.   else
  349.     return FALSE;
  350. #endif
  351. #ifdef _WINDLL // Assume initialized if DLL (no way of telling)
  352.   return TRUE;
  353. #endif
  354. }
  355.  
  356. wxFrame *wxApp::OnInit(void)
  357. {
  358.   return NULL;
  359. }
  360.  
  361. int wxApp::OnExit(void)
  362. {
  363.   return 0;
  364. }
  365.  
  366. #ifdef wx_msw
  367. /*
  368.  * Get and process a message, returning FALSE if WM_QUIT
  369.  * received.
  370.  *
  371.  */
  372. BOOL wxApp::DoMessage(void)
  373. {
  374.   if (!::GetMessage(¤t_msg, NULL, NULL, NULL))
  375.   {
  376.     return FALSE;
  377.   }
  378.  
  379.   // Process the message
  380.   if (!ProcessMessage(¤t_msg))
  381.   {
  382.     ::TranslateMessage(¤t_msg);
  383.     ::DispatchMessage(¤t_msg);
  384.   }
  385.   return TRUE;
  386. }
  387. #endif
  388.  
  389. /*
  390.  * Keep trying to process messages until WM_QUIT
  391.  * received
  392.  */
  393.  
  394. int wxApp::MainLoop(void)
  395. {
  396. #ifdef wx_motif
  397. //  XtRealizeWidget(wxTheApp->topLevel);
  398.   XtAppMainLoop(wxTheApp->appContext);
  399.   return 0;
  400. #endif
  401. #ifdef wx_xview
  402.   Frame frame = (Frame)(wx_frame->GetHandle());
  403.   xv_main_loop(frame);
  404.   return 0;
  405. #endif
  406. #ifdef wx_msw
  407.   Bool keep_going = TRUE;
  408.   while (keep_going)
  409.   {
  410.     while (!::PeekMessage(¤t_msg, NULL, NULL, NULL, PM_NOREMOVE) &&
  411.            OnIdle()) {}
  412.     if (!DoMessage())
  413.       keep_going = FALSE;
  414.   }
  415.   wxCleanUp();
  416.   return current_msg.wParam;
  417. #endif
  418. }
  419.  
  420. #ifdef wx_msw
  421. /*
  422.  * Give all windows a chance to preprocess
  423.  * the message. Some may have accelerator tables, or have
  424.  * MDI complications.
  425.  */
  426. BOOL wxApp::ProcessMessage(MSG *msg)
  427. {
  428.   HWND hWnd;
  429.   wxWnd *wnd = NULL;
  430.  
  431.   // Anyone for a message? Try youngest descendants first.
  432.   for (hWnd = msg->hwnd; hWnd != NULL; hWnd = ::GetParent(hWnd))
  433.   {
  434.     wxWnd *wnd = wxFindWinFromHandle(hWnd);
  435.     if (wnd)
  436.     {
  437.        if (wnd->ProcessMessage(msg))
  438.          return TRUE;
  439.  
  440.        // STOP if we've reached the top of the hierarchy!
  441.        if (wx_frame && (wnd == (wxWnd *)wx_frame->handle))
  442.           return FALSE;
  443.     }
  444.   }
  445.  
  446.   if (wx_frame && ((wxWnd *)wx_frame->handle)->ProcessMessage(msg))
  447.      return TRUE;
  448.   else return FALSE;
  449. }
  450.  
  451. BOOL wxApp::OnIdle(void)
  452. {
  453.   return FALSE;
  454. }
  455. #endif
  456.  
  457. void wxExit(void)
  458. {
  459. #ifdef wx_x
  460.   if (wxTheApp)
  461.     wxTheApp->OnExit();
  462.   wxCleanUp();
  463.  
  464.   _exit(0);
  465. #endif
  466. #ifdef wx_msw
  467.  if (wxTheApp && wxTheApp->wx_frame)
  468.    delete wxTheApp->wx_frame;
  469. #endif
  470. }
  471.  
  472. // Yield to incoming messages
  473. Bool wxYield(void)
  474. {
  475. #ifdef wx_msw
  476.   MSG msg;
  477.   // We want to go back to the main message loop
  478.   // if we see a WM_QUIT. (?)
  479.   while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) && msg.message != WM_QUIT)
  480.   {
  481.     if (!wxTheApp->DoMessage())
  482.       break;
  483.   }
  484. #endif
  485.  
  486.   return TRUE;
  487. }
  488.  
  489. #ifdef wx_motif
  490. /*
  491.  * Not yet used but may be useful.
  492.  *
  493.  */
  494. void wxSetDefaultResources(const Widget w, const char **resourceSpec, const char *name)
  495. {
  496.    int         i;    
  497.    Display    *dpy = XtDisplay (w);      // Retrieve the display pointer
  498.    XrmDatabase rdb = NULL;             // A resource data base
  499.  
  500.    // Create an empty resource database
  501.    rdb = XrmGetStringDatabase ("");
  502.  
  503.    // Add the Component resources, prepending the name of the component
  504.  
  505.    i = 0;
  506.    while ( resourceSpec[i] != NULL )
  507.    {
  508.        char buf[1000];
  509.  
  510.        sprintf(buf, "*%s%s", name, resourceSpec[i++]);
  511.        XrmPutLineResource( &rdb, buf );
  512.    }
  513.  
  514.    // Merge them into the Xt database, with lowest precendence
  515.  
  516.    if ( rdb )
  517.    {
  518. #if (XlibSpecificationRelease>=5)
  519.         XrmDatabase db = XtDatabase(dpy);
  520.     XrmCombineDatabase(rdb, &db, FALSE);
  521. #else
  522.         XrmMergeDatabases ( dpy->db, &rdb );
  523.         dpy->db = rdb;
  524. #endif
  525.     }
  526. }
  527. #endif
  528.