lstree.c

来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 563 行 · 第 1/2 页

C
563
字号
/* 
Copyright 2001-2003 Free Software Foundation, Inc.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  

You may contact the author at:

mailto::camille@bluegrass.net

or by snail mail at:

David Lindauer
850 Washburn Ave Apt 99
Louisville, KY 40222

 **********************************************************************

LSTREE.C defines a two-column tree for use in things like the watch
window and the register window.  The right-hand column is editable.
The editing function is done by superclassing the tree control and adding
editablility.  A higher level window was added as a wrapper to do things
like manage the header.  The watch window will use this control for display
purposes.
 */
#define STRICT
#include <windows.h>
#include <commctrl.h>
#include <stdio.h>
#include "lsctrl.h"

extern HINSTANCE hInstance;
static char *szextTreeWindClassName = "ladSoftextTreeWindow";
static char *szColumnTreeWindClassName = "ladSoftColumnTreeWindow";
static char *szextEditWindClassName = "ladSoftextEditWindow";
static int wndoffstree, wndoffsedit;
static WNDPROC oldproc, oldeditproc;
static LOGFONT fontdata = 
{
    14, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET,
        OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_DONTCARE, 
        "Helvetica"
};

#define DISPLAY_MAX 500
typedef struct
{
    HWND hwndHeader;
    HWND hwndTree;
    HFONT watchFont;
    HTREEITEM displaylist[DISPLAY_MAX];
    int displaycount;
    int sel;
} COLUMNINFO;

typedef struct
{
    HWND hwndEdit;
    HTREEITEM editItem;
    int divider;
} TREEINFO;
LRESULT CALLBACK _export extEditWndProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    LRESULT rv;
    RECT r;
    switch (iMessage)
    {
        case WM_CHAR:
            if (wParam == 13)
            {
                SendMessage(GetParent(hwnd), TCN_EDITDONE, 0, 0);
                return 0;
            }
    }
    return CallWindowProc(oldeditproc, hwnd, iMessage, wParam, lParam);
}

//-------------------------------------------------------------------------

LRESULT CALLBACK _export extTreeWndProc(HWND hwnd, UINT iMessage, WPARAM wParam,
    LPARAM lParam)
{
    static char buf[256];
    LRESULT rv;
    RECT r;
    TREEINFO *ptr;
    HTREEITEM hTreeItem;
    TCData *td;
    TV_HITTESTINFO tvh;
    TV_ITEM item;
    NM_TREEVIEW x;
    HDC dc;
    PAINTSTRUCT ps;
    switch (iMessage)
    {
        case WM_NOTIFY:
            if (((NMHDR*)lParam)->code == TVN_SELCHANGING)
                return TRUE;
            break;
        case WM_CREATE:
            ptr = (TREEINFO*)HeapAlloc(GetProcessHeap(), 0, sizeof(TREEINFO));
            ptr->hwndEdit = 0;
            SetWindowLong(hwnd, wndoffstree, (int)ptr);
            break;
        case WM_DESTROY:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            if (ptr->hwndEdit)
                DestroyWindow(ptr->hwndEdit);
            HeapFree(GetProcessHeap(), 0, ptr);
            break;
        case WM_PAINT:
            GetUpdateRect(hwnd, &r, FALSE);
            rv = CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
            SendMessage(GetParent(hwnd), TCN_PAINT, 0, (LPARAM) &r);
            return rv;
        case WM_LBUTTONDOWN:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            if (!ptr->hwndEdit)
            {
                tvh.pt.x = LOWORD(lParam);
                tvh.pt.y = HIWORD(lParam);
                if (tvh.pt.x < ptr->divider)
                    break;
                TreeView_HitTest(hwnd, &tvh);
                hTreeItem = tvh.hItem;
                if (hTreeItem && tvh.pt.x >= ptr->divider)
                {
                    char *val;
                    x.hdr.code = TCN_EDITQUERY;
                    x.itemOld.mask = 0;
                    x.itemNew.mask = 0;
                    x.itemNew.hItem = hTreeItem;
                    if (val = (char*)SendMessage(GetParent(hwnd), WM_NOTIFY, 0,
                        (LPARAM) &x))
                    {
                        HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0);
                        ptr->editItem = hTreeItem;
                        TreeView_GetItemRect(hwnd, hTreeItem, &r, FALSE);
                        r.left = ptr->divider;
                        item.hItem = hTreeItem;
                        item.mask = TVIF_PARAM;
                        TreeView_GetItem(hwnd, &item);
                        td = (TCData*)item.lParam;
                        ptr->hwndEdit = CreateWindow(szextEditWindClassName,
                            val, WS_CHILD | ES_AUTOHSCROLL, r.left, r.top,
                            r.right - r.left, r.bottom - r.top, hwnd, (HMENU)
                            449, (HINSTANCE)GetWindowLong(GetParent(hwnd),
                            GWL_HINSTANCE), 0);
                        SendMessage(ptr->hwndEdit, WM_SETFONT, (WPARAM)font,
                            MAKELPARAM(0, 0));
                        SendMessage(ptr->hwndEdit, EM_SETSEL, 0, (LPARAM) - 1);
                        SendMessage(ptr->hwndEdit, EM_SETLIMITTEXT, 40, 0);
                        ShowWindow(ptr->hwndEdit, SW_SHOW);
                        SetFocus(ptr->hwndEdit);
                        return 0;
                    }
                }
                break;
            }
            // FALL THROUGH 
        case TCN_EDITDONE:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            SendMessage(ptr->hwndEdit, WM_GETTEXT, 50, (LPARAM)buf);
            DestroyWindow(ptr->hwndEdit);
            ptr->hwndEdit = 0;
            x.hdr.code = TCN_EDITDONE;
            x.itemOld.mask = 0;
            x.itemNew.mask = TVIF_TEXT;
            x.itemNew.hItem = ptr->editItem;
            x.itemNew.pszText = buf;
            SendMessage(GetParent(hwnd), WM_NOTIFY, 0, (LPARAM) &x);
            InvalidateRect(GetParent(hwnd), 0, 0);
            return 0;
        case TCF_SETDIVIDER:
            ptr = (TREEINFO*)GetWindowLong(hwnd, wndoffstree);
            ptr->divider = lParam - GetSystemMetrics(SM_CXBORDER);
            return 0;

    }
    return CallWindowProc(oldproc, hwnd, iMessage, wParam, lParam);
}

