MFC 通讯录

TXLDlg.cpp

// TXLDlg.cpp : 实现文件
//

#include "stdafx.h"
#include "TXL.h"
#include "TXLDlg.h"
#include "afxdialogex.h"


// CTXLDlg 对话框

struct infomation
{
    long long BH;    //编号
    CString bh;       //编号 数据库
    CString XM;     //姓名
    CString XB;     //性别 
    CString XH;     //学号
    CString DH;     //电话
    CString QQ;     //QQ
    CString ZH;     //住址
}stinfo[10];


IMPLEMENT_DYNAMIC(CTXLDlg, CDialogEx)

CTXLDlg::CTXLDlg(CWnd* pParent /*=NULL*/)
    : CDialogEx(IDD_DIALOG2, pParent)
{

}

CTXLDlg::~CTXLDlg()
{
}

void CTXLDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialogEx::DoDataExchange(pDX);
    DDX_Control(pDX, IDC_TXL_LIST, m_TXLList);
}


BEGIN_MESSAGE_MAP(CTXLDlg, CDialogEx)
    ON_NOTIFY(LVN_ITEMCHANGED, IDC_TXL_LIST, &CTXLDlg::OnLvnItemchangedTxlList)
    ON_NOTIFY(NM_CLICK, IDC_TXL_LIST, &CTXLDlg::OnNMClickTxlList)
    ON_BN_CLICKED(IDC_DR_BUTTON, &CTXLDlg::OnBnClickedDrButton)
    ON_BN_CLICKED(IDC_DC_BUTTON, &CTXLDlg::OnBnClickedDcButton)
END_MESSAGE_MAP()


// CTXLDlg 消息处理程序


BOOL CTXLDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // TODO: 在此添加额外的初始化

    m_TXLList.EnsureVisible(m_TXLList.GetItemCount() - 1, FALSE);  //滚动条

    bIsCreateEdit = false;          // 还没有创建编辑框 
    bIsCreateCombobox = false;      //还没有创建下拉列表框

    CRect rect;                     //获取list的客户区,方便调节每一列的宽度
    m_TXLList.GetClientRect(&rect);
    m_TXLList.SetExtendedStyle(m_TXLList.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);
    m_TXLList.InsertColumn(0, _T("编号"), LVCFMT_LEFT, rect.right / 7, 0);
    m_TXLList.InsertColumn(1, _T("姓名"), LVCFMT_LEFT, rect.right / 7, 1);
    m_TXLList.InsertColumn(2, _T("性别"), LVCFMT_LEFT, rect.right / 7, 2);
    m_TXLList.InsertColumn(3, _T("学号"), LVCFMT_LEFT, rect.right / 7, 3);
    m_TXLList.InsertColumn(4, _T("电话"), LVCFMT_LEFT, rect.right / 7, 4);
    m_TXLList.InsertColumn(5, _T("QQ"), LVCFMT_LEFT, rect.right / 7, 5);
    m_TXLList.InsertColumn(6, _T("住址"), LVCFMT_LEFT, rect.right / 7, 6);

    /*for (int i = 0; i <= 0; i++) { m_TXLList.InsertItem(i, _T("")); m_TXLList.SetItemText(i, 0, _T("")); m_TXLList.SetItemText(i, 1, _T("")); m_TXLList.SetItemText(i, 2, _T("")); m_TXLList.SetItemText(i, 3, _T("")); m_TXLList.SetItemText(i, 4, _T("")); m_TXLList.SetItemText(i, 5, _T("")); m_TXLList.SetItemText(i, 6, _T("")); }*/

    //AfxOleInit(); //初始化COM并结束时关闭

    return TRUE;  // return TRUE unless you set the focus to a control
                  // 异常: OCX 属性页应返回 FALSE
}


void CTXLDlg::OnLvnItemchangedTxlList(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    *pResult = 0;
}


