⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ado数据库编程入门.htm

📁 VC程序员的 ADO数据库编程入门.htm
💻 HTM
📖 第 1 页 / 共 5 页
字号:
          struct _Connection *pConnection);<br>
          &nbsp;&nbsp;&nbsp;
          STDMETHODIMP raw_BeginTransComplete(
          LONG TransactionLevel,
          struct Error *pError,
          EventStatusEnum *adStatus,
          struct _Connection *pConnection);<br>
          &nbsp;&nbsp;&nbsp; ......<br>
          };</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          (2). 实现每一个事件的处理函数(凡是带raw_前缀的方法都把它实现了):<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          STDMETHODIMP CConnEvent::raw_InfoMessage(
          struct Error *pError,
          EventStatusEnum *adStatus,
          struct _Connection *pConnection)<br>
          {<br>
          &nbsp;&nbsp;&nbsp;
          *adStatus = adStatusUnwantedEvent;<br>
          &nbsp;&nbsp;&nbsp;
          return S_OK;<br>
          };</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          有些方法虽然你并不需要,但也必须实现它,只需简单地返回一个S_OK即可。但如果要避免经常被调用,还应在其中将adStatus参数设置为adStatusUnwantedEvent,则在本次调用后,以后就不会被调用了。<br>
          另外还必须实现QueryInterface, AddRef, 和Release三个方法:&nbsp;<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          STDMETHODIMP CConnEvent::QueryInterface(REFIID riid, void ** ppv)<br>
          {<br>
          &nbsp;&nbsp;&nbsp;
          *ppv = NULL;<br>
          &nbsp;&nbsp;&nbsp;
          if (riid == __uuidof(IUnknown) ||
          riid == __uuidof(ConnectionEventsVt))<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *ppv = this;<br>
          <br>
          &nbsp;&nbsp;&nbsp;
          if (*ppv == NULL)<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          return ResultFromScode(E_NOINTERFACE);<br>
          <br>
          &nbsp;&nbsp;&nbsp;
          AddRef();<br>
          &nbsp;&nbsp;&nbsp;
          return NOERROR;<br>
          }<br>
          <br>
          STDMETHODIMP_(ULONG) CConnEvent::AddRef() { return ++m_cRef; };<br>
          <br>
          STDMETHODIMP_(ULONG) CConnEvent::Release()<br>
          {<br>
          &nbsp;&nbsp;&nbsp;
          if (0 != --m_cRef)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return m_cRef;<br>
          <br>
          &nbsp;&nbsp;&nbsp;
          delete this;<br>
          &nbsp;&nbsp;&nbsp;
          return 0;<br>
          }</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          (3). 开始响应通知事件<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          // Start using the Connection events<br>
          IConnectionPointContainer *pCPC = NULL;<br>
          IConnectionPoint *pCP = NULL;<br>
          hr = pConn.CreateInstance(__uuidof(Connection));<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;<br>
          <br>
          hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer),
          (void **)&amp;pCPC);<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;<br>
          <br>
          hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<br>
          pCPC-&gt;Release();<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;<br>
          <br>
          pConnEvent = new CConnEvent();<br>
          hr = pConnEvent-&gt;QueryInterface(__uuidof(IUnknown), (void **) &amp;pUnk);<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return rc;<br>
          <br>
          hr = pCP-&gt;Advise(pUnk, &amp;dwConnEvt);<br>
          pCP-&gt;Release();<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;<br>
          <br>
          pConn-&gt;Open(&quot;dsn=Pubs;&quot;, &quot;sa&quot;, &quot;&quot;, adConnectUnspecified);</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          也就是说在连接(Open)之前就做这些事。<br>
          <br>
          (4). 停止响应通知事件<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          pConn-&gt;Close();<br>
          // Stop using the Connection events<br>
          hr = pConn-&gt;QueryInterface(__uuidof(IConnectionPointContainer),
          (void **) &amp;pCPC);<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;<br>
          <br>
          hr = pCPC-&gt;FindConnectionPoint(__uuidof(ConnectionEvents), &amp;pCP);<br>
          pCPC-&gt;Release();<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return rc;<br>
          <br>
          hr = pCP-&gt;Unadvise( dwConnEvt );<br>
          pCP-&gt;Release();<br>
          if (FAILED(hr))<br>
&nbsp;&nbsp;&nbsp; return;</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          在连接关闭之后做这件事。<br>
          <br>
          10、邦定数据<br>
          定义一个绑定类,将其成员变量绑定到一个指定的记录集,以方便于访问记录集的字段值。<br>
          <br>
          (1). 从CADORecordBinding派生出一个类:<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          class CCustomRs : public CADORecordBinding<br>
          {<br>
          &nbsp;&nbsp;&nbsp;
          BEGIN_ADO_BINDING(CCustomRs)<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_szau_fname,
          sizeof(m_szau_fname), lau_fnameStatus, false)<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
          ADO_VARIABLE_LENGTH_ENTRY2(2, adVarChar, m_szau_lname,
          sizeof(m_szau_lname), lau_lnameStatus, false)<br>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
          ADO_VARIABLE_LENGTH_ENTRY2(4, adVarChar, m_szphone,
          sizeof(m_szphone), lphoneStatus, true)<br>
          &nbsp;&nbsp;&nbsp;
          END_ADO_BINDING()<br>
          <br>
          public:<br>
          &nbsp;&nbsp;&nbsp;
          CHAR m_szau_fname[22];<br>
          &nbsp;&nbsp;&nbsp;
          ULONG lau_fnameStatus;<br>
          &nbsp;&nbsp;&nbsp;
          CHAR m_szau_lname[42];<br>
          &nbsp;&nbsp;&nbsp;
          ULONG lau_lnameStatus;<br>
          &nbsp;&nbsp;&nbsp;
          CHAR m_szphone[14];<br>
          &nbsp;&nbsp;&nbsp;
          ULONG lphoneStatus;<br>
          };</font><font face="Arial"><font face="Arial" size=2><br>
          <br>
          其中将要绑定的字段与变量名用BEGIN_ADO_BINDING宏关联起来。每个字段对应于两个变量,一个存放字段的值,另一个存放字段的状态。字段用从1开始的序号表示,如1,2,3等等。<br>
          特别要注意的是:如果要绑定的字段是字符串类型,则对应的字符数组的元素个数一定要比字段长度大2(比如m_szau_fname[22],其绑定的字段au_fname的长度实际是20),不这样绑定就会失败。我分析多出的2可能是为了存放字符串结尾的空字符null和BSTR字符串开头的一个字(表示BSTR的长度)。这个问题对于初学者来说可能是一个意想不到的问题。<br>
          CADORecordBinding类的定义在icrsint.h文件里,内容是:<br>
          <br>
          </font></font>
</font>

          <font face="宋体" size="2" color="#99CCFF">class CADORecordBinding<br>
          {<br>
          public:<br>
          &nbsp;&nbsp;&nbsp; STDMETHOD_(const ADO_BINDING_ENTRY*, GetADOBindingEntries) (VOID) 
          PURE;<br>
          };<br>
          <br>
          </font><font face="Arial" size="2">BEGIN_ADO_BINDING宏的定义也在icrsint.h文件里,内容是:</font><font face="宋体" size="2" color="#99CCFF"><br>
          <br>
          #define BEGIN_ADO_BINDING(cls) public: \<br>
          typedef cls ADORowClass; \<br>
          const ADO_BINDING_ENTRY* STDMETHODCALLTYPE GetADOBindingEntries() { \<br>
          static const ADO_BINDING_ENTRY rgADOBindingEntries[] = {<br>
          ADO_VARIABLE_LENGTH_ENTRY2宏的定义也在icrsint.h文件里:<br>
          #define ADO_VARIABLE_LENGTH_ENTRY2(Ordinal, DataType, Buffer, Size, 
          Status, Modify)\<br>
          &nbsp;{Ordinal, \<br>
          &nbsp;DataType, \<br>
          &nbsp;0, \<br>
          &nbsp;0, \<br>
          &nbsp;Size, \<br>
          &nbsp;offsetof(ADORowClass, Buffer), \<br>
          &nbsp;offsetof(ADORowClass, Status), \<br>
          &nbsp;0, \<br>
          &nbsp;classoffset(CADORecordBinding, ADORowClass), \<br>
          &nbsp;Modify},<br>
          &nbsp;#define END_ADO_BINDING宏的定义也在icrsint.h文件里:<br>
          &nbsp;#define END_ADO_BINDING() {0, adEmpty, 0, 0, 0, 0, 0, 0, 0, FALSE}};\<br>
          &nbsp;return rgADOBindingEntries;}</font><font face="Arial"><font face="Arial" size="2"><br>
          <br>
          (2). 绑定<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          _RecordsetPtr Rs1;<br>
          IADORecordBinding *picRs=NULL;<br>
          CCustomRs rs;<br>
          ......<br>
          Rs1-&gt;QueryInterface(__uuidof(IADORecordBinding),
          (LPVOID*)&amp;picRs));<br>
          picRs-&gt;BindToRecordset(&amp;rs);</font><font face="Arial"><font face="Arial" size="2"><br>
          <br>
          派生出的类必须通过IADORecordBinding接口才能绑定,调用它的BindToRecordset方法就行了。<br>
          <br>
          (3). rs中的变量即是当前记录字段的值<br>
          <br>
          </font>
</font>

<font face="宋体" size="2" color="#99CCFF">

          //Set sort and filter condition:<br>
          // Step 4: Manipulate the data<br>
          Rs1-&gt;Fields-&gt;GetItem(&quot;au_lname&quot;)-&gt;Properties-&gt;GetItem(&quot;Optimize&quot;)-&gt;Value 
          = true;<br>
          Rs1-&gt;Sort = &quot;au_lname ASC&quot;;<br>
          Rs1-&gt;Filter = &quot;phone LIKE '415 5*'&quot;;<br>
          Rs1-&gt;MoveFirst();<br>
          while (VARIANT_FALSE == Rs1-&gt;EndOfFile)<br>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -