SQLite3 客户端程序,Win32 SDK ,C/C++

发布时间 2023-05-23 14:17:59作者: XGZ21

1  WIn32 SDK 程序,尽量放在一个文件中,主要用到 Tree,ListView,Edit 控件。

2  把控件封装成类,但不封装窗口回调函数。类实例为全局变量,方便消息回调函数调用执行。这样做最简单。

3  Edit控件处理按键输入,模仿shell执行SQL查询

4 打开数据库文件时若没有此文件则新建,否则打开,打开后弹出密码对话框,确认则是wxSQLite3数据库吗,取消则是SQLite3数据库。

 

5 程序界面如下:

5.1  打开文件时根据密码选择是否是加密数据库

 5.2 打开后用sqlite_master表数据 在树中显示数据库结构

5.3  菜单常用命令,如查询,显示表结构等,控制台输入SQL命令。

 

实现如下:

1. 把 wxsqlite3-4.5.1.zip\wxsqlite3-4.5.1\sqlite3secure\src 整个目录复制到工程的工作目录。 (更高版本的wxsqlite3的结构不同)
2. 工程属性页配置VC++路径,include和source都加入wxsqlite3的路径
3. 把sqlite3.h和sqlite3secure.c加入工程,对sqlite3secure.c设置属性不使用预编译头,
4.工程属性页的c/c++ 预处理定义中增加wxsqlite3的开关
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

Notes:wsSQLite3若用VC60编译要修改源文件,长整型LL要改为L, C++版本不同,所以最好用VS2010以上版编译

主程序:几个类写在同一个文件中

// SQLClient.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "resource.h"

//xgz file 对话框
#include "commdlg.h"

//xgz 扩展控件用库
#include "Commctrl.h"
#pragma comment(lib,"comctl32.lib")

#include "wxSQLite.h"

class CApp
{
public:
    CApp();
    ~CApp();
public:

    HINSTANCE    m_hInst;
    HINSTANCE   m_hPrevInstance;
    HWND        m_hWnd;
    HWND        m_hWndClient;
    HACCEL        m_hAccelTable;
    HMENU        m_hMenu, m_hPopMenu;

    HWND        m_hStatusbar;
    HWND        m_hToolsbar;

    ATOM        MyRegisterClass(HINSTANCE hInstance, LPCSTR szWndClassName);
    BOOL        InitInstance(HINSTANCE hInstance, int nCmdShow);
    int            Run();

    HWND        CreateToolbar(HWND hWnd);
    HWND        CreateStatusbar(HWND hWnd);

public:
    TCHAR        m_File[1024];
    int            FileOpen();
};


class CEdit
{
public:
    CEdit();
    ~CEdit();

    HMENU        m_hMenu, m_hPopMenu;
    HINSTANCE    m_hInst;
    HWND        m_hWnd;

    HWND        Create(HWND hWndParent);
    int            Init();

    static LONG  OldWndProc;
    static LRESULT CALLBACK NewWndProc(HWND, UINT, WPARAM, LPARAM);

};

class CListView
{
public:
    CListView();
    ~CListView();

    HMENU        m_hMenu, m_hPopMenu;
    HINSTANCE    m_hInst;
    HWND        m_hWnd;

    HWND        Create(HWND hWndParent);
    int            Init();

public:
    int            Update(HWND hListView, int nrow, int ncol, char** pData);
    BOOL        GetItem(LVITEM* pItem);
};

class CTree
{
public:
    CTree();
    ~CTree();

    HMENU        m_hMenu, m_hPopMenu;
    HINSTANCE    m_hInst;
    HWND        m_hWnd;

    HWND        Create(HWND hWndParent);
    int            Init();

public:
    HTREEITEM    m_hRoot;

    HTREEITEM    AddItemToTree(HWND hwndTV, LPTSTR lpszItem, int nLevel);
    HTREEITEM    InsertTreeNode(HWND hWndTV, HTREEITEM hPrev, LPTSTR lpszItem);
    HTREEITEM   InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent = TVI_ROOT, HTREEITEM hInsertAfter = TVI_LAST);

    void        ExpandAll(HTREEITEM hItem);

    int        GetSelectionText(LPTSTR szText, int cchTextMax);

    int        OnLClkTree(LPNMHDR lphr);
    int        OnRClkTree(LPNMHDR lphr);
    int        OnDBLClkTree(LPNMHDR lphr);

    int     DeleteAllItem();

};

//把查询和显示封装在一起
class CSQL
{
public:
    CSQL();
    ~CSQL();

    CwxSQLite m_SQLite;
    TCHAR m_szDBName[256];
    int   m_iDBType;

    int    m_row;
    int    m_colum;

    int    Open(LPTSTR sql);
    int    Query(LPTSTR sql);
    int    PragmaTable(LPTSTR szTableName);
    int    DlgPassword();

};


// Global Variables:
CApp        theApp;
CTree        m_Tree1;
CEdit        m_Edit1;
CListView    m_ListView1;
CSQL        m_SQL1;


TCHAR        command[10000];
int            commandnum;
int            commandtype;
int            lastLength;

//=====================
TCHAR        szTitle[100] = _T("Main");
TCHAR        szWindowClass[100] = _T("XGZ_SQLClient_202305");

int m_SpltterLeft = 200;
int m_SpltterRight = 200;
int m_SpltterBottom = 200;
BOOL m_SpltterLeftMove = FALSE;
BOOL m_SpltterRightMove = FALSE;
BOOL m_SpltterBottomMove = FALSE;

RECT m_rtLeft;
RECT m_rtMain;
RECT m_rtBottom;


//==调试打印
int PRINT(const TCHAR* fmt, ...);
int RerAlign(HWND hWnd);

//==回调函数
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
BOOL  CALLBACK PasswordProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

//==消息处理
int OnCreate(HWND, UINT, WPARAM, LPARAM);
int OnSize(HWND, UINT, WPARAM, LPARAM);
int OnPaint(HWND, UINT, WPARAM, LPARAM);
int OnTimer(HWND, UINT, WPARAM, LPARAM);
int OnNotify(HWND, UINT, WPARAM, LPARAM); //控件的通知是发给父窗口处理
int OnLButtonDown(HWND, UINT, WPARAM, LPARAM);
int OnLButtonUp(HWND, UINT, WPARAM, LPARAM);
int OnMouseMove(HWND, UINT, WPARAM, LPARAM);

//==菜单命令
int OnFileNew(HWND, UINT, WPARAM, LPARAM);
int OnFileOpen(HWND, UINT, WPARAM, LPARAM);
int OnFileSave(HWND, UINT, WPARAM, LPARAM);
int OnSelect100(HWND, UINT, WPARAM, LPARAM);
int OnSelectAll(HWND, UINT, WPARAM, LPARAM);
int OnPragma(HWND, UINT, WPARAM, LPARAM);
int OnPassword(HWND, UINT, WPARAM, LPARAM);

//== I/O 命令
int OnEditCommand(HWND, UINT, WPARAM, LPARAM);


//==main========
int APIENTRY WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR     lpCmdLine,
    int       nCmdShow)
{
    theApp.InitInstance(hInstance, nCmdShow);
    theApp.Run();
    return 1;
}


//==类成员函数=========================
CApp::CApp()
{

}
CApp::~CApp()
{
    
}

ATOM CApp::MyRegisterClass(HINSTANCE hInstance, LPCSTR szWndClassName)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc = (WNDPROC)WndProc;
    wcex.cbClsExtra = 0;
    wcex.cbWndExtra = 0;
    wcex.hInstance = hInstance;
    wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_ICON1);
    wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wcex.lpszMenuName = MAKEINTRESOURCE(IDC_MAINMENU); //(LPCSTR)IDC_TREE;
    wcex.lpszClassName = szWndClassName;
    wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    return RegisterClassEx(&wcex);
}

BOOL CApp::InitInstance(HINSTANCE hInstance, int nCmdShow)
{
    HWND hWnd;

    //初始化全局变量
    command[0] = 0;
    commandnum = 0;
    commandtype = 0;

    m_hInst = hInstance;

    TCHAR szWndClassName[] = _T("wsSQLClient");

    MyRegisterClass(hInstance, szWndClassName);

    hWnd = CreateWindow(szWndClassName, _T("Main"), WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

    if (!hWnd)
    {
        return FALSE;
    }

    //m_hMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDC_MAINMENU));// (LPCSTR)IDC_TREE);

    InitCommonControls();
    m_hToolsbar = CreateToolbar(hWnd);
    m_hStatusbar = CreateStatusbar(hWnd);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    return TRUE;
}

int CApp::Run()
{
    MSG msg;

    m_hAccelTable = LoadAccelerators(m_hInst, (LPCTSTR)IDC_SQLCLIENT);
    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(m_hWnd, m_hAccelTable, &msg))
        {
            //if (hDlgModeless == NULL || !IsDialogMessage(hDlgModeless, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    }

    return 0;
}

//========工具条和状态条==========================
HWND CApp::CreateStatusbar(HWND hWnd)
{
    int Rightend[3];
    RECT rt;

    GetClientRect(hWnd, &rt);

    HWND hWndStatusBar = CreateWindowEx(0, STATUSCLASSNAME, _T(""),
        WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP,
        0, 0, 0, 0,
        hWnd,
        (HMENU)IDC_STATUSBAR,
        (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE),
        NULL);

    if (!hWndStatusBar)
        return NULL;

    Rightend[0] = rt.right / 2;
    Rightend[1] = rt.right * 3 / 4;
    Rightend[2] = rt.right;

    //set statusbar to three segment
    SendMessage(hWndStatusBar, SB_SETPARTS, (WPARAM)3, (LPARAM)Rightend);

    MoveWindow(hWndStatusBar, 0, 0, 0, 0, TRUE);

    //TextOut in statusbar
    SendMessage(hWndStatusBar, SB_SETTEXT, 0, (long)TEXT("Status 0"));
    SendMessage(hWndStatusBar, SB_SETTEXT, 1, (long)TEXT("========test====="));
    SendMessage(hWndStatusBar, SB_SETTEXT, 2, (long)TEXT("Step 2"));

    return hWndStatusBar;
}

HWND CApp::CreateToolbar(HWND hWnd)
{
    // image,COMMAND, STATUS, STYLE, //用系统标准图标
    TBBUTTON tbButton[] = {
        { STD_FILENEW,  IDM_FILE_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FILEOPEN, IDM_FILE_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FILESAVE, IDM_TEST_TEST1, TBSTATE_ENABLED , TBSTYLE_BUTTON , 0L, 0},
        { STD_HELP, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, -1},
        { STD_FIND, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_UNDO, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_REDOW, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { 0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, 0L, -1},
        { STD_COPY, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_PASTE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_CUT, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_DELETE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FILESAVE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_PROPERTIES, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FIND, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_REPLACE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_PRINT, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FILESAVE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_FILESAVE, IDM_TEST_TEST3, TBSTATE_ENABLED, TBSTYLE_BUTTON, 0L, 0},
        { STD_PRINTPRE, 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,  //| WS_BORDER|TBSTYLE_FLAT,
        TBSTYLE_FLAT | WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | CCS_NORESIZE | CCS_ADJUSTABLE | CCS_NODIVIDER | CCS_NOPARENTALIGN, //for rebar 
        0, 0, 0, 0,
        hWnd, (HMENU)IDC_TOOLSBAR, (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE), NULL);

    if (!hWndToolbar)
        return NULL;

    SendMessage(hWndToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0);
    SendMessage(hWndToolbar, TB_SETEXTENDEDSTYLE, 0, (LPARAM)(DWORD)(TBSTYLE_EX_DRAWDDARROWS));

    TBADDBITMAP tbBitmap1;
    tbBitmap1.hInst = HINST_COMMCTRL;
    tbBitmap1.nID = IDB_STD_SMALL_COLOR;
    SendMessage(hWndToolbar, TB_ADDBITMAP, 0, (LPARAM)&tbBitmap1);

    SendMessage(hWndToolbar, TB_SETBITMAPSIZE, 0, (LPARAM)MAKELONG(16, 16)); //size 16x16
    SendMessage(hWndToolbar, TB_AUTOSIZE, 0, 0);
    SendMessage(hWndToolbar, TB_ADDBUTTONS, 15, (LONG)&tbButton);   //add 6 button

    return hWndToolbar;
}

int CApp::FileOpen()
{
    TCHAR szFile[1024];       // buffer for file name
    HANDLE hf;              // file handle

    OPENFILENAME ofn;
    GetOpenFileName(&ofn);   // initialization data

    // Initialize OPENFILENAME
    ZeroMemory(&ofn, sizeof(ofn));
    ofn.lStructSize = sizeof(ofn);
    ofn.hwndOwner = m_hWnd;
    ofn.lpstrFile = szFile;
    // Set lpstrFile[0] to '\0' so that GetOpenFileName does not 
    // use the contents of szFile to initialize itself.
    ofn.lpstrFile[0] = '\0';
    ofn.nMaxFile = sizeof(szFile);
    ofn.lpstrFilter = _T("All\0*.*\0DataBase\0*.db\0");
    ofn.nFilterIndex = 2;  // the second type
    ofn.lpstrFileTitle = NULL;
    ofn.nMaxFileTitle = 0;
    ofn.lpstrInitialDir = NULL;
    //ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;  
    ofn.Flags = OFN_CREATEPROMPT;  //OFN_CREATEPROMPT  mean create a new file

    // Display the Open dialog box. 
    if (GetOpenFileName(&ofn) == TRUE)
    {
        lstrcpy(m_File, ofn.lpstrFile);
    }
    PRINT(_T("\r\n%s\r\n"), ofn.lpstrFile);

    return 1;
}

//==========================
CTree::CTree()
{
}
CTree::~CTree()
{
}

HWND CTree::Create(HWND hWndParent)
{
    InitCommonControls();

    m_hInst = (HINSTANCE)GetWindowLong(hWndParent, GWL_HINSTANCE);

    HWND hWndTreeView = CreateWindow(WC_TREEVIEW, _T("Tree"),
        WS_CHILD | WS_VISIBLE | TVS_HASBUTTONS | TVS_HASLINES | TVS_SHOWSELALWAYS | TVS_LINESATROOT | WS_BORDER | TVS_EDITLABELS,
        0, 0, 0, 0,
        hWndParent,
        (HMENU)IDC_TREE_FILE,
        m_hInst,
        NULL);

    HIMAGELIST hImageList;
    hImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 15, 15);             //size 16x16  X15 
    for (unsigned int i = 0; i < 15; i++)
    {
        HICON  hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_ICON1 + i));
        ImageList_AddIcon(hImageList, hIcon);
        DestroyIcon(hIcon);
    }
    SendMessage(hWndTreeView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList);

    m_hWnd = hWndTreeView; //xgz 直接保存

    m_hMenu = LoadMenu(m_hInst, MAKEINTRESOURCE(IDC_MAINMENU));// (LPCSTR)IDC_TREE);
    m_hPopMenu = GetSubMenu(m_hMenu, 2);    //XGZ 用主菜单的第三列菜单作为弹出菜单

    return (hWndTreeView);

}

int CTree::Init()
{
    HTREEITEM hti;
    
    m_hRoot = InsertItem(_T("Root"), 10, 10);   //0,10
    //hti  = InsertItem(_T("Node1"), 0, 0, m_hRoot);
    //hti = InsertItem(_T("Node2"), 0, 0, m_hRoot, hti);

    //TreeView_Expand(m_hWnd, m_hRoot, TVE_EXPAND);//只展开一个节点
    ExpandAll(m_hRoot);   //递归展开所有节点
    
    return 1;
}

