ADO 데이타 바인딩 다이얼로그 얻기
조경민 오전 10:24 2001-12-24 bro@shinbiro.com
==========================================================

VC++에서 ADO를 이용해서 데이타베이스 간단한 레코드 폼을
얻고 싶을떄 다음처럼 하면 기본적인 코드가 자동으로 완성된다.

Project / Add to Project 한 후 Components and Controls에서

Visual C++ Components 안에 ADO Data Bound Dialog를 선택한다.

원하는 DB 연결을 바인드 위자드에서 선택하면

CRsCgDlg 라는 클래스가 생긴다. 바로 DoModal 시키면 레코드 폼이 나온다.

데이타필드가 에디트컨트롤로 자동으로 부여되고, 데이타 네비게이터 버튼도

있다.



다음은 RsCgDlg를 쓴 간단한 예제이다.
(추가/삭제/수정 및 네비게이션, 검색에 대한 코드를 넣었다. 쓸때 참고하면
좋겠다. )
-------------------------------------------------------------------------

// RsCgDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Common.h"
#include "RsCgDlg.h"
#include "VirusRecordDlg.h"
#include "DBLogic.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CRsCgDlg dialog
#define WM_SEARCH                                (WM_USER+100)

CRsCgDlg::CRsCgDlg(CWnd* pParent /*=NULL*/)
        : CDialog(CRsCgDlg::IDD, pParent)
{
        
        m_strConnection.Format("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s\\scanx.mdb;Persist Security Info=False",
                fnBroGetDir());
        m_strCmdText = _T("VIRUS");

        m_pRs = NULL;
        
        //{{AFX_DATA_INIT(CRsCgDlg)
        m_lDlgiD = 0;
        m_strDlgNAME = _T("");
        m_strDlgFNAME = _T("");
        m_lDlgSIZE = 0;
        //m_strDlgBIN = _T("");
        m_strDlgINFO = _T("");
        m_strDlgTREAT = _T("");
        m_nRec = 0;
        m_nTotRec = 0;
        //}}AFX_DATA_INIT
}

CRsCgDlg::~CRsCgDlg()
{
        m_pRs = NULL;
}

BOOL CRsCgDlg::OnInitDialog()
{
        CDialog::OnInitDialog();

        // 기본으로 전체를 얻어온다.
        Open( m_strCmdText );

        return TRUE;
}

void CRsCgDlg::RefreshBoundData()
{
        if (adFldOK == liDStatus)
                m_lDlgiD = m_liD;
        else
                m_lDlgiD = 0;
        if (adFldOK == lNAMEStatus)
                m_strDlgNAME = m_wszNAME;
        else
                m_strDlgNAME = _T("");
        if (adFldOK == lFNAMEStatus)
                m_strDlgFNAME = m_wszFNAME;
        else
                m_strDlgFNAME = _T("");
        if (adFldOK == lSIZEStatus)
                m_lDlgSIZE = m_lSIZE;
        else
                m_lDlgSIZE = 0;
        //if (adFldOK == lBINStatus)
        //        m_strDlgBIN = m_wszBIN[0];
        //else
        //        m_strDlgBIN = _T("");
        if (adFldOK == lINFOStatus)
                m_strDlgINFO = m_wszINFO;
        else
                m_strDlgINFO = _T("");
        if (adFldOK == lTREATStatus)
        {
                switch( m_wszTREAT[0] )
                {
                case SCANX_TREAT_IGNORE :
                        m_strDlgTREAT = _T("무시/로그");
                        break;
                case SCANX_TREAT_ALERT :
                        m_strDlgTREAT = _T("알림/선택");
                        break;
                case SCANX_TREAT_TERMINATE :
                        m_strDlgTREAT = _T("강제종료");
                        break;
                case SCANX_TREAT_DELETE :
                        m_strDlgTREAT = _T("종료/삭제");
                        break;
                }
                //m_strDlgTREAT = m_wszTREAT;
        }
        else
                m_strDlgTREAT = _T("");

        UpdateData(FALSE);
}

void CRsCgDlg::GenerateError(HRESULT hr, PWSTR pwszDescription)
{
        CString strError;

        strError.Format("Run-time error '%d (%x)'", hr, hr);
        strError += "\n\n";
        strError += pwszDescription;

        AfxMessageBox(strError);
}

void CRsCgDlg::DoDataExchange(CDataExchange* pDX)
{
        CDialog::DoDataExchange(pDX);
        //{{AFX_DATA_MAP(CRsCgDlg)
        DDX_Control(pDX, IDC_EDIT_SEARCH_NAME, m_edtSearchName);
        DDX_Text(pDX, IDC_NAME, m_strDlgNAME);
        DDX_Text(pDX, IDC_FNAME, m_strDlgFNAME);
        DDX_Text(pDX, IDC_FSIZE, m_lDlgSIZE);
        //DDX_Text(pDX, IDC_BIN, m_strDlgBIN);
        DDX_Text(pDX, IDC_INFO, m_strDlgINFO);
        DDX_Text(pDX, IDC_TREAT, m_strDlgTREAT);
        DDX_Text(pDX, IDC_STATIC_REC, m_nRec);
        DDX_Text(pDX, IDC_STATIC_TOTREC, m_nTotRec);
        //}}AFX_DATA_MAP

}


BEGIN_MESSAGE_MAP(CRsCgDlg, CDialog)
        //{{AFX_MSG_MAP(CRsCgDlg)
        ON_BN_CLICKED(IDC_MOVEFIRST, OnMovefirst)
        ON_BN_CLICKED(IDC_MOVELAST, OnMovelast)
        ON_BN_CLICKED(IDC_MOVENEXT, OnMovenext)
        ON_BN_CLICKED(IDC_MOVEPREV, OnMoveprev)
        ON_BN_CLICKED(IDC_SEARCHNAME, OnSearchname)
        ON_BN_CLICKED(IDC_ADD, OnAdd)
        ON_BN_CLICKED(IDC_CLOSE, OnClose)
        ON_BN_CLICKED(IDC_DEL, OnDel)
        ON_BN_CLICKED(IDC_EDIT, OnEdit)
        //}}AFX_MSG_MAP
        ON_MESSAGE( WM_SEARCH, OnSearch )
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRsCgDlg message handlers

void CRsCgDlg::OnMovefirst()
{
        try
        {
                // 처음으로 돌아간다.
                m_pRs->MoveFirst();
                m_nRec = 1;
                // 화면갱신
                RefreshBoundData();

                // 네비게이터 버튼 활성화 조정
                GetDlgItem(IDC_MOVEFIRST)->EnableWindow(FALSE);
                GetDlgItem(IDC_MOVEPREV)->EnableWindow(FALSE);

                GetDlgItem(IDC_MOVELAST)->EnableWindow(TRUE);
                GetDlgItem(IDC_MOVENEXT)->EnableWindow(TRUE);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }
}

void CRsCgDlg::OnMovelast()
{
        try
        {
                m_pRs->MoveLast();
                m_nRec = m_nTotRec;
                // 화면갱신
                RefreshBoundData();

                // 네비게이터 버튼 활성화 조정
                GetDlgItem(IDC_MOVELAST)->EnableWindow(FALSE);
                GetDlgItem(IDC_MOVENEXT)->EnableWindow(FALSE);

                GetDlgItem(IDC_MOVEFIRST)->EnableWindow(TRUE);
                GetDlgItem(IDC_MOVEPREV)->EnableWindow(TRUE);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }
}

void CRsCgDlg::OnMovenext()
{
        try
        {
                m_pRs->MoveNext();
                m_nRec++;
                // 화면갱신
                RefreshBoundData();

                // 네비게이터 버튼 활성화 조정
                m_pRs->MoveNext();
                if( m_pRs->EndOfFile )
                {
                        GetDlgItem(IDC_MOVELAST)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVENEXT)->EnableWindow(FALSE);
                }
                m_pRs->MovePrevious();

                GetDlgItem(IDC_MOVEFIRST)->EnableWindow(TRUE);
                GetDlgItem(IDC_MOVEPREV)->EnableWindow(TRUE);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }
}

void CRsCgDlg::OnMoveprev()
{
        try
        {
                m_pRs->MovePrevious();
                m_nRec--;
                // 화면갱신
                RefreshBoundData();

                // 네비게이터 버튼 활성화 조정
                m_pRs->MovePrevious();
                if( m_pRs->BOF )
                {
                        GetDlgItem(IDC_MOVEFIRST)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVEPREV)->EnableWindow(FALSE);
                }
                m_pRs->MoveNext();

                GetDlgItem(IDC_MOVELAST)->EnableWindow(TRUE);
                GetDlgItem(IDC_MOVENEXT)->EnableWindow(TRUE);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }
}

