home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / omfc.cpp < prev    next >
C/C++ Source or Header  |  1994-12-21  |  20KB  |  807 lines

  1. /* Copyright (c) Oracle Corporation 1994.  All Rights Reserved */
  2.  
  3. /*
  4.     This source code is provided as a debugging aid for developers
  5.     who have purchased Oracle Objects for OLE    .  Please see the
  6.     provided help file for documentation of these classes.
  7.  
  8. */
  9.  
  10. /*
  11.     Oracle Objects for OLE    
  12.     C++ classes for bound Widget support
  13.     MFC version
  14.     
  15.     CREATED    ********   11/22/94
  16.  
  17. */
  18.  
  19. #include <afxwin.h>         // MFC core and standard components
  20. #include <afxext.h>         // MFC extensions (including VB)
  21.  
  22. #ifndef ORACL_ORACLE
  23. #include "oracl.h"
  24. #endif
  25.  
  26. #ifndef OMFC_ORACLE
  27. #include "omfc.h"
  28. #endif
  29.  
  30. //----------------------------
  31. // OraRadioButton: a derived button class (used by OBoundGroupButton)
  32.  
  33. class OraRadioButton : public CButton
  34. {
  35. // Construction
  36. public:
  37.     OraRadioButton();
  38.  
  39.     oresult BindToControl(CWnd *wnd, int itemid, OBoundGroupButton *parent); 
  40.     oresult SetProperty(BOOL mode=OBOUND_READWRITE); 
  41.  
  42. // Attributes
  43. public:
  44.  
  45. // Operations
  46. public:
  47.  
  48. // Overrides
  49.     // ClassWizard generate virtual function overrides
  50.     //{{AFX_VIRTUAL(OraRadioButton)
  51.         // NOTE - the ClassWizard will add and remove member functions here.
  52.     //}}AFX_VIRTUAL
  53.  
  54. // Implementation
  55. public:
  56.     virtual ~OraRadioButton();
  57.  
  58.     // Generated message map functions
  59. protected:
  60.     //{{AFX_MSG(OraRadioButton)
  61.     afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
  62.     afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
  63.     //}}AFX_MSG
  64.     DECLARE_MESSAGE_MAP()
  65. private:
  66.     OBoundGroupButton  *m_group;    // pointer to the button group
  67.     BOOL m_mode;                       // readonly/readwrite mode
  68. };
  69.  
  70. //-----------------------------
  71. // OraScrollBar: a derived scrollbar class (used by OBoundSlider)
  72.  
  73. class OraScrollBar : public CScrollBar
  74. {
  75. // Construction
  76. public:
  77.     OraScrollBar();
  78.  
  79.     BindToControl(CWnd *wnd, int itemid);
  80.     SetProperty(int minvalue, int maxvalue, BOOL mode=OBOUND_READWRITE);
  81. // Attributes
  82. public:
  83.  
  84. // Operations
  85. public:
  86.  
  87. // Overrides
  88.     // ClassWizard generate virtual function overrides
  89.     //{{AFX_VIRTUAL(OraScrollBar)
  90.         // NOTE - the ClassWizard will add and remove member functions here.
  91.     //}}AFX_VIRTUAL
  92.  
  93. // Implementation
  94. public:
  95.     virtual ~OraScrollBar();
  96.  
  97.     // Generated message map functions
  98. protected:
  99.     //{{AFX_MSG(OraScrollBar)
  100.     //}}AFX_MSG
  101.     DECLARE_MESSAGE_MAP()
  102. private:
  103.     BOOL m_mode;      // readonly/readwrite mode
  104. };
  105.  
  106.  
  107. //---------------------------
  108. // OMFCBound member functions
  109.  
  110. OMFCBound::OMFCBound(void)
  111. {
  112.     m_isbound = FALSE;
  113. }
  114.  
  115. OMFCBound::~OMFCBound(void)
  116. {
  117. }
  118.  
  119. oresult OMFCBound::Subclass(CWnd *bwnd, CWnd *wnd, int itemid)
  120. {
  121.     if (m_isbound)
  122.     { // already bound
  123.         return(OFAILURE);
  124.     }
  125.     
  126.     // try getting the dialog item
  127.     if (!wnd->GetDlgItem(itemid))
  128.     { // couldn't get textedit
  129.         return(OFAILURE);
  130.     }
  131.     
  132.     bwnd->SubclassDlgItem(itemid, wnd);
  133.  
  134.     m_isbound = TRUE;
  135.         
  136.     return(OSUCCESS);
  137. }
  138.  
  139.  
  140. // -----------------------------
  141. // OBoundEdit member functions
  142.  
  143. OBoundEdit::OBoundEdit()
  144. {
  145.    m_mode = OBOUND_READWRITE;
  146. }
  147.  
  148. OBoundEdit::~OBoundEdit()
  149. {
  150. }
  151.  
  152. oresult OBoundEdit::Refresh(const OValue &val)
  153. {
  154.     if (!IsBound())
  155.         return(OFAILURE);  // we're not attached to the UI yet
  156.  
  157.     // change text in textedit
  158.     const char *cp = (const char *) val;
  159.     SetWindowText(cp);
  160.     
  161.     return(OSUCCESS);
  162. }
  163.  
  164. oresult OBoundEdit::SaveChange(void)
  165. {
  166.     // get the value from the text
  167.     CString temps;
  168.     GetWindowText(temps);
  169.     
  170.     OValue val = (const char *) temps;
  171.     oresult ores = SetValue(val);
  172.     
  173.     if (ores == OSUCCESS)
  174.         Changed(FALSE);
  175.     
  176.     return(ores);
  177. }
  178.  
  179. oresult OBoundEdit::SetProperty(BOOL mode/* =OBOUND_READWRITE */)
  180. {
  181.     m_mode = mode;    
  182.     return (SetReadOnly(mode) ? OSUCCESS : OFAILURE);
  183. }
  184.  
  185. BEGIN_MESSAGE_MAP(OBoundEdit, CWnd)
  186.     //{{AFX_MSG_MAP(OBoundEdit)
  187.     ON_WM_KEYUP()
  188.     //}}AFX_MSG_MAP
  189. END_MESSAGE_MAP()
  190.  
  191. /////////////////////////////////////////////////////////////////////////////
  192. // OBoundEdit message handlers
  193.  
  194. void OBoundEdit::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  195. {
  196.     if (m_mode == OBOUND_READWRITE)
  197.     {     
  198.       Changed();  // remember that there's been a change
  199.     }    
  200.     CWnd::OnKeyUp(nChar, nRepCnt, nFlags);
  201. }
  202.  
  203. //--------------------------------
  204. // OBoundStatic member functions
  205.  
  206. OBoundStatic::OBoundStatic()
  207. {
  208. }
  209.  
  210. OBoundStatic::~OBoundStatic()
  211. {
  212. }
  213.  
  214. oresult OBoundStatic::Refresh(const OValue &val)
  215. {
  216.     if (!IsBound())
  217.         return(OFAILURE);  // we're not attached to the UI yet
  218.  
  219.     // change text in textedit
  220.     const char *cp = (const char *) val;
  221.     SetWindowText(cp);
  222.     
  223.     return(OSUCCESS);
  224. }
  225.  
  226. BEGIN_MESSAGE_MAP(OBoundStatic, CStatic)
  227.     //{{AFX_MSG_MAP(OBoundStatic)
  228.         // NOTE - the ClassWizard will add and remove mapping macros here.
  229.     //}}AFX_MSG_MAP
  230. END_MESSAGE_MAP()
  231.  
  232. /////////////////////////////////////////////////////////////////////////////
  233. // OBoundStatic message handlers
  234.  
  235.  
  236. //-----------------------------------
  237. // OBoundCheckBox member functions
  238.  
  239. OBoundCheckBox::OBoundCheckBox()
  240. {
  241.     m_mode = OBOUND_READWRITE;
  242.     m_tristate = FALSE;
  243.     m_onvalue = NULL;
  244.     m_offvalue = NULL;
  245.     m_curvalue = NULL;  
  246. }
  247.  
  248. OBoundCheckBox::~OBoundCheckBox()
  249. {
  250. }
  251.  
  252. oresult OBoundCheckBox::Refresh(const OValue &val)
  253. {
  254.     if (!IsBound())
  255.         return(OFAILURE);  // we're not attached to the UI yet
  256.  
  257.     int check;
  258.     m_curvalue = (const char*)"";
  259.     if ((OValue)val == (OValue)m_onvalue)
  260.     {
  261.       check = 1;
  262.     }
  263.     else
  264.     if ((OValue)val == (OValue)m_offvalue)
  265.     {
  266.       check = 0;
  267.     }
  268.     else
  269.     {     
  270.       check = (m_tristate) ? 2 : 0;
  271.       m_curvalue = val;
  272.     }  
  273.     
  274.     SetCheck(check);
  275.       
  276.     return(OSUCCESS);
  277. }
  278.  
  279. oresult OBoundCheckBox::SaveChange(void)
  280. {
  281.     int check = GetCheck();
  282.     oresult ores;
  283.     
  284.     if (check == 0)
  285.     {
  286.         ores = SetValue(m_offvalue);
  287.     }
  288.     else
  289.     if (check == 1)
  290.     {
  291.         ores = SetValue(m_onvalue);
  292.     }
  293.     else
  294.     {           
  295.         ores = SetValue(m_curvalue);
  296.     }
  297.     
  298.     if (ores == OSUCCESS)
  299.         Changed(FALSE);
  300.         
  301.     return(ores);
  302. }
  303.  
  304. oresult OBoundCheckBox::SetProperty(const OValue &onvalue, 
  305.                                     const OValue &offvalue, 
  306.                                     BOOL mode /* =OBOUND_READWRITE */)
  307. {                         
  308.     if (mode == OBOUND_READONLY)      //  readonly
  309.     {
  310.       if (GetButtonStyle() == (UINT)BS_AUTO3STATE)
  311.         SetButtonStyle((UINT)BS_3STATE);
  312.       if (GetButtonStyle() == (UINT)BS_AUTOCHECKBOX)
  313.         SetButtonStyle((UINT)BS_CHECKBOX);
  314.     }
  315.     else                              // readwrite
  316.     {
  317.       if (GetButtonStyle() == (UINT)BS_3STATE)
  318.         SetButtonStyle((UINT)BS_AUTO3STATE);
  319.       if (GetButtonStyle() == (UINT)BS_CHECKBOX)
  320.         SetButtonStyle((UINT)BS_AUTOCHECKBOX);
  321.     }
  322.  
  323.     if ((GetButtonStyle() == (UINT)BS_AUTO3STATE) ||
  324.         (GetButtonStyle() == (UINT)BS_3STATE))
  325.     {
  326.       m_tristate = TRUE;
  327.     }
  328.         
  329.     m_mode = mode;
  330.     m_onvalue = onvalue;
  331.     m_offvalue = offvalue;
  332.     return(OSUCCESS);    // TODO: more accurate error checking
  333. }
  334.  
  335. BEGIN_MESSAGE_MAP(OBoundCheckBox, CButton)
  336.     //{{AFX_MSG_MAP(OBoundCheckBox)
  337.     ON_WM_LBUTTONUP()
  338.     ON_WM_KEYUP()
  339.     //}}AFX_MSG_MAP
  340. END_MESSAGE_MAP()
  341.  
  342. /////////////////////////////////////////////////////////////////////////////
  343. // OBoundCheckBox message handlers
  344.  
  345. void OBoundCheckBox::OnLButtonUp(UINT nFlags, CPoint point) 
  346. {
  347.     int check = GetCheck();
  348.     CButton::OnLButtonUp(nFlags, point);
  349.     if ((m_mode == OBOUND_READWRITE) &&      // double protection
  350.         (GetCheck() != check))
  351.     {
  352.       Changed();
  353.     }  
  354. }
  355.  
  356. void OBoundCheckBox::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  357. {
  358.     int check = GetCheck();
  359.     CButton::OnKeyUp(nChar, nRepCnt, nFlags);
  360.     if ((m_mode == OBOUND_READWRITE) &&      // double protection
  361.         (GetCheck() != check))
  362.     {
  363.       Changed();
  364.     }  
  365. }
  366.  
  367. //-------------------------------------
  368. // OBoundGroupButton member functions
  369.  
  370. OBoundGroupButton::OBoundGroupButton()
  371. {
  372.     m_mode = OBOUND_READWRITE;
  373.     m_head = NULL;
  374.     m_tail = NULL;
  375.     m_current = NULL;
  376.     
  377. }
  378.  
  379. OBoundGroupButton::~OBoundGroupButton()
  380. {
  381.     buttonlist *tmp;
  382.     while(tmp = m_head)
  383.     {
  384.       m_head = m_head->next;
  385.       delete (OraRadioButton *) (tmp->button);
  386.       delete tmp->value;
  387.       delete tmp;
  388.     }  
  389. }
  390.  
  391. oresult OBoundGroupButton::BindToControl(CWnd *wnd, int itemid)
  392. {
  393.     buttonlist *tmp = m_head;              // pointer to the head of button list
  394.     while(tmp)                             // detect whether already bounded
  395.     {
  396.       if (tmp->itemid == itemid)
  397.         return (OFAILURE);                
  398.       tmp = tmp->next;  
  399.     }
  400.  
  401.     // try getting the dialog item
  402.     if (!wnd->GetDlgItem(itemid))
  403.     { // couldn't get this item
  404.         return(OFAILURE);
  405.     }
  406.     
  407.     OraRadioButton *button = new OraRadioButton;    // dynamically create c++ radio button
  408.     button->BindToControl(wnd, itemid, this);       // Bind to windows control
  409.     tmp = new buttonlist;                           // create a button list element
  410.     tmp->button = (void *) button;                           
  411.     tmp->itemid = itemid;
  412.     tmp->next = NULL;
  413.     if (m_tail)                                     // add the new element onto the button list
  414.     {
  415.       m_tail->next = tmp;
  416.       m_tail = tmp;
  417.     }
  418.     else
  419.     {  
  420.       m_head = m_tail = tmp;
  421.     }
  422.     return (OSUCCESS);      
  423. }                                  
  424.  
  425. oresult OBoundGroupButton::SetProperty(int itemid, const OValue &value, BOOL mode /* =OBOUND_READWRITE */)
  426. {
  427.     buttonlist *tmp = m_head;              // pointer to the head of button list
  428.     while(tmp)                             // detect whether already bounded
  429.     {
  430.       if (tmp->itemid == itemid)
  431.         break;                
  432.       tmp = tmp->next;  
  433.     }
  434.  
  435.     if (tmp == NULL)
  436.     { // couldn't get this item
  437.         return(OFAILURE);
  438.     }
  439.     
  440.     OraRadioButton *button = (OraRadioButton *)(tmp->button);
  441.     if (!m_isbound)                        // use m_isbound to indicate if this is the 1st radio button      
  442.       m_mode = mode;          
  443.     button->SetProperty(m_mode);
  444.     OValue *butvalue = new OValue;
  445.     *butvalue = value;
  446.     tmp->value = butvalue;
  447.     m_isbound = TRUE;                      // so far the groupbutton is so-called bounded
  448.     return (OSUCCESS);      
  449. }                                  
  450.  
  451. oresult OBoundGroupButton::Refresh(const OValue &val)
  452. {
  453.     if (!IsBound())
  454.         return(OFAILURE);  // we're not attached to the UI yet
  455.  
  456.     buttonlist *tmp = m_head;
  457.     while (tmp)
  458.     {
  459.       if ((OValue)val == (OValue)*(tmp->value))
  460.         break;
  461.       tmp = tmp->next;  
  462.     }
  463.     
  464.     if (tmp)                                    // There is a matched value
  465.     {
  466.       if (m_current && (m_current != tmp))
  467.         ((OraRadioButton *)(m_current->button))->SetCheck(0);         // Uncheck the current radio button
  468.       ((OraRadioButton *)(tmp->button))->SetCheck(1);                 // Check the new radio button
  469.       m_current = tmp;                          // Bookmark the currently checked radio button 
  470.     }
  471.     else
  472.     {                                           // No matched value
  473.         if (m_current)
  474.         {
  475.           ((OraRadioButton *)(m_current->button))->SetCheck(0);       // Uncheck the current radio button
  476.           m_current = NULL;                     // Curently no checked radio buton
  477.         }       
  478.     }
  479.  
  480.     return(OSUCCESS);
  481. }
  482.  
  483. oresult OBoundGroupButton::SaveChange(void)
  484. {
  485.     buttonlist *tmp = m_head;
  486.     while (tmp)
  487.     {
  488.       if (((OraRadioButton *)(tmp->button))->GetCheck())
  489.         break;
  490.       tmp = tmp->next;  
  491.     }
  492.     
  493.     oresult ores;   
  494.     if (tmp)
  495.         ores = SetValue(*(tmp->value));
  496.     else
  497.     { // no button was set.  Make value NULL
  498.         OValue nullv;  // construct null value
  499.         ores = SetValue(nullv);
  500.     }
  501.     
  502.     if (ores == OSUCCESS)
  503.         Changed(FALSE);
  504.     
  505.     return(ores);
  506. }
  507.  
  508.  
  509. void OBoundGroupButton::ButtonChanged(void *button)
  510. {
  511.     buttonlist *tmp = m_head;
  512.     while (tmp)
  513.     {
  514.       if (tmp->button == button)
  515.         break;
  516.       tmp = tmp->next;  
  517.     }
  518.     m_current = tmp;
  519.     Changed();
  520. }
  521.  
  522. //--------------------------------
  523. // OraRadioButton member functions
  524.  
  525. OraRadioButton::OraRadioButton()
  526. {
  527.   m_group = NULL;
  528.   m_mode = OBOUND_READWRITE;
  529. }
  530.  
  531. OraRadioButton::~OraRadioButton()
  532. {
  533. }
  534.  
  535. oresult OraRadioButton::BindToControl(CWnd *wnd, 
  536.                                       int itemid, 
  537.                                       OBoundGroupButton *parent)
  538. {
  539.     SubclassDlgItem(itemid, wnd);
  540.     m_group = parent;
  541.     return (OSUCCESS);
  542. }                                      
  543.  
  544. oresult OraRadioButton::SetProperty(BOOL mode /*=OBOUND_READWRITE*/) 
  545. {
  546.     m_mode = mode;  
  547.     if (mode == OBOUND_READONLY)      //  readonly
  548.     {
  549.       if (GetButtonStyle() == (UINT)BS_AUTORADIOBUTTON)
  550.         SetButtonStyle((UINT)BS_RADIOBUTTON);
  551.     }
  552.     else                              // readwrite
  553.     {
  554.       if (GetButtonStyle() == (UINT)BS_RADIOBUTTON)
  555.         SetButtonStyle((UINT)BS_AUTORADIOBUTTON);
  556.     }
  557.     return (OSUCCESS);
  558. }                                      
  559.  
  560. BEGIN_MESSAGE_MAP(OraRadioButton, CButton)
  561.     //{{AFX_MSG_MAP(OraRadioButton)
  562.     ON_WM_LBUTTONUP()
  563.     ON_WM_KEYUP()
  564.     //}}AFX_MSG_MAP
  565. END_MESSAGE_MAP()
  566.  
  567. /////////////////////////////////////////////////////////////////////////////
  568. // OraRadioButton message handlers
  569.  
  570. void OraRadioButton::OnLButtonUp(UINT nFlags, CPoint point) 
  571. {
  572.     int check = GetCheck();                  // for most cases, even for keystrokes
  573.     CButton::OnLButtonUp(nFlags, point);
  574.     if ((m_mode == OBOUND_READWRITE) &&      // double protection and speeds up 
  575.         (GetCheck() != check))
  576.     {
  577.       m_group->ButtonChanged((void *) this);
  578.     }  
  579. }
  580.  
  581. void OraRadioButton::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags) 
  582. {
  583.     int check = GetCheck();                   
  584.     CButton::OnKeyUp(nChar, nRepCnt, nFlags); 
  585.     if ((m_mode == OBOUND_READWRITE) &&      // double protection and speeds up
  586.         (GetCheck() != check))
  587.     {    
  588.       m_group->ButtonChanged((void *) this);
  589.     }  
  590. }
  591.  
  592. //-----------------------------
  593. // OraScrollBar member functions
  594.  
  595. OraScrollBar::OraScrollBar()
  596. {
  597.   m_mode = OBOUND_READWRITE;
  598. }
  599.  
  600. OraScrollBar::~OraScrollBar()
  601. {
  602. }
  603.  
  604. oresult OraScrollBar::BindToControl(CWnd *wnd, int itemid)
  605. {
  606.     SubclassDlgItem(itemid, wnd);
  607.     return (OSUCCESS);
  608. }                                      
  609.  
  610. oresult OraScrollBar::SetProperty(int minvalue,
  611.                                   int maxvalue,
  612.                                   BOOL mode /*=OBOUND_READWRITE*/)
  613. {
  614.     SetScrollRange(minvalue, maxvalue);
  615.     m_mode = mode;
  616.     return (OSUCCESS);
  617. }                                      
  618.  
  619. BEGIN_MESSAGE_MAP(OraScrollBar, CScrollBar)
  620.     //{{AFX_MSG_MAP(OraScrollBar)
  621.     //}}AFX_MSG_MAP
  622. END_MESSAGE_MAP()
  623.  
  624. /////////////////////////////////////////////////////////////////////////////
  625. // OraScrollBar message handlers
  626. //--------------------------------
  627. // OBoundSlider member functions
  628.  
  629. OBoundSlider::OBoundSlider()
  630. {
  631.     m_mode = OBOUND_READWRITE;
  632.     m_minvalue = 0;
  633.     m_maxvalue = 0;
  634.     m_currentvalue = 0;
  635.     
  636.     OraScrollBar *sbar = new OraScrollBar;
  637.     m_scrollbar = (void *) sbar;    
  638. }
  639.  
  640. OBoundSlider::~OBoundSlider()
  641. {
  642.     delete ((OraScrollBar *) m_scrollbar);
  643. }
  644.  
  645. oresult OBoundSlider::BindToControl(CWnd *wnd, int scrollbarid, int staticid)
  646. {
  647.     // try getting the dialog item
  648.     if (!wnd->GetDlgItem(scrollbarid))
  649.     { // couldn't get this item
  650.         return(OFAILURE);
  651.     }
  652.     
  653.     // try getting the dialog item
  654.     if (!wnd->GetDlgItem(staticid))
  655.     { // couldn't get this item
  656.         return(OFAILURE);
  657.     }
  658.     OraScrollBar *sbar = (OraScrollBar *) m_scrollbar;           
  659.     sbar->BindToControl(wnd, scrollbarid);
  660.     RECT rect;
  661.     sbar->GetWindowRect(&rect);    
  662.     sbar->GetParent()->ScreenToClient(&rect);
  663.     // right now just give it a random id
  664.     Create(NULL, "OBoundSLIDER", WS_CHILD | WS_VISIBLE, rect, sbar->GetParent(), 12121);
  665.     sbar->SetParent(this);
  666.     sbar->SetWindowPos(NULL, 0, 0, rect.right - rect.left, rect.bottom - rect.top, SWP_NOSIZE);
  667.     m_static.SubclassDlgItem(staticid, wnd);    
  668.     m_isbound = TRUE;                               // so far the slider is so-called bounded
  669.     return (OSUCCESS);      
  670. }                                  
  671.  
  672. oresult OBoundSlider::SetProperty(const OValue &minvalue,
  673.                                   const OValue &maxvalue,
  674.                                   BOOL mode /* =OBOUND_READWRITE */)
  675. {
  676.     m_minvalue = min((int)minvalue, (int)maxvalue);
  677.     m_maxvalue = max((int)maxvalue, (int)maxvalue);
  678.     OraScrollBar * sbar = (OraScrollBar *)m_scrollbar;
  679.     sbar->SetProperty(m_minvalue, m_maxvalue, mode);
  680.     m_mode = mode;                                  // set read/write mode
  681.     return (OSUCCESS);      
  682. }                                  
  683.  
  684. oresult OBoundSlider::Refresh(const OValue &val)
  685. {
  686.     if (!IsBound())
  687.         return(OFAILURE);  // we're not attached to the UI yet
  688.  
  689.     int value = (int)val;
  690.     if (value < m_minvalue)
  691.       value = m_minvalue;
  692.     if (value > m_maxvalue)
  693.       value = m_maxvalue;
  694.     char valbuf[256];
  695.     wsprintf(valbuf, "%d", value);    
  696.     m_static.SetWindowText(valbuf);
  697.     ((OraScrollBar *) m_scrollbar)->SetScrollPos(value);
  698.  
  699.     return(OSUCCESS);
  700. }
  701.  
  702. oresult OBoundSlider::SaveChange(void)
  703. {
  704.     OValue val = (int)m_currentvalue;
  705.     oresult ores = SetValue(val);           
  706.     
  707.     if (ores == OSUCCESS)
  708.         Changed(FALSE);
  709.     
  710.     return(ores);
  711. }
  712.  
  713.  
  714. BEGIN_MESSAGE_MAP(OBoundSlider, CWnd)
  715.     //{{AFX_MSG_MAP(OBoundSlider)
  716.     ON_WM_HSCROLL()
  717.     ON_WM_VSCROLL()
  718.     //}}AFX_MSG_MAP
  719. END_MESSAGE_MAP()
  720.  
  721.  
  722. /////////////////////////////////////////////////////////////////////////////
  723. // OBoundSlider message handlers
  724.  
  725. void OBoundSlider::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  726. {
  727.   if (m_mode = OBOUND_READWRITE)
  728.   {
  729.     switch (nSBCode)
  730.     {
  731.         case SB_LEFT:
  732.              m_currentvalue = m_minvalue;
  733.              break;
  734.              
  735. //      case SB_ENDSCROLL
  736.         case SB_PAGELEFT:
  737.              m_currentvalue -= 9;
  738.         case SB_LINELEFT:
  739.              m_currentvalue = max(m_minvalue, m_currentvalue - 1);
  740.              break;
  741.              
  742.         case SB_PAGERIGHT:
  743.              m_currentvalue += 9;
  744.         case SB_LINERIGHT:
  745.              m_currentvalue = min(m_maxvalue, m_currentvalue + 1);
  746.              break;
  747.              
  748.         case SB_RIGHT:
  749.              m_currentvalue = m_maxvalue;
  750.              break;
  751.              
  752.         case SB_THUMBPOSITION:
  753.         case SB_THUMBTRACK:
  754.              m_currentvalue = (int)nPos;
  755.              break;
  756.         
  757.         default:
  758.              break;     
  759.     }
  760.     OValue val = (int)m_currentvalue;
  761.     Refresh(val);
  762.     Changed();
  763.   }  
  764. }
  765.  
  766. void OBoundSlider::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
  767. {
  768.   if (m_mode == OBOUND_READWRITE)
  769.   {
  770.     switch (nSBCode)
  771.     {
  772.         case SB_TOP:
  773.              m_currentvalue = m_minvalue;
  774.              break;
  775.              
  776. //      case SB_ENDSCROLL
  777.         case SB_PAGEUP:
  778.              m_currentvalue -= 9;
  779.         case SB_LINEUP:
  780.              m_currentvalue = max(m_minvalue, m_currentvalue - 1);
  781.              break;
  782.              
  783.         case SB_PAGEDOWN:
  784.              m_currentvalue += 9;
  785.         case SB_LINEDOWN:
  786.              m_currentvalue = min(m_maxvalue, m_currentvalue + 1);
  787.              break;
  788.              
  789.         case SB_BOTTOM:
  790.              m_currentvalue = m_maxvalue;
  791.              break;
  792.              
  793.         case SB_THUMBPOSITION:
  794.         case SB_THUMBTRACK:
  795.              m_currentvalue = (int)nPos;
  796.              break;
  797.         
  798.         default:
  799.              break;     
  800.     }
  801.     OValue val = (int)m_currentvalue;
  802.     Refresh(val);
  803.     Changed();
  804.   }  
  805. }
  806.  
  807.