HTREEITEM  CTree::InsertItem(LPCTSTR lpszItem, int nImage, int nSelectedImage, HTREEITEM hParent, HTREEITEM hInsertAfter)
{
    TVINSERTSTRUCT tvins;
    TVITEM tvi;

    tvins.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; //TVIF_TEXT| TVIF_PARAM; 
    tvins.item.pszText = (LPTSTR)lpszItem;
    tvins.item.iImage = nImage;          //初始图标都是文件 
    tvins.item.iSelectedImage = nSelectedImage;
    tvins.hParent = hParent;
    tvins.hInsertAfter = hInsertAfter;

    return (HTREEITEM)SendMessage(m_hWnd, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
}

//根据子节点确定图标,保存节点层数据,保存父节点句柄
HTREEITEM CTree::AddItemToTree(HWND hwndTV, LPTSTR lpszItem, int nLevel)
{
    TVITEM tvi;
    TVINSERTSTRUCT tvins;
    static HTREEITEM hPrev = (HTREEITEM)TVI_FIRST;
    static HTREEITEM hPrevRootItem = NULL;
    static HTREEITEM hPrevLev2Item = NULL;
    HTREEITEM hti;

    tvi.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM | TVIF_STATE;

    // Set the text of the item. 
    tvi.pszText = lpszItem;
    tvi.cchTextMax = sizeof(tvi.pszText) / sizeof(tvi.pszText[0]);

    // Assume the item is not a parent item, so give it a 
    // document image. 
    tvi.iImage = 0;// g_nDocument; 
    tvi.iSelectedImage = 0;// g_nDocument; 

    // Save the heading level in the item's application-defined 
    // data area. 
    tvi.lParam = (LPARAM)nLevel;
    tvins.item = tvi;
    tvins.hInsertAfter = hPrev;

    // Set the parent item based on the specified level. 
    if (nLevel == 1)
        tvins.hParent = TVI_ROOT;
    else if (nLevel == 2)
        tvins.hParent = hPrevRootItem;
    else
        tvins.hParent = hPrevLev2Item;

    // Add the item to the tree-view control. 
    hPrev = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM,
        0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);

    if (hPrev == NULL)
        return NULL;

    // Save the handle to the item. 
    if (nLevel == 1)
        hPrevRootItem = hPrev;
    else if (nLevel == 2)
        hPrevLev2Item = hPrev;

    // The new item is a child item. Give the parent item a 
    // closed folder bitmap to indicate it now has child items. 
    if (nLevel > 1)
    {
        hti = TreeView_GetParent(hwndTV, hPrev);
        tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
        tvi.hItem = hti;
        tvi.iImage = 2;//g_nClosed; 
        tvi.iSelectedImage = 2;// g_nClosed; 
        TreeView_SetItem(hwndTV, &tvi);
    }

    return hPrev;
}

HTREEITEM CTree::InsertTreeNode(HWND hWndTV, HTREEITEM hPrev, LPTSTR lpszItem)
{
    TVINSERTSTRUCT tvins;
    TVITEM tvi;

    tvins.item.mask = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_PARAM; //TVIF_TEXT| TVIF_PARAM; 
    tvins.item.pszText = lpszItem;

    if (NULL != hPrev)   //把上级图标改为文件夹
    {
        tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;   //只处理 IMAGE
        tvi.hItem = hPrev;
        tvi.iImage = 10;
        tvi.iSelectedImage = 10;
        TreeView_SetItem(hWndTV, &tvi);
    }

    tvins.item.iImage = 0;          //初始图标都是文件 
    tvins.item.iSelectedImage = 0;

    tvins.hParent = hPrev;
    tvins.hInsertAfter = TVI_LAST;

    return (HTREEITEM)SendMessage(hWndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins);
}

//递归展开
void CTree::ExpandAll(HTREEITEM hItem)
{
    if (!hItem)    return;

    HTREEITEM hChild = TreeView_GetChild(m_hWnd, hItem);

    ExpandAll(hChild);

    if (hChild) TreeView_Expand(m_hWnd, hItem, TVE_EXPAND);//XGZ 有子节点的展开父节点,上个返回可能是NULL

    HTREEITEM hSibling = TreeView_GetNextSibling(m_hWnd, hItem);

    ExpandAll(hSibling);
    //XGZ  sibling节点无需展开
    return;
}


int CTree::GetSelectionText(LPTSTR szText, int cchTextMax)
{
    TVITEM tvi;
    memset(&tvi, 0, sizeof(tvi));

    tvi.mask = TVIF_TEXT;// | TVIF_PARAM;
    tvi.hItem = TreeView_GetSelection(m_hWnd);
    tvi.pszText = szText;
    tvi.cchTextMax = cchTextMax;
    TreeView_GetItem(m_hWnd, &tvi);

    return 1;
}


int CTree::OnLClkTree(LPNMHDR lphr)
{
    TVHITTESTINFO thti;
    HTREEITEM htItem;
    TVITEM tvi;
    POINT point;

    GetCursorPos(&point);
    ScreenToClient(m_hWnd, &point);
    thti.pt = point;
    thti.flags = TVHT_TORIGHT;
    htItem = TreeView_HitTest(m_hWnd, &thti);

    if (htItem == NULL)
        return 0;

    TCHAR szText[20];
    memset(&tvi, 0, sizeof(tvi));
    tvi.mask = TVIF_TEXT | TVIF_PARAM;
    tvi.hItem = htItem;
    tvi.pszText = szText;
    tvi.cchTextMax = sizeof(szText);
    TreeView_GetItem(m_hWnd, &tvi);

    //PRINT(_T("\r\n<INFO>CTree::OnLClkTree= %s"), szText);

    return 1;
}
int CTree::OnRClkTree(LPNMHDR lphr)
{

    TVHITTESTINFO thti;
    HTREEITEM htItem;
    TVITEM tvi;
    POINT point;

    GetCursorPos(&point);
    ScreenToClient(m_hWnd, &point);
    thti.pt = point;
    thti.flags = TVHT_TORIGHT;
    htItem = TreeView_HitTest(m_hWnd, &thti);

    if (htItem == NULL)
        return 0;

    TCHAR szText[20];
    memset(&tvi, 0, sizeof(tvi));
    tvi.mask = TVIF_TEXT | TVIF_PARAM;
    tvi.hItem = htItem;
    tvi.pszText = szText;
    tvi.cchTextMax = sizeof(szText);
    TreeView_GetItem(m_hWnd, &tvi);

    //PRINT(_T("\r\n<INFO>CTree::OnRClkTree = %s"), szText);

    GetCursorPos(&point);

    TrackPopupMenu(m_hPopMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, 0, GetParent(m_hWnd), NULL);  //通知是控件的父窗口处理

    return 1;
}


int CTree::OnDBLClkTree(LPNMHDR lphr)
{
    HTREEITEM htItem;
    TVITEM tvi;
    htItem = TreeView_GetSelection(m_hWnd);

    if (htItem == NULL)
        return 0;

    //    HWND m_hWndClient = ((CXMDIFrameEx*)m_pMainFrame)->m_hWndClient;

    TCHAR szText[20];
    memset(&tvi, 0, sizeof(tvi));

    tvi.mask = TVIF_TEXT | TVIF_PARAM;
    tvi.hItem = htItem;
    tvi.pszText = szText;
    tvi.cchTextMax = sizeof(szText);

    TreeView_GetItem(m_hWnd, &tvi);

    //PRINT(_T("\r\n<INFO>CTree::OnDBLClkTree= %s"), szText);


    memset(&tvi, 0, sizeof(tvi));
    tvi.mask = TVIF_TEXT;
    tvi.hItem = TreeView_GetSelection(m_hWnd);
    tvi.pszText = szText;
    tvi.cchTextMax = sizeof(szText);
    TreeView_GetItem(m_hWnd, &tvi);

    int nrow, ncolum;

    wsprintf(command, _T("select * from %s limit 100;"), szText);

    commandnum = lstrlen(command);
    commandtype = 0;

    SendMessage(GetParent(m_hWnd), WM_COMMAND, (WPARAM)IDX_EDIT_COMMAND, (LPARAM)0);

    return 1;
}


int CTree::DeleteAllItem()
{

    HTREEITEM hItem = TreeView_GetRoot(m_hWnd);

    if (NULL == hItem)
    {
        return 0;
    }
    else
    {
        TreeView_DeleteItem(m_hWnd, hItem);
        return 1;
    }
}

//===================================

LONG  CEdit::OldWndProc = 0;

CEdit::CEdit()
{

}
CEdit::~CEdit()
{

}

HWND CEdit::Create(HWND hWndParent)
{

    m_hInst = (HINSTANCE)GetWindowLong(hWndParent, GWL_HINSTANCE);

    HWND hWndEdit = CreateWindow(TEXT("edit"), NULL,
        WS_CHILD | WS_BORDER | WS_VISIBLE | ES_MULTILINE | WS_VSCROLL,
        0, 0, 0, 0,
        hWndParent, (HMENU)IDC_LISTLOG, m_hInst, NULL);
    OldWndProc = SetWindowLong(hWndEdit, GWL_WNDPROC, (LONG)NewWndProc);

    m_hWnd = hWndEdit; //xgz 直接保存

    m_hMenu = LoadMenu(m_hInst, (LPCSTR)IDC_SQLCLIENT);
    m_hPopMenu = GetSubMenu(m_hMenu, 2);    //XGZ 用主菜单的第三列菜单作为弹出菜单

    return (hWndEdit);

}

