Quantcast
Channel: Active questions tagged header - Stack Overflow
Viewing all articles
Browse latest Browse all 705

How to change CHeaderCtrl height (multiline height)

$
0
0

I try to develope multiline (doubleline) header - CHeaderCtrl of the CListCtrl. I am not able to change the heigth of the header.How I can change the heigth without changing the font?

Code of doubleline CHeaderCtrl:"dlg.h" file

 #pragma once#include "resource.h"#include "framework.h"#include <map>#include <set>using namespace std;//My own header for multiline headerclass CMyHeaderCtrl : public CHeaderCtrl{public:    DECLARE_MESSAGE_MAP()    void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);    void OnLButtonDown(UINT nFlags, CPoint point);};class CMFCtestDlg : public CDialogEx{    // Constructionpublic:    CMFCtestDlg(CWnd *pParent = nullptr);   // standard constructor    ~CMFCtestDlg() { }    // Dialog Data#ifdef AFX_DESIGN_TIME    enum { IDD = IDD_MFC_TEST_DIALOG };#endifprotected:    map<int, LPCTSTR> m_mapOfTab{{0,L"Nula"},{1,L"Jedna"},{2,L"Dva"}};public:    CListCtrl m_cListCtrl;      // First list control    CMyHeaderCtrl m_myHeaderCtrl;protected:    virtual void DoDataExchange(CDataExchange *pDX);    // DDX/DDV support    // Implementationprotected:    HICON m_hIcon;    // Generated message map functions    virtual BOOL OnInitDialog();    DECLARE_MESSAGE_MAP()    CMenu m_SplitMenu;    CMenu m_SplitSubMenu;public:    void OnHeaderDropDown(NMHDR *pNMHDR, LRESULT *pResult);};

"dlg.cpp" file

