Исчерпывающее руководство по написанию всплывающих подсказок - [3]
Рис.4. HTML-код для подсказки
>
>
>
>
>
>
>
>
>
>
>
> Sub WebButton1_Click()
> MsgBox "WebButton was clicked"
> end sub
>-->
>
Элемент ActiveX представляет собой кнопку с подсказкой. Для чего мне возиться с созданием кнопки, когда можно добавить на Web-страницу трехмерную картинку, которая будет выглядеть как кнопка? На это есть две причины. Во-первых, кнопка выглядит реалистичнее – она нажимается и отжимается по щелчку пользователя, как и положено настоящей кнопке. Во-вторых, я хотел показать добавление подсказок к элементам ActiveX, а кнопка – это простейший элемент, который я мог использовать в демонстрационных целях.
Для генерации кода я использовал AppWizard. Я установил флажок "Activate when visible" и отключил все остальные флажки. В опции "Which window class, if any, should this control subclass?" я выбрал BUTTON. AppWizard генерирует массу дополнительного кода, не относящегося к данной статье. В основном, я остановлюсь на коде, добавленном мной в класс CWebButtonCtrl (см. рис.5). Давайте для начала взглянем на пару переменных класса. CWebButtonCtrl::m_bToolTipEnabled устанавливается в TRUE, если подсказки разрешены. В CWebButtonCtrl::m_strToolTipText хранится текст подсказки. Я добавил обе переменные через ClassWizard и они представляют OLE-свойства, автоматические обновляемые библиотекой MFC при их изменении.
Рис.5. CWebButtonCtrl
>// WebButtonCtl.cpp : Implementation of the CWebButtonCtrl OLE control class.
>/////////////////////////////////////////////////////////////////////////////
>// CWebButtonCtrl::RelayToolTipEvent – Pass mouse messages to ToolTip
>void CWebButtonCtrl::RelayToolTipEvent(const MSG* pMsg) {
> MSG MsgCopy;
> ::memcpy(&MsgCopy, pMsg, sizeof(MSG));
> FilterToolTipMessage(&MsgCopy);
>}
>int CWebButtonCtrl::OnToolHitTest(CPoint point, TOOLINFO* pTI) const {
> if (m_bToolTipEnabled && pTI != NULL && pTI->cbSize >= sizeof(TOOLINFO)) {
> // setup the TOOLINFO structure
> pTI->hwnd = m_hWnd;
> pTI->uId = 0;
> pTI->uFlags = 0;
> GetClientRect(&(pTI->rect));
> pTI->lpszText = LPSTR_TEXTCALLBACK;
> }
> return (m_bToolTipEnabled ? 1 : –1);
>}
>/////////////////////////////////////////////////////////////////////////////
>// CWebButtonCtrl message handlers
>int CWebButtonCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) {
> if (COleControl::OnCreate(lpCreateStruct) == –1) {
> return –1;
> }
> if (m_Bitmap.LoadBitmap(IDB_WEBBUTTON)) {
> SendMessage(BM_SETIMAGE, IMAGE_BITMAP, (LPARAM)m_Bitmap.GetSafeHandle());
> } else {
> TRACE("Unable to load bitmap for button.");
> }
> EnableToolTips(TRUE);
> return 0;
>}
>void CWebButtonCtrl::OnMouseMove(UINT nFlags, CPoint point) {
> RelayToolTipEvent(GetCurrentMessage());
> COleControl::OnMouseMove(nFlags, point);
>}
>void CWebButtonCtrl::OnLButtonDown(UINT nFlags, CPoint point) {
> RelayToolTipEvent(GetCurrentMessage());
> COleControl::OnLButtonDown(nFlags, point);
>}
>void CWebButtonCtrl::OnLButtonUp(UINT nFlags, CPoint point) {
> RelayToolTipEvent(GetCurrentMessage());
> COleControl::OnLButtonUp(nFlags, point);
>}
>BOOL CWebButtonCtrl::OnToolNeedText(UINT id, NMHDR * pNMHDR, LRESULT * pResult) {
>TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
> ::strcpy(pTTT->szText, m_strToolTipText);
> return TRUE;
>}
>/////////////////////////////////////////////////////////////////////////////
>// Property changed handlers
>void CWebButtonCtrl::OnToolTipEnabledChanged() {
> SetModifiedFlag();
>}
>void CWebButtonCtrl::OnToolTipTextChanged() {
> SetModifiedFlag();
>}
CWebButtonCtrl::PreCreateWindow манипулирует передаваемой ему структурой CREATESTRUCT. Я задал для кнопки стиль пользовательской отрисовки (owner-draw) – BS_OWNERDRAW – для того, чтобы не рисовалась рамка фокуса (focus rect) при активизации кнопки. В противном случае, рамка была бы все время видна. Как побочный эффект задания такого стиля приходится переопределять функцию CWebButtonCtrl::OnOcmDrawItem для рисования кнопки. CWebButtonCtrl::OnCreate загружает и устанавливает картинку для кнопки посылкой сообщения BM_SETIMAGE. Она также вызывает CWebButton::EnableToolTips, чтобы задействовать поддержку подсказок классом CWnd.
Функции CWebButtonCtrl::OnMouseMove, CWebButtonCtrl::OnLButtonDown, и CWebButtonCtrl::OnLButtonUp делают одно и то же – они все вызывают CWnd::RelayToolTipEvent. Метод CWebButtonCtrl::RelayToolTipEvent делает неконстантную копию переданного ему сообщения и вызывает CWnd::FilterToolTipMessage. Копия сообщения делается из-за того, что CWnd::FilterToolTipMessage требует неконстантного указателя на сообщение. Я мог бы, конечно, привести указатель к неконстантному, но это небезопасно, потому что в этом случае CWnd::FilterToolTipMessage могла бы изменить исходное сообщение. Обычно CWnd автоматически вызывает CWnd::FilterToolTipMessage в функции CWnd::PreTranslateMessage. Однако, в элементе ActiveX сообщения мыши никогда не попадают в CWnd::PreTranslateMessage, она вызывается только как результат клавиатурного ввода (CWnd::PreTranslateMessage в основном используется для работы с клавиатурными акселераторами). В обычном MFC-приложении CWnd::PreTranslateMessage вызывается в результате работы функции CWinThread::PumpMessage.
Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.
Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.
Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.