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

📄 vcg15.htm

📁 Visual C++与数据库的连接经典实例
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<B>           TRACE(&quot;Move(nStepBack) failed Ret = %d Error '%s', cause '%s'\n&quot;,</B>

<B>               e-&gt;m_nRetCode,</B>

<B>            (const char *)e-&gt;m_strError,</B>

<B>               (const char *)e-&gt;m_strStateNativeOrigin);</B>

<B>    }</B>

<B>    END_CATCH</B>

<B>// Once the specified move has been made, we simply update</B>

<B>// the view's display of the record (for the user) and return</B>

<B>    // Show results of move operation</B>

<B>    UpdateData(FALSE);</B>

<B>    return(TRUE);</B>

<B>}</B></FONT></PRE>

<BR>

<A NAME="E70E76"></A>

<H5 ALIGN=CENTER>

<CENTER>

<FONT SIZE=4 COLOR="#FF0000"><B>Adding Update Capability</B></FONT></CENTER></H5>

<BR>

<P>The code in Listings 15.1, 15.2, and 15.3 not only displays data but also updates any records the user has modified. The code in Listing 15.4 shows the process of updating.

<BR>

<P>This process is straightforward: Move to the correct record (the record that is to be updated), get the &quot;new&quot; values for the record, put the new values in the recordset's column variables, and update the record. In the sample program, this is accomplished 10 times (because 10 records can be displayed at once). This lets the user update 10 records at a time, eliminating the inconvenience of being able to edit only the current record.

<BR>

<P>

<FONT COLOR="#000080"><B>Listing 15.4. The update code.</B></FONT>

<BR>

<PRE>

<FONT COLOR="#000080"><B>if (m_pSet-&gt;CanUpdate())</B>

<B>    {</B>

<B>        if (!UpdateData())</B>

<B>            return TRUE;</B>

<B>        nStepBack = 0;</B>

<B>        for (i = 0; i &lt; 10; i++)</B>

<B>        {// Save the current record and then get next one!</B>

<B>            m_pSet-&gt;Edit();</B>

<B>            m_pSet-&gt;m_English_Name = m_EnglishName[i];</B>

<B>            m_pSet-&gt;m_Product_Name = m_ProductName[i];</B>

<B>            m_pSet-&gt;m_Unit_Price = m_UnitPrice[i];</B>

<B>            m_pSet-&gt;m_Units_In_Stock = m_UnitsInStock[i];</B>

<B>            m_pSet-&gt;m_Units_On_Order = m_UnitsOnOrder[i];</B>

<B>            m_pSet-&gt;Update();</B>

<B>            if (!m_pSet-&gt;IsEOF())</B>

<B>            {</B>

<B>                TRY</B>

<B>                {// Use old-style exceptions for Visual C++ 1.5x</B>

<B>                    m_pSet-&gt;MoveNext();</B>

<B>                    --nStepBack;</B>

<B>                }</B>

<B>                CATCH(CDBException, e)</B>

<B>                {// Died. Should use message box to user!</B>

<B>                       TRACE(&quot;MoveNext() fail Ret = %d Error '%s', cause '%s'\n&quot;,</B>

<B>                           e-&gt;m_nRetCode,</B>

<B>                           (const char *)e-&gt;m_strError,</B>

<B>                           (const char *)e-&gt;m_strStateNativeOrigin);</B>

<B>                }</B>

<B>                END_CATCH</B>

<B>            }</B>

<B>            else</B>

<B>            {</B>

<B>                break;</B>

<B>            }</B>

<B>        }</B>

<B>//        Restore the record pointer! Take nStepBack giant steps back!</B>

<B>        TRY</B>

<B>        {// Use old-style exceptions for Visual C++ 1.5x</B>

<B>            m_pSet-&gt;Move(nStepBack);  // Back to original record...</B>

<B>        }</B>

<B>        CATCH(CDBException, e)</B>

<B>        {// Died. Should use message box to user!</B>

<B>               TRACE(&quot;Move(nStepBack) failed Ret = %d Error '%s', cause '%s'\n&quot;,</B>

<B>                   e-&gt;m_nRetCode,</B>

<B>                   (const char *)e-&gt;m_strError,</B>

<B>                   (const char *)e-&gt;m_strStateNativeOrigin);</B>

<B>        }</B>

<B>        END_CATCH</B>

<B>    }</B></FONT></PRE>

<BLOCKQUOTE>

<BLOCKQUOTE>

<HR ALIGN=CENTER>

<BR>

<NOTE><B>NOTE</B>

<BR>

<BR>You can add code to the OnMove() handler that tests the validity of the updates you make to any of the fields before the changes are processed.</NOTE>

<BR>

<HR ALIGN=CENTER>

</BLOCKQUOTE></BLOCKQUOTE>

<BR>

<A NAME="E70E77"></A>

<H5 ALIGN=CENTER>

<CENTER>

<FONT SIZE=4 COLOR="#FF0000"><B>Using an OLE Grid Control</B></FONT></CENTER></H5>

<BR>

<P>The OLE Grid control sample program (called Contin using Grid Control) is simpler than the example just shown. The OLE Grid control sample program doesn't implement user editing of database data, but you can easily add this functionality, as shown in Listing 15.5. This listing shows the view class, which is the only modification needed to implement this program. As with other listings, the lines in bold provide the increased functionality.

<BR>

<P>

<FONT COLOR="#000080"><B>Listing 15.5. Contin using Grid ControlView.cpp.</B></FONT>

<BR>

<PRE>

<FONT COLOR="#000080">// Contin using Grid ControlView.cpp : implementation of the

//                         CContinusingGridControlView class

//

#include &quot;stdafx.h&quot;

#include &quot;Contin using Grid Control.h&quot;

#include &quot;Contin using Grid ControlSet.h&quot;

#include &quot;Contin using Grid ControlDoc.h&quot;

#include &quot;Contin using Grid ControlView.h&quot;

#include &quot;gridctrl.h&quot;

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

/////////////////////////////////////////////////////////////////////////////

// CContinusingGridControlView

IMPLEMENT_DYNCREATE(CContinusingGridControlView, CRecordView)

BEGIN_MESSAGE_MAP(CContinusingGridControlView, CRecordView)

    //{{AFX_MSG_MAP(CContinusingGridControlView)

    ON_WM_DESTROY()

    //}}AFX_MSG_MAP

    // Standard printing commands

    ON_COMMAND(ID_FILE_PRINT, CRecordView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_DIRECT, CRecordView::OnFilePrint)

    ON_COMMAND(ID_FILE_PRINT_PREVIEW, CRecordView::OnFilePrintPreview)

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CContinusingGridControlView construction/destruction

CContinusingGridControlView::CContinusingGridControlView()

    : CRecordView(CContinusingGridControlView::IDD)

{

    //{{AFX_DATA_INIT(CContinusingGridControlView)

        // NOTE: the ClassWizard will add member initialization here

    m_pSet = NULL;

    //}}AFX_DATA_INIT

    // TODO: add construction code here

}

CContinusingGridControlView::~CContinusingGridControlView()

{

}

void CContinusingGridControlView::DoDataExchange(CDataExchange* pDX)

{

    static bFirstTime = TRUE;

    CRecordView::DoDataExchange(pDX);

    //{{AFX_DATA_MAP(CContinusingGridControlView)

    DDX_Control(pDX, IDC_GRID1, m_GridControl);

    //}}AFX_DATA_MAP

<B>    int Column = 0;</B>

<B>    int Row = 0;</B>

<B>    CString    Formatted;</B>

<B>    VARIANT    item;</B>

<B>    // Go to and get first record</B>

<B>    m_pSet-&gt;MoveFirst();</B>

<B>    while (!m_pSet-&gt;IsEOF())</B>

<B>    {// First, process the current record</B>

<B>        item.lVal = ++Row;</B>

<B>        m_GridControl.SetRow(Row);</B>

<B>        m_GridControl.SetSelStartRow(Row);</B>

<B>        m_GridControl.SetSelEndRow(Row);</B>

<B>        // The grid control allows filling multiple columns in a</B>

<B>        // record by separating each column with a tab. You can</B>

<B>        // also fill multiple rows by separating each row with a</B>

<B>        // CR (\x0D) (do not use a \n, however).</B>

<B>        Formatted.Format(_T(&quot; \t%s\t%s\t%s\t%d\t%d&quot;),</B>

<B>            m_pSet-&gt;m_Product_Name,</B>

<B>            m_pSet-&gt;m_English_Name,</B>

<B>            m_pSet-&gt;m_Unit_Price,</B>

<B>            m_pSet-&gt;m_Units_In_Stock,</B>

<B>            m_pSet-&gt;m_Units_On_Order);</B>

<B>        m_GridControl.AddItem(Formatted, item);</B>

<B>        m_pSet-&gt;MoveNext();</B>

<B>    }</B>

<B>    // Swap first and last entry to create a fixed first (title) row:</B>

<B>    for (Column = 0; Column &lt;= 5; Column++)</B>

<B>    {// Do each column in the first and last rows:</B>

<B>        m_GridControl.SetRow(0);</B>

<B>        m_GridControl.SetCol(Column);</B>

<B>        Formatted = m_GridControl.GetText();</B>

<B>        m_GridControl.SetRow(Row);</B>

<B>        m_GridControl.SetText(Formatted);</B>

<B>    }</B>

<B>    // Set title row's text:</B>

<B>    m_GridControl.SetRow(0);</B>

<B>    m_GridControl.SetCol(0);</B>

<B>    m_GridControl.SetText(_T(&quot;&quot;));</B>

<B>    m_GridControl.SetCol(1);</B>

<B>    m_GridControl.SetText(_T(&quot;Product&quot;));</B>

<B>    m_GridControl.SetCol(2);</B>

<B>    m_GridControl.SetText(_T(&quot;Name&quot;));</B>

<B>    m_GridControl.SetCol(3);</B>

<B>    m_GridControl.SetText(_T(&quot;Price&quot;));</B>

<B>    m_GridControl.SetCol(4);</B>

<B>    m_GridControl.SetText(_T(&quot;Quantity in Stock&quot;));</B>

<B>    m_GridControl.SetCol(5);</B>

<B>    m_GridControl.SetText(_T(&quot;Quantity on Order&quot;));</B>

<B>    // And fix the first row as a title row.</B>

<B>    m_GridControl.SetFixedRows(1);</B>

<B>    if (bFirstTime)</B>

<B>    {// Set column widths the first time only. Do not reset on redraw!</B>

<B>        bFirstTime = FALSE;</B>

<B>        // Our default widths are just guesses based on</B>

<B>        // the title's width. For the first two columns, the</B>

<B>        // data is really wide, and the titles are narrow, so</B>

<B>        // we add a bit more for a better view.</B>

<B>        m_GridControl.SetColWidth(0,</B>

<B>            AfxGetApp()-&gt;GetProfileInt(_T(&quot;GridStuff&quot;), _T(&quot;ColWidth1&quot;),</B>

<B>                50));</B>

<B>        m_GridControl.SetColWidth(1,</B>

<B>            AfxGetApp()-&gt;GetProfileInt(_T(&quot;GridStuff&quot;), _T(&quot;ColWidth2&quot;),</B>

<B>                strlen(_T(&quot;Product&quot;)) * 100 + 1000));</B>

<B>        m_GridControl

⌨️ 快捷键说明

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