#include "pch.h"#include "framework.h"#include "MFC_test.h"#include "MFC_testDlg.h"#include "afxdialogex.h"#include "resource.h"#ifdef _DEBUG#define new DEBUG_NEW#endif#define _MAJU_PRG_NAME L"Majklův řez"// CMFCtestDlg dialogCMFCtestDlg::CMFCtestDlg(CWnd *pParent /*=nullptr*/)    : CDialogEx(IDD_MFC_TEST_DIALOG, pParent){    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);    m_SplitMenu.LoadMenu(IDR_MENU);}void CMFCtestDlg::DoDataExchange(CDataExchange *pDX){    CDialogEx::DoDataExchange(pDX);    DDX_Control(pDX, IDC_LIST, m_cListCtrl);}BEGIN_MESSAGE_MAP(CMFCtestDlg, CDialogEx)    ON_NOTIFY(HDN_DROPDOWN, IDC_LIST, &CMFCtestDlg::OnHeaderDropDown)END_MESSAGE_MAP()#define ID_MENU_ITEM1 35600#define ID_MENU_ITEM2 35601BOOL CMFCtestDlg::OnInitDialog(){    CDialogEx::OnInitDialog();    m_cListCtrl.InsertColumn(0, L"Column 1", LVCFMT_CENTER, 100);    m_cListCtrl.InsertColumn(1, L"FirstLine\nSecLin", LVCFMT_CENTER, 150);    CHeaderCtrl *pHeaderCtrl = m_cListCtrl.GetHeaderCtrl();    if(pHeaderCtrl)    {        m_myHeaderCtrl.SubclassWindow(pHeaderCtrl->GetSafeHwnd());        pHeaderCtrl->ModifyStyle(0, pHeaderCtrl->GetStyle() | HDS_BUTTONS);        // Modify the header item style to include the split button style        HDITEM item;        item.mask = HDI_FORMAT;        //item.iItem = 0; // Index of the header item you want to modify        pHeaderCtrl->GetItem(1, &item);        item.fmt |= HDF_SPLITBUTTON;        pHeaderCtrl->SetItem(1, &item);        RECT rect;        pHeaderCtrl->GetClientRect(&rect);        //  rect.bottom += rect.bottom - rect.top; //Resize heigth of the Header to double heigth        rect.bottom += 50;        pHeaderCtrl->SetWindowPos(0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, 0);        //double headerHeight = rect.bottom - rect.top;    }    CString csTxt;    map<int, LPCTSTR>::const_iterator it = m_mapOfTab.begin();    for(int i = 0; it != m_mapOfTab.end(); ++it, ++i)    {        csTxt.Format(L"%i", it->first);        m_cListCtrl.InsertItem(i, csTxt.GetString());        m_cListCtrl.SetItemText(i, 1, it->second);    }    return TRUE;}void CMFCtestDlg::OnHeaderDropDown(NMHDR *pNMHDR, LRESULT *pResult){    LPNMHEADER phdr = reinterpret_cast<LPNMHEADER>(pNMHDR);    // Get the header control    CHeaderCtrl *pHeaderCtrl = m_cListCtrl.GetHeaderCtrl();    if(pHeaderCtrl != nullptr && phdr->iItem >= 0)    {        // Calculate the drop-down button rectangle        CRect rcItem;        pHeaderCtrl->GetItemRect(phdr->iItem, &rcItem);        // Get the position of the drop-down arrow button        CPoint point(rcItem.left, rcItem.bottom); // Show menu below the header item        pHeaderCtrl->ClientToScreen(&point); // Convert to screen coordinates        // Create and display the context menu        // Track the popup menu (display it at the arrow location)        m_SplitMenu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);    }}////////// CMyHeaderCtrlBEGIN_MESSAGE_MAP(CMyHeaderCtrl, CHeaderCtrl)    ON_NOTIFY_REFLECT(NM_CUSTOMDRAW, &CMyHeaderCtrl::OnCustomDraw)    ON_WM_LBUTTONDOWN()    ON_WM_PAINT()END_MESSAGE_MAP()void CMyHeaderCtrl::OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult){    LPNMCUSTOMDRAW pNMCD = reinterpret_cast<LPNMCUSTOMDRAW>(pNMHDR);    if(pNMCD->dwDrawStage == CDDS_PREPAINT)    {        *pResult = CDRF_NOTIFYITEMDRAW;  // Request item draw notifications    }    else if(pNMCD->dwDrawStage == CDDS_ITEMPREPAINT)    {        *pResult = CDRF_SKIPDEFAULT;  // Skip default drawing        // Set up the device context        CDC *pDC = CDC::FromHandle(pNMCD->hdc);        CRect rect = pNMCD->rc;        int itemIndex = static_cast<int>(pNMCD->dwItemSpec);        // Set background color        pDC->FillSolidRect(&rect, RGB(240, 240, 240));        // Draw two lines of text        HDITEM hdItem;        TCHAR text[256];        hdItem.mask = HDI_TEXT;        hdItem.pszText = text;        hdItem.cchTextMax = sizeof(text) / sizeof(TCHAR);        GetItem(itemIndex, &hdItem);        CString headerText(hdItem.pszText);        // Split text by newline character "\n"        CString topText, bottomText;        AfxExtractSubString(topText, headerText, 0, '\n');        AfxExtractSubString(bottomText, headerText, 1, '\n');        // Calculate positions for two lines of text        rect.bottom += 5;        CRect rectTop = rect;        CRect rectBottom = rect;        rectTop.bottom = rect.top + rect.Height() / 2;        rectBottom.top = rectTop.bottom;        // Draw the first and second line of text        CHeaderCtrl *pHeaderCtrl = dynamic_cast<CHeaderCtrl *>(CWnd::FromHandle(pNMCD->hdr.hwndFrom));        HDITEM item;        item.mask = HDI_FORMAT;        pHeaderCtrl->GetItem(pNMCD->dwItemSpec, &item);        UINT uHdFormat = DT_LEFT;        if(item.fmt & LVCFMT_RIGHT)            uHdFormat = DT_RIGHT;        else if(item.fmt & LVCFMT_CENTER)            uHdFormat = DT_CENTER;        pDC->DrawText(topText, &rectTop, uHdFormat | DT_VCENTER | DT_SINGLELINE);        pDC->DrawText(bottomText, &rectBottom, uHdFormat | DT_VCENTER | DT_SINGLELINE);        if(item.fmt & HDF_SPLITBUTTON)        {            rect.left = rect.right - 16;            DrawFrameControl(pDC->m_hDC, &rect, DFC_SCROLL, DFCS_SCROLLDOWN);        }    }}//Split Button#define ID_OPTION1 32500#define ID_OPTION2 32501void CMyHeaderCtrl::OnLButtonDown(UINT nFlags, CPoint point){    // Perform a hit-test to find the header item at the click position    HDHITTESTINFO hitTestInfo = {0};    hitTestInfo.pt = point;    int nItem = SendMessage(HDM_HITTEST, 0, (LPARAM) &hitTestInfo);    // Check if the click was on a split button    if(nItem >= 0 && (hitTestInfo.flags & HHT_ONHEADER))    {        HDITEM hdItem;        hdItem.mask = HDI_FORMAT;        if(GetItem(nItem, &hdItem) && (hdItem.fmt & HDF_SPLITBUTTON))        {            CRect itemRect;            if(!GetItemRect(nItem, &itemRect))                return CHeaderCtrl::OnLButtonDown(nFlags, point);            // Define an approximate width for the split button icon (e.g., 16 pixels)            const int iconWidth = 16;            // Calculate the area on the far right where the icon would be            CRect iconRect = itemRect;            iconRect.left = iconRect.right - iconWidth;            // Check if the click point falls within the icon area            if(iconRect.PtInRect(point))            {                // Show context menu or handle the split button click                CMenu menu;                menu.CreatePopupMenu();                menu.AppendMenu(MF_STRING, ID_OPTION1, _T("Option 1"));                menu.AppendMenu(MF_STRING, ID_OPTION2, _T("Option 2"));                ClientToScreen(&point);                menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, point.x, point.y, this);                return; // Stop further processing            }        }    }    // Call base class for default behavior if it wasn't a split button click    CHeaderCtrl::OnLButtonDown(nFlags, point);}

Viewing all articles
Browse latest Browse all 705

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>