一、界面效果演示
1 程序设计界面
2 为该窗口控件标识和为其关联的变量
3 数据库中表的数据
4 程序实现展示
5 输入字符4
6 再输入字符5
7 再输入6,查询到数据库中条形码为456的记录
二、功能实现
1:在MFC的CListCtrl 列表类中派生一个新类 CCustomGrid
1) 其头文件CCustomGrid.h
#if !defined(AFX_CUSTOMGRID_H__3C747B54_E944_4014_AF85_824299C6AD7A__INCLUDED_) #define AFX_CUSTOMGRID_H__3C747B54_E944_4014_AF85_824299C6AD7A__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // CustomGrid.h : header file // #include "KeyEdit.h" //包含自定义列表框编辑栏类 ///////////////////////////////////////////////////////////////////////////// // CCustomGrid window class CCustomGrid : public CListCtrl //CListCtrl类的派生类CCustomGrid { // Construction public: CCustomGrid(); int row; int col; CKeyEdit edit; bool showedit; // Attributes public: // Operations public: // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CCustomGrid) protected: virtual void PreSubclassWindow(); //添加列表的样式如(填充列表中框格、手指样式) //}}AFX_VIRTUAL // Implementation public: void ShowEdit(); virtual ~CCustomGrid(); DECLARE_DYNAMIC( CCustomGrid) // Generated message map functions protected: //{{AFX_MSG(CCustomGrid) afx_msg void OnLButtonDown(UINT nFlags,CPoint point); //增添鼠标点击列表框相应函数 //}}AFX_MSG DECLARE_MESSAGE_MAP() }; ///////////////////////////////////////////////////////////////////////////// //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_CUSTOMGRID_H__3C747B54_E944_4014_AF85_824299C6AD7A__INCLUDED_)
2) 其CPP文件CCustomGrid.CPP为
// CustomGrid.cpp : implementation file #include "stdafx.h" #include "BookManage.h" #include "CustomGrid.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CCustomGrid IMPLEMENT_DYNAMIC(CCustomGrid, CWnd ) CCustomGrid::CCustomGrid() { row=-1; col=-1; showedit=false; } CCustomGrid::~CCustomGrid() { } BEGIN_MESSAGE_MAP(CCustomGrid, CListCtrl) //{{AFX_MSG_MAP(CCustomGrid) ON_WM_LBUTTONDOWN() //加入响应消息,使鼠标点击列表框使有事件相应 //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CCustomGrid message handlers void CCustomGrid::OnLButtonDown(UINT nFlags,CPoint point) { //点击列表控件时会返回一个位置point,point记录了列表控件单元格的行、列维数 CListCtrl::OnLButtonDown(nFlags,point); LVHITTESTINFO p; p.pt = point ; if(SubItemHitTest(&p)!=-1) { col =p.iSubItem; //指向列表控件的列 row = p.iItem; //指向列表控件的行 ShowEdit(); } } void CCustomGrid::ShowEdit() { CRect rect; //记录当前单元格的坐标 GetSubItemRect(row,col,LVIR_LABEL,rect); //LVIR_LABEL is Returns the bounding rectangle of the entire item //通过行、列获取列表控件单元格坐标,通过rect获取单元格大小 CString str; str = GetItemText(row,col);//通过行、列获取列表控件单元格坐标,获取字符串 edit.MoveWindow(rect); //编辑栏移动到指定单元格 edit.SetWindowText(str); edit.ShowWindow(SW_SHOW); edit.SetSel(0,100); edit.SetFocus(); edit.SetReadOnly(!showedit); //控制编辑栏是否能够输入字符,当为TRUE时列表不可写入数据 UpdateWindow(); } void CCustomGrid::PreSubclassWindow() //列表的样式如(填充列表中框格、手指样式) { //设置列表控件的同时,设置编辑栏控件样式.当列表框控件初始化时,会在列表控件上初始化编辑栏控件 ModifyStyle(LVS_EDITLABELS,0); ModifyStyle(0,LVS_REPORT); //ModifyStyle(0,LVS_SHOWSELALWAYS); SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_HEADERDRAGDROP|LVS_EX_GRIDLINES|LVS_EX_ONECLICKACTIVATE|LVS_EX_FLATSB); //列表的样式如(填充列表中框格、手指样式) edit.Create(WS_CHILD|WS_CLIPSIBLINGS|WS_EX_TOOLWINDOW|WS_BORDER,CRect(80,150,100,500),this,1001); //编辑栏样式(WS_BORDER是生成黑框) CListCtrl::PreSubclassWindow(); }
2:在MFC的CEdit 列表类中派生一个新类 CKeyEdit
1) 其头文件CKeyEdit.h为
#if !defined(AFX_KEYEDIT_H__6E2C9CD6_416B_4DC0_91C8_F796DE8857B4__INCLUDED_)
#define AFX_KEYEDIT_H__6E2C9CD6_416B_4DC0_91C8_F796DE8857B4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// KeyEdit.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CKeyEdit window
class CKeyEdit : public CEdit
{
// Construction
public:
CKeyEdit();
CFont m_font;
bool IsNumber;
COLORREF color;
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CKeyEdit)
//}}AFX_VIRTUAL
// Implementation
public:
void SetEditTextColor(COLORREF Color);
virtual ~CKeyEdit();
DECLARE_DYNAMIC (CKeyEdit)
// Generated message map functions
protected:
//{{AFX_MSG(CKeyEdit)
afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnKillfocus();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_KEYEDIT_H__6E2C9CD6_416B_4DC0_91C8_F796DE8857B4__INCLUDED_)
2) 其CPP文件CKeyEdit.CPP为
// KeyEdit.cpp : implementation file
//
#include "stdafx.h"
#include "BookManage.h"
#include "KeyEdit.h"
#include "CustomGrid.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CKeyEdit
IMPLEMENT_DYNAMIC(CKeyEdit,CEdit);
CKeyEdit::CKeyEdit()
{
IsNumber =true; //相当于一个开关,主程序中可以给其赋值,用于选择编辑栏中是否可以输入字符
color = RGB(255,0,0); //编辑栏字符的颜色
}
CKeyEdit::~CKeyEdit()
{
}
BEGIN_MESSAGE_MAP(CKeyEdit, CEdit)
//{{AFX_MSG_MAP(CKeyEdit)
ON_WM_CTLCOLOR_REFLECT()
ON_WM_CHAR()
ON_WM_CREATE()
ON_CONTROL_REFLECT(EN_KILLFOCUS, OnKillfocus)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CKeyEdit message handlers
HBRUSH CKeyEdit::CtlColor(CDC* pDC, UINT nCtlColor)
{
//设置编辑栏中字体的颜色
pDC->SetTextColor(color);
CBrush brush(color);
return brush;
}
void CKeyEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
//但在编辑栏中输入字符时会调用此函数,此函数作用当前IsNumber值确定编辑栏控件是否可以输入字符,否则会发出蜂鸣声
//当应用程序调用CKEyEdit类时,会给IsNumber赋值赋为false即编辑栏可以输入字符,当为true只可以输入数字
if (IsNumber)
if (((nChar <45)||(nChar>46)&&(nChar<48)||(nChar > 57))&& (nChar != 8))
{
Beep(100,1000);
}
else
CEdit::OnChar(nChar, nRepCnt, nFlags);
else
CEdit::OnChar(nChar, nRepCnt, nFlags);
}
int CKeyEdit::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
//设置编辑框字体样式
if (CEdit::OnCreate(lpCreateStruct) == -1)
return -1;
LOGFONT font;
font.lfHeight = -12; //参数小于0,则将其转换为
font.lfWidth = 0;
font.lfItalic = 0;
font.lfStrikeOut = 0;
font.lfEscapement = 0;
font.lfUnderline = 0;
font.lfWeight = 400; //字的粗细
font.lfCharSet = 134;
strcpy(font.lfFaceName,"宋体");
m_font.DeleteObject();
m_font.CreateFontIndirect(&font);
SetFont(&m_font);
return 0;
}
void CKeyEdit::SetEditTextColor(COLORREF Color)
{
//color = Color;
Invalidate();
}
void CKeyEdit::OnKillfocus()
{
// TODO: Add your control notification handler code here
CWnd* temp = NULL;
temp = GetParent();
if (temp != NULL)
{
if (temp->IsKindOf(RUNTIME_CLASS(CCustomGrid))==true) //判断temp是否属于CCcustomGrid
{
CString str;
GetWindowText(str);
((CCustomGrid*)(temp))->SetItemText(((CCustomGrid*)(temp))->row,((CCustomGrid*)(temp))->col,str);
ShowWindow(SW_HIDE); //当点击列表中某一个格后会出现黑框(说明选中),当焦点从列表控移开黑框是否消失就看ShowWindow()里面的函数了
}
}
}
2:具体实现的窗口类头文件为 BookInput.h
1) 其头文件CBookInput.h
#if !defined(AFX_BOOKINPUT_H__A31A3911_5183_4848_9302_8A8809570A15__INCLUDED_) #define AFX_BOOKINPUT_H__A31A3911_5183_4848_9302_8A8809570A15__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 // BookInput.h : header file #include "KeyEdit.h" #include "CustomGrid.h" ///////////////////////////////////////////////////////////////////////////// // CBookInput dialog class CBookInput : public CDialog { // Construction public: CBookInput(CWnd* pParent = NULL); // standard constructor // Dialog Data //{{AFX_DATA(CBookInput) enum { IDD = IDD_BOOKINPUT }; CCustomGrid m_infolist; CListBox m_provlist; CKeyEdit m_rebate; CKeyEdit m_prov; CCustomGrid m_inputlist; CDateTimeCtrl m_date; //}}AFX_DATA // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CBookInput) public: virtual BOOL PreTranslateMessage(MSG* pMsg); //PreTranslateMessage是消息再送给TranslateMessage函数之前被调用,绝大多数本窗口的消息都要经过这里,当需要在MFC之前处理某些消息,需要在这里添加代码 //MFC消息控制流最具特色的地方是CWnd类的虚拟函数PreTranslateMessage(),通过重载这个函数,我们可以改变MFC的消息控制流,甚至可以做一个全新的控制流 //只有穿过消息队列才受PreTranslateMessage()的影响,采用SendMessage()或其他方式向窗口直接发送而不经过消息队列的消息不会理睬PreTranslateMessage() //的存在 protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: // Generated message map functions //{{AFX_MSG(CBookInput) virtual BOOL OnInitDialog(); virtual void OnCancel(); virtual void OnOK(); afx_msg void OnDblclkProviderlist(); afx_msg void OnKillfocusProviderlist(); afx_msg void OnClickBookinfolist(NMHDR* pNMHDR, LRESULT* pResult); //}}AFX_MSG DECLARE_MESSAGE_MAP() public: void EditChange(); void MoveFocus(); void LoadProvider(); void DoEditKeyDown(UINT nChar, UINT CtrlID); }; //{{AFX_INSERT_LOCATION}} // Microsoft Visual C++ will insert additional declarations immediately before the previous line. #endif // !defined(AFX_BOOKINPUT_H__A31A3911_5183_4848_9302_8A8809570A15__INCLUDED_)
1) 其头文件CBookInput.cpp
// BookInput.cpp : implementation file #include "stdafx.h" #include "BookManage.h" #include "BookInput.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBookInput dialog extern _RecordsetPtr m_pRecordset; extern _ConnectionPtr m_pConnection; CBookInput::CBookInput(CWnd* pParent /*=NULL*/) : CDialog(CBookInput::IDD, pParent) { //{{AFX_DATA_INIT(CBookInput) //}}AFX_DATA_INIT } void CBookInput::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBookInput) DDX_Control(pDX, IDC_BOOKINFOLIST, m_infolist); DDX_Control(pDX, IDC_PROVIDERLIST, m_provlist); DDX_Control(pDX, IDC_REBATE, m_rebate); DDX_Control(pDX, IDC_PROVIDER, m_prov); DDX_Control(pDX, IDC_INPUTLIST, m_inputlist); DDX_Control(pDX, IDC_DATETIME, m_date); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CBookInput, CDialog) //{{AFX_MSG_MAP(CBookInput) ON_LBN_DBLCLK(IDC_PROVIDERLIST, OnDblclkProviderlist) ON_LBN_KILLFOCUS(IDC_PROVIDERLIST, OnKillfocusProviderlist) ON_NOTIFY(NM_CLICK, IDC_BOOKINFOLIST, OnClickBookinfolist) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CBookInput message handlers BOOL CBookInput::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here //添加供应商,用于供货商编辑栏点击pageDown时显示该列表 LoadProvider(); //向表格中添加列 m_inputlist.InsertColumn(0,"仓库名称",LVCFMT_LEFT,80); m_inputlist.InsertColumn(1,"条形码",LVCFMT_LEFT,100); m_inputlist.InsertColumn(2,"书籍名称",LVCFMT_LEFT,80); m_inputlist.InsertColumn(3,"单价",LVCFMT_LEFT,60); m_inputlist.InsertColumn(4,"数量",LVCFMT_LEFT,60); m_inputlist.InsertColumn(5,"折扣",LVCFMT_LEFT,60); m_inputlist.InsertColumn(6,"金额",LVCFMT_LEFT,60); m_infolist.InsertColumn(0,"条形码",LVCFMT_LEFT,100); m_infolist.InsertColumn(1,"书籍名称",LVCFMT_LEFT,80); m_infolist.InsertColumn(2,"作者",LVCFMT_LEFT,60); m_infolist.InsertColumn(3,"图书类型",LVCFMT_LEFT,60); m_infolist.InsertColumn(4,"默认价格",LVCFMT_LEFT,60); //添加空行 m_inputlist.InsertItem(1,""); m_inputlist.SetItemText(0,5,"1.0"); m_rebate.SetWindowText("1.0"); // m_rebate.IsNumber = true; //让列表控件中的编辑栏只能输入数字 // m_factmoney.IsNumber = true; //让列表控件中的编辑栏只能输入数字 m_infolist.SetParent(&m_inputlist); //设置其父窗口,以便在父窗口中显示子窗口 m_provlist.SetParent(&m_inputlist); //设置其父窗口,以便在父窗口中显示子窗口 return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CBookInput::LoadProvider() { m_pRecordset->raw_Close(); m_provlist.SetRedraw(FALSE); //设置重划标志false不改变列表内容,当再次设置为true时改变列表内容 m_provlist.ResetContent(); //删除所有的数据 CString sql; sql = "select Provider from TB_ProviderInfo"; m_pRecordset->Open((_bstr_t)sql,m_pConnection.GetInterfacePtr(),adOpenKeyset,adLockOptimistic,adCmdText); while (!m_pRecordset->adoEOF) { m_provlist.AddString((TCHAR *)(_bstr_t)m_pRecordset->GetFields()->GetItem("provider")->Value); m_pRecordset->MoveNext(); } m_provlist.SetRedraw(TRUE); //改变列表内容 m_provlist.Invalidate(); } void CBookInput::OnCancel() { // TODO: Add extra cleanup here CDialog::OnCancel(); } void CBookInput::OnOK() { // TODO: Add extra validation here CDialog::OnOK(); } BOOL CBookInput::PreTranslateMessage(MSG* pMsg) { if (pMsg->message ==WM_KEYDOWN) //捕捉在图书入库模块中,按下键盘时触发的动作 { /**************************************************************** 说明: 在供应商编辑框获得焦点并按PageDown键,调用DoEditKeyDown方法 ****************************************************************/ //pMsg->wParam == 34中34为按下PageDown键的码值而且pMsg->hwnd为在控件区域(m_prov.m_hWnd编辑栏控件)上。就触发PageDown调用DoEditKeyDown方法 if ((pMsg->wParam == 34)&&(pMsg->hwnd==m_prov.m_hWnd)) { DoEditKeyDown(34,IDC_PROVIDER); //把按键消息和编辑栏句柄传递给DoEditKeyDown函数用于显示隐藏的ListBox控件、将焦点转移到ListBox控件的第一个数据项上。 return true; } /**************************************************************** 说明: 表格中编辑框获得焦点时,按Enter键控制单元格焦点移动 ****************************************************************/ //pMsg->wParam == 13中的34为按下回车键的码值而且pMsg->hwnd为在控件区域(关联到m_inputlist.edit.m_hWnd主列表框控件上单元格的编辑栏)上。触发MoveFocus方法 if ((pMsg->wParam == 13)&&(pMsg->hwnd==m_inputlist.edit.m_hWnd)) { MoveFocus(); return true; } } /**************************************************************** 说明: 当键盘点击列表框控件单元格相应该事件(表格中编辑框改变时的事件) ****************************************************************/ //pMsg->message == WM_KEYUP中WM_KEYUP为按下键盘后弹起时发送的消息而且pMsg->hwnd为在控件区域(关联到m_inputlist.edit.m_hWnd主列表框控件上单元格的编辑栏)上。触发EditChange()消息 if ((pMsg->message == WM_KEYUP)&&(pMsg->hwnd == m_inputlist.edit.m_hWnd)) { EditChange(); } /**************************************************************** 说明: 在窗体中控件获得焦点时,使提示列表不可见(当焦点不在实时显示的列表控件(书籍信息记录)上时,实时显示的列表控件(书籍信息记录)消失) ****************************************************************/ //CBookInput类中无论在那个控件上右击鼠标右键触发此方法 if (pMsg->message==WM_LBUTTONDOWN) { if (pMsg->hwnd!= m_infolist.m_hWnd) //判断点击触发消息的窗口句柄是否实时显示的列表控件(书籍信息记录)上 m_infolist.ShowWindow(SW_HIDE); //实时显示的列表控件(书籍信息记录)消失 } /**************************************************************** 说明: 在单击表格时,根据当前列判断是否显示编辑框 (因为CCustomGrid::ShowEdit()中edit.SetReadOnly(!showedit)用于控制编辑栏是否能够输入字符。 PreTranslateMessage中这个消息处理函数初始m_inputlist.showedit的值(因为编辑框默认不可编辑) ****************************************************************/ if ((pMsg->message ==WM_LBUTTONDOWN)&&(pMsg->hwnd ==m_inputlist.m_hWnd)) { //当前列为商品编号,商品名称为空,显示编辑框,在当前列为商品名称,商品编号为空,显示编辑框, CString tempID,tempname; LVHITTESTINFO pos; pos.pt.x = LOWORD(pMsg->lParam); pos.pt.y = HIWORD(pMsg->lParam); pos.flags = LVHT_ABOVE; int row,col; row = -1; col = -1; if (m_inputlist.SubItemHitTest(&pos)>=0) { m_inputlist.SetFocus(); row = pos.iItem; col = pos.iSubItem; tempID = m_inputlist.GetItemText(row,1); tempname = m_inputlist.GetItemText(row,2); if (col==6) //如果单击金额列,不显示编辑框 return true; m_inputlist.showedit =true; if ((tempname.IsEmpty()==false)&&(col == 1)) m_inputlist.showedit =false; else if((tempID.IsEmpty()==false)&&(col == 2)) m_inputlist.showedit =false; } } return CDialog::PreTranslateMessage(pMsg); } void CBookInput::DoEditKeyDown(UINT nChar, UINT CtrlID) { //按下pagedowm调用此信息,显示供应商的列表控件 m_provlist.ShowWindow(SW_SHOW); //显示列表控件 m_provlist.SetSel(0); //选中指定索引的项 m_provlist.SetFocus(); //将焦点给供应商列表控件 } void CBookInput::OnDblclkProviderlist() { //选择供应商列表框中的值,使编辑栏中的值关联 // TODO: Add your control notification handler code here CString temp; int index = m_provlist.GetCurSel(); //获取点击并选择相应列表控件中记录的顺序数(index) if (index != -1) // 如果没有选择则index为-1 { m_provlist.GetText(index,temp); //通过记录的顺序数(index),把相应的值赋给temp if (! temp.IsEmpty()) m_prov.SetWindowText(temp); //与列表框关联的编辑框获取其值 m_prov.SetFocus(); //编辑栏获得焦点 m_provlist.ShowWindow(SW_HIDE); //列表框隐藏 } } //在列表框中按Enter按钮,移动到下一个单元格 void CBookInput::MoveFocus() { m_inputlist.SetFocus(); // m_list.edit.PostMessage(WM_KILLFOCUS,0,0); if (m_inputlist.col <7) //移动一行的列数小于最大行列数时 { m_inputlist.col = m_inputlist.col+1; //列加一 m_inputlist.ShowEdit(); //显示编辑栏 } else //移动一行的列数大于最大行列数时 { int counts = m_inputlist.GetItemCount(); //获取列表控件中记录的数目 if (m_inputlist.row == counts-1) //当前行为最后一行 { m_inputlist.InsertItem(100,""); m_inputlist.row+=1; //行加一 m_inputlist.SetItemText(m_inputlist.row,5,"1.0"); //将主列表控件每行的第五列设置为“1.0” m_inputlist.col = 0; //每次换行时焦点、编辑栏停留新行的第一列 m_inputlist.ShowEdit(); //显示编辑栏 } else { m_inputlist.row+=1; m_inputlist.col = 0; m_inputlist.ShowEdit(); } } } void CBookInput::OnKillfocusProviderlist() { //因为焦点会在按下供货商编辑栏PageDowm后会将焦点转移到ListBox控件中 // TODO: Add your control notification handler code here m_provlist.ShowWindow(SW_HIDE); //隐藏供应商列表控件 } void CBookInput::EditChange() { CString str; m_inputlist.edit.GetWindowText(str); //str保存列表控件第二列单元格实时输入的数据 CString sql = ""; switch(m_inputlist.col) { case 1: //确定列表控件的坐标(点击一行的第二列) { char ww=str.GetAt(0); //获取列表控件第二列单元格实时输入的字符串的第一个字符 switch(ww) { case '4': //在一行的第二列中输入'4'时,搜索数据库中isbn第一个字符为4的记录 { sql.Format("select isbn,bookname,author,bookconcern,price from TB_BookInfo where isbn like '"+str+"%%' "); //当确认第一个isbn的首字母并检索到相应的数据后,每次列表框控件上的编辑栏再添加字母时动态列表控件中的记录会动态的改变。因为sql语句中嵌入的str变量是根据列表框控件上的编辑栏输入值实时改变的 //不过会有重复记录,需要一个方法消除重复 m_infolist.DeleteAllItems(); //刷新之前遍历数据库的记录,以便导入新的纪录 m_pRecordset.CreateInstance(__uuidof(Recordset)); m_pRecordset->raw_Close(); m_pRecordset->Open((_bstr_t)sql,m_pConnection.GetInterfacePtr(),adOpenKeyset,adLockOptimistic,adCmdText); int i=0; // 行数 if(m_pRecordset->RecordCount>0) { while(! m_pRecordset->adoEOF) { m_infolist.InsertItem(100,""); for(int index=0;index<5;index++) //每一行的列数 { str=(TCHAR*)(_bstr_t)m_pRecordset->GetFields()->GetItem((long)index)->Value; // 获得数据库记录中一行中每一个列(字段)的记录 m_infolist.SetItemText(i,index,(TCHAR*)(_bstr_t)str); //在列表控件一行的每个元素中显示数据库一行的每个元素中数据 }//for m_pRecordset->MoveNext(); i +=1; //同一行的列遍历完成后,跳到下一行遍历 } CRect rect; m_inputlist.GetSubItemRect(m_inputlist.row,m_inputlist.col,LVIR_BOUNDS,rect); //通过CCustomGrid类OnButtonDown(鼠标按下这个动作消息)用raw、col保存列表控件的单元格行、列,从而得到相应坐标。LVIR_BOUNDS返回这个单元格的边界矩形。rect用于保存该矩形区域。 m_infolist.MoveWindow(rect.left,rect.bottom+5,300,150); //rect.left是父列表单元格的左边框坐标(显示子列表控件时,左边框与父左边框对齐)rect.bottom+5是父列表单元格的底边框坐标(显示子列表控件时,上边框与父底边框对齐)子列表框左坐标和顶坐标确定其左上坐标。300,150为子列表框的宽、高。 m_infolist.ShowWindow(SW_SHOW); //确定子列表框的坐标后,便可以显示。 }//if(m_pRecordset->RecordCount>0) break; }//case '4': case '6': { sql.Format("select isbn,bookname,author,bookconcern,price from TB_BookInfo where isbn like '"+str+"%%' "); //当确认第一个isbn的首字母并检索到相应的数据后,每次列表框控件上的编辑栏再添加字母时动态列表控件中的记录会动态的改变。因为sql语句中嵌入的str变量是根据列表框控件上的编辑栏输入值实时改变的 //不过会有重复记录,需要一个方法消除重复 m_infolist.DeleteAllItems(); //刷新之前遍历数据库的记录,以便导入新的纪录 m_pRecordset.CreateInstance(__uuidof(Recordset)); m_pRecordset->raw_Close(); m_pRecordset->Open((_bstr_t)sql,m_pConnection.GetInterfacePtr(),adOpenKeyset,adLockOptimistic,adCmdText); //遍历数据库 int i=0; // 行数 if(m_pRecordset->RecordCount>0) { while(! m_pRecordset->adoEOF) { m_infolist.InsertItem(100,""); for(int index=0;index<5;index++) //每一行的列数 { str=(TCHAR*)(_bstr_t)m_pRecordset->GetFields()->GetItem((long)index)->Value; // 获得数据库记录中一行中每一个列(字段)的记录 m_infolist.SetItemText(i,index,(TCHAR*)(_bstr_t)str); //在列表控件一行的每个元素中显示数据库一行的每个元素中数据 }//for m_pRecordset->MoveNext(); i +=1; //同一行的列遍历完成后,跳到下一行遍历 } //确定动态显示列表记录的位置 CRect rect; m_inputlist.GetSubItemRect(m_inputlist.row,m_inputlist.col,LVIR_BOUNDS,rect); //通过CCustomGrid类OnButtonDown(鼠标按下这个动作消息)用raw、col保存列表控件的单元格行、列,从而得到相应坐标。LVIR_BOUNDS返回这个单元格的边界矩形。rect用于保存该矩形区域。 m_infolist.MoveWindow(rect.left,rect.bottom+5,300,150); //rect.left是父列表单元格的左边框坐标(显示子列表控件时,左边框与父左边框对齐)rect.bottom+5是父列表单元格的底边框坐标(显示子列表控件时,上边框与父底边框对齐)子列表框左坐标和顶坐标确定其左上坐标。300,150为子列表框的宽、高。 m_infolist.ShowWindow(SW_SHOW); //确定子列表框的坐标后,便可以显示。 }//if(m_pRecordset->RecordCount>0) break; }//case '6': }//switch(ww) }//case 1: } //switch(m_inputlist.col) } //在动态生成的编辑栏中添加单击事件消息 void CBookInput::OnClickBookinfolist(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here int row = m_infolist.GetSelectionMark(); //确定是哪一条记录 if (row!=-1) { CString temp; temp = m_infolist.GetItemText(row,0); //设置条形码 m_inputlist.SetItemText(m_inputlist.row,1,temp); //设置书籍名称 m_inputlist.SetItemText(m_inputlist.row,2,m_infolist.GetItemText(row,1)); //设置默认价格 m_inputlist.SetItemText(m_inputlist.row,3,m_infolist.GetItemText(row,4)); m_infolist.ShowWindow(SW_HIDE); } //移动编辑框 //MoveFocus(); m_inputlist.col =3; m_inputlist.ShowEdit(); *pResult = 0; }
完