home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1996 February / PCWK0296.iso / po7_win / object10 / oadvise.cpp < prev    next >
C/C++ Source or Header  |  1994-12-21  |  9KB  |  388 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.     online help for documentation of these classes.
  7. */
  8.  
  9. /*
  10.     Oracle Objects for OLE     C++ Classes
  11.     
  12.     This file implements the OAdvise class
  13.                            
  14.     CREATED    ********   11/22/94
  15.  
  16. */
  17.  
  18. #include "windows.h"
  19. #include <ole2.h>
  20. #include <olenls.h>       
  21. #include <dispatch.h>  
  22.  
  23. #ifndef ORACL_ORACLE
  24. #include "oracl.h"
  25. #endif
  26.  
  27. #ifndef _OracleInProcServer_H_
  28. #include <oratlb.h>
  29. #endif
  30.  
  31. static const IID IID_IOraAdvisorySink =
  32. {0xab598600, 0x0a9a, 0x101b, { 0xad, 0xf2, 0x04, 0x02, 0x1c, 0x00, 0x70, 0x02 } };
  33.  
  34. // ----- OOLEAdvise -----------------------------------------------
  35.  
  36. class OOLEAdvise : public IOraAdvisorySink
  37. public:
  38.     // construction & destruction
  39.     OOLEAdvise(OAdvise *parent = NULL);
  40.     ~OOLEAdvise(void);
  41.  
  42.     // IUnknown overrides
  43.     STDMETHODIMP         QueryInterface(REFIID, void **);
  44.     STDMETHODIMP_(ULONG) AddRef(void);
  45.     STDMETHODIMP_(ULONG) Release(void);
  46.     
  47.     // our entries
  48.     STDMETHODIMP         OnActionRequest(int action);
  49.     STDMETHODIMP         OnAction(int action);
  50.     STDMETHODIMP         OnStatusChange(int action);
  51.         
  52. private:
  53.     unsigned long  refcount;
  54.     OAdvise       *m_parent;
  55. };
  56.  
  57. // ----- OAdvise -----------------------------------------------
  58.  
  59. OAdvise::OAdvise(void)
  60. {
  61. }
  62.  
  63. OAdvise::OAdvise(const OAdvise &other)
  64. {
  65.     Copy(other);
  66. }
  67.  
  68. OAdvise::OAdvise(const ODynaset &dyn)
  69. {
  70.     OAdvise(); // default contructor
  71.     Open(dyn);
  72. }
  73.  
  74. OAdvise::~OAdvise(void)
  75. {
  76.     Cleanup();
  77. }
  78.  
  79. oresult OAdvise::Cleanup(void)
  80. {
  81.     if (IsOpen())
  82.     {
  83.         // disconnect from dynaset
  84.         m_oDyn.ErrorReset();
  85.         ((_IOraDynaset *) (m_oDyn.Internal()))->DUnadvise((OOLEAdvise *) Internal());
  86.         if (0 != m_oDyn.ErrorNumber())
  87.         { // error in unadvise
  88.             SetOtherError(m_oDyn.Internal());
  89.             return(OFAILURE);
  90.         }        
  91.     }
  92.     
  93.     // close the dynaset
  94.     m_oDyn.Close();
  95.     
  96.     return(OOracleObject::Cleanup());
  97. }
  98.  
  99. oresult OAdvise::Copy(const OAdvise &other)
  100. {
  101.     m_oDyn = other.m_oDyn;
  102.     
  103.     // we can't just copy the oipadv (and AddRef) here.  That wouldn't get the
  104.     //   callbacks to our object.  We've got to create a new OOLEAdvise.
  105.     
  106.     OOLEAdvise *tempadv = new OOLEAdvise(this);
  107.     if (!tempadv)
  108.     { // couldn't get memory?
  109.         SetInternalError(OERROR_MEMORY);
  110.         return(OFAILURE);
  111.     }
  112.     
  113.     if (SetObjectInterface((void *) tempadv, FALSE) != OSUCCESS)
  114.         return(OFAILURE);
  115.     
  116.     // tell dynaset about it
  117.     m_oDyn.ErrorReset();
  118.     ((_IOraDynaset *) (m_oDyn.Internal()))->DAdvise(tempadv);
  119.     if (0 != m_oDyn.ErrorNumber())
  120.     { // failure at dynaset
  121.         SetOtherError(m_oDyn.Internal());
  122.         return(OFAILURE);
  123.     }
  124.     
  125.     // everything worked
  126.     return(OSUCCESS);
  127. }
  128.  
  129. oresult OAdvise::Open(const ODynaset &odyn)
  130. {
  131.     if (!odyn.IsOpen())
  132.     {
  133.         SetInternalError(OERROR_INVPARENT); 
  134.         return(OFAILURE);
  135.     }
  136.     
  137.     // create new advisory object
  138.     OOLEAdvise *tempadv = new OOLEAdvise(this);
  139.     if (!tempadv)
  140.     { // couldn't get memory?
  141.         SetInternalError(OERROR_MEMORY);
  142.         return(OFAILURE);
  143.     }
  144.     SetObjectInterface((void *) tempadv, FALSE);
  145.     
  146.     // get a copy of dynaset we're connected to
  147.     m_oDyn = odyn;
  148.     
  149.     // tell dynaset about it
  150.     m_oDyn.ErrorReset();
  151.     ((_IOraDynaset *) (m_oDyn.Internal()))->DAdvise(tempadv);
  152.     if (0 != m_oDyn.ErrorNumber())
  153.     { // failure at dynaset
  154.         SetOtherError(m_oDyn.Internal());
  155.         return(OFAILURE);
  156.     }
  157.     
  158.     // everything worked
  159.     return(OSUCCESS);
  160. }
  161.  
  162. ODynaset OAdvise::GetDynaset(void) const
  163. {
  164.     ActionGetStart(&m_oDyn); // set errors (if needed)
  165.     
  166.     return(m_oDyn);
  167. }
  168.  
  169. oresult OAdvise::Close(void)
  170. {
  171.     return(Cleanup());
  172. }
  173.  
  174. // overloaded assignment operator
  175. OAdvise &OAdvise::operator=(const OAdvise &other)
  176. {
  177.     if (&other == this)
  178.         return(*this); // self assignment - do nothing
  179.     
  180.     // clear out our old state
  181.     if (OSUCCESS == Cleanup())
  182.     {
  183.         Copy(other); // call copy constructor
  184.     }
  185.     // if the cleanup failed (possible but unlikely) we don't do the copy
  186.     //    and as a result, we pass on the unmodified (or partly cleaned!) object
  187.     
  188.     return(*this);
  189.  
  190. oboolean OAdvise::ActionRequest(int movekind)
  191. {
  192.     return(TRUE);
  193. }
  194.  
  195. void OAdvise::ActionNotify(int movekind)
  196. {
  197.     return;
  198. }
  199.  
  200. void OAdvise::StatusChange(int statuskind)
  201. {
  202.     return;
  203. }
  204.  
  205. // messages that oipsrv hands us on advises
  206. #define OIPMSG_BOOKMARK         18
  207. #define OIPMSG_MOVEFIRST          64
  208. #define OIPMSG_MOVENEXT          65
  209. #define OIPMSG_MOVEPREV          66
  210. #define OIPMSG_MOVELAST          67
  211. #define OIPMSG_FINDFIRST          68
  212. #define OIPMSG_FINDNEXT          69
  213. #define OIPMSG_FINDPREV          70
  214. #define OIPMSG_FINDLAST          71
  215. #define OIPMSG_DELETE          72
  216. #define OIPMSG_ADDNEW          73
  217. #define OIPMSG_REFRESH          74
  218. #define OIPMSG_ROLLBACK          76
  219. #define OIPMSG_CLOSE          77
  220. #define OIPMSG_DATAFIELDCHANGED 78
  221. #define OIPMSG_SAVEDATA          79
  222. #define OIPMSG_READDATA          80
  223. #define OIPMSG_UPDATE          81
  224. #define OIPMSG_UNLOAD          82
  225.  
  226. // ----- OOLEAdvise -----------------------------------------------
  227.  
  228. OOLEAdvise::OOLEAdvise(OAdvise *parent) 
  229.     refcount = 1;
  230.     m_parent = parent;
  231.  
  232.  
  233. OOLEAdvise::~OOLEAdvise() 
  234.  
  235. STDMETHODIMP_(ULONG) 
  236. OOLEAdvise::AddRef() 
  237.     return ++refcount; 
  238.  
  239. STDMETHODIMP_(ULONG) 
  240. OOLEAdvise::Release() 
  241.     if (--refcount == 0) 
  242.       { 
  243.         delete this; 
  244.         return 0; 
  245.       } 
  246.  
  247.     return refcount; 
  248.  
  249. STDMETHODIMP 
  250. OOLEAdvise::QueryInterface(REFIID iid, void **ppv) 
  251. {
  252.     if (!IsEqualGUID(iid, IID_IUnknown) && !IsEqualGUID(iid, IID_IOraAdvisorySink)) 
  253.         return ResultFromScode(E_NOINTERFACE);  // unsupported interface
  254.     
  255.     // caller is asking for us
  256.     *ppv = this; 
  257.     AddRef(); 
  258.  
  259.     return NOERROR; 
  260.  
  261. STDMETHODIMP 
  262. OOLEAdvise::OnActionRequest(int action) 
  263. {
  264.     oboolean result;
  265.     int message;  // message we pass
  266.     
  267.     if (!m_parent)
  268.         return(ResultFromScode(S_OK));  // we aren't been bound, so OK request
  269.     
  270.     // translate action
  271.     switch(action)
  272.     {
  273.     case OIPMSG_MOVEFIRST:
  274.         message = OADVISE_MOVE_FIRST;
  275.         break;
  276.     case OIPMSG_MOVEPREV:
  277.          message = OADVISE_MOVE_PREV;
  278.         break;
  279.     case OIPMSG_MOVENEXT:
  280.         message = OADVISE_MOVE_NEXT;
  281.         break;
  282.     case OIPMSG_MOVELAST:
  283.         message = OADVISE_MOVE_LAST;
  284.         break;
  285.     case OIPMSG_BOOKMARK:
  286.         message = OADVISE_MOVE_TOMARK;
  287.         break; 
  288.     case OIPMSG_DELETE:
  289.         message = OADVISE_DELETE;
  290.         break;
  291.     case OIPMSG_ADDNEW:
  292.         message = OADVISE_ADDNEW;
  293.         break;
  294.     case OIPMSG_UPDATE:
  295.         message = OADVISE_UPDATE;
  296.         break;
  297.     case OIPMSG_REFRESH:
  298.         message = OADVISE_REFRESH;
  299.         break;
  300.     case OIPMSG_ROLLBACK:
  301.         message = OADVISE_ROLLBACK;
  302.         break;
  303.     default:
  304.         message = OADVISE_OTHER;
  305.         break;
  306.     }
  307.     
  308.     result = m_parent->ActionRequest(message);
  309.     
  310.     return(result ? ResultFromScode(S_OK) : ResultFromScode(S_FALSE));
  311.  
  312. STDMETHODIMP 
  313. OOLEAdvise::OnAction(int action) 
  314. {
  315.     int message;  // message we pass
  316.     
  317.     if (!m_parent)
  318.         return(ResultFromScode(S_OK));  // we aren't been bound, so OK request
  319.     
  320.     switch(action)
  321.     {
  322.     case OIPMSG_MOVEFIRST:
  323.         message = OADVISE_MOVE_FIRST;
  324.         break;
  325.     case OIPMSG_MOVEPREV:
  326.         message = OADVISE_MOVE_PREV;
  327.         break;
  328.     case OIPMSG_MOVENEXT:
  329.         message = OADVISE_MOVE_NEXT;
  330.         break;
  331.     case OIPMSG_MOVELAST:
  332.         message = OADVISE_MOVE_LAST;
  333.         break;
  334.     case OIPMSG_BOOKMARK:
  335.         message = OADVISE_MOVE_TOMARK;
  336.         break; 
  337.     case OIPMSG_DELETE:
  338.         message = OADVISE_DELETE;
  339.         break;
  340.     case OIPMSG_ADDNEW:
  341.         message = OADVISE_ADDNEW;
  342.         break;
  343.     case OIPMSG_UPDATE:
  344.         message = OADVISE_UPDATE;
  345.         break;
  346.     case OIPMSG_REFRESH:
  347.         message = OADVISE_REFRESH;
  348.         break;
  349.     case OIPMSG_ROLLBACK:
  350.         message = OADVISE_ROLLBACK;
  351.         break;
  352.     default:
  353.         message = OADVISE_OTHER;
  354.         break;
  355.     }
  356.     
  357.     m_parent->ActionNotify(message);
  358.     
  359.     
  360.     return(ResultFromScode(S_OK));
  361.  
  362.  
  363. /* DCAdvisory::OnStatusChange ------------------------------------------ 
  364.  
  365.    Informs the advisory objects of a variety of status changes. 
  366. --------------------------------------------------------------------- */ 
  367.  
  368. STDMETHODIMP
  369. OOLEAdvise::OnStatusChange(int statCode) 
  370. {
  371.     if (statCode == 1) // DCSTAT_LASTKNOWN is 1, so far as I can tell
  372.         m_parent->StatusChange(OADVISE_FOUNDLAST);
  373.     return NOERROR; 
  374.