MFC中动态创建sqlite3页表

时间:2022-07-08 23:03:53

在涉及到sqlite3的操作时不得不考虑创建页表,之前我们都是通过语句直接创建的,你当然也可以这样,不过基于优化界面和考虑到普通用户(我的项目组长这么跟我说的)并不知道sqlite3语句,这时就要思考如何才能做到创建页表.

创建页表最简单的就是拉几个Edit control,往里面输入数据再读取,不过这样做出来的界面仅支持创建你提供的edit control控件个数的字段的页表,并不能做到动态创建页表,例如我下面的就只能创建固定字段的页表

MFC中动态创建sqlite3页表

这是我最开始的想法,不过基于功能的提升及界面的优化,这个界面被我放弃了.在深入了解MFC控件后,我考虑到可以使用list control来作为创建页表的平台.下面讲一下我的具体思路:

①创建一个对话框,里面先拖进list control,给对话框添加好类CTipDlg11(下面控件各项属性最好跟我一致,不然名字太多可能会混乱),给list control添加变量MFC中动态创建sqlite3页表,再拖进几个button作为触发按钮,再拖进几个edit control作为显示,界面大抵如下

MFC中动态创建sqlite3页表

为了方便介绍界面,下面我附上Ctrl+D后的界面

MFC中动态创建sqlite3页表

9是list control设置MFC中动态创建sqlite3页表

添加变量,用于显示要创建的页表的字段以及字段的数据类型和键值

MFC中动态创建sqlite3页表

1添加value变量,用于显示,记录要创建的表名MFC中动态创建sqlite3页表

MFC中动态创建sqlite3页表

10和11是我当时调试界面数据时用到的,我设置的隐形控件,这里就不介绍

12和13是用来显示并记录最终创建页表的SQL语句,给12添加value变量m_string23MFC中动态创建sqlite3页表,给13添加value变量m_string24MFC中动态创建sqlite3页表

②创建一个对话框添加类CTipDlg111,用于控制输入页表字段的各项属性(由于我不是专门做sqlite3开发的,所以这里就简单的意思一下),拖进edit control,拖进combo box用于提示选择数据类型,拖进check box用于选择是否为键值.界面大抵如下

MFC中动态创建sqlite3页表

Ctrl+D

MFC中动态创建sqlite3页表

3用来输入和保存列名,添加value变量MFC中动态创建sqlite3页表设置idMFC中动态创建sqlite3页表

6用来选择数据类型,添加value变量MFC中动态创建sqlite3页表设置MFC中动态创建sqlite3页表

8是用来保存7的返回值,添加value变量MFC中动态创建sqlite3页表设置MFC中动态创建sqlite3页表

③创建一个对话框添加类CTipDlg112,这个界面比较简单,这有一个edit control

MFC中动态创建sqlite3页表

给edit control添加value变量MFC中动态创建sqlite3页表设置MFC中动态创建sqlite3页表

到这里基本的界面就做完了,下面给出各界面对应的代码

首先是创建页表界面,上面我给创建页表界面添加了类CTipDlg11,去解决方案管理器中找到TipDlg11.cpp

TipDlg11.cpp代码如下(因为这不是我的主窗口,所以要自己添加窗口初始化函数BOOL CTipDlg11::OnInitDialog())

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

#include "stdafx.h"
#include "528Update_Mfc.h"
#include "TipDlg11.h"
#include "TipDlg111.h"
#include "TipDlg112.h"


// CTipDlg11 对话框

IMPLEMENT_DYNAMIC(CTipDlg11, CDialog)

CTipDlg11::CTipDlg11(CWnd* pParent /*=NULL*/)
	: CDialog(CTipDlg11::IDD, pParent)
	//, m_string20(_T(""))
	, m_string21(_T(""))
	, m_string23(_T(""))
	, m_string24(_T(""))
{

}

CTipDlg11::~CTipDlg11()
{
}

void CTipDlg11::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_LIST1, m_list5);
	//	DDX_Text(pDX, IDC_EDIT3, m_string20);
	DDX_Text(pDX, IDC_EDIT4, m_string21);
	DDX_Text(pDX, IDC_EDIT9, m_string23);
	DDX_Text(pDX, IDC_EDIT10, m_string24);
}


BEGIN_MESSAGE_MAP(CTipDlg11, CDialog)
	ON_BN_CLICKED(IDC_BUTTON1, &CTipDlg11::OnBnClickedButton1)
	ON_NOTIFY(NM_CLICK, IDC_LIST1, &CTipDlg11::OnNMClickList1)
	ON_BN_CLICKED(IDC_BUTTON2, &CTipDlg11::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CTipDlg11::OnBnClickedButton3)
//	ON_BN_CLICKED(IDC_BUTTON4, &CTipDlg11::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON10, &CTipDlg11::OnBnClickedButton10)
END_MESSAGE_MAP()


// CTipDlg11 消息处理程序

BOOL CTipDlg11::OnInitDialog()   //自己添加
{
	CDialog::OnInitDialog();

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

	if(m_list5.GetItemCount() == 0)  //判断列表项是否存在
	{
		m_list5.InsertColumn(0,_T("字段名"));
		m_list5.InsertColumn(1,_T("数据类型"));
		m_list5.InsertColumn(2,_T("键值"));
	}
	CRect  rect;
	m_list5.SetExtendedStyle(m_list5.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );
	m_list5.GetClientRect(&rect);

	m_list5.SetColumnWidth(0,rect.Width()/3);
	m_list5.SetColumnWidth(1,rect.Width()/3);
	m_list5.SetColumnWidth(2,rect.Width()/3);

	GetDlgItem(IDC_EDIT1)->ShowWindow(false);         //隐藏两个文本框
	GetDlgItem(IDC_EDIT2)->ShowWindow(false);

	return TRUE;  // return TRUE unless you set the focus to a control
	// 异常: OCX 属性页应返回 FALSE
}
char name[20] = {0}; //定义name用来存放增加列时输入的页表名字
void CTipDlg11::OnBnClickedButton1()                                      //增加列
{
	// TODO: 在此添加控件通知处理程序代码
	INT_PTR nRes;             // 用于保存DoModal函数的返回值   
	CTipDlg111 tipDlg1;           // 构造对话框类CTipDlg1的实例   
	nRes = tipDlg1.DoModal();  // 弹出对话框
	UpdateData(TRUE);               // 将各控件中的数据保存到相应的变量
     
	CString buf1 = tipDlg1.m_string18;
	char * buff1 = (char * )buf1.GetBuffer(buf1.GetLength());
	CString buf2 = tipDlg1.m_string19;
	char * buff2 = (char * )buf2.GetBuffer(buf2.GetLength());
	CString buf3 = tipDlg1.m_string20;
	char * buff3 = (char * )buf3.GetBuffer(buf2.GetLength());
    int buff4 = atoi(buff3);    //cstring转int
    /*SetDlgItemText(IDC_EDIT1, buf1);
	SetDlgItemText(IDC_EDIT2, buf2);*/
	CRect rect;   
	// 获取编程语言列表视图控件的位置和大小   
	m_list5.GetClientRect(&rect);   
	// 为列表视图控件添加全行选中和栅格风格
	m_list5.SetExtendedStyle(m_list5.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES );
    if (IDOK == nRes)     //判断窗口的返回值(即窗口返回时点击了什么按钮)
	{
		int i = m_list5.GetItemCount();//获取list里面有多少行  
		CString ttt;  
		ttt.Format("%d",i);  
		m_list5.InsertItem(i,buff1);  //开辟一个行,并且设置行的内容为i的内容  
		m_list5.SetItemText(i,1,buff2);//i代指在第几行插入数据,第二个参数代指第几列,第三个参数代指插入数据的值
		if (1 == buff4)
		{
			m_list5.SetItemText(i,2,_T("primary key"));//i代指在第几行插入数据,第二个参数代指第几列,第三个参数代指插入数据的值
		}
	}
}

void CTipDlg11::OnNMClickList1(NMHDR *pNMHDR, LRESULT *pResult)
{
	// TODO: 在此添加控件通知处理程序代码
	*pResult = 0;
	CString strLangName;    // 选择语言的名称字符串   
	NMLISTVIEW *pNMListView = (NMLISTVIEW*)pNMHDR;   

	if (-1 != pNMListView->iItem)        // 如果iItem不是-1,就说明有列表项被选择   
	{   
		// 获取被选择列表项第一个子项的文本   
		strLangName = m_list5.GetItemText(pNMListView->iItem, 0);
		// 将选择的语言显示与编辑框中   
		SetDlgItemText(IDC_EDIT1, strLangName); 
		SetDlgItemText(IDC_EDIT2, "id为"+strLangName+"的记录被选中");
		//SetDlgItemText(IDC_EDIT3, "    "); 

		UpdateData(TRUE); 
	} 

}

void CTipDlg11::OnBnClickedButton2()  // 删除列    先单击list control表,再点击删除列可以删除
{
	// TODO: 在此添加控件通知处理程序代码
	int nItem = -1;
	POSITION pos;
	while (pos = m_list5.GetFirstSelectedItemPosition())
	{

		nItem = -1;
		nItem = m_list5.GetNextSelectedItem(pos);
		if (nItem >= 0 && m_list5.GetSelectedCount() > 0)
		{
			m_list5.DeleteItem(nItem);
		}
	}
}

void CTipDlg11::OnBnClickedButton10()    //输入表名
{
	// TODO: 在此添加控件通知处理程序代码
	INT_PTR nRes;             // 用于保存DoModal函数的返回值   
	CTipDlg112 tipDlg1;           // 构造对话框类CTipDlg1的实例   
	nRes = tipDlg1.DoModal();  // 弹出对话框
	UpdateData(TRUE);               // 将各控件中的数据保存到相应的变量

	CString buf1 = tipDlg1.m_string22;
	char * buff1 = (char * )buf1.GetBuffer(buf1.GetLength());
	SetDlgItemText(IDC_EDIT4,buf1);
    UpdateData(TRUE);               // 将各控件中的数据保存到相应的变量

}
int allnum = 0; //定义一个变量用于记录list control中有多少数据,这关系到li数组的下标
void CTipDlg11::OnBnClickedButton3()     //创建页表
{
	// TODO: 在此添加控件通知处理程序代码
    int hang = m_list5.GetItemCount();//获取list里面有多少行    行为0~ hang-1
    int lie = 3;  //列为0.1.2
	int jishu = 0;
	//CString str = m_list5.GetItemText(0,0);// 取第一行第一列
	//CString str =m_list5.GetItemText(hang - 1,0); //取第row行第col列!
 //   SetDlgItemText(IDC_EDIT2, str); 
	CString data[1024] = {0};
	char * li[1024] = {0};
	for (int i = 0;i < hang;i++)   //把list control中所有数据取出并转换成char*类型存放在li数组中
	{
	    for(int j = 0;j < lie;j++)
		{
			data[jishu] = m_list5.GetItemText(i,j);
			 li[jishu] = (char * )data[jishu].GetBuffer(data[jishu].GetLength());
			jishu++;
		}
	}
    SetDlgItemText(IDC_EDIT2, data[1]);
	/*CString a;
	a.Format("%s",li[1]);
	SetDlgItemText(IDC_EDIT1, a);*/
    
	CString buf1 = m_string21;   //获取页表名字
	char * buff1 = (char * )buf1.GetBuffer(buf1.GetLength());

   // SetDlgItemText(IDC_EDIT1, buf1);

	allnum = hang*lie;
	/*CString a;          //int转CString
	a.Format("%d", allnum);
	SetDlgItemText(IDC_EDIT1, a);*/
	char str1[] = {" ("};
	char str2[] = {","};
	char str3[] = {")"};
	char str4[] = {" "};
	char str5[] = {"'"};
	int j = 1;
                                           //下面开始编写创建页表的语句
	char lijiaxin[1024] = {"create table "};
	strcat(lijiaxin,buff1);
    strcat(lijiaxin,str1);    //到这里 create table buff1 (
    for(int i = 0 ;i < allnum;i++)
	{
		if(li[i] != "0")
		{
		   strcat(lijiaxin,li[i]);
		   strcat(lijiaxin,str4);
		}
        if(j%3 == 0 && j != allnum)
		{
           strcat(lijiaxin,str2);
		}
		j++;
	}

    strcat(lijiaxin,str3);
	 SetDlgItemText(IDC_EDIT9, lijiaxin);
	                                           //创建页表的语句到这里结束

	 //创建表时自动插入一条语句
    
   
	 char jiaxin[521] = {0};
     sprintf(jiaxin,"insert into %s values ( 001,",buff1);
     char * likeyou = "Please enter";
	 for (int i = 1;i < hang;i++)
	 {
	     strcat(jiaxin,str5);
		 strcat(jiaxin,likeyou);
		// if(i != hang )
		 strcat(jiaxin,str5);
		if(i != hang -1 )
		 strcat(jiaxin,str2);
	 }
	 strcat(jiaxin,str3);
     SetDlgItemText(IDC_EDIT10, jiaxin);
	 //插入语句完成


	//语句写成功,接下来执行exec完成页表的创建
	
}
TipDlg111.cpp代码如下(因为这不是我的主窗口,所以要自己添加窗口初始化函数BOOL CTipDlg11::OnInitDialog())
// TipDlg111.cpp : 实现文件
//

#include "stdafx.h"
#include "528Update_Mfc.h"
#include "TipDlg111.h"


// CTipDlg111 对话框

IMPLEMENT_DYNAMIC(CTipDlg111, CDialog)

CTipDlg111::CTipDlg111(CWnd* pParent /*=NULL*/)
	: CDialog(CTipDlg111::IDD, pParent)
	, m_string18(_T(""))
	, m_string19(_T(""))
	, m_string20(_T(""))
{

}

CTipDlg111::~CTipDlg111()
{
}

void CTipDlg111::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT1, m_string18);
	DDX_CBString(pDX, IDC_COMBO1, m_string19);
	DDX_Control(pDX, IDC_CHECK3, m_check1);
	DDX_Text(pDX, IDC_EDIT2, m_string20);
}


BEGIN_MESSAGE_MAP(CTipDlg111, CDialog)
	ON_CBN_SELCHANGE(IDC_COMBO1, &CTipDlg111::OnCbnSelchangeCombo1)
	ON_BN_CLICKED(IDOK, &CTipDlg111::OnBnClickedOk)
END_MESSAGE_MAP()


// CTipDlg111 消息处理程序

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

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

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

	GetDlgItem(IDC_EDIT2)->ShowWindow(false);
	

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



void CTipDlg111::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	if (1 == m_check1.GetCheck())
	{
        SetDlgItemText(IDC_EDIT2,_T("1"));
	}
	OnOK();
}

CTipDlg112这个窗口没有在源程序中编写代码,就不给TipDlg112.cpp的代码了.

上面我没有给出button的属性参数,可以自己根据代码注释自行修改.

上面的代码可以参考思路过程,由于我是做完后写的博客,可能你在根据本博客实现时会出各种各样的问题,还请自己解决或在下方留言,我工作日都会登录博客,希望可以解决你的问题