Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.86/22: Рейтинг темы: голосов - 22, средняя оценка - 4.86
56 / 52 / 21
Регистрация: 01.01.2012
Сообщений: 347
1

Работа с подсказками baloon hint

13.07.2012, 00:09. Показов 4441. Ответов 42
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Иногда над приложениями появляется ярлык подсказки (Например ярлык, появляющийся над пиктограммами в системном лотке (NOD32 - сообщение, свидетельствующее об устаревших базах и т.д.). Вопрос: существуют какие либо функции вызова этих окон, или программист их сам лепит?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.07.2012, 00:09
Ответы с готовыми решениями:

Неясный HINT [Hint] Unit1.pas(2910): Value assigned to 'a' never used
var a:integer; . . . . a:=0; . . . .

Как убрать baloon "исправить неточность" на яндексМапе
Стилям пытался override сделать, вообще даже в отладчике мои попытки не появлялись, скрипт с...

Меню с подсказками
Здравствуйте. Подскажите как реализовать меню, чтобы при наведении на пункт меню всплывала...

Поле ввода с подсказками
Нахожусь в поиске методов создания поля ввода с подсказками. В HTML есть выпадающий список....

42
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 00:16 21
Author24 — интернет-сервис помощи студентам
Цитата Сообщение от Sasha Посмотреть сообщение
а если я создаю балун при помощи CreateWindowEx()
, то отследить можно только нажатие на ссылку внутри балуна (которая создается текстом "Это <a>ссылка</a>" со включенным флагом TTF_PARSELINKS). Для этого нужно переопределить оконную функцию для окна, которое указано в поле hwnd структуры TOOLINFO, и ловить там WM_NOTIFY + TTN_LINKCLICK... Проверять сейчас негде, поэтому только теоретически.
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 08:18 22
т.е отследить нажатие на крестик никак нельзя?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 11:48 23
Так, ну с нажатием на крестик как раз получилось: родительское окно получает через WM_NOTIFY уведомление TTF_POP в момент закрытия через кнопку (я про "tooltips_class32" со стилем TTS_CLOSE, разумеется). А вот нажатие на сам balloon отследить не удалось.
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 11:52 24
Я вот сделал так
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
void __fastcall TForm1::CreateBalloonTip(TWinControl* Control,int Icon, wchar_t* Title, wchar_t* Text)
{
  HWND hWnd = Control->Handle;
  MyBalloonHint = ::CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, WS_POPUP | TTS_NOPREFIX | TTS_BALLOON | TTS_CLOSE, 0, 0, 0, 0, NULL, NULL, HInstance, NULL);
 
    if (MyBalloonHint)
    {
        //int X = 50, Y = 50;
        //TOOLINFO ToolInfo;
 
        ToolInfo.cbSize = sizeof(TOOLINFO);
        ToolInfo.uFlags = TTF_TRANSPARENT | TTF_TRACK | NIF_INFO | TTF_PARSELINKS | TTF_SUBCLASS;
        ToolInfo.hwnd = hWnd;
        ToolInfo.uId = 0;
        ToolInfo.hinst = HInstance;
        ToolInfo.lpszText = Text;
 
        ::GetClientRect(MyBalloonHint, &ToolInfo.rect);
        ::SendMessage(MyBalloonHint, TTM_ADDTOOL, 0, (LPARAM) &ToolInfo );
        //::SendMessage(MyBalloonHint, TTM_TRACKPOSITION, 0, (LPARAM) (DWORD) MAKELONG (X, Y));
        ::SendMessage(MyBalloonHint, TTM_SETTITLE, Icon % 4, (int)Title);
        ::SendMessage(MyBalloonHint, TTM_TRACKACTIVATE, true, (LPARAM) &ToolInfo);
        // и так далее...
    }
 
void __fastcall TForm1::ShowToolTip(bool show,TControl* Control)
{
   ::SendMessage(MyBalloonHint, TTM_TRACKACTIVATE, show, (LPARAM) &ToolInfo );
 
  if(show)
  {
    TPoint tp = ClientToScreen(TPoint(Control->Left+(Control->Width/2),Control->Top+Control->Height));
    ::SendMessage(MyBalloonHint, TTM_TRACKPOSITION, 0, (LPARAM)MAKELPARAM(tp.x,tp.y));
    //vis = true;
  }
 
}
 
void __fastcall TForm1::FormCreate(TObject *Sender)
{
   WindowProc = myWndProc;
}
 
void __fastcall TForm1::myWndProc(Messages::TMessage &Message)
{
       switch (Message.LParam)
        {
         case WM_LBUTTONDOWN:
         ShowMessage("Нажал на балун");
         break;
        }
       WndProc(Message);
}
А вызваю так
C++
1
2
CreateBalloonTip(Edit1, 2, L"Оповещение", L"1223456");
ShowToolTip(true, Edit1);
Так вот вопрос можноли myWndProc прикрутить как-то к балуну?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 11:53 25
Зачем? Подмени WindowProc для Edit1, именно он будет получать все нотификации от балуна.

C++
1
2
3
4
5
6
7
8
9
void __fastcall TForm1::NewEditWndProc(TMessage &Msg)
{
    // нужные проверки
    FOldEditWndroc(Msg);
}
 
// OnCreate
  FOldEditWndroc = Edit1->WindowProc; // TWndMethod FOldEditWndroc в классе формы
  Edit1->WindowProc = NewEditWndProc;
1
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 12:37 26
Сделал вот так вот, но почему-то ShowMessage() не появляется при нажатии на балун? Может я проверку не правильную делаю?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void __fastcall TForm1::FormCreate(TObject *Sender)
{
 FOldEditWndroc = Edit1->WindowProc;
 Edit1->WindowProc = NewEditWndProc;
 }
void __fastcall TForm1::NewEditWndProc(TMessage &Msg)
{
       switch (Msg.LParam)
        {
         case WM_LBUTTONDOWN:
         ShowMessage("Нажал на балун");
         break;
        }
       FOldEditWndroc(Msg);
}
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 14:00 27
Цитата Сообщение от Sasha Посмотреть сообщение
Может я проверку не правильную делаю?
Нет. Просто предок получает лишь ограниченный список нотификаций: Tooltip Control Notifications, а не все возможные сообщения.

Можешь попробовать сабклассинг TOOLTIPS_CLASS (подмена его оконной функции через SetWindowLong(Ptr) + GWL(P)_WNDPROC), возможно это сработает, но я такого не делал никогда для этого класса. Для других - делал, в поиске есть немало примеров подмены оконной функции. Пробуй
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 14:51 28
volvo, сделал вот так вот. Работает!!!!!!!!!!!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
WNDPROC old_edit_wndproc;
LRESULT APIENTRY edit_new_wndproc( HWND, UINT, WPARAM, LPARAM );
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
 old_edit_wndproc = (WNDPROC)SetWindowLong(Edit1->Handle, GWL_WNDPROC, (long)  edit_new_wndproc);
}
//---------------------------------------------------------------------------
LRESULT APIENTRY edit_new_wndproc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
    switch (msg)
    {
    case WM_LBUTTONDOWN:
        ShowMessage("Нажал на балун");
        break;
    default:
        old_edit_wndproc(hwnd, msg, w_param, l_param);
    }
}
//------------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
    SetWindowLong(Edit1->Handle, GWL_WNDPROC, (long)old_edit_wndproc );
}
А можно в этот код вставить отслеживание нажатия на крестик?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 15:36 29
Цитата Сообщение от Sasha Посмотреть сообщение
А можно в этот код вставить отслеживание нажатия на крестик?
Можно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LRESULT APIENTRY edit_new_wndproc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
    switch (msg)
    {
    case WM_LBUTTONDOWN:
        ShowMessage(L"Нажал на балун");
        break;
 
    case WM_NOTIFY:
        if(reinterpret_cast<LPNMHDR>(l_param)->code == TTN_POP)
        ShowMessage(L"Закрыл балун");
        break;
    default:
        old_edit_wndproc(hwnd, msg, w_param, l_param);
    }
}
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 16:30 30
volvo, наверно задам последний вопрос из этой темы.
У компонента TrayIcon есть свойство BalloonTimeout, которое устанвливает время задержки сообщения над иконкой вот код
C++
1
TrayIcon1->BalloonTimeout = 3000;
Но это свойство есть только у TrayIcon. Так вот вопрос можно ли что-то придумать для CreateWindowEx() и ToolInfo, потому что всё, что я смог придумать это только перетянуть на форму таймер и в нём прописать код показа и скрытия этого сообщения. Может есть какой-нить класс или какой-нить метод при помощи которого можно задать время задержки собщения? Просто не особо хочется использовать компонент Timer.

Добавлено через 7 минут
Или может быть можно какое-нить свойство написать, которое бы отвечало за время задержки?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
07.04.2015, 16:42 31
Свойство написать нельзя, ибо это не VCL-компонент, а виндовый класс. А по поводу установки задержек - все, что можно: TTM_SETDELAYTIME, но тут нет того, что тебе нужно. Так что, похоже, без таймера-таки не обойдешься...
1
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
07.04.2015, 21:58 32
Цитата Сообщение от Sasha Посмотреть сообщение
__fastcall TForm1::~TForm1()
{
* * SetWindowLong(Edit1->Handle, GWL_WNDPROC, (long)old_edit_wndproc );
}
Наверно этот кусок кода здесь будет лишним, потому как форма уничтожается, то и все объекты на ней, по этому нет смысла возвращать старый WNDPROC объекту Edit?
0
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
03.08.2015, 14:48 33
Цитата Сообщение от volvo Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
LRESULT APIENTRY edit_new_wndproc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
  switch (msg)
  {
  case WM_LBUTTONDOWN:
    ShowMessage(L"Нажал на балун");
    break;
case WM_NOTIFY:
    if(reinterpret_cast<LPNMHDR>(l_param)->code == TTN_POP)
    ShowMessage(L"Закрыл балун");
    break;
  default:
  old_edit_wndproc(hwnd, msg, w_param, l_param);
  }
}
volvo, хотел спросить возможно ли отследить исчезновение балуна (когда он сам исчезнет), только не в над Edit, а над самим TrayIcon?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
03.08.2015, 14:59 34
Нет. Можно отследить только тот момент, когда балун готов к тому, чтобы начать исчезновение, но не тот момент, когда он исчез. По крайней мере, стандартные уведомления подобного функционала не представляют.
1
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
03.08.2015, 15:18 35
Цитата Сообщение от volvo Посмотреть сообщение
Можно отследить только тот момент, когда балун готов к тому, чтобы начать исчезновение
Как это сделать?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
03.08.2015, 15:39 36
В процитированном тобой коде это и делается. Когда баллун готов начать исчезать (сам по таймауту, или после нажатия пользователем на "крестик") - он высылает TTN_POP через WM_NOTIFY родительскому окну.
1
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
03.08.2015, 16:33 37
Чё-то не особо получается

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
WNDPROC old_tray_wndproc;
LRESULT APIENTRY tray_new_wndproc( HWND, UINT, WPARAM, LPARAM);
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
        TrayIcon = new Graphics::TIcon;
        TrayIcon->Handle = reinterpret_cast<HICON>
        (LoadImage(HInstance, MAKEINTRESOURCE(MY_ICON), IMAGE_ICON, 0, 0,
        LR_DEFAULTCOLOR));
 
    old_tray_wndproc = (WNDPROC)SetWindowLong(TrayIcon->Handle, GWL_WNDPROC, (long)tray_new_wndproc);
//-----------------------------------------------------------------------------------------------------------------
LRESULT APIENTRY tray_new_wndproc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
    switch (msg)
    {
    case WM_NOTIFY:
        if(reinterpret_cast<LPNMHDR>(l_param)->code == TTN_POP)
        Application->Terminate();
        break;
    default:
        old_tray_wndproc(hwnd, msg, w_param, l_param);
    }
}
Ошибка не может переконвертировать

[bcc32 Error] Unit1.cpp(30): E2034 Cannot convert 'HICON__ *' to 'HWND__ *'
Full parser context
Unit1.cpp(23): parsing: _fastcall TForm1::TForm1(TComponent *)
[bcc32 Error] Unit1.cpp(30): E2342 Type mismatch in parameter 'hWnd' (wanted 'HWND__ *', got 'HICON__ *')
Full parser context
Unit1.cpp(23): parsing: _fastcall TForm1::TForm1(TComponent *)
[bcc32 Warning] Unit1.cpp(53): W8070 Function should return a value
Full parser context
Unit1.cpp(43): parsing: long __stdcall tray_new_wndproc(HWND__ *,unsigned int,unsigned int,long)
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
03.08.2015, 17:44 38
А почему TrayIcon->Handle, собственно? Обрабатывать-то WM_NOTIFY будет родительское окно, которое указано в TOOLINFO.hwnd, вот и укажи там this->Handle, и это же this->Handle - в SetWindowLong.
1
4956 / 2420 / 531
Регистрация: 05.06.2008
Сообщений: 7,518
Записей в блоге: 3
04.08.2015, 08:38 39
volvo, сделал вот так вот
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
WNDPROC old_tray_wndproc;
LRESULT APIENTRY tray_new_wndproc( HWND, UINT, WPARAM, LPARAM);
//---------------------------------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
        TrayIcon = new Graphics::TIcon;
        TrayIcon->Handle = reinterpret_cast<HICON>
        (LoadImage(HInstance, MAKEINTRESOURCE(MY_ICON), IMAGE_ICON, 0, 0,
        LR_DEFAULTCOLOR));
 
old_tray_wndproc = (WNDPROC)SetWindowLong(this->Handle, GWL_WNDPROC, (long)tray_new_wndproc);
//----------------------------------------------------------------------------------------------------------
LRESULT APIENTRY tray_new_wndproc(HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param)
{
    switch (msg)
    {
    case WM_NOTIFY:
        if(reinterpret_cast<LPNMHDR>(l_param)->code == TTN_POP)
        ShowMessage("Выключение");
        Application->Terminate();
        break;
    default:
        old_tray_wndproc(hwnd, msg, w_param, l_param);
    }
}
 
//-----------------------------------------------------------------------------------------------------------------
__fastcall TForm1::~TForm1()
{
    
    SetWindowLong(this->Handle, GWL_WNDPROC, (long)old_tray_wndproc);
}
Что-то не отлавливает сообщение может, где-то явно нужно задать TOOLINFO.hwnd?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
32991 / 21297 / 8180
Регистрация: 22.10.2011
Сообщений: 36,591
Записей в блоге: 8
04.08.2015, 10:31 40
А можно привести полностью минимальный проект, который хотя бы компилируется, но не выполняет того, что должен выполнять? А то какие-то глухие телефоны получаются - в вышеприведенном куске кода ничего подобного созданию балуна в принципе нет, нет даже создания иконки в области уведомлений, а ты хочешь, чтобы отлавливалось исчезание балуна. А вдруг я сделаю показ иконки и балуна ПРАВИЛЬНО, и у меня твой код заработает, что тогда?
0
04.08.2015, 10:31
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
04.08.2015, 10:31
Помогаю со студенческими работами здесь

что случилось с трафиком и подсказками?
Если кратко, то яндекс изменил алгоритм формирования подсказок. использование наиболее часто...

ToolBar, кнопки с картинками и подсказками
Нужен человек, который отлично знает lazarus. Проблема состоит в ToolBar. Не могу разместить на...

TextBox с подсказками по вводимым символам
Доброго времени суток, о, Великие Умы программирования! На практике столкнулась с проблемой...

Флеш карта страны со всплывающими подсказками
Вот тут карта есть Помогите пожалуйста, как можно сделать что то на подобии. В частности...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru