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

  1. //===============================================================
  2. // vdialog.cxx - vDialog class - OS/2
  3. //
  4. // Copyright (C) 1995,1996,1997,1998  Bruce E. Wampler
  5. //
  6. // This file is part of the V C++ GUI Framework, and is covered
  7. // under the terms of the GNU Library General Public License,
  8. // Version 2. This library has NO WARRANTY. See the source file
  9. // vapp.cxx for more complete information about license terms.
  10. //===============================================================
  11. #include <v/vos2.h>             // for OS/2 stuff
  12. #include <v/vdialog.h>          // our header
  13. #include <v/vapp.h>
  14. #include <v/vthislst.h>         // For this list
  15.  
  16.   // Define static data of the class
  17.   MRESULT EXPENTRY DlgProcCB(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
  18.  
  19.   static vThisList _thisList;           // hide this in this file
  20.   vDialog* vDialog::_curModal = 0;      // V:1.13
  21.  
  22. //===================>>> vDialog::vDialog <<<=======================
  23.   vDialog::vDialog(const vDialog& d) : vBaseWindow(d),
  24.     vCmdParent(P_Dialog)
  25.   {
  26.     vSysError("vDialog - V semantics do not support copy constructors!");
  27.     _oldModal = 0;              // V:1.13
  28.   }
  29.  
  30. //=================>>> vDialog::~vDialog <<<=======================
  31.   vDialog::~vDialog()
  32.   {
  33.     SysDebug(Destructor,"vDialog::~vDialog() destructor\n")
  34.     _IsDisplayed = 0;           // The dialog is not up
  35.     if (_hTemplate != 0)
  36.       {
  37.     ::DosFreeMem(_hTemplate);
  38.     _hTemplate = 0;
  39.       }
  40.     closeBaseWindow();          // close this window
  41.     _thisList.Delete((ThisId)_wDialog); // free the this ptr
  42.   }
  43.  
  44. //===================>>> vDialog::vDialog <<<=======================
  45.   vDialog::vDialog(vBaseWindow* creator, int modal, VCONST char* title) :
  46.     vBaseWindow(title), vCmdParent(P_Dialog)            // constructor
  47.   {
  48.      _parentHWND = creator->winHwnd();  // track parent's HWND
  49.      init(modal,title);                 // finish construction
  50.   }
  51.  
  52. //===================>>> vDialog::vDialog <<<=======================
  53.   vDialog::vDialog(vApp* creator, int modal, VCONST char* title) :
  54.     vBaseWindow(title), vCmdParent(P_Dialog)            // constructor
  55.   {
  56.      _parentHWND = creator->winHwnd();  // track parent's HWND
  57.      init(modal,title);                 // finish construction
  58.   }
  59.  
  60. //===================>>> vDialog::vDialog <<<=======================
  61.   void vDialog::init(int modal, VCONST char* title)
  62.   {
  63.     // Initialize dialog box
  64.     _modal = modal;             // settable modal
  65.     SysDebug(Constructor,"vDialog::vDialog() constructor\n")
  66.     _wType = DIALOG;            // a dialog
  67.     _dialogType = aDialog;      // This is a dialog
  68.     _IsDisplayed = 0;           // The dialog is not up
  69.     _wDialog = 0;               // haven't created the dialog yet...
  70.     hwndToolTip = 0;
  71.  
  72.     // Now, build the initial in-memory dialog template using
  73.     // DLGTEMPLATE  pointer _hTemplate.
  74.     int buildOK;
  75.     // Using 8,helv makes it ok to use 8 in calculating control sizes!
  76. #ifdef ALLOW_BOLD_FONT
  77.     // get screen width in pels
  78.     int horRes;
  79.     HDC hDevCxt = GpiQueryDevice(WinGetScreenPS(HWND_DESKTOP));
  80.     DevQueryCaps(hDevCxt, CAPS_WIDTH, 1L, &horRes);
  81.     char *fntname = (horRes <= 800) ? "8.Helv" : "8.HelvBold";
  82. #else
  83.     char *fntname = "8.Helv";
  84. #endif
  85.  
  86. //    PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) "8.Helv"}, {0}};
  87.     PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) fntname}, {0}};
  88.  
  89.     if (_modal)
  90.     buildOK = CreateDlgTemplate( FCF_TITLEBAR | FCF_DLGBORDER |
  91. //       FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  92.        FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS,
  93.        10,25, 1,1, 0, "", "", _name, AssyPresParams(PPel) );
  94.  
  95.     else
  96.     buildOK = CreateDlgTemplate( FCF_TITLEBAR | FCF_DLGBORDER |
  97. //       FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS | WS_SAVEBITS,
  98.        FCF_NOMOVEWITHOWNER, WS_VISIBLE | WS_CLIPSIBLINGS,
  99.        10,25, 1,1, 0, "", "", _name, AssyPresParams(PPel) );
  100.  
  101.     if (!buildOK)
  102.     vSysError("vDialog - Unable to build dialog template");
  103.     _DefaultButton = 0; // No default button described
  104.     _FirstTextIn = 0;   // No text in field
  105.   }
  106.  
  107. //===================>>> vDialog::AddDialogCmds <<<========================
  108.   void vDialog::AddDialogCmds(CommandObject* cList)     // add commands
  109.   {
  110.     // This is called to add commands from the supplied
  111.     // CommandObject list.
  112.     vCmd* defButton = 0;
  113.     DlgCmdList* curCmd;
  114.     // scan the entire list
  115.     for (int ix = 0 ; cList && (cList[ix].cmdType != C_EndOfList) ; ++ix)
  116.       {
  117.     curCmd = new DlgCmdList;                // get a new cell
  118.     curCmd->nextDCL = _cmdList;             // add in at front
  119.     _cmdList = curCmd;
  120.         curCmd->cmdP = 0;                       // not added yet
  121.         curCmd->cmdP = AddCmd(&cList[ix]);
  122.         // Track default button
  123.         if (cList[ix].attrs & CA_DefaultButton)
  124.           {
  125.              defButton = curCmd->cmdP;
  126.           }
  127.         if (cList[ix].cmdType == C_TextIn)
  128.           {
  129.             if (_FirstTextIn == 0)
  130.                 _FirstTextIn = curCmd->cmdP;
  131.           }
  132.       }
  133.     if (defButton)                      // we have a default
  134.       {
  135.         _DefaultButton = defButton;     // Track the default button
  136.       }
  137.     DoneAddingControls();               // all finished with controls
  138.   }
  139.  
  140. //===================>>> vDialog::AddDialogCmdObj <<<========================
  141.   void vDialog::AddDialogCmdObj(CommandObject* Cmd, vCmd* CmdInstance)
  142.   {
  143.     // This is called to add an already instantiated command object to the
  144.     // CommandObject list.
  145.     DlgCmdList* curCmd = new DlgCmdList;                // get a new cell
  146.     curCmd->nextDCL = _cmdList;         // add in at front of list
  147.     _cmdList = curCmd;
  148.     curCmd->cmdP = CmdInstance;         // point to the object
  149.     // Track default button
  150.     if (Cmd->attrs & CA_DefaultButton)
  151.       {
  152.         _DefaultButton = CmdInstance;   // This is the default button
  153.         // This lets us use Enter to activate the default button.
  154.       }
  155.   }
  156.  
  157. //====================>>> vDialog::CancelDialog <<<=======================
  158.   void vDialog::CancelDialog(void)
  159.   {
  160.     // Cancel selected - reset all values to original values
  161.  
  162.     SysDebug(CmdEvents,"vDialog::CancelDialog()\n")
  163.     for (DlgCmdList* cc = _cmdList ; cc != 0  ; cc = cc->nextDCL)
  164.       {
  165.         (cc->cmdP)->ResetItemValue();
  166.       }
  167.     // And close the dialog
  168.     CloseDialog();
  169.   }
  170.  
  171. //====================>>> vDialog::CloseDialog <<<=======================
  172.   void vDialog::CloseDialog(void)
  173.   {
  174.     SysDebug(Build,"vDialog::CloseDialog()\n")
  175.     _IsDisplayed = 0;           // The dialog is not up
  176.     if (!_modal)                // destroy if not modal
  177.       WinDestroyWindow(_wDialog);
  178.  
  179.     _thisList.Delete((ThisId)_wDialog); // free the this ptr
  180.   }
  181.  
  182. //====================>>> vDialog::DialogCommand <<<=======================
  183.   void vDialog::DialogCommand(ItemVal id, ItemVal retval, CmdType ctype)
  184.   {
  185.     // After the user has selected a command from the dialog,
  186.     // this routine is called with the value
  187.  
  188.     SysDebug2(CmdEvents,"vDialog::DialogCommand(id:%d, val:%d)\n",id, retval)
  189.     switch (id)                 // We will do some things depending on value
  190.       {
  191.         case M_Cancel:
  192.             CancelDialog();
  193.             break;
  194.     case M_Done:            // default, close dialog
  195.         case M_OK:
  196.           {
  197.             CloseDialog();
  198.             break;
  199.           }
  200.       }
  201.   }
  202.  
  203. //====================>>> vDialog::DialogDisplayed <<<=======================
  204.   void vDialog::DialogDisplayed()
  205.   {
  206.   }
  207.  
  208. //==================>>> vDialog::ProcessCmd <<<=======================
  209.   void vDialog::ProcessCmd(ItemVal id, ItemVal rv, CmdType ct)
  210.   {
  211.     // simple interface between command objects and the
  212.     // inherited vCmdParent ProcessCmd to the CommandObject which does the work
  213.     DialogCommand(id, rv, ct);
  214.   }
  215.  
  216. //====================>>> vDialog::SetDialogTitle <<<=======================
  217.   void vDialog::SetDialogTitle(VCONST char* title)
  218.   {
  219.     WinSetWindowText(_wDialog, title);
  220.   }
  221.  
  222. //================>>> vDialog::GetDialogPosition <<<========================
  223.   void vDialog::GetDialogPosition(int& left, int& top, int& width, int& height) VCONST
  224.   {
  225.     RECTL rct;
  226.  
  227.     WinQueryWindowRect (_wDialog, &rct);
  228.     WinMapWindowPoints (_wDialog ,HWND_DESKTOP, (PPOINTL) &rct, 2);
  229.  
  230.     LONG DisplayHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  231.  
  232.     // in OS/2 the origin is at the bottom left corner whereas V has the
  233.     // origin in the top left corner.  We need to transform coords from
  234.     // os/2 to V space to get the right results
  235.     // CAUTION: WinQuery return rc coords are inclusive/exclusive
  236.     top = (DisplayHeight-1) - rct.yTop;
  237.     left = rct.xLeft;
  238.     width = rct.xRight - rct.xLeft;
  239.     height = rct.yTop - rct.yBottom;
  240.   }
  241.  
  242. //====================>>> vDialog::SetDialogPosition <<<=======================
  243. //
  244. //  position is relative to the screen, not the application
  245. //
  246.   void vDialog::SetDialogPosition(int left, int top)
  247.   {
  248.     RECTL ar;
  249.     WinQueryWindowRect (_wDialog, &ar);
  250.     int height =  ar.yTop - ar.yBottom;
  251.     LONG DisplayHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
  252.  
  253.     // in OS/2 the origin is at the bottom left corner whereas V has the
  254.     // origin in the top left corner.  We need to transform coords from
  255.     // V to os/2 space to get the right results
  256.     top = (DisplayHeight-1) - top;
  257.  
  258.     // CAUTION: WinSetWindowPos rc coords are inclusive/exclusive
  259.     //          and use the bottom left corner
  260.     int bottom = top - height;
  261.  
  262.     WinSetWindowPos (_wDialog, HWND_TOP,
  263.       left, bottom,
  264.       0,0,
  265.       SWP_MOVE);
  266.   }
  267.  
  268. //====================>>> vDialog::ShowDialog <<<=======================
  269.   void vDialog::ShowDialog(VCONST char* msg)
  270.   {
  271.     //  Show the dialog with the default message
  272.     //  We will control the position of the dialog box based on
  273.     //  the parent's location. The user can move the dialog later.
  274.     SysDebug1(Build,"vDialog::ShowDialog(%s) \n",msg)
  275.  
  276.     if (_IsDisplayed)
  277.       return;                         // make this a no-op
  278.  
  279.     // First, get the values from our parent
  280.     // set the message field -- have to move to the dlgproc init case
  281.  
  282.     if (msg && *msg)
  283.     {
  284.       for (DlgCmdList* cc = _cmdList ; cc != 0  ; cc = cc->nextDCL)
  285.       {
  286.     if (((cc->cmdP)->dlgCmd)->attrs & CA_MainMsg)
  287.     {
  288.       ((cc->cmdP)->dlgCmd)->title = msg;     // repoint to the message
  289.     }
  290.       }
  291.     }
  292.  
  293.     // Since the dialog isn't necessarily re-created each time it is
  294.     // popped up, we need to loop through now to set the original values
  295.     for (DlgCmdList* cc = _cmdList ; cc != 0  ; cc = cc->nextDCL)
  296.     {
  297.       (cc->cmdP)->SaveItemValue();
  298.     }
  299.  
  300.     // Now ready to popup the dialog
  301.     _IsDisplayed = 1;                   // The dialog is up
  302.  
  303.     if (_modal)
  304.     {
  305.       _wDialog = WinCreateDlg(HWND_DESKTOP, _parentHWND, (PFNWP) &DlgProcCB,
  306.     _hTemplate, (PVOID) this);
  307.       _myHWND = _wDialog;
  308.       WinProcessDlg (_wDialog);
  309.       WinDestroyWindow (_wDialog);
  310.  
  311.       _IsDisplayed = 0;
  312.     }
  313.     else
  314.     {
  315.       _wDialog = WinCreateDlg(HWND_DESKTOP, _parentHWND, (PFNWP) &DlgProcCB,
  316.     _hTemplate, (PVOID) this);
  317.       _myHWND = _wDialog;
  318.       SysDebug1(OS2Dev,"    Modeless dialog HWND = %x \n", _wDialog)
  319.     }
  320.   }
  321.  
  322. // ---------------------------------------------------------------------
  323. //====================>>> DlgProc <<<=======================
  324. MRESULT EXPENTRY DlgProcCB(HWND hDlg, ULONG uMsg,
  325.                    MPARAM mp1, MPARAM mp2)
  326. {
  327.   vDialog* useThis;
  328.   if (uMsg == WM_INITDLG) // first time!
  329.   {
  330.     useThis = (vDialog*)mp2;
  331.  
  332.     _thisList.Add((ThisId)hDlg, (void*)useThis);
  333.   }
  334.   else
  335.     useThis = (vDialog*)_thisList.GetThis((ThisId)hDlg);
  336.  
  337.   if (!useThis)
  338.     return WinDefDlgProc(hDlg, uMsg, mp1, mp2);
  339.  
  340.   return (MRESULT) useThis->DynamicDlgProc(hDlg, uMsg, mp1, mp2);
  341. }
  342.  
  343.  
  344.  
  345. //====================>>> vDialog::DynamicDlgProc <<<=======================
  346.   int vDialog::DynamicDlgProc(HWND hDlg, UINT uMsg,
  347.                 MPARAM mp1, MPARAM mp2)
  348.   {
  349.     int fProcessed = 0;
  350.     // This code handles nested modals, a no no....   (V:1.13)
  351.     if (_curModal != 0 && _curModal != this)             // V:1.13
  352.     {
  353.       return 0;
  354.     }
  355.  
  356.     switch (uMsg)
  357.     {
  358.       case WM_INITDLG:
  359.       {
  360.     // Changes here must have equivalents in the vcmdpane.cpp code
  361.  
  362.     // although we can set these later in ShowDialog we need to set them now
  363.     // during creation for those controls that need to set their
  364.     // initial values during window creation
  365.     _wDialog = hDlg;
  366.     _myHWND = hDlg;
  367.  
  368.     WinSetWindowText(_wDialog, _name);
  369.  
  370.     for (DlgCmdList* cc = _cmdList ; cc != 0  ; cc = cc->nextDCL)
  371.     {
  372.       vCmd* cp = cc->cmdP;
  373.  
  374.       // BEW - V 1.17 - Shouldn't have to do this, but the dynamic
  375.       // dialog creation somehow replaces characters > 128 with _.
  376.       // This fixes that problem.
  377.       if ((cp->dlgCmd)->cmdType == C_BoxedLabel ||
  378.         (cp->dlgCmd)->cmdType == C_Button ||
  379.         (cp->dlgCmd)->cmdType == C_CheckBox ||
  380.         (cp->dlgCmd)->cmdType == C_Label ||
  381.         (cp->dlgCmd)->cmdType == C_RadioButton ||
  382.         (cp->dlgCmd)->cmdType == C_TextIn )
  383.       {
  384.         cp->SetCmdStr((cp->dlgCmd)->title);
  385.       }
  386.       else if ((cp->dlgCmd)->cmdType == C_Text)
  387.           {
  388.         if (!(cp->dlgCmd)->itemList || (*(char *)(cp->dlgCmd)->itemList == 0))
  389.           cp->SetCmdStr((cp->dlgCmd)->title);
  390.         else
  391.           cp->SetCmdStr((char*)(cp->dlgCmd)->itemList);
  392.       }
  393.  
  394.       if ((cp->dlgCmd)->cmdType == C_CheckBox && (cp->dlgCmd)->retVal)
  395.         cp->SetCmdVal(1,Checked);
  396.  
  397.       if ((cp->dlgCmd)->cmdType == C_RadioButton && (cp->dlgCmd)->retVal)
  398.         cp->SetCmdVal(1,Checked);
  399.  
  400.       if ((cp->dlgCmd)->cmdType == C_ToggleButton)
  401.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
  402.  
  403.       if ((cp->dlgCmd)->cmdType == C_ToggleIconButton)
  404.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
  405.  
  406.       if ((cp->dlgCmd)->cmdType == C_Icon)
  407.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _wDialog);
  408.  
  409.       if ((cp->dlgCmd)->cmdType == C_Slider || (cp->dlgCmd)->cmdType == C_Spinner)
  410.         cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
  411.  
  412.       if ((cp->dlgCmd)->cmdType == C_ProgressBar)
  413.         cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
  414.  
  415.       if ((cp->dlgCmd)->attrs & CA_MainMsg)
  416.       {
  417.         cp->SetCmdStr((cp->dlgCmd)->title);
  418.       }
  419.  
  420.       if ((cp->dlgCmd)->attrs & CA_DefaultButton)
  421.       {
  422.         WinFocusChange(HWND_DESKTOP,
  423.           WinWindowFromID(_wDialog, (cp->dlgCmd)->cmdId),
  424.           0L);            // Set to default
  425.  
  426.         fProcessed = 1;                  // return 0 if we call SetFocus
  427.       }
  428.  
  429.       if ((cp->dlgCmd)->cmdType == C_TextIn)
  430.       {
  431.         WinFocusChange(HWND_DESKTOP,
  432.           WinWindowFromID(_wDialog, (cp->dlgCmd)->cmdId),
  433.           0L);            // Set to default
  434.  
  435.         fProcessed = 1;           // return 0 if we call SetFocus
  436.       }
  437.  
  438.       if (!(cp->dlgCmd)->Sensitive) // Make insensitive if it was
  439.       {
  440.         cp->SetCmdVal(0,Sensitive);
  441.       }
  442.  
  443.       if ((cp->dlgCmd)->attrs & CA_Hidden) // Hide it!
  444.       {
  445.         cp->SetCmdVal(1,Hidden);
  446.       }
  447.  
  448.       if ((cp->dlgCmd)->cmdType == C_List
  449.         || (cp->dlgCmd)->cmdType == C_SList
  450.         || (cp->dlgCmd)->cmdType == C_ComboBox
  451.         || (cp->dlgCmd)->cmdType == C_SComboBox
  452.         || (cp->dlgCmd)->cmdType == C_Spinner)
  453.       {
  454.         int curval = cp->GetCmdValue((cp->dlgCmd)->cmdId);
  455.         cp->SetCmdVal(curval,ChangeList);
  456.       }
  457.  
  458.       if ((cp->dlgCmd)->cmdType == C_Icon || (cp->dlgCmd)->cmdType == C_Frame
  459.         || (cp->dlgCmd)->cmdType == C_ToggleFrame)
  460.       {
  461. //        cp->SetCmdVal(0,Sensitive); // Trick to avoid getting focus
  462.       }
  463.  
  464. // TOOLTIPS NOT IMPLEMENTED YET!!!!
  465.       if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
  466.       {
  467.         /* add the control to the tooltip. TTF_SUBCLASS causes the
  468.         tooltip to automatically subclass the window and look for the
  469.         messages it is interested in. */
  470.         if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
  471.         {
  472.         }
  473.       }
  474.     }
  475.     DialogDisplayed();
  476.  
  477.     return fProcessed;
  478.       }
  479.  
  480.       case WM_CONTROL:
  481.       {
  482.     vCmd* UseThis = (vCmd *) getThisFromId((ItemVal)SHORT1FROMMP(mp1));
  483.     if (!UseThis)
  484.     {
  485.       fProcessed = 0;
  486.       break;
  487.     }
  488.     UseThis->CmdCallback(uMsg, mp1, mp2);
  489.       }
  490.       return fProcessed;
  491.  
  492.       case WM_COMMAND:
  493.       {
  494.     vCmd* UseThis = (vCmd *) getThisFromId((ItemVal) mp1);
  495.     if (!UseThis)
  496.     {
  497.       fProcessed = 0;
  498.       break;
  499.     }
  500.     UseThis->CmdCallback(uMsg, mp1, mp2);
  501.       }
  502.       return fProcessed;
  503.  
  504.  
  505.       case WM_FOCUSCHANGE:
  506.       {
  507.     vCmd* UseThis = (vCmd *) getThisFromId((ItemVal) mp1);
  508.     if (!UseThis)
  509.     {
  510.       fProcessed = 0;
  511.       break;
  512.     }
  513.     UseThis->CmdCallback(uMsg, mp1, mp2);
  514.       }
  515.       return fProcessed;
  516.  
  517. /*
  518.     case WM_HSCROLL:
  519.     case WM_VSCROLL:
  520.     {
  521.       vCmd* UseThis = (vCmd *) getThisFromId(SHORT1FROMMP(mp1));
  522.  
  523.       int code = SHORT2FROMMP(mp2);
  524.       if (!UseThis || code == SB_ENDSCROLL)
  525.       {
  526.     fProcessed = 0; break;
  527.       }
  528.  
  529.       UseThis->CmdCallback(uMsg, mp1, mp2);
  530.     }
  531.     break;
  532. */
  533.     default:
  534.       fProcessed = FALSE;
  535.       break;
  536.     }
  537.  
  538.   return (int) WinDefDlgProc(hDlg, uMsg, mp1, mp2);
  539. }
  540.