void CTXLDlg::OnNMClickTxlList(NMHDR *pNMHDR, LRESULT *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate = reinterpret_cast<LPNMITEMACTIVATE>(pNMHDR);
    // TODO: 在此添加控件通知处理程序代码
    NM_LISTVIEW  *pEditCtrl = (NM_LISTVIEW *)pNMHDR;         /////////// &&&&& important &&&////////////////////////////////////////////////
    //printf("行:%d,列:%d\n", pEditCtrl->iItem, pEditCtrl->iSubItem);
    if (pEditCtrl->iItem == -1)//点击到非工作区
    {
        if (bIsCreateEdit == true)//如果之前创建了编辑框就销毁掉
        {
            DistroyEdit(&m_TXLList, &m_Edit, e_Item, e_SubItem);//销毁单元格编辑框对象
            bIsCreateEdit = false;
        }
        if (bIsCreateCombobox == true)//如果之前创建了下拉列表框就销毁掉
        {
            DistroyCombobox(&m_TXLList, &m_ComBox, e_Item, e_SubItem);
            bIsCreateCombobox = false;
        }
    }
    else if (pEditCtrl->iSubItem != 2)//如果不是性别选项
    {
        if (bIsCreateCombobox == true)//如果之前创建了编辑框就销毁掉
        {
            DistroyCombobox(&m_TXLList, &m_ComBox, e_Item, e_SubItem);
            bIsCreateCombobox = false;
        }
        if (bIsCreateEdit == true)
        {
            if (!(e_Item == pEditCtrl->iItem && e_SubItem == pEditCtrl->iSubItem))//如果点中的单元格不是之前创建好的
            {
                DistroyEdit(&m_TXLList, &m_Edit, e_Item, e_SubItem);
                bIsCreateEdit = false;
                CreateEdit(pEditCtrl, &m_Edit, e_Item, e_SubItem, bIsCreateEdit);//创建编辑框
                m_TXLList.InsertItem(pEditCtrl->iItem, _T("")); ///////***************************************************************
            }
            else//点中的单元格是之前创建好的
            {
                m_Edit.SetFocus();//设置为焦点 
            }
        }
        else
        {
            e_Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
            e_SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
            CreateEdit(pEditCtrl, &m_Edit, e_Item, e_SubItem, bIsCreateEdit);//创建编辑框
            m_TXLList.InsertItem(pEditCtrl->iItem, _T("")); //////***************************************************************
        }
    }
    else//如果是性别选项,在单元格处生成下拉列表项
    {
        if (bIsCreateEdit == true)//如果之前创建了编辑框就销毁掉
        {
            DistroyEdit(&m_TXLList, &m_Edit, e_Item, e_SubItem);
            bIsCreateEdit = false;
        }
        if (bIsCreateCombobox == true)
        {
            if (!(e_Item == pEditCtrl->iItem && e_SubItem == pEditCtrl->iSubItem))//如果点中的单元格不是之前创建好的
            {
                DistroyCombobox(&m_TXLList, &m_ComBox, e_Item, e_SubItem);
                bIsCreateCombobox = false;
                CreateCombobox(pEditCtrl, &m_ComBox, e_Item, e_SubItem, bIsCreateCombobox);//创建编辑框
                m_TXLList.InsertItem(pEditCtrl->iItem, _T("")); //////***************************************************************
                m_ComBox.AddString(L"男");             ///*****
                m_ComBox.AddString(L"女");
                m_ComBox.ShowDropDown();//自动下拉
            }
            else//点中的单元格是之前创建好的
            {
                m_ComBox.SetFocus();//设置为焦点 
            }
        }
        else
        {
            e_Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
            e_SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
            CreateCombobox(pEditCtrl, &m_ComBox, e_Item, e_SubItem, bIsCreateCombobox);//创建编辑框
            m_TXLList.InsertItem(pEditCtrl->iItem, _T("")); //////***************************************************************
            m_ComBox.AddString(L"男");
            m_ComBox.AddString(L"女");
            m_ComBox.ShowDropDown();//自动下拉
        }
    }

    *pResult = 0;
}


