展开消息处理函数

// 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;
}
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值