基于Win32 SDK的SQLite3客户端开发
核心功能设计
本项目实现一个基于Win32 SDK的轻量级SQLite3数据库管理工具,采用单文件架构,集成树形结构显示、列表视图展示及命令行输入交互。程序通过封装控件类实现模块化,全局变量便于消息回调调用。
关键技术实现
- 控件封装:将Tree、ListView、Edit控件分别封装为独立类,保持窗口过程分离,通过全局实例访问
- 加密支持:集成wxSQLite3库,根据用户操作判断是否为加密数据库(密码对话框确认/取消)
- 动态结构加载:打开数据库后,自动读取sqlite_master表构建树形目录结构
- 命令行执行:Edit控件支持回车执行SQL,ESC切换输入模式,支持粘贴与键盘输入
工程配置要点
- 复制wxsqlite3-4.5.1\sqlite3secure\src至项目目录
- VC++包含路径添加wxsqlite3源码路径,源文件包含sqlite3.h和sqlite3secure.c
- 设置sqlite3secure.c属性为不使用预编译头
- 定义预处理宏:
SQLITE_ENABLE_RTREE SQLITE_ENABLE_COLUMN_METADATA SQLITE_HAS_CODEC=1 SQLITE3ENCRYPT_EXPORTS SQLITE_ENABLE_FTS3 SQLITE_ENABLE_FTS3_PARENTHESIS SQLITE_SECURE_DELETE SQLITE_SOUNDEX CODEC_TYPE=CODEC_TYPE_AES256
界面布局与交互
界面采用分栏布局,左侧树形控件显示数据库对象层级,中间列表视图呈现查询结果,底部编辑区支持SQL命令输入。
核心类结构
class CApp // 主应用类,管理窗口生命周期 class CTree // 树形控件封装,支持递归展开与右键菜单 class CListView // 列表视图封装,动态更新数据 class CEdit // 编辑控件增强,拦截按键并处理命令 class CSQL // SQL执行器,封装数据库操作逻辑
关键代码片段
编辑控件按键处理
LRESULT CALLBACK CEdit::NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_CHAR:
switch (wParam) {
case '\r': // 回车执行
SendMessage(GetParent(hWnd), WM_COMMAND, IDX_EDIT_COMMAND, 0);
command[0] = 0;
commandnum = 0;
break;
case VK_ESCAPE: // ESC切换模式
commandtype = (commandtype + 1) % 3;
PRINT("\r\n%hs>", modeText[commandtype]);
break;
case '\b': // 删除
if (commandnum > 0) commandnum--;
break;
default:
if (commandnum < 10000) {
command[commandnum++] = wParam;
command[commandnum] = 0;
}
break;
}
break;
}
return CallWindowProc(OldWndProc, hWnd, message, wParam, lParam);
}
数据库结构加载
int CSQL::Open(LPTSTR szFileName)
{
m_SQLite.Open(szFileName);
DlgPassword(); // 弹出密码对话框
m_Tree1.DeleteAllItem();
Query(_T("SELECT type,name,tbl_name,rootpage, sql FROM sqlite_master ORDER BY type"));
HTREEITEM hRoot = m_Tree1.InsertTreeNode(NULL, _T("wxSQLite3"));
HTREEITEM hDB = m_Tree1.InsertTreeNode(hRoot, szFileName);
for (int i = 0; i < m_row; i++) {
TCHAR type[32], name[256];
ListView_GetItemText(m_ListView1.m_hWnd, i, 0, type, 31);
ListView_GetItemText(m_ListView1.m_hWnd, i, 1, name, 255);
HTREEITEM parent = (i == 0 || strcmp(type, lastType)) ?
m_Tree1.InsertTreeNode(hDB, type) : parent;
m_Tree1.InsertTreeNode(parent, name);
strcpy(lastType, type);
}
m_Tree1.ExpandAll(hDB); // 展开所有节点
return 1;
}
密码对话框实现
BOOL CALLBACK PasswordProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG:
pSQLite = (CwxSQLite*)lParam;
SetDlgItemText(hDlg, IDC_EDIT_OP1, _T("password"));
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
GetDlgItemText(hDlg, IDC_EDIT_OP1, szPassWord, 256);
pSQLite->SetPassWord(1, szPassWord, NULL); // 设置密码
EndDialog(hDlg, TRUE);
break;
}
break;
}
return FALSE;
}