其他分享
首页 > 其他分享> > TreeView 和 Header 控件配合成表结构

TreeView 和 Header 控件配合成表结构

作者:互联网

1.利用TreeView和Header控件配合,对TreeView进行部分重绘,做成一个可以展开的表结构。

2.重绘要注意先后顺序。

效果如图。

 

 

程序如下:

HeaderTest.cpp

// HeaderTest.cpp : Defines the entry point for the application.
// TreeView 和 Header 控件配合成表结构
// XGZ 2022-05-15 SZ

#include "stdafx.h"
#include "HeaderTest.h"
#include "Commctrl.h"
#pragma comment(lib,"comctl32.lib")

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                    // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];            // the main window class name

// Forward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int PRINT(TCHAR *fmt, ...);

int OnCreate(HWND, UINT, WPARAM, LPARAM);
int OnSize(HWND, UINT, WPARAM, LPARAM);
int OnDestroy(HWND, UINT, WPARAM, LPARAM);
int OnNotify(HWND, UINT, WPARAM, LPARAM);

HTREEITEM AddItemToTree(HWND hwndTV, LPTSTR lpszItem, int nLevel);
HWND CreateTreeView (HWND hwndParent);
HTREEITEM InsertTreeNode(HWND hWndTV, HTREEITEM hPrev, LPTSTR lpszItem);
int  InitTreetView (HWND hTreeView);

HTREEITEM m_hNodeDevice;
HTREEITEM m_hNodeDataBase;
HTREEITEM m_hNodeTest;

#define IDC_HHEAD                                        1001 
#define IDM_VIEW_TREEVIEW1                        1002 
#define IDC_EDIT                                            1003 

HWND hWndHead;
HWND hWndEdit;
HWND hWndTree;

int OnTreePaint(HWND, UINT, WPARAM, LPARAM);
LONG lpfnDefTree = 0;

LRESULT CALLBACK TreeWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    TCHAR wBuf[1024];
    switch (message)
    {
    case WM_PAINT:
        OnTreePaint(hWnd, message, wParam, lParam);
        break;
    default:
        break;
    } 
    return CallWindowProc((WNDPROC)lpfnDefTree, hWnd,  message,  wParam,  lParam);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

     // TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    // Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_HEADERTEST, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HEADERTEST));

    // Main message loop:
    while (GetMessage(&msg, NULL, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}

ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style            = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra        = 0;
    wcex.cbWndExtra        = 0;
    wcex.hInstance        = hInstance;
    wcex.hIcon            = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HEADERTEST));
    wcex.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName    = MAKEINTRESOURCE(IDC_HEADERTEST);
    wcex.lpszClassName    = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassEx(&wcex);
}

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

   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

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

   return TRUE;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_CREATE:
        OnCreate(hWnd, message, wParam, lParam);
        break;
    case WM_SIZE:
        OnSize(hWnd, message, wParam, lParam);
        break;
    case WM_DESTROY:
        OnDestroy(hWnd, message, wParam, lParam);
        break;
    case WM_NOTIFY:
        OnNotify(hWnd, message, wParam, lParam);
        break;
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

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

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

int HeadInsertItem(HWND hwndHeader, int iInsertAfter, 
    int nWidth, LPTSTR lpsz) 
{ 
    HDITEM hdi; 
    int index; 

    hdi.mask = HDI_TEXT | HDI_FORMAT | HDI_WIDTH; 
    hdi.cxy = nWidth; 
    hdi.pszText = lpsz; 
    hdi.cchTextMax = sizeof(hdi.pszText)/sizeof(hdi.pszText[0]); 
    hdi.fmt = HDF_LEFT | HDF_STRING; 

    index = SendMessage(hwndHeader, HDM_INSERTITEM, 
        (WPARAM) iInsertAfter, (LPARAM) &hdi); 

    return index; 
}

int OnCreate(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int i=0;
    InitCommonControls();

    RECT rcParent; 
    HDLAYOUT hdl; 
    WINDOWPOS wp; 
    hWndHead = CreateWindow(WC_HEADER, NULL,
        WS_CHILD | WS_BORDER |WS_VISIBLE| HDS_BUTTONS | HDS_HORZ,
        0,0,0,0,
        hWnd, (HMENU) IDC_EDIT, hInst, NULL);

    GetClientRect(hWnd, &rcParent); 

    hdl.prc = &rcParent; 
    hdl.pwpos = ℘ 
    SendMessage(hWndHead, HDM_LAYOUT, 0, (LPARAM) &hdl);

// Set the size, position, and visibility of the header control. SetWindowPos(hWndHead, wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags | SWP_SHOWWINDOW); HeadInsertItem( hWndHead, 0,100, _T("First")); HeadInsertItem( hWndHead, 1,100, _T("Second")); HeadInsertItem( hWndHead, 2,100, _T("Third")); TCHAR strBuf[1024]; hWndEdit = CreateWindow(TEXT("edit"),NULL, WS_CHILD|WS_BORDER|WS_VISIBLE|ES_MULTILINE|WS_VSCROLL, 10,130,600,400, hWnd, (HMENU) IDC_EDIT, hInst, NULL); hWndTree = CreateTreeView(hWnd); InitTreetView(hWndTree); SendMessage(hWndTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)m_hNodeDataBase); lpfnDefTree = SetWindowLong(hWndTree, GWL_WNDPROC, (LONG)TreeWndProc); return 1; } int OnSize(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int cxClient,cyClient; cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); MoveWindow(hWndHead, 5, 5, cxClient-10, 20, TRUE); MoveWindow(hWndTree, 5, 25, cxClient-10, 200, TRUE); //MoveWindow(hWndTree, 5, 25, 100, 200, TRUE); MoveWindow(hWndEdit, 5, 280, cxClient-10, cyClient-290, TRUE); return DefWindowProc(hWnd, message, wParam, lParam); } int OnDestroy(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PostQuitMessage(0); return 1; } int PRINT(TCHAR *fmt, ...) { TCHAR buffer[1024]; va_list argptr; int cnt; int iEditTextLength; HWND hWnd = hWndEdit; if(NULL == hWnd) return 0; va_start(argptr, fmt); //cnt = vsprintf(buffer, fmt, argptr); cnt = vswprintf_s(buffer, fmt, argptr); 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); } int OnNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { RECT rt; int i; int ItemCount; HTREEITEM hti; TVITEM tvi; TCHAR text[1024]; LPNMHDR lphr = (LPNMHDR)lParam; if (lphr->hwndFrom == hWndHead) { switch (lphr->code) { case HDN_ITEMCLICK: PRINT(_T("\r\n HDN_ITEMCLICK ")); break; case HDN_ITEMCHANGED: PRINT(_T("\r\n HDN_ITEMCHANGED")); ItemCount = Header_GetItemCount(hWndHead); for( i=0; i<ItemCount;i++) { Header_GetItemRect( hWndHead, i, &rt ); PRINT(_T("\r\n hWndHead %d, [%d,%d]"), i, rt.left, rt.right); } InvalidateRect(hWndTree, NULL, TRUE); break; default: break; } } return DefWindowProc(hWnd, message, wParam, lParam); } HWND CreateTreeView (HWND hwndParent) { InitCommonControls(); HINSTANCE app_hInst = (HINSTANCE)GetWindowLong(hwndParent,GWL_HINSTANCE); HWND hWndTreeView = CreateWindow(WC_TREEVIEW, NULL, WS_CHILD|WS_VISIBLE|TVS_HASBUTTONS|TVS_HASLINES|TVS_SHOWSELALWAYS|TVS_LINESATROOT|WS_BORDER, 0, 0,0,0, hwndParent, (HMENU)IDM_VIEW_TREEVIEW1, app_hInst, NULL); return (hWndTreeView); } HTREEITEM 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_PARAM|TVIF_STATE; // Set the text of the item. tvi.pszText = lpszItem; tvi.cchTextMax = sizeof(tvi.pszText)/sizeof(tvi.pszText[0]); tvi.lParam = (LPARAM)nLevel; tvins.item = tvi; tvins.hInsertAfter = hPrev; hPrev = (HTREEITEM)SendMessage(hwndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); if (hPrev == NULL) return NULL; return hPrev; } HTREEITEM InsertTreeNode(HWND hWndTV, HTREEITEM hPrev, LPTSTR lpszItem) { TVINSERTSTRUCT tvins; TVITEM tvi; tvins.item.mask = TVIF_TEXT ; tvins.item.pszText = lpszItem; tvins.hParent = hPrev; tvins.hInsertAfter = TVI_LAST; return (HTREEITEM)SendMessage(hWndTV, TVM_INSERTITEM, 0, (LPARAM)(LPTVINSERTSTRUCT)&tvins); } int InitTreetView(HWND hTreeView) { HTREEITEM hti; m_hNodeDevice = InsertTreeNode(hTreeView, NULL, _T("Device")); m_hNodeDataBase = InsertTreeNode(hTreeView, NULL, _T("DataBase")); m_hNodeTest = InsertTreeNode(hTreeView, NULL, _T("Test")); hti = InsertTreeNode(hTreeView, m_hNodeDevice, _T("IO1")); hti = InsertTreeNode(hTreeView, m_hNodeDevice, _T("IO2")); hti = InsertTreeNode(hTreeView, m_hNodeDevice, _T("Option")); hti = InsertTreeNode(hTreeView, m_hNodeDataBase, _T("SQLite3")); hti = InsertTreeNode(hTreeView, m_hNodeDataBase, _T("Company")); hti = InsertTreeNode(hTreeView, hti, _T("SubCompany")); hti = InsertTreeNode(hTreeView, m_hNodeTest, _T("XTMusic")); hti = InsertTreeNode(hTreeView, m_hNodeTest, _T("XTVideo")); hti = InsertTreeNode(hTreeView, m_hNodeTest, _T("XTCipher")); return 1; } int OnTreePaint(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; RECT rt; HTREEITEM hti; TVITEM tvi; int iPos[10]; CallWindowProc((WNDPROC)lpfnDefTree, hWnd, message, wParam, lParam); //先画好原来的 //hdc = BeginPaint(hWnd, &ps); //会无效化之前的区域,如使用需指定区域 hdc = GetDC(hWnd); // 保留原先的 int ItemCount = Header_GetItemCount(hWndHead); for( int i=0; i<ItemCount;i++) { Header_GetItemRect( hWndHead, i, &rt ); iPos[i] = rt.right; } TCHAR szText[20]; hti = TreeView_GetFirstVisible(hWndTree ); while(hti) { memset(&tvi, 0, sizeof(tvi)); tvi.mask = TVIF_TEXT | TVIF_PARAM; tvi.hItem = hti; tvi.pszText = szText; tvi.cchTextMax = sizeof(szText); TreeView_GetItem(hWndTree, &tvi); TreeView_GetItemRect(hWnd, hti, &rt, TRUE); //TRUE only Tesxt rt.left = iPos[0]; rt.right = iPos[1]; DrawText(hdc, szText, wcslen(szText), &rt, DT_LEFT); rt.left = iPos[1]; rt.right = iPos[2]; Rectangle(hdc, iPos[1],rt.top+1,iPos[2],rt.bottom-1); DrawText(hdc, _T("50%"),wcslen(_T("50%")), &rt, DT_CENTER); int iDrawMode = SetROP2(hdc, R2_NOT); //画笔取反 Rectangle(hdc, iPos[1], rt.top+1, iPos[1]+(iPos[2]-iPos[1]) * 0.5,rt.bottom-1); SetROP2(hdc, iDrawMode); hti =TreeView_GetNextVisible(hWndTree,hti); } //EndPaint(hWnd, &ps); ReleaseDC(hWnd, hdc); return 1; }

 

标签:wParam,控件,lParam,int,hWnd,Header,HWND,成表,message
来源: https://www.cnblogs.com/xgz21/p/16273412.html