Роджер Джек - Исчерпывающее руководство по написанию всплывающих подсказок
- Название:Исчерпывающее руководство по написанию всплывающих подсказок
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Роджер Джек - Исчерпывающее руководство по написанию всплывающих подсказок краткое содержание
Исчерпывающее руководство по написанию всплывающих подсказок - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
CODListBox представляет собой пример реализации подсказок TitleTips для элемента "список" с пользовательской отрисовкой (см. рис.13). Константа CODListBox::m_nEdgeSpace используется для добавления пространства по краям текста. Константа CODListBox::m_nFontHeight представляет желаемую высоту шрифта для отображения строк. В переменной CODListBox::m_Font хранится шрифт для отображения строк. CODListBox::CODListBox создает шрифт (m_Font) и использует его при отрисовке элемента "список".
Рис.13. CODListBox
// ODListBox.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CODListBox window
#include "TitleTipListBox.h"
class CODListBox : public CTitleTipListBox { // Construction public:
CODListBox();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CODListBox)
public:
virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
virtual void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CODListBox();
protected:
const int m_nEdgeSpace; // Дополнительное пространство вокруг текста
const int m_nFontHeight; // Высота шрифта
CFont m_Font; // Шрифт для отображения строк
virtual int GetIdealItemRect(int nIndex, LPRECT lpRect);
// Generated message map functions protected:
//{{AFX_MSG(CODListBox)
// NOTE – the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
///////////////////////////////////////////////////////////////////////////// // ODListBox.cpp : implementation file //
#include "stdafx.h"
#include "TTDemo.h"
#include "ODListBox.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CODListBox
CODListBox::CODListBox() : m_nEdgeSpace(4), m_nFontHeight(20) {
VERIFY(m_Font.CreateFont(m_nFontHeight, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"));
}
CODListBox::~CODListBox() { }
int CODListBox::GetIdealItemRect(int nIndex, LPRECT lpRect) {
ASSERT(nIndex >= 0);
int nResult = GetItemRect(nIndex, lpRect);
if (nResult != LB_ERR) {
CClientDC DC(this);
CFont* pOldFont = DC.SelectObject(&m_Font);
// Calculate the text length.
CString strItem;
GetText(nIndex, strItem);
CSize TextSize = DC.GetTextExtent(strItem);
// Взять максимум от обычной ширины и идеальной ширины.
lpRect->right = max(lpRect->right, lpRect->left + TextSize.cx + (m_nEdgeSpace * 2));
DC.SelectObject(pOldFont);
}
return nResult;
}
BEGIN_MESSAGE_MAP(CODListBox, CTitleTipListBox)
//{{AFX_MSG_MAP(CODListBox)
// NOTE – the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CODListBox message handlers
void CODListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
ASSERT_VALID(pDC);
int nSavedDC = pDC->SaveDC();
CString strItem;
if (lpDrawItemStruct->itemID != –1) {
GetText(lpDrawItemStruct->itemID, strItem);
}
COLORREF TextColor;
COLORREF BackColor;
UINT nItemState = lpDrawItemStruct->itemState;
if (nItemState & ODS_SELECTED) {
TextColor = RGB(255, 255, 255); // Белый
BackColor = RGB(255, 0, 0); // Красный
} else {
TextColor = RGB(255, 0, 0); // Красный
BackColor = RGB(255, 255, 255); // Белый
}
CRect ItemRect(lpDrawItemStruct->rcItem);
// Нарисовать фон
pDC->FillSolidRect(ItemRect, BackColor);
// Нарисовать текст
pDC->SetTextColor(TextColor);
pDC->SetBkMode(TRANSPARENT);
pDC->SelectObject(&m_Font);
ItemRect.left += m_nEdgeSpace;
pDC->DrawText(strItem, ItemRect, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
ItemRect.left –= m_nEdgeSpace;
// Нарисовать по необходимости рамку фокуса
if (nItemState & ODS_FOCUS) {
pDC->DrawFocusRect(ItemRect);
}
pDC->RestoreDC(nSavedDC);
}
void CODListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) {
lpMeasureItemStruct->itemHeight = m_nFontHeight + (m_nEdgeSpace * 2);
}
CODListBox::GetIdealItemRect перекрывает такой же метод в классе CTitleTipListBox. Как вы видите, его реализация похожа на реализацию метода в базовом классе, за исключением того, что новый метод использует для шрифта переменную m_Font. Конечно, я мог бы добиться результата и без переопределения метода базового класса, если бы воспользовался CWnd::SetFont для установки шрифта для списка. Однако я хотел показать, как нужно перекрывать этот метод в других случаях. Например, вам придется переопределить CTitleTipListBox::GetIdealItemRect, если вы захотите показывать в списке картинки.
CODListBox::DrawItem рисует строку по информации из структуры DrawItemStruct. Этот код аналогичен коду в функции CTitleTip::OnPaint, за исключением того, что вместо цветов по умолчанию используются красный и белый цвета. Помните, что этот метод может вызываться из класса CTitleTip для рисования внутри его окна.
CODListBox::MeasureItem вычисляет высоту строки на основе шрифта и заданного пустого пространства вокруг текста. Этот метод вызывается Windows только один раз, потому что у этого элемента "список" установлен стиль LBS_OWNERDRAWFIXED. В случае со стилем LBS_OWNERDRAWVARIABLE метод будет вызываться для каждой строки.
В диалоге CTTDemoDlg присутствуют оба рассмотренных элемента "список", и большая часть кода была сгенерирована AppWizard'ом (см. рис.14). Я добавил в класс переменные m_RegListBox и m_ODListBox для обычного списка и списка с пользовательской отрисовкой, соответственно. Еще я добавил код в функцию CTTDemoDlg::OnInitDialog, где производится сабклассинг обоих элементов "список" вызовом CWnd::SubclassWindow. Я загружаю оба списка из статического массива pszItemArray.
Рис.14. CTTDemoDlg
// TTDemoDlg.h : header file /////////////////////////////////////////////////////////////////////////////
// CTTDemoDlg dialog
#include "TitleTipListBox.h"
#include "ODListBox.h"
class CTTDemoDlg : public CDialog { // Construction public:
CTTDemoDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CTTDemoDlg)
enum { IDD = IDD_TTDEMO_DIALOG };
// NOTE: the ClassWizard will add data members here
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CTTDemoDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
CTitleTipListBox m_RegListBox; // Обычный список
CODListBox m_ODListBox; // Список с пользовательской отрисовкой
// Generated message map functions
//{{AFX_MSG(CTTDemoDlg)
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
// TTDemoDlg.cpp : implementation file
#include "stdafx.h"
#include "TTDemo.h"
#include "TTDemoDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CTTDemoDlg dialog
CTTDemoDlg::CTTDemoDlg(CWnd* pParent /*=NULL*/) : CDialog(CTTDemoDlg::IDD, pParent) {
//{{AFX_DATA_INIT(CTTDemoDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CTTDemoDlg::DoDataExchange(CDataExchange* pDX) {
Интервал:
Закладка: