Исчерпывающее руководство по написанию всплывающих подсказок - [8]
Рис.11. CTitleTip
>/////////////////////////////////////////////////////////////////////////////
>// CTitleTip window
>class CTitleTip : public CWnd {
>public:
> CTitleTip();
> virtual BOOL Create(CListBox* pParentWnd);
> virtual void Show(CRect DisplayRect, int nItemIndex);
> virtual void Hide();
>// Overrides
> // ClassWizard generated virtual function overrides
> //{{AFX_VIRTUAL(CTitleTip)
> //}}AFX_VIRTUAL
> // Implementation
>public:
> virtual ~CTitleTip();
>protected:
> const int m_nNoIndex; // Пустой индекс
> static LPCSTR m_pszWndClass; // Имя зарегистрированного класса
> int m_nItemIndex; // Индекс строки, для которой показывается подсказка
> CListBox* m_pListBox; // Родительское окно
> BOOL IsListBoxOwnerDraw();
> // Generated message map functions
>protected:
> //{{AFX_MSG(CTitleTip)
> afx_msg void OnPaint();
> //}}AFX_MSG
> DECLARE_MESSAGE_MAP()
>};
>/////////////////////////////////////////////////////////////////////////////
>// TitleTip.cpp : implementation file //
>#include "stdafx.h"
>#include "TitleTip.h"
>#ifdef _DEBUG
>#define new DEBUG_NEW
>#undef THIS_FILE
>static char THIS_FILE[] = __FILE__;
>#endif
>/////////////////////////////////////////////////////////////////////////////
>// CTitleTip
>LPCSTR CTitleTip::m_pszWndClass = NULL;
>CTitleTip::CTitleTip() : m_nNoIndex(-1) {
> // Зарегистрировать класс окна, если он еще не зарегистрирован
> // другим экземпляром CTitleTip.
> if (m_pszWndClass == NULL) {
> m_pszWndClass = AfxRegisterWndClass(CS_SAVEBITS | CS_HREDRAW | CS_VREDRAW);
> }
> m_nItemIndex = m_nNoIndex;
> m_pListBox = NULL;
>}
>CTitleTip::~CTitleTip() { }
>BOOL CTitleTip::Create(CListBox* pParentWnd) {
> ASSERT_VALID(pParentWnd);
> m_pListBox = pParentWnd;
> // Не рисовать рамку для обычных элементов "список", так как
> // строки с пользовательской отрисовкой добавляют рамку автоматически.
> DWORD dwStyle = WS_POPUP;
> if (!IsListBoxOwnerDraw()) {
> dwStyle |= WS_BORDER;
> }
> return CreateEx(0, m_pszWndClass, NULL, dwStyle, 0, 0, 0, 0, pParentWnd->GetSafeHwnd(), NULL, NULL);
>}
>BOOL CTitleTip::IsListBoxOwnerDraw() {
> ASSERT_VALID(m_pListBox);
> DWORD dwStyle = m_pListBox->GetStyle();
> return (dwStyle & LBS_OWNERDRAWFIXED) || (dwStyle & LBS_OWNERDRAWVARIABLE);
>}
>void CTitleTip::Show(CRect DisplayRect, int nItemIndex) {
> ASSERT_VALID(m_pListBox);
> ASSERT(nItemIndex < m_pListBox->GetCount());
> ASSERT(nItemIndex >= 0);
> ASSERT(::IsWindow(m_hWnd));
> ASSERT(!DisplayRect.IsRectEmpty());
> // Пометить для обновления, если новая строка.
> if (m_nItemIndex != nItemIndex) {
> m_nItemIndex = nItemIndex;
> InvalidateRect(NULL);
> }
> // Установить позицию и видимость окна.
> CRect WindowRect;
> GetWindowRect(WindowRect);
> int nSWPFlags = SWP_SHOWWINDOW | SWP_NOACTIVATE;
> if (WindowRect == DisplayRect) {
> nSWPFlags |= SWP_NOMOVE | SWP_NOSIZE;
> }
> VERIFY(SetWindowPos(&wndTopMost, DisplayRect.left, DisplayRect.top, DisplayRect.Width(), DisplayRect.Height(), nSWPFlags));
>}
>void CTitleTip::Hide() {
> ASSERT(::IsWindow(m_hWnd));
> ShowWindow(SW_HIDE);
>}
>BEGIN_MESSAGE_MAP(CTitleTip, CWnd)
> //{{AFX_MSG_MAP(CTitleTip)
> ON_WM_PAINT()
> //}}AFX_MSG_MAP
>END_MESSAGE_MAP()
>/////////////////////////////////////////////////////////////////////////////
>// CTitleTip message handlers
>void CTitleTip::OnPaint() {
> ASSERT(m_nItemIndex != m_nNoIndex);
> CPaintDC DC(this);
> int nSavedDC = DC.SaveDC();
> CRect ClientRect;
> GetClientRect(ClientRect);
> if (IsListBoxOwnerDraw()) {
> // Доверим рисование элементу "список".
> DRAWITEMSTRUCT DrawItemStruct;
> DrawItemStruct.CtlType = ODT_LISTBOX;
> DrawItemStruct.CtlID = m_pListBox->GetDlgCtrlID();
> DrawItemStruct.itemID = m_nItemIndex;
> DrawItemStruct.itemAction = ODA_DRAWENTIRE;
> DrawItemStruct.hwndItem = m_pListBox->GetSafeHwnd();
> DrawItemStruct.hDC = DC.GetSafeHdc();
> DrawItemStruct.rcItem = ClientRect;
> DrawItemStruct.itemData = m_pListBox->GetItemData(m_nItemIndex);
> DrawItemStruct.itemState = (m_pListBox->GetSel(m_nItemIndex) > 0 ? ODS_SELECTED : 0);
> if (m_pListBox->GetStyle() & LBS_MULTIPLESEL) {
> if (m_pListBox->GetCaretIndex() == m_nItemIndex) {
> DrawItemStruct.itemState |= ODS_FOCUS;
> }
> } else {
> DrawItemStruct.itemState |= ODS_FOCUS;
> }
> m_pListBox->DrawItem(&DrawItemStruct);
> } else {
> // Рисуем самостоятельно
> CFont* pFont = m_pListBox->GetFont();
> ASSERT_VALID(pFont);
> DC.SelectObject(pFont);
> COLORREF clrBackground = RGB(255, 255, 255);
> if (m_pListBox->GetSel(m_nItemIndex) > 0) {
> DC.SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
> clrBackground = ::GetSysColor(COLOR_HIGHLIGHT);
> }
> // Рисуем фон
> DC.FillSolidRect(ClientRect, clrBackground);
> // Рисуем текст строки
> CString strItem;
> m_pListBox->GetText(m_nItemIndex, strItem);
> ASSERT(!strItem.IsEmpty());
> DC.SetBkMode(TRANSPARENT);
> DC.TextOut(1, –1, strItem);
> }
> DC.RestoreDC(nSavedDC);
> // Не вызываем CWnd::OnPaint() для сообщений отрисовки
>}
CTitleTip::CTitleTip регистрирует класс окна вызовом функции AfxRegisterWndClass и сохраняет имя класса в переменной CTitleTip::m_pszWndClass. Я использую функцию AfxRegisterWndClass, чтобы иметь возможность зарегистрировать класс окна с установленным стилем CS_SAVEBITS. Флаг CS_SAVEBITS используется для оптимизации – Windows сохраняет кусок окна, заслоненного элементом TitleTip, как картинку. В результате, этому окну не нужно посылать сообщение WM_PAINT, когда подсказка убирается с экрана. CTitleTip::Create создает подсказку в виде popup-окна. К окну подсказки рамка добавляется только если элемент "список" является обычным, так как Windows автоматически добавляет рамку к элементам "список" с пользовательской отрисовкой перед посылкой сообщения WM_DRAWITEM. Обратите внимание, что значение переменной CTitleTip::m_pszWndClass передается в качестве имени класса окна в функцию CWnd::CreateEx. CTitleTip::IsListBoxOwnerDraw возвращает TRUE, если родительский элемент "список" является элементом с пользовательской отрисовкой. Функция узнает об этом по стилю элемента "список".
В этой книге автор, сам прошедший путь от разработчика до менеджера в сфере IT, рассказывает неочевидные моменты, которые являются критически важными для правильного управления. Почему разработчики увольняются после повышения зарплаты? Как делать FixedPrice проекты? Почему Scrum не упрощает менеджмент? Книга содержит ответ на эти и многие другие вопросы. В книге есть много баек, которые показывают тяжёлую, но интересную жизнь менеджера в разработке. Иллюстратор обложки: Ксения Ерощенко. Иллюстрации в тексте книги авторские.
Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)
В учебно-методическом пособии рассматриваются основы языка программирования PL/SQL, реализованного в системе управления базами данных Oracle Database Server. Приводятся сведения о поддерживаемых типах данных, структуре программ PL/SQL и выполнении SQL-предложений в них. Отдельно рассмотрено создание хранимых в базах данных Oracle программ PL/SQL – процедур, функций, пакетов и триггеров.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Вниманию читателей предлагается справочник по JavaScript.Справочник предназначается для людей, уже освоивших азы программирования в JavaScript.Справочник создан на основе информации, предоставленной на сайте «Справочник Web-языков» www.spravkaweb.ru.Дата выхода данной версии справочника: 12:33, 21 марта 2007.
Вниманию читателей предлагается справочник по PHP.Справочник предназначается для людей, уже освоивших азы программирования на языке PHP.Справочник создан на основе информации, предоставленной на сайте «Справочник Web-языков» www.spravkaweb.ru.