Я пытаюсь создать многострочный (двустрочный) заголовок — CHeaderCtrl из CListCtrl. Я не могу изменить высоту заголовка.
Как изменить высоту, не меняя шрифт?
Код двойной строки CHeaderCtrl:
файл «dlg.h»
#pragma once
#include "resource.h"
#include "framework.h"
#include
#include
using namespace std;
//My own header for multiline header
class CMyHeaderCtrl : public CHeaderCtrl
{
public:
DECLARE_MESSAGE_MAP()
void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);
void OnLButtonDown(UINT nFlags, CPoint point);
};
class CMFCtestDlg : public CDialogEx
{
// Construction
public:
CMFCtestDlg(CWnd *pParent = nullptr); // standard constructor
~CMFCtestDlg() { }
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFC_TEST_DIALOG };
#endif
protected:
map 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
// Implementation
protected:
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»
#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 dialog
CMFCtestDlg::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 35601
BOOL 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::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(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);
}
}
////////// CMyHeaderCtrl
BEGIN_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(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(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(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 32501
void 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);
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... ine-heigth
Как изменить высоту CHeaderCtrl (многострочную высоту) ⇐ C++
Программы на C++. Форум разработчиков
-
Anonymous
1731618555
Anonymous
Я пытаюсь создать многострочный (двустрочный) заголовок — CHeaderCtrl из CListCtrl. Я не могу изменить высоту заголовка.
Как изменить высоту, не меняя шрифт?
Код двойной строки CHeaderCtrl:
файл «dlg.h»
#pragma once
#include "resource.h"
#include "framework.h"
#include
#include
using namespace std;
//My own header for multiline header
class CMyHeaderCtrl : public CHeaderCtrl
{
public:
DECLARE_MESSAGE_MAP()
void OnCustomDraw(NMHDR *pNMHDR, LRESULT *pResult);
void OnLButtonDown(UINT nFlags, CPoint point);
};
class CMFCtestDlg : public CDialogEx
{
// Construction
public:
CMFCtestDlg(CWnd *pParent = nullptr); // standard constructor
~CMFCtestDlg() { }
// Dialog Data
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFC_TEST_DIALOG };
#endif
protected:
map 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
// Implementation
protected:
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»
#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 dialog
CMFCtestDlg::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 35601
BOOL 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::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(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);
}
}
////////// CMyHeaderCtrl
BEGIN_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(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(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(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 32501
void 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);
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79183907/how-to-change-cheaderctrl-heigth-multiline-heigth[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия