home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tricks of the Windows Gam…ming Gurus (2nd Edition)
/
Disc2.iso
/
msdn_vcb
/
samples
/
vc98
/
mfc
/
database
/
daoctl
/
daocndlg.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1998-03-26
|
13KB
|
540 lines
// DAOCnDlg.cpp : implementation file
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "DAOCont.h"
#include "DAOCnDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
// variant handling
#ifndef _UNICODE
#define V_BSTRT(b) (LPSTR)V_BSTR(b)
#else
#define V_BSTRT(b) V_BSTR(b)
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDAOContDlg dialog
CDAOContDlg::CDAOContDlg(CWnd* pParent /*=NULL*/)
: CDialog(CDAOContDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CDAOContDlg)
m_bAllowEdits = FALSE;
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pDB = NULL;
m_pRS = NULL;
m_bAllowEdits = TRUE;
}
CDAOContDlg::~CDAOContDlg()
{
if (m_pRS)
if (m_pRS->IsOpen())
m_pRS->Close();
delete m_pRS;
if (m_pDB)
if (m_pDB->IsOpen())
m_pDB->Close();
delete m_pDB;
}
void CDAOContDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CDAOContDlg)
DDX_Control(pDX, IDC_RECNUM, m_ctlRecNum);
DDX_Control(pDX, IDC_SPIN1, m_ctlSpin);
DDX_Control(pDX, IDC_TREE1, m_ctlTree);
DDX_Control(pDX, IDC_ACCESSPICTCTRL1, m_ctlPicture);
DDX_Check(pDX, IDC_ALLOW_EDITS, m_bAllowEdits);
//}}AFX_DATA_MAP
for (int i=0; i<4; i++)
DDX_Control(pDX, IDC_COLNAME1 + i, m_ctlColName[i]);
for (i=0; i<4; i++)
DDX_Control(pDX, IDC_DAOEDITCTRL1 + i, m_ctlEdit[i]);
}
BEGIN_MESSAGE_MAP(CDAOContDlg, CDialog)
//{{AFX_MSG_MAP(CDAOContDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_CONNECT_DAO, OnConnectDao)
ON_BN_CLICKED(IDC_CONNECT_ODBC, OnConnectOdbc)
ON_NOTIFY(NM_DBLCLK, IDC_TREE1, OnDblclkTree1)
ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN1, OnDeltaposSpin1)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDAOContDlg message handlers
BOOL CDAOContDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Create the Image List
m_ctlImage.Create(IDB_TREEIMAGE,16,0,RGB(255,0,255));
m_ctlImage.SetBkColor(GetSysColor(COLOR_WINDOW));
/// Attach image list to Tree
m_ctlTree.SetImageList(&m_ctlImage);
m_pDB = new CDaoDatabase;
m_pRS = new CDaoRecordset(m_pDB);
m_ctlTree.ModifyStyle(0,TVS_HASLINES | TVS_HASBUTTONS,0);
m_ctlTree.GetRootItem().AddTail(_T("No Database loaded!"));
m_ctlSpin.SetRange(0,2);
m_ctlSpin.SetPos(1);
m_bUpdating = FALSE;
Clear();
return TRUE; // return TRUE unless you set the focus to a control
}
void CDAOContDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CDAOContDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the m_cursor to display while the user drags
// the minimized window.
HCURSOR CDAOContDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CDAOContDlg::OnConnectDao()
{
m_bODBC = FALSE;
CFileDialog dlgFile(
TRUE,
_T(".mdb"),
NULL,
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
_T("Access Files (*.mdb)|*.mdb|All Files (*.*)|*.*||"));
if (dlgFile.DoModal() != IDOK)
return;
m_ctlTree.DeleteAllItems();
m_ctlTree.GetRootItem().AddTail(_T("No Database loaded!"));
CWaitCursor wait;
UpdateWindow();
if (m_pDB->IsOpen())
m_pDB->Close();
try
{
m_pDB->Open(dlgFile.GetFileName());
}
catch (CDaoException* e)
{
AfxMessageBox(e->m_pErrorInfo->m_strDescription);
e->Delete();
}
if (m_pDB->IsOpen())
PopulateTree();
}
void CDAOContDlg::OnConnectOdbc()
{
m_bODBC = TRUE;
m_ctlTree.DeleteAllItems();
m_ctlTree.GetRootItem().AddTail(_T("No Database loaded!"));
if (m_pDB->IsOpen())
m_pDB->Close();
CWaitCursor wait;
UpdateWindow();
try
{
m_pDB->Open(_T(""),FALSE,FALSE,_T("ODBC;"));
}
catch (CDaoException* e)
{
AfxMessageBox(e->m_pErrorInfo->m_strDescription);
e->Delete();
}
if (m_pDB->IsOpen())
PopulateTree();
}
void CDAOContDlg::PopulateTree()
{
m_ctlTree.DeleteAllItems();
ASSERT(m_pDB);
ASSERT(m_pDB->IsOpen());
// Insert root node by call to tree object this time
m_cursDB = m_ctlTree.GetRootItem().AddTail(m_pDB->GetName(),IID_DATABASE);
// From now on call via iterators
m_cursTDS = m_cursDB.AddTail(_T("Tables"),IID_TABLES);
CDaoTableDefInfo tabInfo;
CDaoFieldInfo fieldInfo;
int nTableDefCount = m_pDB->GetTableDefCount();
for (int i = 0; i < nTableDefCount; i++)
{
m_pDB->GetTableDefInfo(i,tabInfo);
if (tabInfo.m_lAttributes & dbSystemObject)
continue;
AddItem(IID_TABLE,tabInfo.m_strName);
}
m_cursDB.Expand();
}
void CDAOContDlg::AddItem(WORD nItemType, LPCTSTR lpszName)
{
switch (nItemType)
{
case IID_TABLE:
{
m_cursTD = m_cursTDS.AddTail(lpszName,IID_TABLE);
CDaoTableDef td(m_pDB);
try
{
td.Open(lpszName);
CDaoFieldInfo fieldInfo;
int nFieldCount = td.GetFieldCount();
for (int j=0; j < nFieldCount; j++)
{
td.GetFieldInfo(j,fieldInfo);
int nImageID;
switch (fieldInfo.m_nType){
case dbLongBinary:
nImageID = IID_PICTURE; break;
case dbText:
case dbMemo:
nImageID = IID_GOODFIELD; break;
default:
nImageID = IID_BADFIELD;
}
m_cursTD.AddTail(fieldInfo.m_strName, nImageID);
}
}
catch(CDaoException* e)
{
e->Delete();
}
td.Close();
break;
}
}
}
void CDAOContDlg::OnDblclkTree1(NMHDR* pNMHDR, LRESULT* pResult)
{
CTreeCursor cursSel = m_ctlTree.GetSelectedItem();
UINT nImageID = cursSel.GetImageID();
CString strTableName;
strTableName = cursSel.GetParent().GetText();
switch (nImageID)
{
case IID_GOODFIELD:
SetRecordset(strTableName);
m_ctlEdit[m_nEditIndex].SetFieldName(cursSel.GetText());
m_ctlColName[m_nEditIndex].SetWindowText(cursSel.GetText());
m_nEditIndex = (m_nEditIndex + 1) % 4;
UpdateFields();
break;
case IID_PICTURE:
SetRecordset(strTableName);
m_strPictCol = cursSel.GetText();
UpdateFields();
break;
case IID_BADFIELD:
AfxMessageBox(_T("Field type not supported"));
break;
}
*pResult = 0;
}
void CDAOContDlg::SetRecordset(LPCTSTR strTableName)
{
if (strTableName == m_strTableName)
return;
Clear();
try
{
CString strQuery = _T("Select * from ");
strQuery += strTableName;
m_pRS->Open(dbOpenDynaset,strQuery);
m_pRS->m_bCheckCacheForDirtyFields = FALSE;
}
catch(CDaoException* e)
{
AfxMessageBox(e->m_pErrorInfo->m_strDescription);
e->Delete();
}
m_strTableName = strTableName;
}
void CDAOContDlg::Clear()
{
if (m_pRS->IsOpen())
m_pRS->Close();
for (int i=0; i<4; i++){
m_ctlEdit[i].SetText(_T(""));
m_ctlEdit[i].SetFieldName(_T(""));
m_ctlColName[i].SetWindowText(_T(""));
}
m_strPictCol = _T("");
m_ctlPicture.SetData(NULL);
m_nEditIndex = 0;
m_strTableName = _T("");
m_ctlRecNum.SetWindowText(_T(""));
m_nRecNum = 1;
}
void CDAOContDlg::UpdateFields()
{
m_bUpdating = TRUE; // Don't want data binding notifications during updates
CString strRecNum;
strRecNum.Format(_T("(%d)"),m_nRecNum);
m_ctlRecNum.SetWindowText(strRecNum);
for (int i=0; i<4; i++)
{
CString strFieldName = _T("[") + m_ctlEdit[i].GetFieldName() + _T("]");
if (strFieldName != _T("[]"))
{
COleVariant var = m_pRS->GetFieldValue(strFieldName);
m_ctlEdit[i].SetText(CString(V_BSTRT(&var)));
}
}
if (m_strPictCol != _T(""))
{
CString strFieldName = _T("[") + m_strPictCol + _T("]");
COleVariant var = m_pRS->GetFieldValue(strFieldName);
try
{
m_ctlPicture.SetData(&var);
}
catch (COleException* e)
{
// This is used to catch exceptions thrown
// by the picture control when it can't display
// the data we gave it for some reason
e->Delete();
}
}
m_bUpdating = FALSE;
}
void CDAOContDlg::OnDeltaposSpin1(NMHDR* pNMHDR, LRESULT* pResult)
{
// Force the current control to receive a WM_KILLFOCUS
CWnd* wndFocus = GetFocus();
m_ctlSpin.SetFocus();
wndFocus->SetFocus();
NM_UPDOWN* pNMUpDown = (NM_UPDOWN*)pNMHDR;
if (m_pRS->IsOpen())
{
if (pNMUpDown->iDelta == 1)
{
if (!m_pRS->IsEOF())
{
m_pRS->MoveNext();
m_nRecNum++;
}
if (m_pRS->IsEOF())
{
m_pRS->MovePrev();
m_nRecNum--;
}
}
if (pNMUpDown->iDelta == -1)
{
if (!m_pRS->IsBOF())
{
m_pRS->MovePrev();
m_nRecNum--;
}
if (m_pRS->IsBOF())
{
m_pRS->MoveNext();
m_nRecNum++;
}
}
UpdateFields();
}
m_ctlSpin.SetPos(1);
*pResult = 0;
}
BEGIN_EVENTSINK_MAP(CDAOContDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CDAOContDlg)
//}}AFX_EVENTSINK_MAP
ON_PROPNOTIFY_RANGE(CDAOContDlg, IDC_DAOEDITCTRL1, IDC_DAOEDITCTRL4, DISPID_TEXT, OnRequestEdit, OnChanged)
// ON_PROPNOTIFY_RANGE(theClass, idFirst, idLast, dispid, pfnRequest, pfnChanged)
END_EVENTSINK_MAP()
BOOL CDAOContDlg::OnRequestEdit(UINT nID, BOOL* pBool)
{
UpdateData(TRUE);
if (m_bUpdating)
*pBool = TRUE;
else
*pBool = m_bAllowEdits;
return TRUE;
}
BOOL CDAOContDlg::OnChanged(UINT nID)
{
// Filter out changes due to refreshing the control
if (m_bUpdating)
return TRUE;
if (m_pRS->IsOpen())
{
UINT nCtl = nID - IDC_DAOEDITCTRL1;
CString strFieldName = _T("[") + m_ctlEdit[nCtl].GetFieldName() + _T("]");
m_pRS->Edit();
COleVariant var(m_ctlEdit[nCtl].GetText(), VT_BSTRT);
m_pRS->SetFieldValue(strFieldName, var);
m_pRS->Update();
}
return TRUE;
}