//-------------------------------------------------------------------------

LRESULT CALLBACK _export ColumnTreeWndProc(HWND hwnd, UINT iMessage, WPARAM
    wParam, LPARAM lParam)
{
    HTREEITEM titem;
    HD_LAYOUT hdl;
    WINDOWPOS wp;
    COLUMNINFO *ptr;
    RECT r, r1,  *rp;
    HD_ITEM hie;
    TCHeader *h;
    HD_NOTIFY *n;
    TV_DISPINFO *t;
    LPTV_INSERTSTRUCT is;
    int i;
    TV_ITEM item;
    TCData *td;
    TV_HITTESTINFO tvh;
    TREEINFO *treeinfo;
    PAINTSTRUCT ps;
    HDC dc;
    POINT pos;
    NM_TREEVIEW *ntv;
    if (iMessage >= TV_FIRST && iMessage < TV_FIRST + 100)
    {
        ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
        switch (iMessage)
        {
            case TVM_HITTEST:
                tvh.pt = ((TV_HITTESTINFO*)lParam)->pt;
                ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
                GetRelativeRect(hwnd, ptr->hwndTree, &r);
                tvh.pt.x -= r.left;
                tvh.pt.y -= r.top;
                treeinfo = TreeView_HitTest(ptr->hwndTree, &tvh);
                if (treeinfo)
                {
                    ((TV_HITTESTINFO*)lParam)->flags = tvh.flags;
                    ((TV_HITTESTINFO*)lParam)->hItem = tvh.hItem;
                }
                return treeinfo;
            case TVM_INSERTITEM:
                is = (LPTV_INSERTSTRUCT)lParam;
                #if !defined( _WIN32_IE) && !defined(__CCDL__)
                    is->item.mask |= TVIF_TEXT | TVIF_PARAM;
                    is->item.pszText = LPSTR_TEXTCALLBACK;
                #else 
                    is->u.item.mask |= TVIF_TEXT | TVIF_PARAM;
                    is->u.item.pszText = LPSTR_TEXTCALLBACK;
                #endif 
                titem = (HTREEITEM)SendMessage(ptr->hwndTree, iMessage, wParam,
                    lParam);
                return titem;
            default:
                return SendMessage(ptr->hwndTree, iMessage, wParam, lParam);
        }
    }
    else if (iMessage >= HDM_FIRST && iMessage < HDM_FIRST + 100)
    {
        ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
        return SendMessage(ptr->hwndHeader, iMessage, wParam, lParam);
    }
    switch (iMessage)
    {
        case WM_NOTIFY:
            n = (HD_NOTIFY*)lParam;
            ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
            switch (n->hdr.code)
            {
            case NM_RCLICK:
                #ifdef XXXXX
                    ptr = (COLUMNINFO*)GetWindowLong(hwnd, 0);
                    GetCursorPos(&pos);
                    ScreenToClient(ptr->hwndTree, &pos);
                    titem = TreeView_HitTest(ptr->hwndTree, &pos);
                    for (i = 0; i < ptr->displaycount; i++)
                    if (titem == ptr->displaylist[i])
                    {
                        ptr->sel = i;
                        InvalidateRect(ptr->hwndTree, 0, 0);
                        break;
                    }
                #endif 
                return SendMessage(GetParent(hwnd), iMessage, wParam, lParam);
            case TVN_SELCHANGING:
                return TRUE;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?