使用C编程实现Listview控件与数据库的无缝连接操作 (c listview 添加数据库)

Listview控件是Windows中常用的一种视窗控件,它可以在Windows的用户界面中显示类似于列表的数据。而数据库是现在最常用的一种数据存储方式,它可以帮助我们储存、管理和检索数据。在许多Windows应用程序中,需要把这两种技术结合起来,将数据库中的数据通过Listview控件展示出来,从而实现更好的用户体验。在本文中,将介绍如何。

一、环境搭建

首先要搭建C编程的环境,这里我们使用Visual Studio 2023。打开Visual Studio后,选择“新建项目”,选择Visual C++ → Windows桌面,选择“Windows桌面向导”。

在窗口右边选择“Windows应用程序”,填写应用程序名称和位置。选择合适的位置,这里选择“桌面(Desktop)”,然后单击“下一步”。在下一个窗口中,我们可以选择我们希望生成的代码类型,这里选择“空项目”。

单击“完成”来生成项目。

二、关联ListView控件

接下来,我们将开始创建Listview控件。选择“解决方案资源管理器”中的项目名称,右键单击,选择“添加新项”。

在弹出的向导窗口中,选择“对话框”并输入名称,这里命名为“ListviewDialog”。

在左侧的“工具箱”面板中找到“ListView”控件,将其拖动到对话框上,然后更改ListView的ID名称,命名为“IDC_LISTVIEW1”。

在对话框上单击两次“OK”保存更改。

三、实现与数据库的连接操作

接下来,我们需要创建一个SQLite数据库,这里我们使用SQLite3 C API。SQLite是一种轻型的关系型数据库管理系统,非常适合开发小型的应用程序。

1. 引入SQLite头文件

我们需要在代码中加入头文件sqlite3.h,在stdc++头文件之前定义_MSC_VER要求Visual Studio使用C99标准。

#ifdef _MSC_VER

# define _CRT_SECURE_NO_WARNINGS

#endif

#include

#include

#include

#ifndef _MSC_VER

# define _T

#endif

#include “sqlite3.h”

2. 创建数据库并连接

我们需要在代码中创建一个数据库,并连接到该数据库。在这个过程中,我们还需要定义一个回调函数,用于告诉我们关于数据库操作的信息。

//定义数据库操作回调函数

static int callback(void *NotUsed, int argc, char **argv, char **azColName) {

for (int i = 0; i

printf(“%s = %s\n”, azColName[i], argv[i] ? argv[i] : “NULL”);

}

printf(“\n”);

return 0;

}

//创建数据库并连接

int createDatabase() {

sqlite3 *db;

char *zErrMsg = 0;

int rc;

rc = sqlite3_open(“test.db”, &db);

if (rc) {

fprintf(stderr, “Can’t open database: %s\n”, sqlite3_errmsg(db));

return(0);

}

else {

fprintf(stderr, “Opened database successfully\n”);

}

sqlite3_close(db);

return(0);

}

3. 创建表

现在,我们应该已经创建了一个空的数据库。 接下来,我们将在该数据库中创建一张表,并将其与Listview控件进行关联。在我们的例子中,我们将创建一张名为“students”的表。

int createTable() {

sqlite3* db;

char* zErrMsg = 0;

int rc;

rc = sqlite3_open(“test.db”, &db);

if (rc) {

fprintf(stderr, “Can’t open database: %s\n”, sqlite3_errmsg(db));

return(0);

}

else {

fprintf(stderr, “Opened database successfully\n”);

}

char* sql = “CREATE TABLE students (” \

“ID INT PRIMARY KEY NOT NULL,” \

“NAME TEXT NOT NULL,” \

“AGE INT NOT NULL,” \

“ADDRESS CHAR(50),” \

“SALARY REAL );”;

rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);

if (rc != SQLITE_OK) {

fprintf(stderr, “SQL error: %s\n”, zErrMsg);

sqlite3_free(zErrMsg);

}

else {

fprintf(stdout, “Table created successfully\n”);

}

sqlite3_close(db);

return 0;

}

四、查询数据库

创建完表之后,我们需要从数据库中查询数据,并将其填充到Listview控件中。我们需要使用sqlite3_prepare_v2()函数准备查询语句,并使用sqlite3_step()函数执行查询。我们需要将Listview控件用到的数据加载到内存中,再使用ListView控件的消息机制将其显示,这些都需要使用Win32 API来完成。

1.加载查询结果到内存

我们将创建一个名为“loadDataToListView”的函数。这个函数将会从数据库中查询数据,然后将其存储到一个数组中。在完成数据加载之后,我们还必须将数组中的数据加载到ListView控件中。

static int loadDataToListView(HWND hWndListView) {

sqlite3 *db;

sqlite3_stmt *stmt;

int rc;

TCHAR szTemp[256];

LVCOLUMN lvColumn;

LRESULT nIndex;

TCHAR szText[256];

rc = sqlite3_open(“test.db”, &db);

if (rc) {

fprintf(stderr, “Can’t open database: %s\n”, sqlite3_errmsg(db));

sqlite3_close(db);

return FALSE;

}

else {

fprintf(stderr, “Opened database successfully\n”);

}

TCHAR* szSelectSql = _T(“SELECT * FROM students”);

BOOL bContinue = TRUE;

while (bContinue) {

nIndex = SendMessage(hWndListView, LVM_GETITEMCOUNT, 0, 0);

lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;

lvColumn.fmt = LVCFMT_LEFT;

lvColumn.cx = 150;

lvColumn.pszText = _T(“ID”);

SendMessage(hWndListView, LVM_INSERTCOLUMN, 0, (LPARAM)&lvColumn);

lvColumn.pszText = _T(“NAME”);

SendMessage(hWndListView, LVM_INSERTCOLUMN, 1, (LPARAM)&lvColumn);

lvColumn.pszText = _T(“AGE”);

SendMessage(hWndListView, LVM_INSERTCOLUMN, 2, (LPARAM)&lvColumn);

lvColumn.pszText = _T(“ADDRESS”);

SendMessage(hWndListView, LVM_INSERTCOLUMN, 3, (LPARAM)&lvColumn);

lvColumn.pszText = _T(“SALARY”);

SendMessage(hWndListView, LVM_INSERTCOLUMN, 4, (LPARAM)&lvColumn);

rc = sqlite3_prepare_v2(db, szSelectSql, -1, &stmt, 0);

if (rc == SQLITE_OK) {

int nColCount = sqlite3_column_count(stmt);

while (sqlite3_step(stmt) == SQLITE_ROW) {

TCHAR szText[256];

TCHAR szText2[256];

TCHAR szText3[256];

TCHAR szText4[256];

TCHAR szText5[256];

LV_ITEM lvItem = { 0 };

lvItem.mask = LVIF_TEXT;

nIndex = SendMessage(hWndListView, LVM_GETITEMCOUNT, 0, 0);

lvItem.iItem = nIndex;

sprintf(szText, “%d”, sqlite3_column_int(stmt, 0));

sprintf(szText2, “%s”, sqlite3_column_text(stmt, 1));

sprintf(szText3, “%d”, sqlite3_column_int(stmt, 2));

sprintf(szText4, “%s”, sqlite3_column_text(stmt, 3));

sprintf(szText5, “%.2f”, sqlite3_column_double(stmt, 4));

lvItem.pszText = szText;

SendMessage(hWndListView, LVM_INSERTITEM, 0, (LPARAM)&lvItem);

lvItem.pszText = szText2;

SendMessage(hWndListView, LVM_SETITEMTEXT, nIndex, (LPARAM)&lvItem);

lvItem.pszText = szText3;

SendMessage(hWndListView, LVM_SETITEMTEXT, nIndex, (LPARAM)&lvItem);

lvItem.pszText = szText4;

SendMessage(hWndListView, LVM_SETITEMTEXT, nIndex, (LPARAM)&lvItem);

lvItem.pszText = szText5;

SendMessage(hWndListView, LVM_SETITEMTEXT, nIndex, (LPARAM)&lvItem);

}

sqlite3_finalize(stmt);

}

else {

bContinue = FALSE;

}

sqlite3_close(db);

return TRUE;

}

}

我们可以通过调用loadDataToListView()函数,将查询结果加载到ListView控件中。

2. 定义窗口过程

接下来,我们需要定义一个窗口过程,该过程将负责处理Listview控件的事件。我们可以在窗口过程中处理如下事件:

– 初始化Listview控件

– 加载数据到Listview控件

– 响应Listview控件的事件,如选中事件、删除事件等

//定义窗口过程

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

{

static HWND hWndListView;

switch (message)

{

case WM_CREATE:

{

RECT rcList;

GetClientRect(hWnd, &rcList);

hWndListView = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, _T(“List View”),

WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_EDITLABELS,

rcList.left, rcList.top, rcList.right – rcList.left, rcList.bottom – rcList.top,

hWnd, (HMENU)IDC_LISTVIEW1, GetModuleHandle(NULL), NULL);

SendMessage(hWndListView, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);

loadDataToListView(hWndListView);

break;

}

case WM_NOTIFY:

{

switch (((LPNMHDR)lParam)->code)

{

case LVN_ITEMCHANGED: {

LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE)lParam;

if ((lpnmitem->uNewState & LVIS_SELECTED) == LVIS_SELECTED) {

int nIndex = ListView_GetSelectionMark(hWndListView);

TCHAR szText[256];

ListView_GetItemText(hWndListView, nIndex, 1, szText, 256);

MessageBox(hWnd, szText, _T(“Title”), MB_OK);

}

}

}

break;

}

case WM_COMMAND:

int wmId, wmEvent;

wmId = LOWORD(wParam);

wmEvent = HIWORD(wParam);

// Parse the menu selections:

switch (wmId)

{

case ID_FILE_EXIT:

DestroyWindow(hWnd);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

break;

case WM_PNT:

{

PNTSTRUCT ps;

HDC hdc = BeginPnt(hWnd, &ps);

// TODO: Add any drawing code that uses hdc here…

EndPnt(hWnd, &ps);

break;

}

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

五、测试

现在,我们已经完成了数据库和Listview控件的关联,我们需要运行程序,来检查是否正确显示了数据库中的数据。

启动程序后,我们可以看到程序主窗口中显示了一个Listview控件,其中显示了我们之前创建的student表格中的数据。如果我们单击某行数据,程序会显示出该行数据的第二列,也就是学生的名字。

六、


数据运维技术 » 使用C编程实现Listview控件与数据库的无缝连接操作 (c listview 添加数据库)