ВОПРОС-ОТВЕТ
Как создать многострочный тултип?
Начиная с версии 4.70 библиотеки Comctl32.dll тултипы поддерживают многострочный режим работы. По умолчанию он выключен, и всё, что требуется от нас – активизировать его. Для этого предназначено сообщение TTM_SETMAXTIPWIDTH, которое позволяет задать ширину тултипа (в пикселях). По умолчанию ширина установлена в –1, что соответствует однострочному режиму работы. В этом режиме тултип игнорирует все пары '\r\n' в тексте подсказки, выдавая его в одну строку. Задание любого положительного значения ширины переводит тултип в многострочный режим работы.
В многострочном режиме тултип корректно обрабатывает комбинации '\r\n', переходя на новую строку. Кроме того, он старается вписать текст в заданную ширину, разбивая его на строки самостоятельно. Переход на новую строку возможен только между словами, поэтому если в тексте подсказки есть длинные слова, заданная ширина может быть превышена. Если вы не хотите, чтобы тултип разбивал текст на строки по своему усмотрению, задайте значение ширины, заведомо превышающее ширину экрана. Например:
SendMessage(hTip, TTM_SETMAXTIPWIDTH, 0, (LPARAM)0xFFFFFF);
В MFC аналогичного эффекта можно добиться, используя фукцию CToolTipCtrl::SetMaxTipWidth. Единственный параметр, который она получает – новое значение ширины тултипа. Например:
// m_tt - объект класса CToolTipCtrl
m_tt.SetMaxTipWidth(0xFFFFFF);
Проблемы возникают только в том случае, когда вы используете встроенную поддержку тултипов класса CWnd. В этом случае тултип создаётся и уничтожается в недрах MFC, причём документированного способа добраться до него не существует. Выйти из положения можно, воспользовавшись недокументированным: MFC сохраняет указатель на созданный ею объект класса CToolTipCtrl в структуре _AFX_THREAD_STATE, и можно получить к нему доступ, используя выражение AfxGetThreadState()->m_pToolTip.
Вторая проблема состоит в том, что MFC сама следит за временем жизни тултипа, и мы не можем точно знать, когда он уничтожается и создаётся заново. Поэтому ширину тултипа необходимо заново задавать всякий раз, когда тултип "собирается" появиться на экране. Удобнее всего делать это в ответ на уведомление TTN_NEEDTEXT, например:
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXT, 0, 0xFFFFFFFF, OnToolTipText)
END_MESSAGE_MAP()
BOOL CMainFrame::OnToolTipText(...) {
CToolTipCtrl* ptt = AfxGetThreadState()->m_pToolTip;
ptt->SetMaxTipWidth(0xFFFFFF);
return CFrameWnd::OnToolTipText(…);
}
ОБРАТНАЯ СВЯЗЬ
Здравствуйте!
Благодарю Вас за прекрасную и очень полезную рассылку! Полагаю, что мою благодарность разделяют очень многие ее читатели.
В номере 36 от 11.03.2001 г. рассылки "Программирование на VC++" Сергей Петухов задал вопрос о русификации элементов окна предварительного просмотра перед печатью. В номере 38 от 25.03.2001 г. на него дал обстоятельный ответ Александр Шаргин. Предложенный в ответе метод решения проблемы имеет огромное неоспоримое достоинство – он работоспособен! Однако, не лишен и некоторых очевидных недостатков, связанных с необходимостью ручного редактирования информации ресурсных файлов в каждом из проектов, ориентированных на русскоязычного пользователя. Такой метод пригоден скорее для случаев, когда нужно изменить именно вид стандартного интерфейса MFC в соответствии с требованиями конкретного приложения, а не его язык.
MSDN предлагает иной путь решения. Кратко он освещен в статье "Localization of MFC Components" (MSDN/Visual C++ Documentation/Reference/MFC Library and Templates/MFC Library/MFC Technical notes/TN057). Чуть подробнее последовательность необходимых действий описан в статье "HOWTO: #include the Localized MFC Resources in an EXE or DLL" (ID: Q198536) Knowledge Base.
Суть заключается в том, что все языкозависимые ресурсы MFC размещены в каталогах MFC\INCLUDE\L.* и при статическом присоединении ресурсов MFC к проекту, должны использоваться именно они. Для подключения нужного подкаталога достаточно указать его в командной строке компилятора ресурсов с ключом /I (пример из MSDN /IC:\PROGRAM FILES\DEVSTUDIO\VC\MFC\INCLUDE\L.DEU).
Все довольно просто. Создаем новый подкаталог MFC\INCLUDE\L.RUS, записываем в него по образу других языков семь файлов *.rc и русифицируем их в текстовом редакторе (в редакторе ресурсов VS это сделать не удастся, т.к. файлы защищены от изменения специальной директивой). Затем указываем на вкладке свойств проекта Resources (поле Additional resource include directories) наш новый русскоязычный каталог (например, C:\PROGRAM FILES\DEVSTUDIO\VC\MFC\INCLUDE\L.RUS). В статье из KB рекомендуется еще и удалить все директивы _AFXDLL препроцессора, которые видны на той же вкладке, но в моих приложениях, со статическим присоединением ресурсов MFC, таковые не попадались. Затем открываем меню "View" и выбираем пункт "Resource Includes" и в окне "Compile-time directives" изменяем код языка и номер кодовой страницы. Данные о кодах можно найти в файле "winnt.h". Там они представлены в шестнадцатеричном формате и их следует привести к основанию 10. Для русского языка нужные строки будут выглядеть так:
Читать дальше