home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / vos2-121.zip / v / srcos2 / vapp.cpp < prev    next >
C/C++ Source or Header  |  1999-01-24  |  32KB  |  893 lines

  1. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  2. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  3. //                                                     VV         VV       //
  4. //  VV       VV     V - A Portable C++ GUI Framework    VV       VV        //
  5. //   VV     VV           designed and written by         VV     VV         //
  6. //    VV   VV                                             VV   VV          //
  7. //     VV VV              Bruce E. Wampler, Ph.D.          VV VV           //
  8. //      VVV               e-mail: bruce@objectcentral.com   VVV            //
  9. //       V                                                   V             //
  10. //                 Ported to OS/2 by Jon B. Hacker, Ph.D.                  //
  11. //                                                                         //
  12. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  13. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  14. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  15. //                                                                         //
  16. // vapp.cxx - The vApp control object (For OS/2)                           //
  17. //                                                                         //
  18. // Copyright (C) 1995-1998  Bruce E. Wampler                               //
  19. //                                                                         //
  20. // This file is part of the V C++ GUI Framework.                           //
  21. //                                                                         //
  22. // This library is free software; you can redistribute it and/or           //
  23. // modify it under the terms of the GNU Library General Public             //
  24. // License as published by the Free Software Foundation; either            //
  25. // version 2 of the License, or (at your option) any later version.        //
  26. //                                                                         //
  27. // This library is distributed in the hope that it will be useful,         //
  28. // but WITHOUT ANY WARRANTY; without even the implied warranty of          //
  29. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       //
  30. // Library General Public License for more details.                        //
  31. //                                                                         //
  32. // You should have received a copy of the GNU Library General Public       //
  33. // License along with this library (see COPYING.LIB); if not, write to the //
  34. // Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. //
  35. //                                                                         //
  36. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  37. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
  38. #include <v/vos2.h>            // for OS/2 stuff
  39. #include <v/vapp.h>            // my header file
  40. #include <v/vwindow.h>         // Win header
  41. #include <v/vfont.h>           // for font stuff
  42. #include <v/vcmdwin.h>
  43. #include <v/vTimer.h>
  44. #include <v/vcmdpane.h>
  45. #include <v/vthislst.h>
  46. #include <stdlib.h>
  47.  
  48. //    extern MRESULT EXPENTRY vTimerProc(HWND hwnd, UINT msg, UINT idTimer, ULONG mp2);
  49.  
  50.     // Globals available to the world
  51.     vApp* theGlobalApp = NULL;    // to be filled in upon instantiation
  52.     int (*pAppMain)(int, char**);
  53.     DebugMask DebugState;
  54.     static int _destroyed;         // for destructor
  55.  
  56.     // OS/2 bldlevel.exe signature
  57.     static char bldlevel[] =  "@#Jon Hacker:1.21a100#@VGUI for OS/2";
  58.     static char copyright[] =
  59.       "****> Copyright (C) 1995-1999 Bruce E. Wampler; under terms of the\
  60.  GNU Library General Public License, version 2 <****";
  61.  
  62.  //========================>>> vApp::vApp <<<=======================
  63.   vApp::vApp(VCONST char* appName, int simSDI, int frameHeight, int frameWidth) :
  64.        vBaseItem(appName)      // constructor
  65.   {
  66.     // First, set the global pointer to the main App. This happens
  67.     // when the user declares the instance of the app, either from
  68.     // a vApp object direct, or an object from a class derived
  69.     // from the vApp class.
  70.     theGlobalApp = this;        // this is our object
  71.  
  72.     // now the data members
  73.     _curThis = 0;
  74.     _running = 0;               // we are running
  75.     _WindowList = 0;        // no windows registered
  76.     _CmdPaneList = 0;        // no command panes registered
  77.     _clipText = 0;
  78.     _inExit = 0;
  79.     _simSDI = simSDI;           // not used in OS/2
  80.     _frameWidth = frameWidth;
  81.     _frameHeight = frameHeight;
  82.     _DefaultHeight = 300;       // default sizes for canvas window
  83.     _DefaultWidth = 500;
  84.     _destroyed = 0;             // Not destroyed yet
  85.     _Frame = 0;                 // Not initiated yet.
  86.     // Set which debug items to show
  87.     DebugState.System = 0;                     // System debug messages
  88.     DebugState.CmdEvents = 0;                  // Show command events (buttons, etc.)
  89.     DebugState.MouseEvents = 0;                        // Show mouse events
  90.     DebugState.WindowEvents = 0;               // Window events (resize, etc.)
  91.     DebugState.Build = 0;                      // Define/Build window
  92.     DebugState.BadVals= 0;                     // Error values
  93.     DebugState.Misc = 0;                       // Misc stuff
  94.     DebugState.Text = 0;                       // Text events
  95.     DebugState.Constructor = 0;                        // Show constructors
  96.     DebugState.Destructor = 0;                 // Show destructors
  97.     DebugState.User = 0;                       // Debug user events
  98.     DebugState.UserApp1 = 0;                   // Level 1 User App
  99.     DebugState.UserApp2 = 0;                   // Level 2 User App
  100.     DebugState.UserApp3 = 0;                   // Level 3 User App
  101.     DebugState.OS2Dev = 0;                     // OS/2 Development Debug
  102.   }
  103. //========================>>> vApp::initialize <<<=======================
  104.   void vApp::initialize(int& argc, char** argv)
  105.   {
  106.     // Main interface to the parent windowing system
  107.     for (int argn = 1 ; argn < argc ; ++argn)  // look for vDebug switch
  108.     {
  109.       if (strcmp(argv[argn],"-vDebug") == 0)
  110.       {
  111.        // Turn them all off
  112.        DebugState.System = 0;                  // System debug messages
  113.        DebugState.CmdEvents = 0;               // Show command events (buttons, etc.)
  114.        DebugState.MouseEvents = 0;             // Show mouse events
  115.        DebugState.WindowEvents = 0;            // Window events (resize, etc.)
  116.        DebugState.Build = 0;                   // Define/Build window
  117.        DebugState.BadVals= 0;                  // Error values
  118.        DebugState.Misc = 0;                    // Misc stuff
  119.        DebugState.Text = 0;                    // Text events
  120.        DebugState.Constructor = 0;             // Show constructors
  121.        DebugState.Destructor = 0;              // Show destructors
  122.        DebugState.User = 0;                    // Debug user events
  123.        DebugState.UserApp1 = 0;                // Level 1 User App
  124.        DebugState.UserApp2 = 0;                // Level 2 User App
  125.        DebugState.UserApp3 = 0;                // Level 3 User App
  126.        DebugState.OS2Dev = 0;                  // OS/2 Development Debug
  127.        for (char* cp = argv[argn+1] ; *cp ; ++cp)
  128.        {
  129.          switch (*cp)
  130.          {
  131.            case 'S':
  132.              DebugState.System = 1;            // System debug messages
  133.              break;
  134.            case 'c':
  135.              DebugState.CmdEvents = 1; // Show command events (buttons, etc.)
  136.              break;
  137.            case 'm':
  138.              DebugState.MouseEvents = 1;       // Show mouse events
  139.              break;
  140.            case 'w':
  141.              DebugState.WindowEvents = 1;      // Window events (resize, etc.)
  142.              break;
  143.            case 'b':
  144.              DebugState.Build = 1;             // Define/Build window
  145.              break;
  146.            case 'v':
  147.              DebugState.BadVals= 1;            // Error values
  148.              break;
  149.            case 'o':
  150.              DebugState.Misc = 1;              // (Other) Misc stuff
  151.              break;
  152.            case 't':
  153.              DebugState.Text = 1;              // Text events
  154.              break;
  155.            case 'C':
  156.              DebugState.Constructor = 1;       // Show constructors
  157.              break;
  158.            case 'D':
  159.              DebugState.Destructor = 1;        // Show destructors
  160.              break;
  161.            case 'x':
  162.              DebugState.OS2Dev = 1;            // OS/2 Development
  163.              break;
  164.            case 'U':
  165.              DebugState.User = 1;              // Debug user events
  166.              break;
  167.            case '1':
  168.              DebugState.UserApp1 = 1;  // Level 1 User App
  169.              break;
  170.            case '2':
  171.              DebugState.UserApp2 = 1;  // Level 2 User App
  172.              break;
  173.            case '3':
  174.              DebugState.UserApp3 = 1;        // Level 3 User App
  175.              break;
  176.          }
  177.        }
  178.  
  179.        // Now fixup the argument list and break loop
  180.        int ia;
  181.        for (ia = argn ; ia < argc ; ++ia)
  182.          argv[ia] = argv[ia+2];
  183.        argv[ia] = 0;
  184.        argc -= 2;      // eat the -vDebug args
  185.        break;
  186.       }
  187.     }
  188.     // This is pretty much the standard OS/2 startup code
  189.     // required by all OS/2 applications.
  190.     // We create an empty invisible frame to get
  191.     // things going, then defer to vWindow to generate
  192.     // useful visible windows.
  193.  
  194.     // register the client window class
  195.     WinRegisterClass(_hab,
  196.                     szvWindowClass,                    // window-class name
  197.                     (PFNWP)&wpWindowProc,              // window-procedure ID
  198.                     CS_SIZEREDRAW,                     // default window style
  199.                     4L);                               // reserved storage
  200.  
  201.     // define frame window attributes
  202.     ULONG flCtlData= FCF_SYSMENU        |        // system menu
  203.                     FCF_TITLEBAR       |        // titlebar
  204.                     FCF_SIZEBORDER     |        // resizeable border
  205. //                  FCF_MENU           |        // application menu
  206.                     FCF_ICON           |        // associate icon
  207. //                  FCF_TASKLIST       |        // app name in tasklist
  208. //                  FCF_ACCELTABLE     |        // use an accelerator table
  209. //                  FCF_MINMAX         |        // min/max buttons
  210.                     FCF_SHELLPOSITION;          // default window size & position
  211.  
  212.     // create the empty frame window
  213.     _Frame = WinCreateStdWindow(HWND_DESKTOP,     // parent is desktop
  214.                               0,                    // frame window style
  215.                               &flCtlData,           // frame creation flags
  216. //                            (PSZ)szWindowClass,   // client-window class name
  217.                               NULL,                 // suppress client window creation
  218.                               _name,                // title bar text
  219.                               0,                    // client-window style
  220.                               (HMODULE)NULL,        // resource ID
  221.                               vID_FRAME,            // frame-window ID
  222.                               0);                   // suppress client-window handle
  223.  
  224.     _vHandle = _Frame;
  225.     SysDebug1(Build,"vApp::Initialize (dummy) _Frame = %u\n", _Frame)
  226.  
  227.  
  228. /*
  229.     // center and size the window
  230.     // find the screen size for the system
  231.     LONG lDisplayWidth = ::WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
  232.     LONG lDisplayHeight = ::WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  233.     // now set the origin and width to center the window on the screen
  234.     // if not using default values
  235.     if (_frameHeight <=0 || _frameWidth <=0 )
  236.     {
  237.       WinSetWindowPos(_Frame,
  238.                      HWND_TOP,
  239.                      (lDisplayWidth - _frameWidth)/2,
  240.                      (lDisplayHeight - _frameHeight)/2,
  241.                      _frameWidth,
  242.                      _frameHeight,
  243.                      SWP_SIZE | SWP_MOVE     |
  244.                      SWP_SHOW | SWP_ACTIVATE  );
  245.     }
  246. */
  247.  
  248.     // we get the system codepage it will be needed for menu templates
  249.     HPS hpsTemp = WinGetPS(_Frame);
  250.     _codePage = GpiQueryCp(hpsTemp);
  251.     WinReleasePS(hpsTemp);
  252.  
  253.     hAccel = 0;                                // No accelerators
  254.     _workTimer = 0;
  255.  
  256. //    WinUpdateWindow(_Frame);
  257.     _running = 1;
  258.   }
  259.  
  260. //======================>>> vApp::~vApp <<<=======================
  261.   vApp::~vApp()
  262.   {
  263.     // WARNING! This destructor never gets called automatically,
  264.     // at least with Borland C++ 4.5.
  265.     SysDebug(Destructor,"vApp::~vApp destructor\n")
  266.  
  267.     if (_clipText != 0)
  268.       delete [] _clipText;
  269.  
  270.     _destroyed = 1;
  271.   }
  272.  
  273. //======================>>> vApp::Exit <<<=======================
  274.   void vApp::Exit(void)
  275.   {
  276.     // Close All registered windows and exit
  277.     WindList *curWin;
  278.     vWindow *tmp;
  279.  
  280.     SysDebug(Build,"vApp::Exit()\n")
  281. /*
  282. //  this code was moved to doEventLoop()
  283.     if (_workTimer)        // Stop events first
  284.     {
  285.       _workTimer->TimerStop();
  286.       delete _workTimer;
  287.       _workTimer = 0;
  288.     }
  289. */
  290.     _inExit = 1;                       // Kludge - CloseAppWin needs this
  291.     for (curWin = _WindowList ; curWin !=0 ; curWin = _WindowList)
  292.     {
  293.       int retv;
  294.       tmp = curWin->window;
  295.  
  296.       if (IsHelpWin(tmp))
  297.     retv = CloseHelpWin(tmp);
  298.       else
  299.       {
  300.     retv = CloseAppWin(tmp);       // use local or derived close app
  301.       }
  302.       if (!retv)
  303.       {
  304.     _inExit = 0;
  305.     return;
  306.       }
  307.     }
  308.     _inExit = 0;                       // done now, so can exit
  309.     AppExit(0);
  310.   }
  311.  
  312. //======================>>> vApp::AppExit <<<=======================
  313.   void vApp::AppExit(int exitVal)
  314.   {
  315.     if (!_inExit)              // Only ONE, please!
  316.     {
  317.        WinPostQueueMsg(_hmq, WM_QUIT, (void*) exitVal ,0);
  318.     }
  319.   }
  320.  
  321. //========================>>> vApp::CheckEvents <<<=======================
  322. // This should probably be handled with threads in OS/2.
  323.   void vApp::CheckEvents()
  324.   {
  325.     QMSG qmsg;
  326.  
  327.     while (WinPeekMsg(_hab, &qmsg, 0, 0, 0, PM_REMOVE))
  328.     {
  329.       WinDispatchMsg(_hab,&qmsg);
  330.     }
  331.   }
  332.  
  333. //==================>>> vApp::CloseLastCmdWindow <<<=======================
  334.   void vApp::CloseLastCmdWindow(vWindow* win, int exitcode)
  335.   {
  336.     // This method, new in 1.21, allows an empty MDI frame for
  337.     // Windows. Default behavior is to exit on last close. To
  338.     // overide, the derived CloseLastCmdWindow should simply return.
  339.  
  340.     AppExit(0);
  341.   }
  342.  
  343. //==================>>> vApp::ClipboardSetText <<<=======================
  344.   int vApp::ClipboardSetText(VCONST char* text) VCONST
  345.   {
  346.     // set the system clipboard to the value in text
  347.  
  348.     int retval = 1;
  349.     int lines = 0;  // how many lines in text
  350.  
  351.     // count number of lines and leave extra space for /n
  352.     for (VCONST char *tp = text ; *tp ; ++tp)
  353.       if (*tp == '\n')
  354.     ++lines;  // count up lines
  355.  
  356.     char* temp = new char[strlen(text)+lines+4]; // space for txt
  357.     char* to = temp;
  358.     char VCONST *from = text;
  359.     // this routine does a unix2dos sort of thing
  360.     // *to and *temp are the same thing
  361.     // *from and *text are the same thing
  362.     while (*from)
  363.     {
  364.       if (*from != '\r')    // all except CRs
  365.       {
  366.     if (*from == '\n')    // force all cr/lf or lf to cr/lf
  367.       *to++ = '\r';
  368.     *to++ = *from;
  369.       }
  370.       ++from;
  371.     }
  372.     *to = 0;            // terminate
  373.     int len = strlen(temp);    // how long string really is
  374.  
  375.     // Now, copy to system clipboard
  376.     PVOID hMem;
  377.     DosAllocSharedMem( &hMem, NULL, len+1, PAG_WRITE | PAG_COMMIT | OBJ_GIVEABLE );
  378.     if (hMem != 0)
  379.     {
  380.       strcpy((char*) hMem, temp);    // copy our string
  381.       if (WinOpenClipbrd(_hab))
  382.       {
  383.     if (WinEmptyClipbrd(_hab))
  384.     {
  385.       WinSetClipbrdOwner (_hab, _Frame);
  386.       WinSetClipbrdData (_hab, (ULONG) hMem, CF_TEXT, CFI_POINTER);
  387.     }
  388.     WinCloseClipbrd(_hab);
  389.       }
  390.       else
  391.       {
  392.     // couldn't grab the clipboard so free up mem and punt
  393.     DosFreeMem (hMem);
  394.     retval = 0;
  395.       }
  396.     }
  397.     else
  398.       retval = 0;
  399.  
  400.     delete [] temp;
  401.     return retval;
  402.   }
  403.  
  404. //====================>>> vApp::ClipboardGetText <<<=====================
  405.   char* vApp::ClipboardGetText() VCONST
  406.   {
  407.     // return a pointer to the clipboard text - we will allocate
  408.     // space for it as needed
  409.  
  410.     if (!WinOpenClipbrd(_hab))
  411.     return 0;
  412.  
  413.     if (_clipText != 0)            // had some previous data
  414.     delete [] _clipText;
  415.     _clipText = 0;            // make 0 for default return
  416.  
  417.     PVOID hMem = (PVOID) WinQueryClipbrdData(_hab, CF_TEXT);
  418.  
  419.     if (hMem != NULL)            // Got some text data
  420.     {
  421.       char* str = (char*) hMem;
  422.       _clipText = new char[strlen(str)+1];
  423.       strcpy(_clipText, str);
  424.     }
  425.     WinCloseClipbrd (_hab);
  426.     return _clipText;
  427.   }
  428.  
  429. //====================>>> vApp::ClipboardCheckText <<<===================
  430.   int vApp::ClipboardCheckText() VCONST
  431.   {
  432.     ULONG format;
  433.     // check if text available on system clipboard
  434.     return WinQueryClipbrdFmtInfo (_hab, CF_TEXT, &format);
  435.   }
  436.  
  437. //====================>>> vApp::ClipboardClear <<<========================
  438.   void vApp::ClipboardClear() VCONST
  439.   {
  440.     // Clear out the clipboard
  441.     if (WinOpenClipbrd(_hab))
  442.     {
  443.       WinEmptyClipbrd(_hab);
  444.       WinCloseClipbrd(_hab);
  445.     }
  446.   }
  447.  
  448. //========================>>> vApp::CloseAppWin <<<=======================
  449.   int vApp::CloseAppWin(vWindow* win)
  450.   {
  451.     SysDebug(Build,"vApp::CloseAppWin()\n");
  452.     win->CloseWin();                   // let the window close itself
  453.  
  454.     unregisterWindow(win);             // take it off the list
  455.     delete win;                        // free the window
  456.     return 1;
  457.   }
  458.  
  459. //========================>>> vApp::CloseHelpWin <<<=======================
  460.   int vApp::CloseHelpWin(vWindow* win)
  461.   {
  462.     SysDebug(Build,"vApp::CloseHelpWin()\n");
  463.     win->CloseWin();                   // let the window close itself
  464.     unregisterWindow(win);             // take it off the list
  465.     delete win;                        // free the window
  466.     return 1;
  467.   }
  468.  
  469. //========================>>> vApp::IsHelpWin <<<=======================
  470.   int vApp::IsHelpWin(vWindow *Win)
  471.   {
  472.     WindList *curWin;
  473.     for (curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  474.     {
  475.       if (curWin->window == Win)
  476.       {
  477.         return (curWin->info == 0); // Help if 0
  478.       }
  479.     }
  480.     return 0;
  481.   }
  482.  
  483. //===========================>>> vApp::AppCommand <<<=========================
  484.   void vApp::AppCommand(vWindow* win, ItemVal id, ItemVal retval, CmdType ctype)
  485.   {
  486.     // Do nothing by default.
  487.     SysDebug1(CmdEvents,"vApp::AppCmd(id: %d)\n",id);
  488.  
  489.     if (id == M_Exit)
  490.     Exit();
  491.   }
  492.  
  493. //========================>>> vApp::GetDefaultFont <<<=======================
  494.  
  495.   vFont vApp::GetDefaultFont()
  496.   {
  497.     vFont sysF(vfDefaultSystem);       // construct a system font instance
  498.     return sysF;                       // return it
  499.   }
  500.  
  501. //========================>>> vApp::getAppWinInfo <<<=======================
  502.   vAppWinInfo* vApp::getAppWinInfo(vWindow *Win)
  503.   {
  504.     // Search list to find associated vAppWinInfo.
  505.     WindList *curWin;
  506.     for (curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  507.       {
  508.        if (curWin->window == Win)
  509.          {
  510.            return curWin->info;        // return assocated info ptr
  511.          }
  512.       }
  513.     return 0;
  514.   }
  515.  
  516. //===========================>>> vApp::KeyIn  <<<===========================
  517.   void vApp::KeyIn(vWindow* win, vKey key, unsigned int shift)
  518.   {
  519.     // Do nothing by default.
  520.     SysDebug(Misc,"vApp::KeyIn\n");
  521.   }
  522.  
  523. //========================>>> vApp::NewAppWin <<<=======================
  524.   vWindow* vApp::NewAppWin(vWindow* win, VCONST char* name, int w, int h,
  525.        vAppWinInfo* winInfo)
  526.   {
  527.     // The derived vApp needs to call this.
  528.     vWindow* thisWin = win;
  529.     vAppWinInfo* awinfo = winInfo;
  530.     SysDebug1(Build,"vApp::NewAppWin(%s)\n",name);
  531.     if (!thisWin)              // Not created
  532.        thisWin = new vCmdWindow(name, w, h);
  533.     if (!winInfo)
  534.        awinfo = new vAppWinInfo(name);
  535.     registerWindow(thisWin, awinfo);   // register this window
  536.     return thisWin;
  537.   }
  538. //========================>>> vApp::NewHelpWin <<<=======================
  539.   vWindow* vApp::NewHelpWin(vWindow* win, VCONST char* name, int w, int h)
  540.   {
  541.     vWindow* thisWin = win;
  542.     SysDebug1(Build,"vApp::NewHelpWin(%s)\n",name);
  543.     if (!thisWin)              // Not created
  544.        return 0;
  545.     registerWindow(thisWin, 0);        // register this window
  546.     return thisWin;
  547.   }
  548.  
  549. //========================>>> vApp::registerWindow <<<=======================
  550.   void vApp::registerWindow(vWindow *Win, vAppWinInfo *awinfo)
  551.   {
  552.     WindList* newList = new WindList;  // new cell to add to list
  553.     SysDebug1(Misc,"vApp::registerWindow - %s\n",Win->name())
  554.     newList->window = Win;                     // remember the window
  555.     newList->info = awinfo;                    // and its info class
  556.     newList->nextWinList = _WindowList;        // link in at front
  557.     _WindowList = newList;
  558.   }
  559.  
  560. //========================>>> vApp::unregisterWindow <<<=======================
  561.   void vApp::unregisterWindow(vWindow *Win)
  562.   {
  563.     // Scan window list to unregister this window and free some space
  564.     WindList *curWin, *tmp, *last, *next;
  565.     last = 0;
  566.  
  567.     for (curWin = _WindowList ; curWin !=0 ; curWin = next)
  568.     {
  569.       next = curWin->nextWinList;
  570.       if (curWin->window == Win)
  571.       {
  572.         SysDebug1(Misc,"vApp::unregisterWindow - %s\n",Win->name())
  573.         tmp = curWin;
  574.         if (curWin == _WindowList)
  575.           _WindowList = curWin->nextWinList;
  576.         else
  577.           last->nextWinList = curWin->nextWinList;
  578.         delete curWin->info;        // free the info space
  579.         delete tmp;                 // free the list space
  580.       }
  581.       last = curWin;
  582.     }
  583.   }
  584.  
  585. //========================>>> vApp::registerCmdPane <<<======================
  586.   void vApp::registerCmdPane(vCommandPane* cmdPane)
  587.   {
  588.     CmdPaneList* newList = new CmdPaneList;    // new cell to add to list
  589.     SysDebug(Misc,"vApp::registerCmdPane\n")
  590.     newList->commandPane = cmdPane;            // remember the cmd pane
  591.     newList->nextCPList = _CmdPaneList;                // link in at front
  592.     _CmdPaneList = newList;
  593.   }
  594.  
  595. //========================>>> vApp::unregisterCmdPane <<<=======================
  596.   void vApp::unregisterCmdPane(vCommandPane* cmdPane)
  597.   {
  598.     // Scan pane list to unregister this window and free some space
  599.     CmdPaneList *curCP, *tmp, *last, *next;
  600.     last = 0;
  601.     for (curCP = _CmdPaneList ; curCP !=0 ; curCP = next)
  602.     {
  603.       next = curCP->nextCPList;
  604.       if (curCP->commandPane == cmdPane)
  605.       {
  606.         SysDebug(Misc,"vApp::unregisterCmdPane\n")
  607.         tmp = curCP;
  608.         if (curCP == _CmdPaneList)
  609.           _CmdPaneList = curCP->nextCPList;
  610.         else
  611.           last->nextCPList = curCP->nextCPList;
  612.         delete tmp;                 // free the list space
  613.       }
  614.       last = curCP;
  615.     }
  616.   }
  617.  
  618. //========================>>> vApp::selectCmdPanes <<<=======================
  619. /*
  620.   void vApp::selectCmdPanes(vWindow* parent)
  621.   {
  622.     // This is needed by the MDI interface conventions.
  623.     // This will turn off _isShown for panes that are children of other windows
  624.     // and turn on all cmd panes that are in our window
  625.     CmdPaneList *curCP;
  626.     // First, turn off all command panes in other windows
  627.     for (curCP = _CmdPaneList ; curCP !=0 ; curCP = curCP->nextCPList)
  628.     {
  629.       if ((curCP->commandPane)->_parentWin != parent)
  630.       {
  631.        (curCP->commandPane)->_isShown = 0;
  632.        if (WinIsWindow(_hab, (curCP->commandPane)->_wDialog) &&
  633.          WinIsWindowVisible((curCP->commandPane)->_wDialog))
  634.        {
  635.          WinShowWindow((curCP->commandPane)->_wDialog, FALSE);
  636.        }
  637.          }
  638.       }
  639.     // Now, turn ours on
  640.     for (curCP = _CmdPaneList ; curCP !=0 ; curCP = curCP->nextCPList)
  641.     {
  642.       if ((curCP->commandPane)->_parentWin == parent)
  643.       {
  644.        (curCP->commandPane)->_isShown = 1;
  645.        if (WinIsWindow(_hab, (curCP->commandPane)->_wDialog) &&
  646.          !WinIsWindowVisible((curCP->commandPane)->_wDialog))
  647.        {
  648.          WinShowWindow((curCP->commandPane)->_wDialog, TRUE);
  649.        }
  650.       }
  651.     }
  652.   }
  653. */
  654. //========================>>> vApp::SendWindowCommandAll <<<=======================
  655.   void vApp::SendWindowCommandAll(ItemVal id, int val, CmdType ctype)
  656.   {
  657.     // send a command to all windows
  658.     for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  659.       {
  660.        (curWin->window)->WindowCommand(id, val, ctype);
  661.       }
  662.   }
  663.  
  664. //========================>>> vApp::UpdateAllViews <<<=======================
  665.   void vApp::UpdateAllViews(vWindow* sender, int hint, void* pHint)
  666.   {
  667.     // Easy way to do MVC - call UpdateView in all windows
  668.     // This function is called by the user whenever a change is made to
  669.     // the model e.g the document. This causes vWindow::UpdateView to be
  670.     // called for every open window. The parameters are used to both filter and
  671.     // hint the windows on which actions to take in vWindow::UpdateView:
  672.     //
  673.     //     sender: If this is not zero, this window will not invoke UpdateView,
  674.     //             because typically the change of model was a result of
  675.     //             an interaction with this window.
  676.     //     hint:   This should be an enum defined in your derived app class.
  677.     //             Hints about which kind of change is made, so that only
  678.     //             appropriate action is taken on appropriate windows.
  679.     //     pHint:  This is normally a pointer to the object representing the
  680.     //             document
  681.  
  682.     for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  683.     {
  684.       if (curWin->window != sender)
  685.         (curWin->window)->UpdateView(sender, hint, pHint);
  686.     }
  687.   }
  688.  
  689. //========================>>> vApp::SetValueAll <<<=======================
  690.   void vApp::SetValueAll(ItemVal id, int val, ItemSetType setType)
  691.   {
  692.     // Set a Value in all windows
  693.     for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  694.     {
  695.       (curWin->window)->SetValue(id, val, setType);
  696.     }
  697.   }
  698.  
  699. //======================>>> vApp::SetAppTitle <<<==========================
  700.   void vApp::SetAppTitle(VCONST char* title)
  701.   {
  702.     WinSetWindowText(_Frame, title);
  703.   }
  704.  
  705. //========================>>> vApp::SetStringAll <<<=======================
  706.   void vApp::SetStringAll(ItemVal id, VCONST char* str)
  707.   {
  708.     // Set a string in all windows
  709.     for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  710.       {
  711.        (curWin->window)->SetString(id, str);
  712.       }
  713.   }
  714.  
  715. //========================>>> vApp::ShowList <<<=======================
  716.   int vApp::ShowList(void)
  717.   {
  718.     // This is a utility routine to show current information
  719. //#ifdef HAS_PRINTF
  720.     printf("Registered windows:\n");
  721.     for (WindList* curWin = _WindowList ; curWin !=0 ; curWin = curWin->nextWinList)
  722.     {
  723.       printf("    %s\n",(curWin->window)->name());
  724.     }
  725. //#endif
  726.     return 1;
  727.   }
  728.  
  729. //====================>>> _appWorkTimer::TimerTick <<<====================
  730.   void _appWorkTimer::TimerTick()
  731.   {
  732.    theApp->DispatchWork();
  733.   }
  734.  
  735. //========================>>> vApp::EnableWorkSlice <<<====================
  736.   int vApp::EnableWorkSlice(long slice)
  737.   {
  738.     if (slice > 0)
  739.     {
  740.       if (_workTimer == 0)            // First time to start timer
  741.       {
  742.         _workTimer = new _appWorkTimer;
  743.       }
  744.       return _workTimer->TimerSet(slice);
  745.     }
  746.     else
  747.     {
  748.       if (_workTimer)
  749.         _workTimer->TimerStop();
  750.     }
  751.     return 1;
  752.   }
  753.  
  754. //========================>>> vApp::DispatchWork <<<=======================
  755.   void vApp::DispatchWork(void)
  756.   {
  757.     WorkSlice();               // Work Slice for App
  758.     // Call WorkSlice for all windows
  759.     for (WindList* curWin = _WindowList ; curWin !=0 ;
  760.             curWin = curWin->nextWinList)
  761.     {
  762.       (curWin->window)->WorkSlice();
  763.     }
  764.   }
  765.  
  766. //========================>>> vApp::doEventLoop <<<=======================
  767.   int vApp::doEventLoop(void)
  768.   {
  769.     // This is where we grab and handle events from the
  770.     // parent windowing system
  771.     QMSG qmsg;
  772.  
  773.     while (WinGetMsg(_hab, &qmsg, 0, 0, 0))
  774.     {
  775.       // timer events come thru here.  We look for those events not
  776.       // assigned to a particular window and send them to vTimerProc
  777.       // for handling.
  778.       if (qmsg.msg == WM_TIMER)
  779.       {
  780.         if (qmsg.hwnd == 0)
  781.         {
  782.           SHORT idTimer = SHORT1FROMMP(qmsg.mp1);
  783.           vTimerProc(qmsg.hwnd, qmsg.msg, idTimer, (ULONG) qmsg.mp2);
  784.         }
  785.       }
  786.       WinDispatchMsg (_hab, &qmsg);
  787.     }
  788.  
  789.     // Turns out that the destructor for the static
  790.     // vApp object never gets called once PostQuitMessage is called. We do come
  791.     // through here, however, so here is where we can return these
  792.     // resources.
  793.     if (_workTimer)
  794.     {
  795.       _workTimer->TimerStop();
  796.       delete _workTimer;
  797.     }
  798.  
  799.     WinDestroyWindow (_Frame);
  800.     return (int) qmsg.mp1;
  801.   }
  802.  
  803. //===========================>>> wpWindowProc <<<================================
  804.   MRESULT EXPENTRY wpWindowProc(HWND hwnd, ULONG message,
  805.                                MPARAM mp1, MPARAM mp2)
  806.   {
  807.     static vWindow* createThis = 0;
  808.     vWindow* thisWin = (vWindow*) WinQueryWindowPtr(hwnd, 0);
  809.  
  810.     if (!thisWin && message == WM_CREATE)
  811.     {
  812.       // We need to intercept the message here to recover the vWindow
  813.       // this of the window. It is sent in mp1
  814.       createThis = thisWin = (vWindow*)mp1;   // remember the this!
  815.     }
  816.     else if (createThis != 0 && message == WM_ACTIVATE)
  817.     {
  818.       thisWin = createThis;
  819.       createThis = 0;
  820.  //     WinSetActiveWindow (HWND_DESKTOP, hwnd);
  821.     }
  822.  
  823.     if (!thisWin)
  824.     {
  825.       return WinDefWindowProc(hwnd, message, mp1, mp2);
  826.     }
  827.     else
  828.     {
  829.       return (MRESULT) thisWin->vWindowProc(hwnd, message, mp1, mp2);
  830.     }
  831.   }
  832.  
  833. //#########################################################################
  834. // The user function AppMain is accessed through a pointer. This function
  835. // stores the user's AppMain in a pointer to function that is used inside
  836. // the V library. This was added to enable V Win32 DLL. It works also
  837. // with a static library.
  838. //
  839. V_EXPORT void vRegisterAppMain( int (*p)(int, char**) )
  840. {
  841.   pAppMain = p;
  842. }
  843.  
  844. // Actually we should return vApp*, but VC++ complains that it
  845. // can't find vGetApp when linking the application.
  846. ULONG vGetApp()
  847. {
  848.   return (ULONG) theGlobalApp;
  849. }
  850.  
  851. //=========================>>> CMain <<<====================================
  852. // this is just chained from main in vstartup.cpp
  853.   int CMain(int argc, char** argv)
  854.   {
  855.     int retcode;
  856.  
  857.     // initialize app anchor block and message queue
  858.     theApp->_hab = WinInitialize( 0 );
  859.     if( theApp->_hab )
  860.       theApp->_hmq = WinCreateMsgQueue( theApp->_hab, 0 );
  861.  
  862.     if( theApp->_hmq )
  863.     {
  864.       theApp->initialize(argc, argv);              // Create top level widget
  865.       if ((retcode = pAppMain(argc, argv)) == 0)   // call the app main program
  866.         theApp->doEventLoop();                     // And enter the event loop
  867.     }
  868.  
  869.     // cleanup and exit
  870.     if( theApp->_hmq )
  871.        WinDestroyMsgQueue( theApp->_hmq );
  872.     if( theApp->_hab )
  873.        WinTerminate( theApp->_hab );
  874.     return (retcode);
  875.   }
  876.  
  877. // Utilities
  878. //=========================>>> vSysWarning <<<============================
  879.   void vSysWarning(VCONST char* msg)
  880.   {
  881.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
  882.                  "V", 1, MB_ICONEXCLAMATION | MB_OK);
  883.   }
  884.  
  885. //=========================>>> vSys <<<============================
  886.   void vSysError(VCONST char* msg)
  887.   {
  888.     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, msg,
  889.                  "V", 1, MB_ICONEXCLAMATION | MB_OK);
  890.     theApp->AppExit(99);
  891.   }
  892.  
  893.