int CEdit::Init()
{
    LOGFONT logfont;
    ZeroMemory(&logfont, sizeof(LOGFONT));
    //_tcscpy(logfont.lfFaceName, _T("tahoma"));
    logfont.lfCharSet = OEM_FIXED_FONT;
    logfont.lfHeight = 16;
    HFONT hFont = CreateFontIndirect(&logfont);
    SendMessage(m_hWnd, WM_SETFONT, (WPARAM)hFont, TRUE);

    PRINT(_T("SQL>"));

    return 1;
}


LRESULT CALLBACK CEdit::NewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int iLength;
    int i;

    HANDLE hG;
    char* phG;

    int nowLength;
    int getLength;
    TCHAR selText[1000];

    switch (message)
    {
    case WM_CREATE:
        //不会执行
        break;
    case WM_DESTROY:
        return 0;
    case WM_KEYDOWN:
    {
        SetCaretPos(3, 3);
        iLength = GetWindowTextLength(hWnd);
        SendMessage(hWnd, EM_SETSEL, iLength, iLength);
        switch (wParam)
        {
        case VK_RETURN:
        {
            break;
        }
        case VK_ESCAPE:        //#define VK_ESCAPE         0x1B
            commandtype++;
            if (commandtype > 2)
            {
                commandtype = 0;
            }
            switch (commandtype)
            {
            case 0:
                PRINT("\r\nSQL>");
                break;
            case 1:
                PRINT("\r\nSYS>");
                break;
            case 2:
                PRINT("\r\nUSR>");
                break;
            default:
                PRINT("\r\nSQL>");
                break;
            }

            break;
        case VK_END:

            break;
        default:

            break;
        }
    }
    break;
    case WM_CHAR:
        switch (wParam)
        {
        case '\r':

            SendMessage(GetParent(hWnd), WM_COMMAND, (WPARAM)IDX_EDIT_COMMAND, (LPARAM)0);
            commandnum = 0;
            command[0] = 0;
            lastLength = GetWindowTextLength(hWnd);

            switch (commandtype)
            {
            case 0:
                PRINT("\r\nSQL>");
                break;
            case 1:
                PRINT("\r\nSYS>");
                break;
            case 2:
                PRINT("\r\nUSR>");
                break;
            default:
                PRINT("\r\nSQL>");
                break;
            }

            return TRUE;  //不处理return,把光标留在原位置
            break;
        case '\n':
            PRINT("case N");
            break;
        case 0x1b:
            //    PRINT("\r\nI reived ESCAPE - ESC");
            break;
        case '\b':
            command[commandnum] = 0;
            commandnum--;
            if (commandnum < 0)
            {
                commandnum = 0;
            }
            break;
        default:
            if (commandnum < 10000)
            {
                command[commandnum] = wParam;
                commandnum++;
                command[commandnum] = 0;
            }
            else
            {
                PRINT(_T("\r\n<FAIL> COMMAND OVERFLOW!"));
            }
            break;
        }
        SendMessage(GetParent(hWnd), message, wParam, lParam);
        break;
    case WM_PASTE:
        iLength = GetWindowTextLength(hWnd);
        SendMessage(hWnd, EM_SETSEL, iLength, iLength);
        OpenClipboard(hWnd);
        hG = GetClipboardData(CF_TEXT);
        phG = (char*)GlobalLock(hG);

        iLength = strlen(phG);
        if (iLength > 10000)
        {
            iLength = 10000;
        }


        for (i = 0; i < iLength; i++)
        {

            if (commandnum < 10000)
            {
                command[commandnum] = *(phG + i);
                commandnum++;
            }
            else
            {
                PRINT(_T("\r\n<FAIL> COMMAND OVERFLOW!"));
            }
        }

        command[commandnum] = 0;
        GlobalUnlock(hG);
        ///EmptyClipboard();  ////  empty after handled 
        CloseClipboard();
        //return TRUE;    /// no defalt paste
        break;
    default:
        break;

    }
    return CallWindowProc((WNDPROC)OldWndProc, hWnd, message, wParam, lParam);
}

//==========================================
CListView::CListView()
{
}
CListView::~CListView()
{
}

HWND CListView::Create(HWND hWndParent)
{
    InitCommonControls();

    m_hInst = (HINSTANCE)GetWindowLong(hWndParent, GWL_HINSTANCE);

    DWORD dwStyle;
    // Create the list-view window in report view with label editing enabled.
    dwStyle = WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT | WS_TABSTOP; //|LVS_EDITLABELS; //|LVS_AUTOARRANGE
    HWND hWndListView = CreateWindow(WC_LISTVIEW, TEXT("ListTest"),
        dwStyle,
        0, 0,
        0, 0,
        hWndParent,
        (HMENU)IDC_LISTVIEW_VIEW,
        m_hInst,
        NULL);

    ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);  //|LVS_EX_CHECKBOXES| LVS_EX_SUBITEMIMAGES

    HIMAGELIST hImageList;
    hImageList = ImageList_Create(16, 16, ILC_COLOR32 | ILC_MASK, 15, 15);             //size 16x16  X15 
    for (unsigned int i = 0; i < 15; i++)
    {
        HICON  hIcon = LoadIcon(m_hInst, MAKEINTRESOURCE(IDI_ICON1 + i));
        ImageList_AddIcon(hImageList, hIcon);
        DestroyIcon(hIcon);
    }
    SendMessage(hWndListView, TVM_SETIMAGELIST, 0, (LPARAM)hImageList);

    m_hWnd = hWndListView; //xgz 直接保存

    m_hMenu = LoadMenu(m_hInst, (LPCSTR)IDC_MAINMENU);
    m_hPopMenu = GetSubMenu(m_hMenu, 2);    //XGZ 用主菜单的第三列菜单作为弹出菜单

    return (hWndListView);
}

int CListView::Init()
{
    int i, j;
    int lvColumWidth[10] = { 70,70,70,50,50,50 };
    TCHAR* ColumName[10] =
    {
        _T("ID"),
        _T("Data"),
        NULL,
    };
    TCHAR* ItemData[10][10] =
    {
        //{_T("001"), _T("100"),},
        //{_T("002"), _T("101"),},
    };

    LV_COLUMN    lvColum;
    LVITEM        lvItem;
    //    HIMAGELIST    ImgList;

    lvColum.mask = LVCF_TEXT | LVCF_WIDTH; //|LVCF_SUBITEM;

    lvColum.cx = 80;

    for (i = 0; i < 3; i++)
    {
        lvColum.cx = lvColumWidth[i];
        lvColum.iSubItem = i;
        lvColum.pszText = ColumName[i];
        ListView_InsertColumn(m_hWnd, i, &lvColum);
    }


    ListView_SetItemCount(m_hWnd, 100); // for memory

    lvItem.mask = LVIF_TEXT;

    for (i = 0; i < 5; i++)
    {
        lvItem.iItem = i;
        lvItem.iSubItem = 0;
        lvItem.pszText = 0;  // first should have this or direct use data
        ListView_InsertItem(m_hWnd, &lvItem);  // for cell

        for (j = 0; j < 3; j++)
        {
            lvItem.iSubItem = j;
            lvItem.pszText = ItemData[i][j];
            ListView_SetItem(m_hWnd, &lvItem);  // for cell
        }
    }
    return 1;
}

int CListView::Update(HWND hListView, int nrow, int ncol, char** pData)
{
    int i, j;

    LV_COLUMN    lvColum;
    LVITEM        lvItem;
    HIMAGELIST    ImgList;

    SendMessage(hListView, LVM_DELETEALLITEMS, 0, 0);

    HWND hWndListViewHeader = (HWND)SendMessage(hListView, LVM_GETHEADER, 0, 0);

    int  nOldCols = SendMessage(hWndListViewHeader, HDM_GETITEMCOUNT, 0, 0);

    nOldCols--;

    for (; nOldCols >= 0; nOldCols--)
        SendMessage(hListView, LVM_DELETECOLUMN, nOldCols, 0);


    lvColum.mask = LVCF_TEXT | LVCF_WIDTH;//|LVCF_SUBITEM;

    lvColum.cx = 100;


    for (i = 0; i < ncol; i++)
    {
        lvColum.iSubItem = i;
        lvColum.pszText = pData[i];
        ListView_InsertColumn(hListView, i, &lvColum);
    }

    ListView_SetItemCount(hListView, 100); // for memory

    lvItem.mask = LVIF_TEXT;

    lvItem.pszText = 0;  // first should have this or direct use data

    for (i = 1; i < nrow + 1; i++)
    {
        lvItem.iItem = i - 1;
        lvItem.iSubItem = 0;
        ListView_InsertItem(hListView, &lvItem);  // for cell

        for (j = 0; j < ncol; j++)
        {
            lvItem.iSubItem = j;
            lvItem.pszText = pData[i * ncol + j];
            ListView_SetItem(hListView, &lvItem);  // for cell
        }

    }
    return 1;
}

