用ListView 控件修改单元格数据,并update到SQLite数据库
用ListView控件显示SQlite数据,响应双击消息,在对应的单元格上放置Edit控件,编辑后回车,保存数据,更新Item中字符串,ESC取消数据。
保存时,利用备份的单元格数据和ListView Item显示的数据一起构建成 update语句,保存进数据库。
主要的代码:
SQLView.h
#pragma once #include "xmdiview.h" #include "stdio.h" #include "sqlite3.h" struct SQLCell { int x_row; int y_colum; int len; int Modifyed; TCHAR *text; }; class CSQLTable { public: CSQLTable(void); ~CSQLTable(void); int Max_row; int Max_column; int Modifyed; int Select_column; int Select_row; TCHAR table[1024]; SQLCell** Cell; int Empty(); }; class CSQLView : public CXMDIView { public: CSQLView(void); ~CSQLView(void); XDECLARE_DYNCREATE(CSQLView) public: CXWnd* m_pMainFrame; virtual BOOL PreCreateWindow(WNDCLASSEX &cs); virtual BOOL PreCreateWindow(MDICREATESTRUCT &mdicreate); int OnCreate(HWND, UINT, WPARAM, LPARAM); int OnPaint(HWND, UINT, WPARAM, LPARAM); int OnSize(HWND, UINT, WPARAM, LPARAM); int OnChar(HWND, UINT, WPARAM, LPARAM); int OnClose(HWND, UINT, WPARAM, LPARAM); int OnNotify(HWND, UINT, WPARAM, LPARAM); virtual int OnDestroy(HWND, UINT, WPARAM, LPARAM); int OnExit(HWND, UINT, WPARAM, LPARAM); int OnTest1(HWND, UINT, WPARAM, LPARAM); int OnTest2(HWND, UINT, WPARAM, LPARAM); int OnSQL(HWND, UINT, WPARAM, LPARAM); int OnEXEC(HWND, UINT, WPARAM, LPARAM); int OnTables(HWND, UINT, WPARAM, LPARAM); HWND m_hListView1; HWND m_hWndLVEdit; LV_COLUMN m_List1; LVITEM m_Item1; HIMAGELIST m_ImgList1; HWND CreateListView (HWND hwndParent); int InitListView (HWND hListView); int UpdateListView (HWND hListView, int nrow, int ncol, TCHAR **pData); HTREEITEM hNodeSQLite3; void *pTree; static LONG lpfnDefLVEdit; static LRESULT CALLBACK LVEditWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); static TCHAR LVEditText[1024]; HWND m_hWndToolBar; HWND CreateToolbar(HWND hWnd); sqlite3 *db; char *szErrMsg; int rc; char sql[1024]; static int sqlcallback(void *NotUsed, int argc, char **argv, char **azColName); int OnSaveTables(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); int Open(HWND hWnd); int ListTables(HWND hWnd); int OnSQLData(TCHAR* wSQL); int OnSqlExec(TCHAR* wSQL); CSQLTable m_SQLTable; int OnSQLData(TCHAR* wSQL, CSQLTable &wSQLTable); int SQLUpdateListView(CSQLTable &wSQLTable); XDECLARE_MESSAGE_MAP() };
SQLView.cpp
#include "StdAfx.h" #include "SQLView.h" #include "sqlite3.h" #include "main.h" #include "PrjTree.h" CSQLTable::CSQLTable(void) { Max_row = 0; Max_column = 0; } CSQLTable::~CSQLTable(void) { Empty(); } int CSQLTable::Empty() { int i,j; Modifyed = 0; Select_column = 0; Select_row =0; if(Max_row == 0) return 0; for(i=0;i<Max_row; i++) // include head { for(j = 0; j< Max_column;j++) { delete[] Cell[i][j].text; } delete [] Cell[i]; } delete [] Cell; Max_row = 0; Max_column = 0; return 1; } XIMPLEMENT_DYNCREATE(CSQLView, CXMDIView) XBEGIN_MESSAGE_MAP(CSQLView, CXMDIView) XON_MESSAGE(WM_CREATE, OnCreate) XON_MESSAGE(WM_SIZE, OnSize) XON_MESSAGE(WM_DESTROY, OnDestroy) XON_MESSAGE(WM_COMMAND, OnCommand) XON_MESSAGE(WM_CHAR, OnChar) XON_MESSAGE(WM_CLOSE, OnClose) XON_MESSAGE(WM_NOTIFY, OnNotify) XON_COMMAND(IDM_TVIEW_TEST_TEST1, OnTest1) XON_COMMAND(IDM_TVIEW_TEST_TEST2, OnTest2) XON_COMMAND(IDM_SQLVIEW_SQL, OnSQL) XON_COMMAND(IDM_SQLVIEW_EXEC, OnEXEC) XON_COMMAND(IDM_SQLVIEW_TABLES, OnTables) XON_COMMAND(IDM_SQLVIEW_SAVETABLES, OnSaveTables) XEND_MESSAGE_MAP() CSQLView::CSQLView(void) { wcscpy_s(szWindowClass,_T("XSQLView")); // The title bar text wcscpy_s(szTitle,_T("XSQLView")); m_hWnd = NULL; } CSQLView::~CSQLView(void) { } TCHAR CSQLView::LVEditText[1024]= _T("") ; LONG CSQLView::lpfnDefLVEdit = 0; LRESULT CALLBACK CSQLView::LVEditWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hListView; HWND hSQLView; static CSQLTable *wSQLTable = NULL; int row,colum; LVITEM lvItem; TCHAR wBuf[1024]; switch (message) { case WM_CREATE: break; case WM_ACTIVATE: PRINT(_T("\r\n WM_ACTIVATE-r ")); ShowWindow(hWnd, SW_HIDE); break; case WM_SIZE: break; case WM_COMMAND: { switch(wParam) { case EN_CHANGE: PRINT(_T("\r\nchange ")); break; case 0: wSQLTable = (CSQLTable *)lParam; PRINT(_T("\r\SelectCell=%d,%d "), wSQLTable->Select_column,wSQLTable->Select_row); break; } } break; case WM_CHAR: switch(wParam) { case '\r': PRINT(_T("\r\n get -r ")); GetWindowText(hWnd,wBuf,1024); ShowWindow(hWnd, SW_HIDE); hListView = GetParent(hWnd); hSQLView = GetParent(hListView); row =wSQLTable->Select_row; colum = wSQLTable->Select_column; lvItem.mask = LVIF_TEXT; lvItem.iItem = row -1; lvItem.iSubItem = colum; lvItem.pszText = wBuf; ListView_SetItem(hListView,&lvItem); // for cell SendMessage(hSQLView, WM_COMMAND, IDM_TVIEW_TEST_TEST2, (LPARAM)hWnd); break; case '\n': PRINT(_T("\r\n get -n ")); break; case 0x1b: PRINT(_T("\r\n get -ESC ")); ShowWindow(hWnd, SW_HIDE); break; default: break; } break; default: break; } return CallWindowProc((WNDPROC)lpfnDefLVEdit, hWnd, message, wParam, lParam); } HWND CSQLView::CreateListView (HWND hwndParent) { DWORD dwStyle; dwStyle = WS_TABSTOP|WS_CHILD|WS_BORDER|WS_VISIBLE|LVS_REPORT; HWND hWndListView = CreateWindow (WC_LISTVIEW, _T("ListView"), dwStyle, 0, 0,0,0, hwndParent, (HMENU)IDC_VIEW_LISTVIEW,m_hInst,NULL);
ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT| LVS_EX_GRIDLINES); // LVS_EX_FULLROWSELECT is important ? //LVS_EX_CHECKBOXES return (hWndListView); } BOOL CSQLView::PreCreateWindow(WNDCLASSEX &cs) { return TRUE; } BOOL CSQLView::PreCreateWindow(MDICREATESTRUCT &mdicreate) { m_hMenu = LoadMenu(m_hInst, TEXT("MDIMENUTESTVIEW")); //for MDIFrame Menu When Active m_hMenuWindow = GetSubMenu(m_hMenu, TEST_MENU_POS); //Windows Menu Pos return TRUE; } int CSQLView::OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { m_hListView1 = CreateListView(hWnd); m_hWndLVEdit = CreateWindow(TEXT("edit"), NULL, WS_CHILD|WS_BORDER, 0,0,0,0, m_hListView1, (HMENU) 0, m_hInst, NULL); lpfnDefLVEdit = SetWindowLong(m_hWndLVEdit, GWL_WNDPROC, (LONG)LVEditWndProc); m_hWndToolBar = CreateToolbar(hWnd); if(Open(hWnd)) { PRINT(_T("\r\n test.db Open OK!")); } ListTables(hWnd); return 0; } int CSQLView::OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rt; hdc = BeginPaint(hWnd, &ps); EndPaint(hWnd, &ps); return 0; } int CSQLView::OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int cxClient,cyClient; cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); MoveWindow(m_hListView1, 0, 25, cxClient, cyClient -25, TRUE); MoveWindow(m_hWndToolBar, 0, 0, 0, 0, TRUE); return DefMDIChildProc(hWnd, message, wParam, lParam); } int CSQLView::OnChar(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { return DefMDIChildProc(hWnd, message, wParam, lParam); } int CSQLView::OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { m_hWnd = NULL; sqlite3_close(db); // PostQuitMessage(0); return 0; } int CSQLView::OnExit(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { DestroyWindow(hWnd); return 0; } int CSQLView::OnClose(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { return DefMDIChildProc(hWnd, message, wParam, lParam); } int CSQLView::OnTest1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PRINT(_T("\r\n Test1!")); return 0; } int CSQLView::OnTest2(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { LV_COLUMN lvColum; LVITEM lvItem; TCHAR wBuf[1024]; PRINT(_T("\r\n Test2!")); int row,colum; row = m_SQLTable.Select_row-1; colum = m_SQLTable.Select_column; lvColum.mask = LVCF_TEXT; lvColum.iSubItem = 0; lvColum.pszText = _T("*No"); ListView_SetColumn(m_hListView1,0, &lvColum); lvItem.mask = LVIF_TEXT; lvItem.iItem =row; lvItem.iSubItem = 0; // No swprintf(wBuf, _T("*%4d"),row+1); //begin from 0 lvItem.pszText = wBuf; ListView_SetItem(m_hListView1,&lvItem); // for cell return 0; } int CSQLView::OnSQL(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR wSTR[1024]; HWND hStr = ((CMain*)m_pMainFrame)->m_pPBottom->m_pStrBox->m_hWndEditMsg; //for input sql GetWindowText(hStr, wSTR, 1024); PRINT(_T("\r\n OnSQL=%s"), wSTR); m_SQLTable.Empty(); OnSQLData(wSTR, m_SQLTable); SQLUpdateListView(m_SQLTable); return 0; } int CSQLView::OnEXEC(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PRINT(_T("\r\n OnSQL!")); TCHAR wSTR[1024]; HWND hStr = ((CMain*)m_pMainFrame)->m_pPBottom->m_pStrBox->m_hWndEditMsg; GetWindowText(hStr,wSTR, 1024); PRINT(_T("\r\n OnSQL=%s"), wSTR); OnSqlExec(wSTR); return 0; } int CSQLView::OnTables(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PRINT(_T("\r\nselect * from sqlite_master;")); m_SQLTable.Empty(); OnSQLData(_T("select * from sqlite_master;"), m_SQLTable); SQLUpdateListView(m_SQLTable); return 0; } int CSQLView::OnSaveTables(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int i,j; int column, row; LV_COLUMN lvColum; LVITEM lvItem; TCHAR wBuf[1024]=_T(""); TCHAR wSQL[1024]=_T(""); TCHAR wLVText[1024]=_T(""); char str[1024]=""; if(m_SQLTable.Max_row == 0) { PRINT(_T("\r\nNothing in table;")); return 0; } if(m_SQLTable.Modifyed == 0) { PRINT(_T("\r\nNothing to save;")); //return 0; } column=m_SQLTable.Max_column; row=m_SQLTable.Select_row; swprintf(wSQL, _T("UPDATE TTest SET ")); // how to get the Table name in SQL i = row; j=0; ListView_GetItemText(m_hListView1,i-1, j+1, wLVText, 1024); swprintf(wBuf, _T("%s=%s "), m_SQLTable.Cell[0][j].text, wLVText ); wcscat(wSQL, wBuf); for( j=1; j<column; j++) { ListView_GetItemText(m_hListView1,i-1, j+1, wLVText, 1024); swprintf(wBuf, _T(",%s=%s "), m_SQLTable.Cell[0][j].text, wLVText ); wcscat(wSQL, wBuf); } j=0; wcscat(wSQL, _T("WHERE ")); swprintf(wBuf, _T("%s=%s "), m_SQLTable.Cell[0][j].text, m_SQLTable.Cell[i][j].text ); wcscat(wSQL, wBuf); for( j=1; j<column; j++) { swprintf(wBuf, _T("and %s=%s "), m_SQLTable.Cell[0][j].text, m_SQLTable.Cell[i][j].text ); wcscat(wSQL, wBuf); } wcscat(wSQL, _T(";")); PRINT(wSQL); OnSqlExec( wSQL); return 0; } HWND CSQLView::CreateToolbar(HWND hWnd) { // image,COMMAND, STATUS, STYLE, TBBUTTON tbButton[] = { { 0, IDM_SQLVIEW_SQL, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 1, IDM_SQLVIEW_EXEC, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 2, IDM_SQLVIEW_TABLES, TBSTATE_ENABLED , TBSTYLE_BUTTON , 0L, 0}, { 3, IDM_SQLVIEW_SAVETABLES, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, -1}, { 4, IDM_SQLVIEW_OPENTABLES, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 5, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 6, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, -1}, { 7, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 8, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 9, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 10, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 11, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 12, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 13, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 14, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 15, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 16, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0}, { 17, IDM_EXIT, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0} }; HINSTANCE hLib = (HINSTANCE) GetWindowLong(hWnd, GWL_HINSTANCE); //It can be other DLL,here same as m_hInst HWND hWndToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, _T(""), WS_VISIBLE|WS_CHILD|TBSTYLE_TOOLTIPS|TBSTYLE_FLAT, //| WS_BORDER 0,0, 0,0, hWnd, (HMENU) IDC_MAINTOOLSBAR, m_hInst, NULL); if(!hWndToolbar) return NULL; SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0); SendMessage(hWndToolbar, TB_SETEXTENDEDSTYLE, 0, (LPARAM)(DWORD)(TBSTYLE_EX_DRAWDDARROWS)); HIMAGELIST hImageList; hImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, //size 16x16 sizeof(tbButton)/sizeof(tbButton[0]), sizeof(tbButton)/sizeof(tbButton[0])); //double space for(unsigned int i = 0 ; i <= sizeof(tbButton)/sizeof(tbButton[0]) ; i++) { HICON hIcon = LoadIcon(hLib, MAKEINTRESOURCE(IDI_ICON1 + i)); ImageList_AddIcon(hImageList, hIcon); DestroyIcon(hIcon); } SendMessage(hWndToolbar, TB_SETIMAGELIST, 0, (LPARAM)hImageList); SendMessage(hWndToolbar, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(16, 16)); //size 16x16 SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0); SendMessage(hWndToolbar, TB_ADDBUTTONS, 16, (LONG) &tbButton); //add 16-2 button return hWndToolbar; } //sql执行回调函数 int CSQLView::sqlcallback(void *NotUsed, int argc, char **argv, char **azColName) { int i; for(i=0; i<argc; i++){ PRINT(_T("%s = %s\n"), azColName[i], argv[i]?argv[i]:"NULL"); } PRINT(_T("\r\n")); return 0; } //打开数据库 int CSQLView::Open(HWND hWnd) { rc=sqlite3_open("test.db", &db); /* open database */ if(rc) { PRINT(_T("\r\n<ERR>Can't open database: %s\n"), sqlite3_errmsg(db)); sqlite3_close(db); return -1; } //wsprintf(StatusText, _T(" test.db open")); return 1; } int CSQLView::ListTables(HWND hWnd) { int i,j; m_SQLTable.Empty(); OnSQLData(_T("select * from sqlite_master limit 100;"), m_SQLTable); // MAX 100 SQLUpdateListView(m_SQLTable); HWND hTree; HTREEITEM m_hNodeSQL; HTREEITEM m_hNodeDB; HTREEITEM hti; CPrjTree *pTree = NULL; pTree = ((CMain*)m_pMainFrame)->m_pPLeft->m_pPrjTree; hTree =pTree->m_hWndTree; m_hNodeSQL =pTree->m_hNodeSQLite3; m_hNodeDB =pTree->m_hNodeSQLite3DB; m_hNodeDB = pTree->InsertTreeNode(hTree, m_hNodeSQL, _T("Test1.db")); for(i=1;i<m_SQLTable.Max_row;i++) { hti = pTree->InsertTreeNode(hTree, m_hNodeDB, m_SQLTable.Cell[i][2].text); } hti = pTree->InsertTreeNode(hTree, m_hNodeDB, _T("Table2")); SendMessage(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)m_hNodeDB); return 1; } int CSQLView::OnSQLData(TCHAR* wSQL, CSQLTable &wSQLTable) { int i,j; TCHAR wBuf[1024]; wcstombs(sql, wSQL, 1024); char ss[1024]; wcstombs(ss, wSQL, 1024); char *token; char *next_token = NULL; //strcpy(sql,"select * from sqlite_master"); token = strtok_s(ss, "from", &next_token); token = strtok_s(NULL, " ", &next_token); token = strtok_s(NULL, " ", &next_token); mbstowcs(wBuf, token, 1024); PRINT(_T("\r\nTable: %s\n"),wBuf); char **sresult; int nrow = 0, ncolum = 0; rc=sqlite3_get_table(db, sql, &sresult, &nrow, &ncolum,&szErrMsg); /* execute SQL statement */ if(rc!=SQLITE_OK) { if(NULL != szErrMsg) { mbstowcs(wBuf, szErrMsg, 1024); PRINT(_T("\r\n<ERR>SQL error: %s\n"),wBuf); sqlite3_free(szErrMsg); } PRINT(_T("\r\n<OK>select success!")); } PRINT(_T("\r\n row:%d, colum:%d"), nrow, ncolum); wSQLTable.Max_column = ncolum; wSQLTable.Max_row = nrow+1; // include the head wSQLTable.Cell = new SQLCell *[nrow+1]; for(i=0;i<nrow+1; i++) { wSQLTable.Cell[i] = new SQLCell[ncolum]; for(j = 0; j< ncolum;j++) { if(sresult[i*ncolum+j] !=NULL) { wSQLTable.Cell[i][j].len = 0; wSQLTable.Cell[i][j].len = strlen(sresult[i*ncolum+j]) + 1; //xgz 长度要加上结尾符号??? wSQLTable.Cell[i][j].text = new TCHAR[wSQLTable.Cell[i][j].len]; mbstowcs(wSQLTable.Cell[i][j].text, sresult[i*ncolum+j], 1024); } else { wSQLTable.Cell[i][j].len = 5; wSQLTable.Cell[i][j].text = new TCHAR[5]; mbstowcs(wSQLTable.Cell[i][j].text, "NULL", 1024); } } } sqlite3_free_table(sresult); return 1; } int CSQLView::SQLUpdateListView(CSQLTable &wSQLTable) { TCHAR wBuf[10]; LV_COLUMN lvColum; LVITEM lvItem; HIMAGELIST ImgList; SendMessage(m_hListView1, LVM_DELETEALLITEMS,0,0); HWND hWndListViewHeader = (HWND)SendMessage(m_hListView1, LVM_GETHEADER, 0 , 0); int nOldCols = SendMessage(hWndListViewHeader, HDM_GETITEMCOUNT, 0 , 0); nOldCols -- ; for (; nOldCols >= 0; nOldCols-- ) SendMessage(m_hListView1, LVM_DELETECOLUMN, nOldCols, 0); lvColum.mask = LVCF_TEXT| LVCF_WIDTH;//|LVCF_SUBITEM; int nrow = wSQLTable.Max_row; int ncolum = wSQLTable.Max_column+1; // add the No colum lvColum.cx = 40; //宽度 lvColum.iSubItem = 0; lvColum.pszText = _T("No"); ListView_InsertColumn(m_hListView1,0, &lvColum); int i,j; lvColum.cx = 100; //宽度 for(i=1;i<ncolum;i++) { lvColum.iSubItem = i; lvColum.pszText = wSQLTable.Cell[0][i-1].text; ListView_InsertColumn(m_hListView1,i, &lvColum); } ListView_SetItemCount(m_hListView1,nrow+2); // for memory lvItem.mask = LVIF_TEXT; for(i=1;i<nrow;i++) // nrow include head { lvItem.iItem = i-1; lvItem.iSubItem = 0; // No swprintf(wBuf, _T("%4d"),i-1); //begin from 0 lvItem.pszText = wBuf; ListView_InsertItem(m_hListView1,&lvItem); // for cell for(j=1;j<ncolum;j++) { lvItem.iSubItem = j; lvItem.pszText = wSQLTable.Cell[i][j-1].text; //have No colum ListView_SetItem(m_hListView1,&lvItem); // for cell } } return 1; } int CSQLView::OnSqlExec(TCHAR* wSQL) { TCHAR wBuf[1024]; wcstombs(sql, wSQL, 1024); rc=sqlite3_exec(db, sql, sqlcallback,0,&szErrMsg); /* execute SQL statement */ if(rc!=SQLITE_OK){ mbstowcs(wBuf, szErrMsg, 1024); PRINT(_T("\r\n<ERR>SQL error: %s"), wBuf); //szErrMsg sqlite3_free(szErrMsg); return -1; } PRINT(_T("\r\n EXEC OK")); return 1; } int CSQLView::OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rt; int iItem; int iSubItem; LVITEM lvItem; TCHAR text[1024]; LPNMHDR lphr = (LPNMHDR)lParam; if (lphr->hwndFrom == m_hWndLVEdit) { PRINT(_T("\r\nm_hWndLVEdit code=%x"),lphr->code); } if (lphr->hwndFrom == m_hListView1) { switch (lphr->code) { case NM_DBLCLK: iItem = ((LPNMITEMACTIVATE)lParam)->iItem; iSubItem=((LPNMITEMACTIVATE)lParam)->iSubItem; if(iSubItem ==0) break; ListView_GetSubItemRect(m_hListView1, iItem, iSubItem,LVIR_BOUNDS,&rt); PRINT(_T("\r\n NM_CLICK = %d %d -[%d %d : %d %d]"), iItem,iSubItem, rt.left,rt.top,rt.right,rt.bottom); ListView_GetItemText(m_hListView1,iItem, iSubItem, text, 1024); MoveWindow(m_hWndLVEdit, rt.left,rt.top,rt.right-rt.left,rt.bottom-rt.top,TRUE); SetWindowText(m_hWndLVEdit, text); ShowWindow(m_hWndLVEdit,SW_SHOW); m_SQLTable.Select_column = iSubItem; m_SQLTable.Select_row = iItem+1; SendMessage(m_hWndLVEdit, WM_COMMAND, 0, (LPARAM) &m_SQLTable); break; case NM_CLICK: ShowWindow(m_hWndLVEdit,SW_HIDE); break; default: //PRINT(_T("\r\n code=%x"),lphr->code); break; } } // return 0; return DefMDIChildProc(hWnd, message, wParam, lParam); }
C++ 编好框架后,写起程序来更方便。做一个花里胡哨的界面,如果用C语言可能代码组织起来会困难一些。
UNICODE编程,对于接口程序,需要转换,比较麻烦。