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

  1. //===============================================================
  2. // vCommandPane - the command bar pane class used by the vWindow class
  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/vcmdpane.h>
  13. #include <v/vwindow.h>          // we are part of a window
  14. #include <v/vthislst.h>         // For this list
  15.  
  16. // Define static data of the class
  17.   MRESULT EXPENTRY CPProcCB(HWND hDlg, ULONG uMsg, MPARAM mp1, MPARAM mp2);
  18.  
  19.   static vThisList _thisList;   // hide this in this file
  20.  
  21. //===================>>> vCommandPane::vCommandPane <<<====================
  22.   vCommandPane::vCommandPane(CommandObject* cList) :
  23.        vPane(P_Commands), vCmdParent(P_Commands)
  24.   {
  25.  
  26.     SysDebug(Constructor,"vCommandPane::vCommandPane() constructor\n")
  27.     _origList = cList;          // handle to list of commands
  28.     _dialogType = aCmdBar;      // this is a command pane
  29.     _isDisplayed = 1;           // Command bars visible by default
  30.     _cmdObj = 0;                // no list
  31.     _cmdObjCount = 0;
  32.     _TextInActive = 0;
  33.   }
  34.  
  35. //===================>>> vCommandPane::vCommandPane <<<====================
  36. // Constructor for vStatus type status bars
  37. // the list of elements are assumed to be just text labels
  38. // implemented here as vBoxedLabels
  39.  
  40.   vCommandPane::vCommandPane(vStatus* s_bar) :
  41.         vPane(P_Status), vCmdParent(P_Status)
  42.   {
  43.     _dialogType = aStatBar;     // this is really a command pane
  44.     _isDisplayed = 1;           // Status bars visible by default
  45.     char* cp;
  46.     SysDebug(Constructor,"vStatusPane::vStatusPane() constructor\n")
  47.  
  48.     // get number of objects in pane
  49.     for (_cmdObjCount = 1; s_bar[_cmdObjCount].label; ++_cmdObjCount);
  50.  
  51.     _cmdObj = new CommandObject[_cmdObjCount+1];
  52.     for (int ix = 0; ix <= _cmdObjCount; ++ix)
  53.     {
  54.       if (!s_bar[ix].label)           // end of list
  55.       {
  56.         _cmdObj[ix].cmdType = C_EndOfList;
  57.         _cmdObj[ix].title = 0;
  58.         break;
  59.       }
  60.       _cmdObj[ix].cmdType = C_BoxedLabel;
  61.  
  62.       _cmdObj[ix].cmdId = s_bar[ix].statId;
  63.       _cmdObj[ix].Sensitive = s_bar[ix].sensitive;
  64.       _cmdObj[ix].retVal = 0;
  65.       cp = new char[strlen(s_bar[ix].label)+1];       // copy string
  66.       strcpy(cp, s_bar[ix].label);
  67.       _cmdObj[ix].title = cp;
  68.       _cmdObj[ix].itemList = 0;
  69.       _cmdObj[ix].attrs = s_bar[ix].attrs;
  70.       _cmdObj[ix].cFrame = 0;
  71.       _cmdObj[ix].cRightOf = 0;
  72.       _cmdObj[ix].cBelow = 0;
  73.       _cmdObj[ix].size = s_bar[ix].width;
  74.       _cmdObj[ix].tip = 0;
  75.     }
  76.     _origList = _cmdObj;                // handle to list of commands
  77.   }
  78.  
  79. //===================>>> vCommandPane::~vCommandPane <<<====================
  80.   vCommandPane::~vCommandPane()
  81.   {
  82.     SysDebug(Destructor,"vCommandPane::~vCommandPane() destructor\n")
  83. //  theApp->unregisterCmdPane(this);
  84.     _parentWin->unregisterCmdPane(this);  // vWindow is tracking pane
  85.  
  86.     if (_hTemplate !=0)
  87.     {
  88.       DosFreeMem(_hTemplate);
  89.       _hTemplate = 0;
  90.     }
  91.     if (_cmdObj != 0)
  92.     {
  93.       for (int ix = 0 ; ix < _cmdObjCount ; ++ix)
  94.       {
  95.         if (_cmdObj[ix].title)
  96.           delete [] _cmdObj[ix].title;    // free strings
  97.       }
  98.       delete [] _cmdObj;                              // free list
  99.     }
  100.     _thisList.Delete((ThisId)_barHwnd); // free the this ptr
  101.   }
  102.  
  103. //==================>>> vCommandPane::ProcessCmd <<<=======================
  104.   void vCommandPane::ProcessCmd(ItemVal id, ItemVal rv, CmdType ct)
  105.   {
  106.     // simple interface between command objects and the
  107.     // inherited vCmdParent ProcessCmd to the CommandObject which does the work
  108.     _parentWin->WindowCommand(id, rv, ct);
  109.   }
  110. //====================>>> vCommandPane::GetPaneValue <<<======================
  111.   int vCommandPane::GetPaneValue(ItemVal id, int& val) VCONST
  112.   {
  113.     if (HasId(id))              // make sure the id is in the pane
  114.       {
  115.         val = GetValue(id);
  116.         return 1;               // assume 0 if not found
  117.       }
  118.     else
  119.         return 0;       // can't find this id
  120.   }
  121. //===================>>> vCommandPane::SetPaneValue <<<========================
  122.   void vCommandPane::SetPaneValue(ItemVal id, int val, ItemSetType setType)
  123.   {
  124.     SetValue(id,val,setType);
  125.   }
  126.  
  127. //====================>>> vCommandPane::SetPaneString <<<======================
  128.   void vCommandPane::SetPaneString(ItemVal id, VCONST char* str)
  129.   {
  130.     SetString(id,str);
  131.   }
  132. //====================>>> vCommandPane::ShowPane <<<======================
  133.   void vCommandPane::ShowPane(int OnOrOff) VCONST
  134.   {
  135.     if (OnOrOff != _isDisplayed)        // only need to do something if changed
  136.      {
  137.        _isDisplayed = OnOrOff;
  138.  
  139.        if (_isDisplayed)
  140.        {
  141.          WinShowWindow (_barHwnd, TRUE);
  142.          _parentWin->_numPanes++;
  143.        }
  144.        else
  145.        {
  146.          WinShowWindow (_barHwnd, FALSE);
  147.          _parentWin->_numPanes--;
  148.        }
  149.        _parentWin->AdjustSize(this);
  150.      }
  151.   }
  152. //====================>>> vCommandPane::initialize <<<=======================
  153.   void vCommandPane::initialize(vWindow* pWin, HWND hOwner)
  154.   {
  155.     // now, build the menu items in the widget provided
  156.     DlgCmdList* curCmd;
  157.  
  158.     vPane::initialize(pWin, hOwner);       // initialize base class
  159.     _hOwner = hOwner;
  160.     // Now, build the initial in-memory dialog template using
  161.     // OS/2 Dialog template handle _hTemplate.
  162.  
  163.     // Using 8,helv makes it ok to use 8 in calculating control sizes!
  164.     PPElement PPel[] = { {PP_FONTNAMESIZE,(ULONG) "8.Helv"}, {0}};
  165.  
  166. //    int buildOK = CreateDlgTemplate(FCF_NOBYTEALIGN, WS_VISIBLE | WS_CLIPSIBLINGS,
  167.     int buildOK = CreateDlgTemplate(FCF_NOBYTEALIGN, WS_CLIPSIBLINGS,
  168.       0,0, 0,0, 0, "", "", "", AssyPresParams(PPel) );
  169.  
  170.     if (!buildOK)
  171.       vSysError("vDialog - Unable to build dialog template");
  172.  
  173.     int ix;
  174.     // Add each control to the template via AddCmd
  175.     for (ix = 0 ; _origList && (_origList[ix].cmdType != C_EndOfList) ; ++ix)
  176.     {
  177.       curCmd = new DlgCmdList;                // get a new cell
  178.       curCmd->nextDCL = _cmdList;             // add in at front
  179.       _cmdList = curCmd;
  180.       curCmd->cmdP = 0;                       // not added yet
  181.       curCmd->cmdP = AddCmd(&_origList[ix]);
  182.     }
  183.     DoneAddingControls();               // All finished adding controls
  184.     // Now ready to create the dialog
  185.  
  186.     _barHwnd = WinCreateDlg(WinQueryWindow(hOwner, QW_PARENT), hOwner,
  187.       (PFNWP) &CPProcCB, _hTemplate, (PVOID) this);
  188.  
  189.     SysDebug2(OS2Dev,"vCommandPane::initialize hOwner:%u _barHwnd:%u \n", hOwner, _barHwnd)
  190.  
  191.     if( _barHwnd)
  192.     {
  193.       _wDialog = _barHwnd;
  194.       pWin->registerCmdPane(this);  // if created ok, then register with vWindow
  195.       pWin->AdjustSize(this);   // resize the frame to accomodate pane
  196.     }
  197.  
  198.     DosFreeMem(_hTemplate);
  199.     _hTemplate = 0;
  200.  
  201.   }
  202. // ---------------------------------------------------------------------
  203. //====================>>> DlgProc <<<=======================
  204.   MRESULT EXPENTRY CPProcCB(HWND hDlg, ULONG uMsg,
  205.                               MPARAM mp1, MPARAM mp2)
  206.   {
  207.     vCommandPane* useThis;
  208.     if (uMsg == WM_INITDLG)  // first time!
  209.     {
  210.       useThis = (vCommandPane*)mp2;
  211.       _thisList.Add((ThisId)hDlg, (void*)useThis);
  212.     }
  213.     else
  214.       useThis = (vCommandPane*)_thisList.GetThis((ThisId)hDlg);
  215.  
  216.     if (!useThis)
  217.       return WinDefDlgProc(hDlg, uMsg, mp1, mp2);
  218.  
  219.     return (MRESULT) useThis->DynamicDlgProc(hDlg, uMsg, mp1, mp2);
  220.   }
  221.  
  222. //====================>>> vCommandPane::OnInitDialog <<<==================
  223.   int vCommandPane::OnInitDialog(HWND hwnd, MPARAM mp1, MPARAM mp2)
  224.   {
  225.     // Changes here must have equivlalents in the vDialog.cpp code
  226.     for (DlgCmdList* cc = _cmdList ; cc != 0  ; cc = cc->nextDCL)
  227.     {
  228.       vCmd* cp = cc->cmdP;
  229.  
  230.       // BEW - V 1.17 - Shouldn't have to do this, but the dynamic
  231.       // dialog creation somehow replaces characters > 128 with _.
  232.       // This fixes that problem.
  233.  
  234.       if ((cp->dlgCmd)->cmdType == C_BoxedLabel ||
  235.         (cp->dlgCmd)->cmdType == C_Button ||
  236.     (cp->dlgCmd)->cmdType == C_CheckBox ||
  237.     (cp->dlgCmd)->cmdType == C_Label ||
  238.     (cp->dlgCmd)->cmdType == C_RadioButton ||
  239.     (cp->dlgCmd)->cmdType == C_TextIn)
  240.       {
  241.     cp->SetCmdStr((cp->dlgCmd)->title);
  242.       }
  243.       else if ((cp->dlgCmd)->cmdType == C_Text)
  244.       {
  245.     if (!(cp->dlgCmd)->itemList || (*(char *)(cp->dlgCmd)->itemList == 0))
  246.       cp->SetCmdStr((cp->dlgCmd)->title);
  247.     else
  248.       cp->SetCmdStr((char*)(cp->dlgCmd)->itemList);
  249.       }
  250.  
  251.       if ((cp->dlgCmd)->cmdType == C_CheckBox && (cp->dlgCmd)->retVal)
  252.     cp->SetCmdVal(1,Checked);
  253.  
  254.       if ((cp->dlgCmd)->cmdType == C_RadioButton && (cp->dlgCmd)->retVal)
  255.         cp->SetCmdVal(1,Checked);
  256.  
  257.       if ((cp->dlgCmd)->cmdType == C_BoxedLabel)
  258.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
  259.  
  260.       if ((cp->dlgCmd)->cmdType == C_Text)
  261.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
  262.  
  263.       if ((cp->dlgCmd)->cmdType == C_ToggleButton)
  264.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
  265.  
  266.       if ((cp->dlgCmd)->cmdType == C_ToggleIconButton)
  267.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
  268.  
  269.       if ((cp->dlgCmd)->cmdType == C_Icon)
  270.         cp->DRAWITEM((cp->dlgCmd)->cmdId, (OWNERITEM*) _barHwnd);
  271.  
  272.       if ((cp->dlgCmd)->cmdType == C_Slider || (cp->dlgCmd)->cmdType == C_Spinner)
  273.         cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
  274.  
  275.       if ((cp->dlgCmd)->cmdType == C_ProgressBar)
  276.         cp->SetCmdVal(cp->GetCmdValue((cp->dlgCmd)->cmdId),Value);
  277.  
  278.  
  279.       if (!(cp->dlgCmd)->Sensitive)           // Make insensitive if it was
  280.       {
  281.         cp->SetCmdVal(0,Sensitive);
  282.       }
  283.  
  284.       if ((cp->dlgCmd)->attrs & CA_Hidden)    // Hide it!
  285.       {
  286.         cp->SetCmdVal(1,Hidden);
  287.       }
  288.  
  289.       if ((cp->dlgCmd)->cmdType == C_List
  290.         || (cp->dlgCmd)->cmdType == C_ComboBox
  291.         || (cp->dlgCmd)->cmdType == C_SComboBox
  292.         || (cp->dlgCmd)->cmdType == C_Spinner
  293.         || (cp->dlgCmd)->cmdType == C_SList )
  294.       {
  295.         int curval = cp->GetCmdValue((cp->dlgCmd)->cmdId);
  296.         cp->SetCmdVal(curval,ChangeList);
  297.       }
  298.  
  299.       if ((cp->dlgCmd)->cmdType == C_Icon || (cp->dlgCmd)->cmdType == C_Frame)
  300.       {
  301. //       cp->SetCmdVal(0,Sensitive); // Trick to avoid getting focus
  302.       }
  303.  
  304.       // Now add ToolTip if it has a message
  305.       if ((cp->dlgCmd)->tip && *(cp->dlgCmd)->tip)
  306.       {
  307. /*  ToolTips code not implemented in OS/2 yet.  More effort needed!!!
  308.     TOOLINFO ti;
  309.     char *cc = (char*) &ti;
  310.     int lim = sizeof (ti);
  311.     for (int i = 0 ; i++ < lim ; *cc++ = 0)
  312.       ;
  313.     ti.cbSize = sizeof(ti);
  314.     ti.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
  315.     ti.hwnd = hwnd;
  316.     ti.uId = (UINT)GetDlgItem(hwnd,(cp->dlgCmd)->cmdId);
  317.     ti.lpszText = TEXT((cp->dlgCmd)->tip);
  318.     SendMessage(hwndToolTip, TTM_ADDTOOL, 0, (LPARAM)&ti);
  319. */
  320.       }
  321.     }
  322.  
  323. //    _isShown = 1;                               // We will be shown now
  324.     RECTL rc;                                   // to get our size
  325.     WinQueryWindowRect (_barHwnd, &rc);         // the rect of the command bar
  326.  
  327.     _windowY = 0;                               // put pane at bottom for now
  328.     _windowH =  rc.yTop - rc.yBottom;           // compute height
  329.  
  330. //    WinEnableWindow(_barHwnd, TRUE);
  331.  
  332.     return 0;
  333.   }
  334. //====================>>> vCommandPane::OnEnable <<<==================
  335.   void vCommandPane::OnEnable(HWND hwnd, BOOL fEnable)
  336.   {
  337.     WinEnableWindow (hwnd, fEnable);
  338. /*
  339.     // Make all child windows have the same status as the dialog box.
  340.     for (HWND hwndCtl = (HWND) WinQueryWindow (hwnd, QW_TOP); hwndCtl != NULLHANDLE ;
  341.       hwndCtl = (HWND) WinQueryWindow (hwnd, QW_NEXT))
  342.     {
  343.       WinEnableWindow (hwndCtl, fEnable);
  344.     }
  345. */
  346.   }
  347.  
  348. //====================>>> vCommandPane::OnPaint <<<==================
  349.   int vCommandPane::OnPaint(HWND hwnd)
  350.   {
  351.     // Paint dividing lines around command/status bar
  352.     RECTL rc, rcInner, rcGrip;
  353.     POINTL  pnt = {0,0};
  354.     LINEBUNDLE ShadowPen, LightPen;
  355.     int borderH, borderV;
  356.     int gripPitch, frameV, frameH;
  357.  
  358.     borderH = WinQuerySysValue (HWND_DESKTOP, SV_CYBORDER);
  359.     borderV = WinQuerySysValue (HWND_DESKTOP, SV_CXBORDER);
  360.     frameV = 0;  // space from edge of bar to frame boundary
  361.     frameH = 1;
  362.     gripPitch = 2;   // pitch of grip ribs
  363.  
  364.     ShadowPen.lColor = SYSCLR_BUTTONDARK;
  365.     ShadowPen.usMixMode = FM_OVERPAINT;
  366.     ShadowPen.usType = LINETYPE_SOLID;
  367.  
  368.     LightPen.lColor = SYSCLR_BUTTONLIGHT;
  369.     LightPen.usMixMode = FM_OVERPAINT;
  370.     LightPen.usType = LINETYPE_SOLID;
  371.  
  372.     // begin painting here
  373.     HPS hdc = WinBeginPaint (_barHwnd, NULLHANDLE, &rc);
  374.     WinQueryWindowRect(_barHwnd, &rc);
  375.     WinFillRect(hdc, &rc, SYSCLR_BUTTONMIDDLE);
  376.  
  377.     if (paneType() == P_Status)         // Paint a status bar
  378.     {
  379.  
  380.       rcInner.xLeft = rc.xLeft + frameH;
  381.       rcInner.xRight = rc.xRight - frameH +1;
  382.       rcInner.yBottom = rc.yBottom + frameV;
  383.       // to make it look centered, we need to add the border thickness to the top
  384.       rcInner.yTop = rc.yTop - frameV - 2*borderV;
  385.       WinDrawBorder(hdc,
  386.                &rcInner,
  387.                borderV,
  388.                borderH,
  389.                SYSCLR_BUTTONMIDDLE,
  390.                SYSCLR_BUTTONMIDDLE,
  391.                DB_DEPRESSED);
  392.  
  393.       // Paint diagonal grip ribs on status pane
  394.       // draw grip area rectangle
  395.       rcGrip.xLeft = rcInner.xRight - 6*gripPitch;
  396.       rcGrip.yBottom = rcInner.yBottom;
  397.       rcGrip.xRight = rcInner.xRight;
  398.       rcGrip.yTop = rcInner.yBottom + 6*gripPitch;
  399.       WinFillRect(hdc, &rcGrip, SYSCLR_BUTTONMIDDLE);
  400. //      WinFillRect(hdc, &rcGrip, CLR_GREEN);
  401.  
  402.       rcInner.xRight -= 1;  // the drawing commands are inclusive
  403.       // draw bottom hash
  404.       pnt.x = rcInner.xRight -gripPitch;
  405.       pnt.y = rcInner.yBottom;
  406.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
  407.       GpiSetCurrentPosition (hdc, &pnt);
  408.       pnt.x = rcInner.xRight;
  409.       pnt.y = rcInner.yBottom +gripPitch;
  410.       GpiLine (hdc, &pnt);
  411.  
  412.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
  413.       pnt.x = rcInner.xRight -2*gripPitch;
  414.       pnt.y = rcInner.yBottom;
  415.       GpiSetCurrentPosition (hdc, &pnt);
  416.       pnt.x = rcInner.xRight;
  417.       pnt.y = rcInner.yBottom +2*gripPitch;
  418.       GpiLine (hdc, &pnt);
  419.  
  420.       // draw middle hash
  421.       pnt.x = rcInner.xRight -3*gripPitch;
  422.       pnt.y = rcInner.yBottom;
  423.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
  424.       GpiSetCurrentPosition (hdc, &pnt);
  425.       pnt.x = rcInner.xRight;
  426.       pnt.y = rcInner.yBottom +3*gripPitch;
  427.       GpiLine (hdc, &pnt);
  428.  
  429.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
  430.       pnt.x = rcInner.xRight -4*gripPitch;
  431.       pnt.y = rcInner.yBottom;
  432.       GpiSetCurrentPosition (hdc, &pnt);
  433.       pnt.x = rcInner.xRight;
  434.       pnt.y = rcInner.yBottom +4*gripPitch;
  435.       GpiLine (hdc, &pnt);
  436.  
  437.       // draw top hash
  438.       pnt.x = rcInner.xRight -5*gripPitch;
  439.       pnt.y = rcInner.yBottom;
  440.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
  441.       GpiSetCurrentPosition (hdc, &pnt);
  442.       pnt.x = rcInner.xRight;
  443.       pnt.y = rcInner.yBottom +5*gripPitch;
  444.       GpiLine (hdc, &pnt);
  445.  
  446.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
  447.       pnt.x = rcInner.xRight -6*gripPitch;
  448.       pnt.y = rcInner.yBottom;
  449.       GpiSetCurrentPosition (hdc, &pnt);
  450.       pnt.x = rcInner.xRight;
  451.       pnt.y = rcInner.yBottom +6*gripPitch;
  452.       GpiLine (hdc, &pnt);
  453.     }
  454.     else                                // Paint a command bar
  455.     {
  456.       GpiSetCurrentPosition (hdc, &pnt);
  457.  
  458.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &ShadowPen);
  459.  
  460.       pnt.x = rc.xRight;
  461.       pnt.y = 0;
  462.       GpiLine (hdc, &pnt);
  463.  
  464.       GpiSetAttrs(hdc, PRIM_LINE, LBB_COLOR | LBB_TYPE, 0, &LightPen);
  465.  
  466.       pnt.x = 0;
  467.       pnt.y = _windowH - borderH;
  468.       GpiSetCurrentPosition (hdc, &pnt);
  469.  
  470.       pnt.x = rc.xRight;
  471.       pnt.y = _windowH - borderH;
  472.       GpiLine (hdc, &pnt);
  473.  
  474.     }
  475.     WinEndPaint (hdc);
  476.  
  477.     return 0;
  478.   }
  479.  
  480. //====================>>> vCommandPane::OnCommand <<<==================
  481.   void vCommandPane::OnCommand (vCmd *UseThis, int uMsg, MPARAM mp1,
  482.     MPARAM mp2)
  483.   {
  484.     // A very dangerous thing can happen here if the button causes
  485.     // vApp::Exit to be called. This can cause things to be destructed,
  486.     // which means that the command object goes away, which means
  487.     // that UseThis no longer points to something valid, which is of
  488.     // course a problem. Exit can get called in CmdCallback, so we
  489.     // will remember the command type first for the test after the call.
  490.  
  491.     CmdType ct = (UseThis->dlgCmd)->cmdType;    // will be ok still
  492.     UseThis->CmdCallback(uMsg, mp1, mp2);
  493.  
  494.     // We need a SetFocus to get the focus back to the
  495.     // canvas so that cursor will work, but for
  496.     // lists and combos, SetFocus breaks them.  Also, we don't
  497.     // want timer updates to text controls to cause focus grabbing
  498.     // so we have to check for them too.
  499.     if ((ct == C_ComboBox || ct == C_SComboBox) && SHORT2FROMMP(mp1) != CBN_ENTER)
  500.       return;
  501.  
  502.     if ((ct == C_List || ct == C_SList)
  503.       && SHORT2FROMMP(mp1) != LN_ENTER && SHORT2FROMMP(mp1) != LN_SELECT)
  504.       return;
  505.  
  506.     if (ct == C_BoxedLabel || ct == C_ColorLabel || ct == C_Label || ct == C_ProgressBar
  507.       || ct == C_Text || ct == C_Icon)
  508.     {
  509.       return;
  510.     }
  511.  
  512.     // we need to flag when the user is inputing data into a text in box
  513.     // so that we can know not to mess with the focus when the mouse
  514.     // buttons are being clicked
  515.     if (ct == C_TextIn)
  516.     {
  517.       if (SHORT2FROMMP(mp1) == EN_SETFOCUS)
  518.         _TextInActive = 1;
  519.       else if(SHORT2FROMMP(mp1) == EN_KILLFOCUS)
  520.         _TextInActive = 0;
  521.       return;
  522.     }
  523.  
  524.     // The idea here is that we change the focus back to the client after
  525.     // any WM_CONTROL/WM_COMMAND message occurs, but we only do this if the
  526.     // app is currently active.  If it is not, then we do nothing which prevents
  527.     // automatic timer updates of things like text boxes from yanking away focus
  528.     // from another app that is curently active.
  529.     // note: parent of cmdpane should be our frame
  530.     if ( WinQueryActiveWindow(HWND_DESKTOP) == WinQueryWindow(_barHwnd, QW_PARENT) )
  531.     {
  532.       WinFocusChange(HWND_DESKTOP, WinQueryWindow(_barHwnd, QW_OWNER),
  533.         FC_NOSETACTIVE | FC_NOSETSELECTION);
  534.     }
  535.   }
  536.  
  537. //====================>>> vCommandPane::DynamicDlgProc <<<==================
  538.   int vCommandPane::DynamicDlgProc(HWND hDlg, UINT uMsg,MPARAM mp1, MPARAM mp2)
  539.   {
  540.     switch (uMsg)
  541.     {
  542.       case WM_INITDLG:
  543.         _barHwnd = hDlg;
  544.         _wDialog = hDlg;  // used by vCmdParent
  545.         return OnInitDialog(hDlg, mp1, mp2);
  546.  
  547. /*
  548.       case WM_ENABLE:
  549.         OnEnable(hDlg, (BOOL) SHORT1FROMMP(mp1));
  550.         break;
  551. */
  552.       case WM_PAINT:
  553.         return OnPaint(hDlg);
  554.  
  555.       case WM_CONTROL:
  556.       case WM_COMMAND:
  557.       {
  558.         vCmd* UseThis = (vCmd *) getThisFromId((ItemVal)SHORT1FROMMP(mp1));
  559.         if (!UseThis)
  560.         {
  561.           return 0;
  562.         }
  563.         OnCommand(UseThis, uMsg, mp1, mp2);
  564.         return 0;
  565.       }
  566.  
  567.       // we need to monitor if the cmdpane gets focus and then send the
  568.       // focus right back to the client
  569.       case WM_BUTTON1UP:
  570.       case WM_BUTTON2UP:
  571.       case WM_BUTTON3UP:
  572.       case WM_CONTEXTMENU:
  573.       case WM_BEGINSELECT:
  574.       case WM_SINGLESELECT:
  575.       {
  576.         // if the user is inputing text into a textin box, then we
  577.         // don't want to mess with the focus when user clicks the mouse
  578.         // in the command bar (yes, it's a kludge!!!)
  579.         if (_TextInActive == 1)
  580.           return 0;
  581.  
  582.         WinFocusChange(HWND_DESKTOP, WinQueryWindow(_barHwnd ,QW_OWNER),
  583.           FC_NOSETACTIVE | FC_NOSETSELECTION);
  584.         break;
  585.       }
  586.  
  587.       default:
  588.         break;
  589.     }
  590.     return (int) WinDefDlgProc(hDlg, uMsg, mp1, mp2);
  591.   }
  592.  
  593.