Имя: Пароль:
1C
1C 7.7
v7: ВК и всплывающие подсказки
,
0 comprech
 
16.08.11
21:06
Не могу заставить показаться всплывающие подсказки.
Среда разработки: Visual C++ 2008 SP1
Используемые библиотеки: ATL, WTL, STL.
Сбивает с толку тот факт, что если код, создающий объект диалогового окна и его запуск в модальном режиме (окно всплывающей подсказки создается в обработчике WM_INITDIALOG) поместить внутрь DllMain(), то код вызывается еще на этапе регистрации ВК (до запуска 1С) и прекрасно работает. Стоит перенести код внутрь метода ВК (например Init()), то имеем тот же диалог, но без всплывающих подсказок.
Может, есть у кого пример ВК с диалогом и работающими всплывающими подсказками?
1 kittystark
 
17.08.11
04:00
есть такая ВК RTooltips, попробуй ее заюзать, там окно подсказки явно не является дочерним окном 1с-ки
2 popcorn
 
17.08.11
04:03
(0) ты чтоли семерку в ВКонтакте интегрировал? Расскажи по подробнее
3 comprech
 
17.08.11
10:51
(1) Спасибо, поищу.
(2) Разрабатываемая мной ВК к сети "ВКонтакте" отношения не имеет.
4 comprech
 
17.08.11
12:05
(1) RToolTips - это ВК-обертка для библиотеки с сайта www.tooltips.net, в этой библиотеке не используется стандартный для Windows подсказок оконный класс "tooltips_class32" и сообщения вида TTM_XXXXXXXX. Библиотека, конечно, крутая, позволяет по сути показывать веб-страницы в качестве всплывающей подсказки, но я спрашивал о простых стандартных Windows-подсказках, как это реализовано в самой 1С 7.7.
5 comprech
 
17.08.11
13:37
может, все же кто реализовывал стандартные подсказки?
6 ildary
 
17.08.11
16:41
(5) у Ромикса было в его плагинах.
7 ildary
 
17.08.11
16:42
+(6) правда там на дельфи было
8 comprech
 
18.08.11
13:06
(5) (6) скачал все архивы со страницы Ромикса.
Нашел лишь использование всплывающих подсказок в трее через модуль:

unit uBalloon;
(*
Образцы кода взяты из
Delphi Russian Knowledge Base
from Vit
Version 2.2

*)

В данном модуле всю работу делает WINAPI метод Shell_NotifyIcon(), мне же надо выяснить, почему некорректно обрабатываются сообщения с префиксом "TTM_", в частности TTM_ADDTOOL
9 Torquader
 
18.08.11
16:22
Если использовать стандартный tooltip, то он работает при помощи перехвата очереди сообщений через SetWindowsHook - не знаю, насколько это можно сделать в 1С, так как у неё в очереди валяется ещё куча всяких своих сообщений.
Кроме того, в 1С есть встроенная поддержка своих всплывающих подсказок, и вместо применения ещё одной (а две, скорей всего, работать не будут), нужно научиться той подсовывать необходимую строку.
10 Ёпрст
 
18.08.11
16:24
11 comprech
 
18.08.11
18:18
(9) вглубь самой 1С мне пока лезть не надо, диалог требуется создать в рамках ВК, и tooltip нужен для некоторых из дочерних контролов в этом диалоге, поэтому здесь никаких пересечений с "тонкой душевной внутренней организацией 1С" нет)))
Проблема не в подсовывании строки tooltip'у, а в самом сообщении TTM_ADDTOOL, регистрирующем подсказку для любого контрола / диалога.
Сам код, создающий окно тултипа и регистрирующий контрол/диалог, для которого надо показывать подсказку, не меняется. Я лишь пробовал вызывать этот код в разных местах проекта. Результаты - разные.
12 comprech
 
18.08.11
19:09
(10) Спасибо за предложенный пример. Несмотря на то, что пример требует для запуска каких-то ВК (судя по исходнику, DynamicWrapperX и, предполагаю 1С++), анализ исходного кода на языке vbscript из обработки показал, что автор преднамеренно (или случайно) избежал моей проблемы, использовав ANSI-версию WINAPI-функции создания окна CreateWindowExA.
У меня, в соответствии с настройками проекта, вызывалась Юникод-версия CreateWindowExW.
Также автор обработки использовал ANSI-версии для:
1) TTTOOLINFOA - структуры, отправляемой в сообщениях TTM_ADDTOOL и TTM_TRACKACTIVATE
2) TTM_ADDTOOLA - сообщение для первичной установки тултипа
Сделав аналогичные изменения, ANSI-версия тултипа заработала в моем Юникод-проекте!
Но решение половинчатое. Тем более я видел, что и Юникод-версия отрабатывает до запуска 1С корректно, если воткнуть код создания диалога и тултипа в код DllMain().
В примере standalone-приложения (не ВК) Юникод-подсказки тоже работают прекрасно.

Прошу помощи в создании полноценной юникод-версии.
13 comprech
 
18.08.11
20:22
(12) Оказалось, что CreateWindowExW() не является причиной ошибки. Все упирается в сообщение TTM_ADDTOOL:
ANSI-версия сообщения TTM_ADDTOOLA - работает в диалоге ВК, но и принимает только ANSI-текст.
Uncode-версия сообщения TTM_ADDTOOLW - не работает в диалоге ВК, но работает до подключения ВК в 1С - в DllMain() самой ВК.
Может кто знает, почему?
14 Torquader
 
18.08.11
23:14
(13) Дело в том, что 1С - это не Unicode приложение и оно использует настройки locale для работы с однобайтовыми символами. Как она это делает - надо спрашивать у Windows, но в этом случае все строки предполагаются не Unicode.
Кроме того, TTM_ADDTOOL - это сообщение, которое посылается элементу управления ToolTip, в LPARAM которого содержится структура, в которой описаны данные подсказки. Различие, видимо, будет в том, что будет вызываться SendMessageA или SendMessageW
Но, в DLL не может быть своей очереди сообщений и сообщения обрабатывает системная очередь 1С, где будет стоять GetMessageA (а не GetMessageW), то есть control, конечно, получит первоначально структуру Unicode, но при нотификации и отсылке обратных сообщений и общения с системой он будет получать сообщения в ANSI версии - и, как и следовало ожидать, будут глюки.
Удачи.
P.S. не пихайте Unicode туда, где его изначально не было.
15 Cthulhu
 
18.08.11
23:28
а кнопку "рекомендовать в базу знаний" совсем убрали?..
16 Torquader
 
18.08.11
23:38
(15) Вместо неё есть кнопка "закладка", чтобы каждый "вёл свою базу знаний".
17 Cthulhu
 
18.08.11
23:40
(16): не то.
18 Злопчинский
 
19.08.11
04:07
(16) а где эту "свою базу знаний" посмотреть можно?
19 comprech
 
19.08.11
15:41
(14) Как оказалось, тултипу все равно, через что с ним общаются, SendMessageA или SendMessageW, вся соль именно в сообщении в формате TTM_ADDTOOLA.
На другом форуме подсказали, что проблема старая и дали ссылку: http://www.rsdn.ru/forum/winapi/2153367.flat.aspx.
Я все же попытаюсь заставить работать тултип с юникодом-строками, согласно обсуждения, приведенного в ссылке.
P.S. без юникода обойтись не получается, т.к. в ВК используется API c жестко заданными юникод параметрами.
20 Torquader
 
21.08.11
15:03
(19) А в чём проблема перевести Unicode в ANSI и передавать этому "чуду" ANSI-строку, хотя всё остальное останется в Unicode ?
21 comprech
 
22.08.11
12:19
(20) Вопрос с конвертацией "решил", отложив передачу требуемой строки для подсказки до момента показа самого тултипа на экране. Это решение достигается сабклассингом тултипа и в сообщении TTM_ADDTOOLA указываем вместо строки подсказки (параметр TOOLINFO.lpszText) сигнальное значение LPSTR_TEXTCALLBACK, объясняя тултипу, что саму строку он получит в notify-сообщении TTN_GETDISPINFO. Причем, несмотря на то, что подсказка регистрируется через ANSI-версию сообщения TTM_ADDTOOLA, сам тултип шлет Unicode-версию сообщения TTN_GETDISPINFOW, в нем уже без проблем отдаем тултипу строки в желаемом Unicode.
Возникла другая проблема: не могу разобраться, как заставить стандартный тултип показаться рядом с необходимым контролом БЕЗ наведения на него мышкой.
Пример такой ситуации - нажатие на кнопку диалога вызывает функцию валидации введенных пользователем в диалоге данных и с помощью тултипа нужно показать ему, где он ошибся, не заставляя его самого догадываться и наводить мышку на ошибочное поле ввода.
Пробовал посылать тултипу сообщение TTM_POPUP - визуальной реакции нет.
22 Torquader
 
22.08.11
15:46
(21) Придётся слать сообщения мыши.
Проще тогда посмотреть tool-tip, который из WinHelp - там можно окно и куда угодно приляпать.
Ну, наконец, можно свой написать, так как пользователь ошибётся не всегда в одном месте и неплохо бы ему все ошибки сразу показать - другое дело, что это проще делать изменением цвета элемента управления, а не чем-то всплывающим.
P.S. может оно и появляется, но мышь в другом месте, и оно тут же исчезает.
23 comprech
 
23.08.11
14:30
(22) Все же рассчитываю обойтись без эмуляторов чего-либо)))
С всплытием по требованию (через mouse tracking или что-то другое) еще есть вопросы, а вот с тем, почему же в Unicode-проекте DLL не работала Unicode-версия сообщения TTM_ADDTOOLW все же разобрался:
ответ кроется в MSDN, но найти его удалось косвенно (пока гуглил про проблему с TTM_POPUP).
Вот статья MSDN "Enabling Visual Styles": http://msdn.microsoft.com/en-us/library/bb773175(v=VS.85).aspx#mmc, данная ссылка сразу ведет на нужный подраздел статьи "Adding Visual Style Support to an Extension, Plug-in, MMC Snap-in or a DLL That Is Brought into a Process"
Проблема с Unicode-сообщениями решилась путем добавления макроса #define ISOLATION_AWARE_ENABLED 1 в начало хидера "stdafx.h". Вуаля. Этим макросом заявляется, что DLL все равно, какой контекст у среды выполнения основного процесса, в DLL все будет так, как захотим.
Что сразу бросилось в глаза - заработали визуальные стили Windows XP: контролы приняли обтекаемую форму с закругленными углами.

P.S. TTM_POPUP заставить работать не получается, несмотря на то, что все условия, указанные тут - http://msdn.microsoft.com/en-us/library/bb760402(v=vs.85).aspx, я выполнил: манифест на использование последней 6-ой версии CommonControls имеется, включен в проект, ресурсом интегрируется в DLL (проверял просмотром бинарника DLL). Но решение рядом: посмотрел через "MS Spy++" - теперь при отправке TTM_POPUP тултип в обработчике этого сообщения шлет сам себе сообщение TTM_WINDOWFROMPOINT (до включения указанного выше макроса ничего не посылалось) для определения, какую подсказку из набора зарегистрированных ему следует показать. Осталось найти, как приклеить свой обработчик сообщения к субклассинговой оконной функции самого тултипа (об этом говорится в MSDN: http://msdn.microsoft.com/en-us/library/bb760429(v=VS.85).aspx, а не объекта диалога, куда я пытался его пристроить в очередь сообщений. Видел примеры реализации классов-наследников для типовых Windows-контролов (аля CMyCToolTipCtrl) со своими обработчиками в карте сообщений, но без них никак нельзя обойтись?
24 comprech
 
23.08.11
14:33
(22) Если бы все зависело от меня, но есть заказчик, и есть исполнитель, и в данном случае вид и форму сообщения об ошибке ввода данных выбирать не мне )))
25 comprech
 
23.08.11
21:09
Все, раскопки закончены, требуемый результат достигнут!
Вот заготовки фрагментов кода, может кому пригодятся в качестве примера...
Все обошлось... сабклассингом)))
void CDlg::ShowToolTip(HWND hwndDlgCtrl, LPTSTR lpstrErrorText)
{
CToolInfo cti(TTF_CENTERTIP, hwndDlgCtrl, 0, 0, lpstrErrorText, 0);
m_Tooltip.AddTool(&cti);
SetWindowSubclass(m_Tooltip, ToolTipProc, 0, 0);
// ...
m_Tooltip.Popup();
}

В коде ToolTipProc() в обработчике сообщения TTM_WINDOWFROMPOINT можно подставить хэндл нужного контрола, чтобы подсказка отобразилась рядом с ним:
LRESULT CALLBACK ToolTipProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
   UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
{
   switch (uMsg) {
   case TTM_WINDOWFROMPOINT:
       return hwndErrorDlgCtrl; // handle to error control
   /// other messages
   }
   return DefSubclassProc(hWnd, uMsg, wParam, lParam);
}

И не забываем создать сам контрол тултипа:
LRESULT CDlg::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
   CAxDialogImpl<CDlg>::OnInitDialog(uMsg, wParam, lParam, bHandled);
   // create tool tip
   m_Tooltip.Create(*this, 0, 0, WS_POPUP | TTS_NOPREFIX, WS_EX_TOPMOST);
   m_Tooltip.SetDelayTime(TTDT_RESHOW, 3000); // 3 секунды; если не увеличить задержку TTDT_RESHOW, то тултип быстро исчезнет, т.к. по дефолту 0,11 сек
   // ....
}
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.