// Test1Dlg.cpp : implementation file
//
#include "stdafx.h"
#include "Test1.h"
#include "Test1Dlg.h"
#include "afxdialogex.h"
#include "expat.h"
#include "sqlite3.h"
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <cassert>
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define NODE_ORG (0) // ORG
#define NODE_VIEW (1) // View
#define NODE_GROUP (2) // Group
#define NODE_USER (3) // User
list <string> g_IdList; // 保存各级的ID,是一个栈的模式开始标记时添加,结束标记时删除
sqlite3 *g_db = NULL;
void TableInit();
void InsertTable(int Id, char* NameValue, int ParentId, char* NodeName);
//HTREEITEM HtParent;
CString t_name;
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// Dialog Data
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
// Implementation
protected:
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()
// CTest1Dlg dialog
CTest1Dlg::CTest1Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CTest1Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTest1Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_TREE1, m_CTreeCtrl);
}
BEGIN_MESSAGE_MAP(CTest1Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BN_LOAD, &CTest1Dlg::OnBnClickedBnLoad)
ON_BN_CLICKED(ID_DISPLAY, &CTest1Dlg::OnBnClickedDisplay)
ON_NOTIFY(TVN_ITEMEXPANDING, IDC_TREE1, &CTest1Dlg::OnDblClkTree) //子项目列表正将展开或收起
//ON_NOTIFY(TVN_GETDISPINFO, IDC_TREE1, &CTest1Dlg::OnDblClkTree) //子项目列表被展开或收起
ON_WM_RBUTTONDBLCLK()
ON_WM_NCLBUTTONDBLCLK()
END_MESSAGE_MAP()
// CTest1Dlg message handlers
BOOL CTest1Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
void CTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CTest1Dlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CTest1Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void startElement(void *userdata, const char *name, const char **atts)
{
// 处理根节点情况
if (name == string("ORG"))
{
InsertTable(0, "ORG", -1, "");
g_IdList.push_front("0"); // 进栈一个“0”
}
else // 一般情况
{
string NodeId = atts[3];
string pID = g_IdList.front(); // 父亲节点ID就是ID栈的前面第一个元素
char* NodeName = const_cast<char*>(atts[1]);
InsertTable(atoi(NodeId.c_str()), NodeName, atoi(pID.c_str()), const_cast<char*>(name));
g_IdList.push_front(atts[3]); // 当前ID进栈
}
return;
}
void endElement(void *userdata, const char *name)
{
g_IdList.pop_front(); // ID出栈
return;
}
void CTest1Dlg::OnBnClickedBnLoad()
{
// TODO: Add your control notification handler code here
char buf[1024] = {0};
int nRead = 0;
FILE *fp = NULL;
XML_Parser parser;
int done;
int depth = 0;
void *userData;
const char *name;
const char **atts;
fp = fopen("E:\\org.xml","r");
if(fp == NULL)
return;
TableInit();//初始化表结构
parser = XML_ParserCreate(NULL);
XML_SetUserData(parser, &depth);
XML_SetElementHandler(parser, startElement, endElement);
do
{
nRead = fread(buf, sizeof(char),1024, fp);
if(nRead == 0)
break;
else if(nRead == 1024)
done = 0;
else
done = 1;
if(XML_Parse(parser, buf, nRead, done) == XML_STATUS_ERROR)
{
return;
}
}while(!done);
XML_ParserFree(parser);
fclose(fp);
return;
}
//初始化表结构
void TableInit()
{
int rc = sqlite3_open("xml.db", &g_db);
if (rc)
{
fprintf(stderr, "can't open db!\n", sqlite3_errmsg(g_db));
sqlite3_close(g_db);
exit(1);
}
else
{
printf("db open successfully!\n");
}
sqlite3_exec(g_db,
"CREATE TABLE XMLDATA(INT NODEID PRIMARY KEY, NAMEVALUE VARCHAR(20) NOT NULL, PARENTID INT DEFAULT NULL, NODENAME VARCHAR(10));",
0, 0, 0);
return;
}
// 插入数据到数据库中的XMLDATA表中
void InsertTable(int Id, char* NameValue, int ParentId, char* NodeName)
{
char sql[200] = "";
sprintf(sql, "INSERT INTO XMLDATA VALUES (%d, '%s', %d, '%s')", Id, NameValue, ParentId, NodeName);
sqlite3_exec(g_db, sql, 0, 0, 0);
}
// 显示按钮
void CTest1Dlg::OnBnClickedDisplay()
{
// TODO: Add your control notification handler code here
// 插入根节点
HTREEITEM Ht1 = m_CTreeCtrl.InsertItem(CString("0"),TVI_ROOT); // 显示ID
HTREEITEM Ht1 = m_CTreeCtrl.InsertItem(CString("ORG"),TVI_ROOT);
// 指定含有子节点,节点前方有加号
TVITEM tvItem = {0};
tvItem.mask = TVIF_HANDLE | TVIF_CHILDREN;
tvItem.hItem = Ht1;
tvItem.cChildren = 1;
m_CTreeCtrl.SetItem(&tvItem);
return;
}
// 展开事件处理函数
void CTest1Dlg::OnDblClkTree(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CPoint pt;
pt=GetCurrentMessage()->pt;
m_CTreeCtrl.ScreenToClient(&pt);
UINT uFlag = 0;
// //HTREEITEM hCur = m_CTreeCtrl.GetSelectedItem(); //双击节点进行操作
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR); // 点击“+”号有反应
HTREEITEM hCur = pNMTreeView->itemNew.hItem;
HTREEITEM hItem = m_CTreeCtrl.HitTest(pt, &uFlag);
//if (hItem)
//{
//if ((m_CTreeCtrl.GetItemState(hItem,TVIS_EXPANDEDONCE )&TVIS_EXPANDEDONCE )!=0 ) //判断是否扩展过一次,若是直接调用EXPAND
//{
// m_CTreeCtrl.SelectItem(hItem); //收缩节点时,必须先选择改节点
//m_CTreeCtrl.Expand(hItem,TVE_TOGGLE);
//}
if ((m_CTreeCtrl.GetItemState(hItem,TVIS_EXPANDEDONCE )&TVIS_EXPANDEDONCE ) == 0)
{
int rc = sqlite3_open("xml.db", &g_db);
if (rc)
{
fprintf(stderr, "can't open db!\n", sqlite3_errmsg(g_db));
sqlite3_close(g_db);
exit(1);
}
// 得到节点文本值
CString S1 = m_CTreeCtrl.GetItemText(hCur);
int iTextLen = WideCharToMultiByte ( CP_UTF8, 0, S1, -1, NULL, 0, NULL, NULL);
char* pElementText = new char[iTextLen + 1];
memset((void*)pElementText, 0, sizeof(char)*(iTextLen + 1));
WideCharToMultiByte( CP_UTF8,0, S1, -1, pElementText, iTextLen, NULL, NULL );
int i, nrows, ncols;
char *errmsg = NULL;
char **results;
char sql[200] = "";
/*sprintf(sql, "SELECT * FROM XMLDATA WHERE PARENTID = %d", _ttoi(S1));
sqlite3_get_table(g_db, sql, &results, &nrows, &ncols, &errmsg);*/ //显示ID
sprintf(sql, "SELECT * FROM XMLDATA WHERE NAMEVALUE = '%s'", pElementText); // 由nodename得到当前ID,作为父节点ID查找所有子节点并显示 (LPSTR)(LPCTSTR)s;
sqlite3_get_table(g_db, sql, &results, &nrows, &ncols, &errmsg);
results[4];
int nrows1, ncols1;
char *errmsg1 = NULL;
char **results1;
char sql1[200] = "";
sprintf(sql1, "SELECT * FROM XMLDATA WHERE PARENTID = %d", atoi(results[4]));
sqlite3_get_table(g_db, sql1, &results1, &nrows1, &ncols1, &errmsg1);
//AfxMessageBox(CString(results[5]));
for (i = 1; i < nrows1+1; i++) // 插入该节点所有的子节点
{
WCHAR wtext[MAX_PATH] = {0};
int nReturn = MultiByteToWideChar(CP_UTF8, 0, results1[4*i+1], -1, wtext, MAX_PATH);// 将namaAttribute转换为宽字符wtext
CString NameValue(wtext, nReturn);
HTREEITEM Ht = m_CTreeCtrl.InsertItem(NameValue, hCur, TVI_LAST); // 插入子节点
CString NodeName = CString(results1[4*i+3]);
//HTREEITEM Ht = m_CTreeCtrl.InsertItem(CString(results[4*i]), hCur, TVI_LAST); //显示ID
if (NodeName != "User") // 节点类型不是User,为节点前面添上加号
{
TVITEM tvItem = {0};
tvItem.mask = TVIF_HANDLE | TVIF_CHILDREN;
tvItem.hItem = Ht;
tvItem.cChildren = 1;
m_CTreeCtrl.SetItem(&tvItem);
}
}
sqlite3_close(g_db);
}
//}
//AfxMessageBox(S1);
*pResult = 0;
}
/*
//从数据库中查找PARENTID为PID的所有节点,将其添加到父节点ht下
void CTest1Dlg::m_InsertTree(char* PId, HTREEITEM ht)
{
int i, nrows, ncols;
char *errmsg = NULL;
char **results;
char sql[200] = "";
sprintf(sql, "SELECT * FROM XMLDATA WHERE PARENTID = %d", atoi(PId));
sqlite3_get_table(g_db, sql, &results, &nrows, &ncols, &errmsg);
for (i = 1; i < nrows+1; i++) // 插入该节点所有的子节点
{
WCHAR wtext[MAX_PATH] = {0};
int nReturn = MultiByteToWideChar(CP_UTF8, 0, results[4*i+1], -1, wtext, MAX_PATH);// 将namaAttribute转换为宽字符wtext
CString NodeName(wtext, nReturn);
HTREEITEM htt = m_CTreeCtrl.InsertItem(NodeName, ht, TVI_LAST); // 插入子节点
m_InsertTree(results[4*i], htt); // 递归调用,插入该子节点的子节点
}
sqlite3_free_table(results); // free
return;
}
*/
展开消息处理函数
最新推荐文章于 2018-10-25 17:30:54 发布