//===============================
CSQL::CSQL()
{
}
CSQL::~CSQL()
{
}

int CSQL::Open(LPTSTR szFileName)
{
    lstrcpy(m_szDBName, szFileName);

    int nrow, ncolum;
    int i, j;

    HTREEITEM hItem;
    HTREEITEM hPItem;
    HTREEITEM hRoot;


    if (m_SQLite.m_IsOpen)
    {
        m_SQLite.Close();
    }

    if (!m_SQLite.Open(m_szDBName))
    {
        PRINT("<ERR> Open Failed");
        return -1;
    }

    DlgPassword();

    m_Tree1.DeleteAllItem();

    TCHAR* sql = _T("SELECT type,name,tbl_name,rootpage, sql FROM sqlite_master order by type");
    Query(sql);

    TCHAR ItemText[256];
    int levNow = 0;
    HTREEITEM  hParent = NULL;
    HTREEITEM  hCurrent = NULL;
    HTREEITEM  hDB = NULL;

    hRoot = m_Tree1.InsertTreeNode(m_Tree1.m_hWnd, NULL, _T("wxSQLite3"));
    hDB = m_Tree1.InsertTreeNode(m_Tree1.m_hWnd, hRoot, m_szDBName);

    ncolum = Header_GetItemCount(ListView_GetHeader(m_ListView1.m_hWnd));
    nrow = ListView_GetItemCount(m_ListView1.m_hWnd);

    char type_last[256] = "";
    char type[256];

    for (i = 0; i < nrow; i++)
    {
        ListView_GetItemText(m_ListView1.m_hWnd, i, 0, type, 255);//第一列
        if (0 != strcmp(type, type_last))
        {
            hParent = m_Tree1.InsertTreeNode(m_Tree1.m_hWnd, hDB, type);
            memset(type_last, 0, 256);
            memcpy(type_last, type, 255);
        }
        ListView_GetItemText(m_ListView1.m_hWnd, i, 1, ItemText, 255);
        hCurrent = m_Tree1.InsertTreeNode(m_Tree1.m_hWnd, hParent, ItemText);
    }
    SendMessage(m_Tree1.m_hWnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)hRoot);
    //SendMessage(m_Tree1.m_hWnd, TVM_SETBKCOLOR, 0, RGB(255, 255, 230));  //RGB(200,230,150)
    m_Tree1.ExpandAll(hDB);

    return 1;
}


int CSQL::Query(LPTSTR sql)
{
    PRINT("\r\nSQL>%s", sql);
    m_SQLite.Query(sql, m_row, m_colum);
    m_ListView1.Update(m_ListView1.m_hWnd, m_row, m_colum, m_SQLite.m_sresult);
    PRINT("\r\nrow=%d,colum=%d", m_row, m_colum);

    return m_row;
}


int CSQL::DlgPassword()
{
    
    //HINSTANCE hInst = (HINSTANCE)GetWindowLong(hWnd, GWL_HINSTANCE);
    DialogBoxParam(theApp.m_hInst, (LPCTSTR)IDD_PASSWORDBOX, theApp.m_hWnd, (DLGPROC)PasswordProc, (LPARAM)&m_SQLite);
    return 1;
}


//=========================================

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR szHello[] = _T("Hello");

    switch (message)
    {
    case WM_CREATE:
        OnCreate(hWnd, message, wParam, lParam);
        break;
    case WM_SIZE:
        OnSize(hWnd, message, wParam, lParam);
        break;
    case WM_PAINT:
        OnPaint(hWnd, message, wParam, lParam);
        break;
    case WM_TIMER:
        OnTimer(hWnd, message, wParam, lParam);
        break;
    case WM_LBUTTONDOWN:
        OnLButtonDown(hWnd, message, wParam, lParam);
        break;
    case WM_LBUTTONUP:
        OnLButtonUp(hWnd, message, wParam, lParam);
        break;
    case WM_MOUSEMOVE:
        OnMouseMove(hWnd, message, wParam, lParam);
        break;
    case WM_NOTIFY: //XGZ  控件通知
        OnNotify(hWnd, message, wParam, lParam);
        break;
    case WM_COMMAND:
        wmId = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDX_EDIT_COMMAND:
                OnEditCommand(hWnd, message, wParam, lParam);
            //PRINT("\r\n Command =%d, %s", theApp.commandnum, theApp.command);
            break;
        case IDM_FILE_NEW:
            OnFileNew(hWnd, message, wParam, lParam);
            break;
        case IDM_FILE_OPEN:
            OnFileOpen(hWnd, message, wParam, lParam);
            break;
        case IDM_FILE_SAVE:
            OnFileSave(hWnd, message, wParam, lParam);
            break;
        case IDM_DB_SELECT100:
            OnSelect100(hWnd, message, wParam, lParam);
            break;
        case IDM_DB_SELECTALL:
            OnSelectAll(hWnd, message, wParam, lParam);
            break;
        case IDM_DB_PRAGMA:
            OnPragma(hWnd, message, wParam, lParam);
            break;
        case IDM_DB_PASSWORD:
            OnPassword(hWnd, message, wParam, lParam);
            break;
            

        case IDM_TREE_EDIT:
            //            OnTreeEdit(hWnd, message, wParam, lParam);
            break;
        case IDM_TREE_INSERTCHILD:
            //            m_Tree1.InsertChild();
            break;
        case IDM_TREE_INSERTSIBLING:
            //            m_Tree1.InsertSibling();
            break;
        case IDM_TREE_DB_PRAGMA:
            OnPragma(hWnd, message, wParam, lParam);
            break;
        case IDM_ABOUT:
            //MessageBox(hWnd, "Test", "Test", MB_OK);
            DialogBox(theApp.m_hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;

    case WM_DESTROY:


        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}



int OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
    SetTimer(hWnd, 1, 10000, NULL);   //10s

    m_Tree1.Create(hWnd);
    m_Tree1.Init();

    m_ListView1.Create(hWnd);
    m_ListView1.Init();

    m_Edit1.Create(hWnd);
    m_Edit1.Init();
    
    return 1;
}



int RerAlign(HWND hWnd)
{
    int splitterwith = 4 / 2;
    int toolsbarhigh = 25;
    int statusbarhigh = 25;

    RECT rt;

    GetClientRect(hWnd, &rt);

    int cxClient = rt.right - rt.left;
    int cyClient = rt.bottom - rt.top;

    m_rtLeft.left = 0;
    m_rtLeft.right = m_SpltterLeft - splitterwith;
    m_rtLeft.top = toolsbarhigh; //toolsbar
    m_rtLeft.bottom = rt.bottom - statusbarhigh; //statusbar

    m_rtBottom.left = m_SpltterLeft + splitterwith;
    m_rtBottom.right = rt.right;
    m_rtBottom.top = rt.bottom - toolsbarhigh - m_SpltterBottom + splitterwith; //toolsbar
    m_rtBottom.bottom = rt.bottom - statusbarhigh;

    m_rtMain.left = m_SpltterLeft + splitterwith;
    m_rtMain.right = rt.right;
    m_rtMain.top = toolsbarhigh; //toolsbar
    m_rtMain.bottom = rt.bottom - statusbarhigh - m_SpltterBottom - splitterwith;  //statusbar

    MoveWindow(m_Tree1.m_hWnd, m_rtLeft.left, m_rtLeft.top, m_rtLeft.right - m_rtLeft.left, m_rtLeft.bottom - m_rtLeft.top, TRUE);
    MoveWindow(m_Edit1.m_hWnd, m_rtBottom.left, m_rtBottom.top, m_rtBottom.right - m_rtBottom.left, m_rtBottom.bottom - m_rtBottom.top, TRUE);
    MoveWindow(m_ListView1.m_hWnd, m_rtMain.left, m_rtMain.top, m_rtMain.right - m_rtMain.left, m_rtMain.bottom - m_rtMain.top, TRUE);
    return 1;
}

//留一个状态条的位置
int OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int cxClient, cyClient;

    cxClient = LOWORD(lParam);
    cyClient = HIWORD(lParam);

    MoveWindow(theApp.m_hToolsbar, 0, 0, cyClient, 25, TRUE);  //Toolsbar 25
    MoveWindow(theApp.m_hStatusbar, 0, 0, 0, 0, TRUE);         //Statusbar 25

    RerAlign(hWnd);

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

}

int OnPaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    RECT rt;

    hdc = BeginPaint(hWnd, &ps);
    GetClientRect(hWnd, &rt);
    //DrawText(hdc, StatusText, strlen(StatusText), &rt, DT_LEFT|DT_BOTTOM|DT_SINGLELINE);
    EndPaint(hWnd, &ps);

    return 1;
}

int OnTimer(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return 1;
}


int OnEditCommand(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    int nrow = 0, ncolum = 0;

    if (commandnum == 0)
    {
        //PRINT("\r\n COMMMAND=0");
        return 0;
    }
    switch (commandtype)
    {
    case 0:
        m_SQL1.Query(command);
        break;
    case 1:
        PRINT("\r\n%s", command);
        break;
    case 2:
        PRINT("\r\nUSR>");
        break;
    default:
        PRINT("\r\nSQL>");
        break;
    }

    return 1;
}


int OnFileNew(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PRINT("\r\nOnFileNew");
    return 1;
}


int OnFileOpen(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    theApp.FileOpen();
    m_SQL1.Open(theApp.m_File);

    return 1;
}

int OnFileSave(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    return 1;
}

int OnSelect100(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HTREEITEM htItem;
    
    htItem = TreeView_GetSelection(m_Tree1.m_hWnd);

    if (htItem == NULL)
        return 0;
        

    TCHAR szText[256];
    m_Tree1.GetSelectionText(szText, 255);
        
    wsprintf(command, _T("select * from %s limit 100;"), szText);
        
    m_SQL1.Query(command);
    return 1;
}
int OnSelectAll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    HTREEITEM htItem;

    htItem = TreeView_GetSelection(m_Tree1.m_hWnd);

    if (htItem == NULL)
        return 0;


    TCHAR szText[256];
    m_Tree1.GetSelectionText(szText, 255);

    wsprintf(command, _T("select * from %s;"), szText);
    m_SQL1.Query(command);

    return 1;
}
int OnPragma(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        
    TCHAR szText[256];
    m_Tree1.GetSelectionText(szText,255);
    wsprintf(command, _T("PRAGMA table_info(%s);"), szText);
    m_SQL1.Query(command);
        

    return 1;
}

int OnPassword(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    m_SQL1.DlgPassword();
    return 1;
}

int OnTreeEdit(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    PRINT("\r\nOnTreeEdit");

    return 1;
}


int OnLButtonDown(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    RECT rt;

    GetClientRect(hWnd, &rt);

    int cxClient = rt.right - rt.left;
    int cyClient = rt.bottom - rt.top;

    int cxMouse = LOWORD(lParam);
    int cyMouse = HIWORD(lParam);

    if ((cxMouse - m_SpltterLeft > -5) && (cxMouse - m_SpltterLeft < 5))
    {
        SetCursor(LoadCursor(NULL, IDC_SIZEWE));
        SetCapture(hWnd);
        m_SpltterLeftMove = TRUE;
    }
    else if ((cyMouse - (cyClient - m_SpltterBottom - 25) > -5) && (cyMouse - (cyClient - m_SpltterBottom - 25) < 5) && (cxMouse > m_SpltterLeft + 5))
    {
        SetCursor(LoadCursor(NULL, IDC_SIZENS));
        SetCapture(hWnd);
        m_SpltterBottomMove = TRUE;
    }

    return 1;
}



int OnLButtonUp(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    if (m_SpltterBottomMove)
    {
        m_SpltterBottomMove = FALSE;
        ReleaseCapture();
    }
    if (m_SpltterLeftMove)
    {
        m_SpltterLeftMove = FALSE;
        ReleaseCapture();
    }

    return 1;
}

int OnMouseMove1(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    RECT rt;

    GetClientRect(hWnd, &rt);

    int cxClient = rt.right - rt.left;
    int cyClient = rt.bottom - rt.top;


    int cxMouse = LOWORD(lParam);
    int cyMouse = HIWORD(lParam);

    //在分割区
    if ((cxMouse - m_SpltterLeft > -5) && (cxMouse - m_SpltterLeft < 5))
    {
        SetCursor(LoadCursor(NULL, IDC_SIZEWE));
        SetCapture(hWnd);
    }
    else if ((cyMouse - (cyClient - m_SpltterBottom - 25) > -5) && (cyMouse - (cyClient - m_SpltterBottom - 25) < 5))
    {
        SetCursor(LoadCursor(NULL, IDC_SIZENS));
        SetCapture(hWnd);
    }
    else
    {
        ReleaseCapture();
    }

    
    //左右保留区
    if ((m_SpltterLeftMove) && (cxMouse > 50) && (cxMouse < (cxClient - m_SpltterRight) - 50))
    {
        m_SpltterLeft = cxMouse;

        SetCapture(hWnd);
        RerAlign(hWnd);
        //InvalidateRect(hWnd, NULL, TRUE); //会刷工具条

    }
    //上下保留区
    else if ((m_SpltterBottomMove) && (cyMouse > 100) && (cyMouse < cyClient - 50))
    {
        m_SpltterBottom = cyClient - cyMouse - 25;
        RerAlign(hWnd);
        SetCapture(hWnd);
        //InvalidateRect(hWnd, NULL, TRUE); //会刷工具条
    }

    else
    {
        //m_SpltterLeftMove = FALSE;
        //m_SpltterBottomMove = FALSE;
        //ReleaseCapture();
    }
    return 1;
}

int OnMouseMove(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    OnMouseMove1(hWnd, message, wParam, lParam);
    //    m_Tree1.OnMouseMove(hWnd, message, wParam, lParam);

    return 1;
}

int OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    int idCtrl = (int)wParam;  //控件的 ID  
    LPNMHDR lphr = (LPNMHDR)lParam; //先看是哪个控件,再决定结构

    if (lphr->hwndFrom == m_Tree1.m_hWnd)
    {
        NM_TREEVIEW* pTree = (NM_TREEVIEW*)lParam; //是树控件,所以用树控件通知结构

        switch (pTree->hdr.code)
        {
        case NM_CLICK:
            m_Tree1.OnLClkTree(lphr);
            break;
        case NM_RCLICK:
            m_Tree1.OnRClkTree(lphr);
            break;
        case NM_DBLCLK:
            m_Tree1.OnDBLClkTree(lphr);
            break;
        
        default:
            //PRINT("\r\nm_hWndTree=%d  %d", m_hWndTree, pTree->hdr.code);
            break;
        }
    }

    return 0; //返回消息是给控件处理

}


// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_INITDIALOG:
        return TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return TRUE;
        }
        break;
    }
    return FALSE;
}


BOOL  CALLBACK PasswordProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i;

    static CwxSQLite SQLite, * pSQLite;

    TCHAR szPassWord[256];
    TCHAR szPassWordNew[256];
    TCHAR szPassWordNew2[256];

    
    switch (message)
    {
    case WM_INITDIALOG:
    
        RECT rtDesk;
        RECT rtDlg;
        GetWindowRect(GetDesktopWindow(), &rtDesk);
        GetWindowRect(hDlg, &rtDlg);
        
        SetWindowPos(hDlg, HWND_TOPMOST,
            rtDesk.right / 2 - rtDlg.right / 2,
            rtDesk.bottom / 2 - rtDlg.bottom / 2,
            rtDlg.right - rtDlg.left, rtDlg.bottom - rtDlg.top,
            SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
        

        pSQLite = (CwxSQLite*)lParam;
        SQLite = *pSQLite;
        SetDlgItemText(hDlg, IDC_EDIT_OP1, _T("password"));

        return FALSE;
    case WM_COMMAND:
        switch (LOWORD(wParam))
        {
        case IDOK:

            GetDlgItemText(hDlg, IDC_EDIT_OP1, (LPTSTR)szPassWord, 256);
            GetDlgItemText(hDlg, IDC_EDIT_OP2, (LPTSTR)szPassWordNew, 256);
            GetDlgItemText(hDlg, IDC_EDIT_OP3, (LPTSTR)szPassWordNew2, 256);

            PRINT(szPassWord);
            PRINT(szPassWordNew);
            PRINT(szPassWordNew2);
            SQLite.SetPassWord(1, szPassWord, szPassWordNew);

            EndDialog(hDlg, TRUE);
            PRINT("\r\nIDOK");
            return TRUE;
        case IDCANCEL:
            EndDialog(hDlg, FALSE);
            PRINT("\r\nIDCANCEL");
            return TRUE;
        case IDRESET:
            EndDialog(hDlg, TRUE);
            PRINT("\r\nIDRESET");
            return TRUE;
        }
        break;

    }

    return FALSE;
}