void CTXLDlg::CreateEdit(NM_LISTVIEW  *pEditCtrl, CEdit *CtEdit, int &Item, int &SubItem, bool &bIsCreateEdit)//创建单元格编辑框函数
//pEditCtrl为列表对象指针,CreateEdit为编辑框指针对象,Item为创建单元格在列表中的行,SubItem则为列,bIsCreateEdit为对象创建标记
{
    Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
    SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
    CtEdit->Create(ES_AUTOHSCROLL | WS_CHILD | ES_LEFT | ES_WANTRETURN,CRect(0, 0, 0, 0), this, IDC_EDIT_CREATEID);//创建编辑框对象,IDC_EDIT_CREATEID为控件ID号3000,在文章开头定义
    bIsCreateEdit = true;
    CtEdit->SetFont(this->GetFont(), FALSE);//设置字体,不设置这里的话上面的字会很突兀的感觉
    CtEdit->SetParent(&m_TXLList);//将list control设置为父窗口,生成的Edit才能正确定位,这个也很重要
    CRect  EditRect;
    m_TXLList.GetSubItemRect(e_Item, e_SubItem, LVIR_LABEL, EditRect);//获取单元格的空间位置信息
    EditRect.SetRect(EditRect.left + 1, EditRect.top + 1, EditRect.left + m_TXLList.GetColumnWidth(e_SubItem) - 1, EditRect.bottom - 1);//+1和-1可以让编辑框不至于挡住列表框中的网格线/////////////////////// EditRect.top - 1? EditRect.bottom + 1?*******************************************
    CString strItem = m_TXLList.GetItemText(e_Item, e_SubItem);//获得相应单元格字符 可能之前有字符
    CtEdit->SetWindowText(strItem);//将单元格字符显示在编辑框上
    CtEdit->MoveWindow(&EditRect);//将编辑框位置放在相应单元格上
    CtEdit->ShowWindow(SW_SHOW);//显示编辑框在单元格上面
    CtEdit->SetFocus();//设置为焦点 
    CtEdit->SetSel(-1);//设置光标在文本框文字的最后
}

void CTXLDlg::DistroyEdit(CListCtrl *list, CEdit* DyEdit, int &Item, int &SubItem)
{
    CString meditdata;
    DyEdit->GetWindowText(meditdata); //*******************************************************************************************************************************************GetWindowsTextW???
    list->SetItemText(Item, SubItem, meditdata);//获得相应单元格字符
    DyEdit->DestroyWindow();//销毁对象,有创建就要有销毁,不然会报错
}

void CTXLDlg::CreateCombobox(NM_LISTVIEW  *pEditCtrl, CComboBox *CtCombobox, int &Item, int &SubItem, bool &bIsCreateCombox)//创建单元格下拉列表框函数
                                                                                                                                               //pEditCtrl为列表对象指针,CreateCcombobox为下拉列表框指针对象,
                                                                                                                                               //Item为创建单元格在列表中的行,SubItem则为列,bIsCreateEdit为对象创建标记
{
    Item = pEditCtrl->iItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
    SubItem = pEditCtrl->iSubItem;//将点中的单元格的行赋值给“刚编辑过的行”以便后期处理
    CtCombobox->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWN | CBS_OEMCONVERT, CRect(0, 0, 0, 0), this, IDC_COMBOX_CREATEID);
    bIsCreateCombox = true;
    CtCombobox->SetFont(this->GetFont(), FALSE);//设置字体,不设置这里的话上面的字会很突兀的感觉
    CtCombobox->SetParent(&m_TXLList);//将list control设置为父窗口,生成的Combobox才能正确定位,这个也很重要
    CRect  EditRect;
    m_TXLList.GetSubItemRect(e_Item, e_SubItem, LVIR_LABEL, EditRect);//获取单元格的空间位置信息
    EditRect.SetRect(EditRect.left + 1, EditRect.top + 1, EditRect.left + m_TXLList.GetColumnWidth(e_SubItem) - 1, EditRect.bottom - 1);//+1和-1可以让编辑框不至于挡住列表框中的网格线//******* EditRect.top - 1?*********************************************************
    CString strItem = m_TXLList.GetItemText(e_Item, e_SubItem);//获得相应单元格字符
    CtCombobox->SetWindowText(strItem);//将单元格字符显示在编辑框上
    CtCombobox->MoveWindow(&EditRect);//将编辑框位置放在相应单元格上
    CtCombobox->ShowWindow(SW_SHOW);//显示编辑框在单元格上面
}

void CTXLDlg::DistroyCombobox(CListCtrl *list, CComboBox* DyCombox, int &Item, int &SubItem)
{
    CString meditdata;
    DyCombox->GetWindowText(meditdata);   //*******************************************************************************************************************************************GetWindowsTextW???
    list->SetItemText(Item, SubItem, meditdata);    //更新相应单元格字符
    DyCombox->DestroyWindow();  //销毁对象,有创建就要有销毁,不然会报错
}


void CTXLDlg::OnOK()
{
}




void CTXLDlg::OnKillfocusEdit()
{
    if (bIsCreateEdit == true)//如果之前创建了编辑框就销毁掉
    {
        DistroyEdit(&m_TXLList, &m_Edit, e_Item, e_SubItem);//销毁单元格编辑框对象
        bIsCreateEdit = false;
    }
    if (bIsCreateCombobox == true)//如果之前创建了下拉列表框就销毁掉
    {
        DistroyCombobox(&m_TXLList, &m_ComBox, e_Item, e_SubItem);
        bIsCreateCombobox = false;
    }
}

void CTXLDlg::OnKillfocusCcomboBox()
{
    if (bIsCreateEdit == true)//如果之前创建了编辑框就销毁掉
    {
        DistroyEdit(&m_TXLList, &m_Edit, e_Item, e_SubItem);//销毁单元格编辑框对象
        bIsCreateEdit = false;
    }
    if (bIsCreateCombobox == true)//如果之前创建了下拉列表框就销毁掉
    {
        DistroyCombobox(&m_TXLList, &m_ComBox, e_Item, e_SubItem);
        bIsCreateCombobox = false;
    }
}




void CTXLDlg::OnBnClickedDrButton()
{
    // TODO: 在此添加控件通知处理程序代码
    /////////////////////////////////////////////////////////////////////////////////////
    //ADO 打开数据库
    _ConnectionPtr m_pConnection;//数据库 智能指针
    AfxOleInit();     //初始化COM并结束时关闭
    m_pConnection.CreateInstance(__uuidof(Connection));
    //打开TXL.mdp
    try
    {
        m_pConnection->Open("Provider=Microsoft.Jet.OLEDB.4.0;Data Sourse=TXL.mdp","","",adModeUnknown);
    }
    catch(_com_error e)
    {
        MessageBox(_T("数据库连接失败,请检查数据库TXL.mdp路径是否正确!"));
        return ;
    }
////////////////////////////////////////////////////////////////////////////////
    //打开数据表
    _RecordsetPtr m_pRecordset;
    m_pRecordset.CreateInstance(__uuidof(Recordset));
    try
    {
        m_pRecordset->Open("SELECT *FORM 通讯录",/*theApp.*/m_pConnection.GetInterfacePtr(),adOpenDynamic,adLockOptimistic,adCmdText);
    }
    catch (_com_error e)
    {
        AfxMessageBox(_T("表内数据为空!"));
        return;
    }
//////////////////////////////////////////////////////////////////
    //获取字段 编号 姓名 性别 学号 电话 QQ 住址
    //将表内数据全部读出并显示在列表框内
    //如果没有遇到表结束标志adoEOF,则用GetCollect(字段名)或m_pRecordset->Fields->GetItem(字段名)->Value方法,来获取当前记录指针所指的字段值,
    //然后再用MoveNext()方法移动到下一条记录位置
    _variant_t var;
    try
    {
        if (!m_pRecordset->BOF)
            m_pRecordset->MoveFirst();
        else
        {
            AfxMessageBox(_T("表内数据为空"));
            return;
        }
        // 读入库中各字段并加入列表框中
        while (!m_pRecordset->adoEOF)
        {
            var = m_pRecordset->GetCollect("编号");    //记录集返回值为结构体_variant_t,用vt成员判断是否为空
            if (var.vt != VT_NULL)
                stinfo[0].bh = (LPCSTR)_bstr_t(var);
            var = m_pRecordset->GetCollect("姓名");
            if (var.vt != VT_NULL)
                stinfo[0].XM = (LPCSTR)_bstr_t(var);
            var = m_pRecordset->GetCollect("性别");
            if (var.vt != VT_NULL)
                stinfo[0].XB = (LPCSTR)_bstr_t(var);
            var = m_pRecordset->GetCollect("学号");
            if (var.vt != VT_NULL)
                stinfo[0].XH= (LPCSTR)_bstr_t(var);
            var = m_pRecordset->GetCollect("电话");
            if (var.vt != VT_NULL)
                var = m_pRecordset->GetCollect("QQ");
            if (var.vt != VT_NULL)
                stinfo[0].QQ = (LPCSTR)_bstr_t(var);
                var = m_pRecordset->GetCollect("住址");
            if (var.vt != VT_NULL)
                stinfo[0].ZH = (LPCSTR)_bstr_t(var);

            //m_TXLList.AddString(stinfo[0].bh + " --> " + stinfo[0].XM + " --> " + stinfo[0].XB + " --> " + stinfo[0].XH + " --> " + stinfo[0].DH + " --> " + stinfo[0].QQ + " --> " + stinfo[0].ZH);//*****************************************************************

            m_pRecordset->MoveNext();
    }

    // 默认列表指向第一项,同时移动记录指针并显示 
    //m_TXLList.SetCurSel(0);//**********************************************************************************************************************
}
catch (_com_error *e)
{
    AfxMessageBox(e->ErrorMessage());
}
//////////////////////////////////////////////////////////////

try
{
    // 写入各字段值
    m_pRecordset->AddNew();
    m_pRecordset->PutCollect("编号", _variant_t(stinfo[0].BH));
    m_pRecordset->PutCollect("姓名", _variant_t(stinfo[0].XM));
    m_pRecordset->PutCollect("性别", _variant_t(stinfo[0].XB));
    m_pRecordset->PutCollect("学号", _variant_t(stinfo[0].XH));
    m_pRecordset->PutCollect("电话", _variant_t(stinfo[0].DH));
    m_pRecordset->PutCollect("QQ", _variant_t(stinfo[0].QQ));
    m_pRecordset->PutCollect("地址", _variant_t(stinfo[0].ZH));

    m_pRecordset->Update();

    AfxMessageBox(_T("插入成功!"));
}
catch (_com_error *e)
{
    AfxMessageBox(e->ErrorMessage());
}
         // 移动记录指针。移动记录指针可以通过MoveFirst()方法移动到第一条记录、MoveLast()方法移动到最后一条记录、MovePrevious()方法移动到当前记录的前一条记录、MoveNext()方法移动到当前记录的下一条记录。但我们有时经常需要随意移动记录指针到任意记录位置时,可以使用Move(记录号)方法来实现,注意: Move()方法是相对于当前记录来移动指针位置的,正值向后移动、负值向前移动,如:Move(3),当前记录是3时,它将从记录3开始往后再移动3条记录位置。代码如下所示:

try
{
    //int curSel = m_TXLList.GetCurSel();
    // 先将指针移向第一条记录,然后就可以相对第一条记录来随意移动记录指针
    m_pRecordset->MoveFirst();
    //m_pRecordset->Move(long(curSel));

}
catch (_com_error *e)
{
    AfxMessageBox(e->ErrorMessage());
}
    //修改记录中字段值。可以将记录指针移动到要修改记录的位置处,直接用PutCollect(字段名,值)将新值写入并Update()更新数据库既可。可以用上面方法移动记录指针,修改字段值代码如下所示:

try
{
    // 假设对第二条记录进行修改
    m_pRecordset->MoveFirst();
    m_pRecordset->Move(1);        // 从0开始
    m_pRecordset->AddNew();
    m_pRecordset->PutCollect("编号", _variant_t(stinfo[0].BH));
    m_pRecordset->PutCollect("姓名", _variant_t(stinfo[0].XM));
    m_pRecordset->PutCollect("性别", _variant_t(stinfo[0].XB));
    m_pRecordset->PutCollect("学号", _variant_t(stinfo[0].XH));
    m_pRecordset->PutCollect("电话", _variant_t(stinfo[0].DH));
    m_pRecordset->PutCollect("QQ", _variant_t(stinfo[0].QQ));
    m_pRecordset->PutCollect("地址", _variant_t(stinfo[0].ZH));
    m_pRecordset->Update();
}
catch (_com_error *e)
{
    AfxMessageBox(e->ErrorMessage());
}
//删除记录。删除记录和上面修改记录的操作类似,先将记录指针移动到要修改记录的位置,直接用Delete()方法删除它并用Update()来更新数据库既可。代码如下所示:

try
{
    // 假设删除第二条记录
    m_pRecordset->MoveFirst();
    m_pRecordset->Move(1);        // 从0开始
    m_pRecordset->Delete(adAffectCurrent);  // 参数adAffectCurrent为删除当前记录
    m_pRecordset->Update();
}
catch (_com_error *e)
{
    AfxMessageBox(e->ErrorMessage());
}
//关闭记录集。直接用Close方法关闭记录集并赋于其空值。代码如下所示:

m_pRecordset->Close();
m_pRecordset = NULL;


//////////////////////////////////////////////////////////////////
    //关闭数据库连接
    if (m_pConnection->State)
    {
        m_pConnection->Close();
    }
    m_pConnection = NULL;
    //////////////////////////////////////////////////////
}


void CTXLDlg::OnBnClickedDcButton()
{
    // TODO: 在此添加控件通知处理程序代码



}

你可能感兴趣的:(MFC 通讯录)