void CRsCgDlg::Open( LPCTSTR lpszSQL )
{
        HRESULT hr = NOERROR;
        IADORecordBinding *piAdoRecordBinding = NULL;

        try
        {
                m_nRec = 0;
                m_pRs = NULL;
                m_pRs.CreateInstance(__uuidof(Recordset));

                m_pRs->CursorLocation = adUseClient;
                m_pRs->Open((LPCTSTR)lpszSQL, (LPCTSTR)m_strConnection, adOpenStatic,
                        adLockBatchOptimistic, adCmdTableDirect);

                if (FAILED(hr = m_pRs->QueryInterface(__uuidof(IADORecordBinding), (LPVOID *)&piAdoRecordBinding)))
                        _com_issue_error(hr);
                if (FAILED(hr = piAdoRecordBinding->BindToRecordset(this)))
                        _com_issue_error(hr);

                if( m_pRs->EndOfFile && m_pRs->BOF)
                {
                        m_nTotRec = 0;
                }
                else
                {
                        m_pRs->MoveLast();
                        m_pRs->MoveFirst();
                        m_nTotRec = m_pRs->GetRecordCount();
                        m_nRec = 1;
                }

                // 추가 삭제 수정 버튼 Enable 할것인지 결정
                BOOL bEnableOpt = TRUE;
                if( m_nTotRec == 0 )
                {
                        bEnableOpt = FALSE;
                        m_strDlgNAME = _T("");
                        m_strDlgFNAME = _T("");
                        m_lDlgSIZE = 0;
                        m_strDlgINFO = _T("");
                        m_strDlgTREAT = _T("");
                }

                GetDlgItem(IDC_ADD)->EnableWindow(bEnableOpt);
                GetDlgItem(IDC_DEL)->EnableWindow(bEnableOpt);
                GetDlgItem(IDC_EDIT)->EnableWindow(bEnableOpt);


                if( m_nTotRec < 2)
                {
                        // 레코드가 없거나 하나다
                        GetDlgItem(IDC_MOVEFIRST)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVEPREV)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVENEXT)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVELAST)->EnableWindow(FALSE);
                }
                else
                {
                        // 레코드가 있다.
                        GetDlgItem(IDC_MOVEFIRST)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVEPREV)->EnableWindow(FALSE);
                        GetDlgItem(IDC_MOVENEXT)->EnableWindow(TRUE);
                        GetDlgItem(IDC_MOVELAST)->EnableWindow(TRUE);
                }

                if( m_nTotRec != 0 )
                        RefreshBoundData();
                else
                        UpdateData(FALSE);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }

        if (piAdoRecordBinding)
                piAdoRecordBinding->Release();        
}

LRESULT CRsCgDlg::OnSearch( WPARAM wparam, LPARAM lparam )
{
        CString sSearchName;
        m_edtSearchName.GetWindowText(sSearchName);
        CString sSQL;
        // 원하는 SQL문을 만들어낸다.
        sSQL.Format("SELECT * FROM VIRUS WHERE NAME like '%s", sSearchName );
        sSQL+="%'";
        
        Open(sSQL);

        CString sMsg;
        sMsg.Format("총 %lu개의 레코드가 검색되었습니다.", m_nTotRec );
        MessageBox( sMsg, "검색 완료" );
        return 1;
}

BOOL CRsCgDlg::PreTranslateMessage(MSG* pMsg)
{
        // TODO: Add your specialized code here and/or call the base class
        if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
        {
                if( GetFocus() == &m_edtSearchName )
                        PostMessage( WM_SEARCH );
        }
        return CDialog::PreTranslateMessage(pMsg);
}


void CRsCgDlg::OnSearchname()
{
        // TODO: Add your control notification handler code here
        PostMessage( WM_SEARCH );
}

void CRsCgDlg::OnAdd()
{
        // TODO: Add your control notification handler code here
        CVirusRecordDlg dlg;
        // 추가창 모드로 연다.
        dlg.m_nMode = MODE_INSERT;
        if( dlg.DoModal() == IDOK )
        {
                CString sBin,sFName;
                if( !CDBLogic::GetBin( dlg.m_sFilePath , &sBin) )
                        return;
                try
                {
                        m_pRs->AddNew();
                        m_pRs->Fields->GetItem("NAME")->put_Value( _variant_t(dlg.m_sName) );
                        m_pRs->Fields->GetItem("FNAME")->put_Value( _variant_t(dlg.m_sFileName) );
                        m_pRs->Fields->GetItem("SIZE")->put_Value( _variant_t(dlg.m_sSize) );
                        m_pRs->Fields->GetItem("BIN")->put_Value( _variant_t(sBin) );
                        m_pRs->Fields->GetItem("INFO")->put_Value( _variant_t(dlg.m_sInfo) );
                        m_pRs->Fields->GetItem("TREAT")->put_Value( _variant_t(CString(dlg.m_sTreat[0])) );

                        m_pRs->Update();
                        //m_pRs->Requery(adCmdTable);
                        m_pRs->UpdateBatch(adAffectCurrent);
                        //RefreshBoundData();        
                }
                catch (_com_error &e)
                {
                        GenerateError(e.Error(), e.Description());
                }                

                Open( _T("VIRUS"));
        }
}

void CRsCgDlg::OnClose()
{
        // TODO: Add your control notification handler code here
        EndDialog(IDOK);
}

void CRsCgDlg::OnDel()
{
        // TODO: Add your control notification handler code here
        try
        {
                m_pRs->Delete(adAffectCurrent);
                m_pRs->UpdateBatch(adAffectCurrent);
        }
        catch (_com_error &e)
        {
                GenerateError(e.Error(), e.Description());
        }                

        //RefreshBoundData();        
        Open( _T("VIRUS"));
}

void CRsCgDlg::OnEdit()
{
        // TODO: Add your control notification handler code here
        CVirusRecordDlg dlg;
        // 추가창 모드로 연다.
        dlg.m_nMode = MODE_EDIT;
        dlg.m_sName = (LPCTSTR)(_bstr_t)(_variant_t)(m_pRs->Fields->GetItem("NAME")->Value);
        dlg.m_sInfo = (LPCTSTR)(_bstr_t)(_variant_t)(m_pRs->Fields->GetItem("INFO")->Value);
        dlg.m_sSize = (LPCTSTR)(_bstr_t)(_variant_t)(m_pRs->Fields->GetItem("SIZE")->Value);
        dlg.m_sTreatOnEdit = (LPCTSTR)(_bstr_t)(_variant_t)(m_pRs->Fields->GetItem("TREAT")->Value);
        dlg.m_sFileName = (LPCTSTR)(_bstr_t)(_variant_t)(m_pRs->Fields->GetItem("FNAME")->Value);
        
        if( dlg.DoModal() == IDOK )
        {
                CString sBin;
                if( dlg.m_bPathSelected )
                {
                        if( !CDBLogic::GetBin( dlg.m_sFilePath , &sBin) )
                                return;
                }

                try
                {
                        m_pRs->Fields->GetItem("NAME")->put_Value( _variant_t(dlg.m_sName) );
                        m_pRs->Fields->GetItem("INFO")->put_Value( _variant_t(dlg.m_sInfo) );
                        m_pRs->Fields->GetItem("TREAT")->put_Value( _variant_t(CString(dlg.m_sTreat[0])) );

                        if( !sBin.IsEmpty() )
                        {
                                m_pRs->Fields->GetItem("FNAME")->put_Value( _variant_t(dlg.m_sFileName) );
                                m_pRs->Fields->GetItem("SIZE")->put_Value( _variant_t(dlg.m_sSize) );                         
                                m_pRs->Fields->GetItem("BIN")->put_Value( _variant_t(sBin) );
                        }

                        m_pRs->Update();
                        //m_pRs->Requery(adCmdTable);
                        m_pRs->UpdateBatch(adAffectCurrent);
                        //RefreshBoundData();        
                }
                catch (_com_error &e)
                {
                        GenerateError(e.Error(), e.Description());
                }                
        
                Open( _T("VIRUS"));
        }
}

'KB > MFC/Win32' 카테고리의 다른 글

ISAPI필터dll Attach to Process로 디버깅하기  (0) 2004.03.19
ADO 성능 높이기  (0) 2004.03.19
ime이용 한영키 전환  (0) 2004.03.19
수동 언인스톨  (0) 2004.03.19
파일 패스 매크로  (0) 2004.03.19

+ Recent posts