int PRINT(const TCHAR* fmt, ...)
{
    TCHAR buffer[1024];

    va_list argptr;
    int cnt;

    int iEditTextLength;
    HWND hWnd = m_Edit1.m_hWnd;

    if (NULL == hWnd) return 0;

    va_start(argptr, fmt);
    cnt = wvsprintf(buffer, fmt, argptr);  // not %f

    va_end(argptr);

    iEditTextLength = GetWindowTextLength(hWnd);
    if (iEditTextLength + cnt > 30000)       // edit text max length is 30000
    {
        SendMessage(hWnd, EM_SETSEL, 0, 10000);
        SendMessage(hWnd, WM_CLEAR, 0, 0);
        iEditTextLength = iEditTextLength - 10000;
    }
    SendMessage(hWnd, EM_SETSEL, iEditTextLength, iEditTextLength);
    SendMessage(hWnd, EM_REPLACESEL, 0, (LPARAM)buffer);

    return(cnt);
}

 

其他文件:

#pragma once
#include "sqlite3.h"

class CwxSQLite
{
public:
    CwxSQLite(void);
    ~CwxSQLite(void);



public:
    sqlite3*    m_db;
    char**        m_sresult;
    BOOL        m_IsOpen;

public:
    BOOL    Open(char* filename);
    int        SetPassWord(int Mode, char* szPassWord, char* szPassWordNew);
    void    Close(); 
    BOOL    Query(char* sql, int &nrow, int &ncolum);
    BOOL    OnSqlExec(char* sql);
    static int sqlcallback(void* NotUsed, int argc, char** argv, char** azColName);
//xgz    int     ReadBLOB(char* sql, void* value); //xgz 读一个blob数据
    BOOL     SaveBLOB(char* sql, void* value, int len);

//xgz    int     ReadBlobRtf(char* sql, CString &str);//xgz 读一个blob数据
    //BOOL    InsertBLOB1(char* sql, void* value, int len);//xgz 插入一个blob数据
    BOOL    UpdateBLOB1(char* sql, void* value, int len);//xgz 更新一个blob数据

    BOOL    InsertBLOB(char* sql, int column_index, void* value, int len); //xgz 插入一个blob数据, 位置

};
#include "StdAfx.h"
#include "wxSQLite.h"

//#pragma comment(lib,"sqlite3.lib")

CwxSQLite::CwxSQLite(void)
{
    m_sresult = NULL;
    m_db = NULL;
    m_IsOpen = FALSE;
}


CwxSQLite::~CwxSQLite(void)
{
    if (NULL != m_sresult)
    {
        sqlite3_free_table(m_sresult);
        m_sresult = NULL;
    }

    if (NULL != m_db)
    {
        sqlite3_close(m_db);
        m_db = NULL;
    }

    m_IsOpen = FALSE;
}


BOOL CwxSQLite::Open(char* filename)
{
    int rc;

    if (NULL != m_db)
    {
        sqlite3_close(m_db);
        m_db = NULL;
        m_IsOpen = FALSE;
    }

    rc = sqlite3_open(filename, &m_db);
    if (rc)
    {
        sqlite3_close(m_db);
        return FALSE;
    }
    else
    {
        //m_IsOpen = TRUE;
    }
  
    m_IsOpen = TRUE;
    return TRUE;

}

int CwxSQLite::SetPassWord(int Mode, char* szPassWord, char* szPassWordNew)
{
    int rc;

    switch (Mode)
    {
    case 1: //SET 
        rc = sqlite3_key(m_db, szPassWord, 8); //使用密码,第一次为设置密码,以后为解密,最后是密码长度 
        break;
    case 2: //RESET
        rc = sqlite3_key(m_db, szPassWord, 8);
        rc = sqlite3_rekey(m_db, NULL, 0); //清空密码
        break;
    case 3: //CLEAR
        rc = sqlite3_key(m_db, szPassWord, 8);
        rc = sqlite3_rekey(m_db, szPassWordNew, 8); //RESET 
        break;
    default:
        break;
    }

    return 1;
}
void CwxSQLite::Close()
{
    if (NULL != m_db)
    {
        sqlite3_close(m_db);
        m_db = NULL;
    }

    m_IsOpen = FALSE;
}
//查询SQL
BOOL CwxSQLite::Query(char* sql, int& nrow, int& ncolum)
{
    char* szErrMsg;
    int rc;

    if (NULL != m_sresult)
    {
        sqlite3_free_table(m_sresult);
        m_sresult = NULL;
    }

    rc = sqlite3_get_table(m_db, sql, &m_sresult, &nrow, &ncolum, &szErrMsg);  /* execute SQL statement */
    if (rc != SQLITE_OK)
    {
        if (NULL != szErrMsg)
        {
            //PRINT(_T("\r\n<ERR>SQL error: %s\n"), szErrMsg);
            sqlite3_free(szErrMsg);
            return FALSE;
        }
        //PRINT(_T("\r\n<OK>select success!"));
    }

    return TRUE;
}

//sql执行回调函数
int  CwxSQLite::sqlcallback(void* NotUsed, int argc, char** argv, char** azColName)
{
    int i;
    for (i = 0; i < argc; i++)
    {
    }
    return 0;
}
//执行SQL
BOOL  CwxSQLite::OnSqlExec(char* sql)
{
    char* szErrMsg;
    int rc;
    rc = sqlite3_exec(m_db, sql, sqlcallback, 0, &szErrMsg);  /* execute SQL statement */
    if (rc != SQLITE_OK) 
    {
        sqlite3_free(szErrMsg);
        return FALSE;
    }

    return TRUE;
}
// xgz 只UPDATE一个数据,利用参数(:abc)传递 
//eg. char* sql = "UPDATE Table SET data = :abc  WHERE name = 'blob123';";
BOOL CwxSQLite::SaveBLOB(char* sql, void* value, int len)
{
    sqlite3_stmt* stmt = 0;
    //int index;
    int rc;
    const char* error = 0;
    //char* sql = "UPDATE TTestB SET data = :abc  WHERE name = 'blob123';";
    rc = sqlite3_prepare(m_db, sql, strlen(sql), &stmt, &error);
    if (rc != SQLITE_OK)
    {
        return FALSE;
    }

    rc = sqlite3_bind_blob(stmt, 1, (const void*)value, len, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);
    return TRUE;
}

BOOL CwxSQLite::InsertBLOB(char* sql, int column_index, void* value, int len)
{
    sqlite3_stmt* stmt = 0;
    //int index;
    int rc;
    const char* error = 0;

    rc = sqlite3_prepare(m_db, sql, strlen(sql), &stmt, &error);
    if (rc != SQLITE_OK)
    {
        return FALSE;
    }
    rc = sqlite3_bind_blob(stmt, column_index, (const void*)value, len, SQLITE_STATIC);

    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);
    return TRUE;
}

//xgz
BOOL CwxSQLite::UpdateBLOB1(char* sql, void* value, int len)
{
    sqlite3_stmt* stmt = 0;
    //int index;
    int rc;
    const char* error = 0;

    rc = sqlite3_prepare(m_db, sql, strlen(sql), &stmt, &error);
    if (rc != SQLITE_OK)
    {
        return FALSE;
    }

    rc = sqlite3_bind_blob(stmt, 1, (const void*)value, len, SQLITE_STATIC);  //XGZ 只用第一个字段
    rc = sqlite3_step(stmt);
    sqlite3_finalize(stmt);
    return TRUE;
}

资源头文件

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by SQLCLIENT.RC
//

//==程序相关
#define IDI_SQLCLIENT                    101
#define IDC_SQLCLIENT                    101


//==图标
#define IDI_ICON1                       131
#define IDI_ICON2                       132
#define IDI_ICON3                       133
#define IDI_ICON4                       134
#define IDI_ICON5                       135
#define IDI_ICON6                       136
#define IDI_ICON7                       137
#define IDI_ICON8                       138
#define IDI_ICON9                       139
#define IDI_ICON10                       140
#define IDI_ICON11                       141
#define IDI_ICON12                       142
#define IDI_ICON13                       143
#define IDI_ICON14                       144
#define IDI_ICON15                       145
#define IDI_ICON16                       146
#define IDI_ICON17                       147
#define IDI_ICON18                       148
#define IDI_ICON19                       149
#define IDI_ICON20                       150
//==菜单
#define IDC_MAINMENU                     201
//==对话框===== 
#define IDD_PASSWORDBOX                     210
#define IDD_ABOUTBOX                     211
//==控件=======
#define IDC_STATUSBAR                    1001
#define IDC_TOOLSBAR                    1002
#define IDC_LISTLOG                        1003 

#define IDC_TREE_FILE                    1101 
#define IDC_LISTVIEW_VIEW                1102 

#define IDC_EDIT_OP1                       1201
#define IDC_EDIT_OP2                       1202
#define IDC_EDIT_OP3                       1203
#define IDC_EDIT_OP4                       1204
#define IDRESET                            1205
#define ID_DLG_OPEN                        1206


//==菜单 COMMAND ID,
#define IDM_FILE_NEW                        40011
#define IDM_FILE_OPEN                        40012
#define IDM_FILE_SAVE                        40013
#define IDM_FILE_SAVEAS                        40014
#define IDM_TEST_TEST1                        40015
#define IDM_TEST_TEST2                        40016
#define IDM_TEST_TEST3                        40017
#define IDM_TEST_TEST4                        40018
#define IDM_TREE_EDIT                        40105
#define IDM_TREE_INSERTCHILD                40106
#define IDM_TREE_INSERTSIBLING                40107
#define IDM_TREE_ADD                        40108
#define IDM_TREE_DELETE                        40109
#define IDM_TREE_REFRESH                    40110
#define IDM_TREE_DB_CONNECT                    40119
#define IDM_TREE_DB_DISCONNECT                40120
#define IDM_TREE_DB_PRAGMA                    40121
#define IDM_DB_SELECT100                    40122
#define IDM_DB_PRAGMA                        40123
#define IDM_DB_SELECTALL                    40124
#define IDM_DB_PASSWORD                     40125

//==自定义消息 COMMAND ID
#define IDX_EDIT_COMMAND                      50001

//==默认框架
#define IDR_MAINFRAME                    128
#define IDD_NT2_DIALOG        102

#define IDS_APP_TITLE                    103
#define IDM_ABOUT                        104
#define IDM_EXIT                        105
#define IDS_HELLO                        106
#define IDI_SMALL                        108
#define IDC_MYICON                        2
#define IDC_STATIC                        -1

// Next default values for new objects
// 
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NEXT_RESOURCE_VALUE        129
#define _APS_NEXT_COMMAND_VALUE         32771
#define _APS_NEXT_CONTROL_VALUE         1000
#define _APS_NEXT_SYMED_VALUE           110
#endif
#endif

资源文件

//Microsoft Visual C++ generated resource script.
//

#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
#ifdef _WIN32
LANGUAGE 4, 2
#pragma code_page(936)
#endif //_WIN32

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.

IDI_SQLCLIENT       ICON    DISCARDABLE     "SQLClient.ICO"
IDI_SMALL               ICON    DISCARDABLE     "SMALL.ICO"


IDI_ICON1               ICON            ".\\Res\\Win95\\UtilityText.ico"
IDI_ICON2               ICON            ".\\Res\\Win95\\OPENFOLD.ico"
IDI_ICON3               ICON            ".\\Res\\Win95\\DISK06.ico"
IDI_ICON4               ICON            ".\\Res\\Win95\\DISKS04.ico"
IDI_ICON5               ICON            ".\\Res\\Win95\\EXPLORER.ico"
IDI_ICON6               ICON            ".\\Res\\Win95\\DRIVENET.ico"
IDI_ICON7               ICON            ".\\Res\\Win95\\DRIVEDSC.ico"
IDI_ICON8               ICON            ".\\Res\\Win95\\MYCOMP.ico"
IDI_ICON9               ICON            ".\\Res\\Win95\\NETHOOD.ico"
IDI_ICON10               ICON            ".\\Res\\Win95\\525FLOP1.ico"
IDI_ICON11               ICON            ".\\Res\\Win95\\CLSDFOLD.ico"
IDI_ICON12               ICON            ".\\Res\\Win95\\properties_wnd.ico"
IDI_ICON13               ICON            ".\\Res\\Win95\\undo.ico"
IDI_ICON14               ICON            ".\\Res\\Win95\\redo.ico"
IDI_ICON15               ICON            ".\\Res\\Win95\\DESKTOP.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Menu
//

IDC_SQLCLIENT MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...",           IDM_ABOUT
    END
END


IDC_MAINMENU MENU DISCARDABLE
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "&New", IDM_FILE_NEW
        MENUITEM "&Open", IDM_FILE_OPEN
        MENUITEM "&Save", IDM_FILE_SAVE
        MENUITEM "&Save As", IDM_FILE_SAVEAS
        MENUITEM "E&xit", IDM_EXIT
    END
    POPUP "&Test"
    BEGIN
        MENUITEM "&Test1", IDM_TEST_TEST1
        MENUITEM "&Test2", IDM_TEST_TEST2
        MENUITEM "&Test3", IDM_TEST_TEST3
        MENUITEM "&Test4", IDM_TEST_TEST4
    END
    POPUP "&DataBase"
    BEGIN
    MENUITEM "Select100", IDM_DB_SELECT100
    MENUITEM "Pragma", IDM_DB_PRAGMA
    MENUITEM "SelectAll", IDM_DB_SELECTALL
    MENUITEM "Password", IDM_DB_PASSWORD
    POPUP "Other"
    BEGIN
    MENUITEM "&Connect", IDM_TREE_DB_CONNECT
    MENUITEM "&Disconnect", IDM_TREE_DB_DISCONNECT
    MENUITEM "&Pragma", IDM_TREE_DB_PRAGMA
    END
    END
    POPUP "T&ree"
    BEGIN
        MENUITEM "&Edit", IDM_TREE_EDIT
        MENUITEM "&InsertChild", IDM_TREE_INSERTCHILD
        MENUITEM "&InsertSibling", IDM_TREE_INSERTSIBLING
        MENUITEM "&Delete", IDM_TREE_DELETE
        MENUITEM "&ReFresh", IDM_TREE_REFRESH
        POPUP "&DateBase"
        BEGIN
            MENUITEM "&Connect", IDM_TREE_DB_CONNECT
            MENUITEM "&Disconnect", IDM_TREE_DB_DISCONNECT
            MENUITEM "&Pragma", IDM_TREE_DB_PRAGMA
        END
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...", IDM_ABOUT
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//

IDC_SQLCLIENT ACCELERATORS MOVEABLE PURE
BEGIN
    "?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//


IDD_PASSWORDBOX DIALOG DISCARDABLE  22, 17, 178, 128
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "PASSWORD"
FONT 8, "System"
BEGIN
    ICON            IDI_ICON1, IDCANCEL, 14, 9, 20, 20
    LTEXT           "XT Version 1.0", IDC_STATIC, 50, 7, 72, 8, SS_NOPREFIX
    LTEXT           "Copyright (C) 2023", IDC_STATIC, 49, 20, 119, 8
    DEFPUSHBUTTON   "OK", IDOK, 133, 44, 30, 11, WS_GROUP
    PUSHBUTTON      "CANCEL", IDCANCEL, 133, 68, 30, 11, WS_GROUP
    PUSHBUTTON      "RESET", IDRESET, 133, 92, 30, 11, WS_GROUP
    EDITTEXT        IDC_EDIT_OP1, 42, 42, 80, 14, ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT_OP2, 42, 66, 80, 14, ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT_OP3, 42, 90, 80, 14, ES_AUTOHSCROLL
END

IDD_ABOUTBOX DIALOG DISCARDABLE  22, 17, 230, 75
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "About"
FONT 8, "System"
BEGIN
    ICON            IDI_SQLCLIENT,IDC_MYICON,14,9,16,16
    LTEXT           "SQLClient Version 1.0",IDC_STATIC,49,10,119,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2023",IDC_STATIC,49,20,119,8
    DEFPUSHBUTTON   "OK",IDOK,195,6,30,11,WS_GROUP
END


#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//


2 TEXTINCLUDE DISCARDABLE 
BEGIN
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""windows.h""\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""resource.h""\r\n"
    "\0"
END

3 TEXTINCLUDE DISCARDABLE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED




/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE DISCARDABLE 
BEGIN
   IDC_SQLCLIENT   "SQLCLIENT"
   IDS_APP_TITLE       "SQLClient"
   IDS_HELLO           "Hello World!"
END

#endif
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED