Форум программистов, компьютерный форум, киберфорум
Pure Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
 Аватар для alhimera
5 / 5 / 2
Регистрация: 07.05.2014
Сообщений: 39

Всплывающее меню в трее

19.04.2017, 09:16. Показов 2436. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Заранее извиняюсь, если подобная тема уже существует. К сожалению не могу воспользоваться поиском с телефона, так как поиск почемуто сворачивается.

Стандартное меню в трее работает отлично. Но, так как основное окно используется не системное, а рисованное, то решил сделать и меню рисовынным.
Используется системное окно, невидимое с привязкой ImageGadget.
Вопрос в следующем:
Как реализовать его поведение, как у стандартного меню
1. При клике вне области окна закрыть его.
Пробовал разные варианты, но CloseWindow и HideWindow не хочет его закрывать.
2. При клике по кнопке меню закрыть окно.

Со вторым я думаю разберусь, интересует как реализовать закрытие при клике вне области меню.
Помогите люди добрые намеком или кусочком кода.
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
19.04.2017, 09:16
Ответы с готовыми решениями:

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

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

Всплывающее название иконки в трее
Ув. форумчане, подскажите пожалуйста, как сделать так, что бы при наведении указателя на иконку в трее появлялась всплывающая подсказка с...

2
Эксперт по электронике
6576 / 3203 / 335
Регистрация: 28.10.2011
Сообщений: 12,499
Записей в блоге: 7
19.04.2017, 15:16
Цитата Сообщение от alhimera Посмотреть сообщение
1. При клике вне области окна закрыть его.
Нужно ловить событие #PB_Event_DeactivateWindow

Цитата Сообщение от alhimera Посмотреть сообщение
Пробовал разные варианты, но CloseWindow и HideWindow не хочет его закрывать.
Окно созданное функцией OpenWindow не закрывается?

Рисовать можно на стандартном меню. http://pure-basic.narod.ru/libs.html
1
 Аватар для alhimera
5 / 5 / 2
Регистрация: 07.05.2014
Сообщений: 39
20.04.2017, 12:27  [ТС]
Лучший ответ Сообщение было отмечено alhimera как решение

Решение

Весь вечер выковыривал код из проекта, в общем код большой, но внимание обратите на обработку событий в самом низу.
Кнопки меню нормально работают, но при клике вне меню ничего не происходит.
locm событие #PB_Event_DeactivateWindow не работает, у меня 4.51, не вижу такого эвента у себя.
Решил прятать окно меню, а не закрывать. Но тоже не прячется.
Проблема в отлавливании клика вне окна.

PureBasic
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
Enumeration
  #window  ; основное окно
  #menu0  ;кнопки всплыващего меню в трее
  #menu1  ;
  #menu2  ;
  #menu3  ;
  #menu_0_img
  #menu_1_img
  #menu_2_img
  #icon1  ;иконка трея
  #win_pop  ;окно меню
  #win_head;нарисованное окно
  #win_head_img;картинка окна
  #TrayText;
  #IMAGE_head  ; изображение заголовка основного окна
  #IMAGE_fon  ; фон основного окна
  #IMAGE_X  ; изображение кнопки закрытия основного окна
  #IMAGE_GADGET_1  ;заголовок
  #IMAGE_GADGET_2  ;фон
  #IMAGE_GADGET_X  ;кнопка закрытия основного окна
EndEnumeration
     Global w_width.l=200
     Global w_height.l=92
;ПОМЕЩАЕМ ОКНО НАД ТРЕЕМ
Procedure PosWinInfo(Window)  
  If IsWindow(Window)>0 ; Окно с таким идентификаторм существует  
  TrayWnd = FindWindow_("Shell_TrayWnd", 0)  
  TrayNofifyWnd = FindWindowEx_(TrayWnd, 0, "TrayNotifyWnd", 0)  
  GetWindowRect_(TrayNofifyWnd,@win.RECT) ; Узнаём высоту трея  
   
  Win_x=GetSystemMetrics_(#SM_CXSCREEN)-WindowWidth(Window)-8  
  Win_y=GetSystemMetrics_(#SM_CYSCREEN)-(win\bottom-win\top)-WindowHeight(Window)-35  
  ResizeWindow(Window, Win_x, Win_y, #PB_Ignore, #PB_Ignore)  
  EndIf  
EndProcedure 
;{БАЛУНТИП В ТРЕЕ
  #NIN_BALLOONSHOW=$402 
  #NIN_BALLOONHIDE=$403 
  #NIN_BALLOONTIMEOUT =$404 
  #NIN_BALLOONUSERCLICK=$405 
  #NOTIFYICON_VERSION = $3 
  #NOTIFYICONDATA_V1_SIZE = 88 
  #NOTIFYICONDATA_V2_SIZE = 488 
  #NOTIFYICONDATA_V3_SIZE = 504 
Structure NOTIFYICONDATA_95
  cbSize.l
  hwnd.l 
  uID.l 
  uFlags.l 
  uCallbackMessage.l 
  hIcon.l 
  szTip.b[64] 
EndStructure 
Structure NOTIFYICONDATA_2K Extends NOTIFYICONDATA_95
  szTipEx.b[64] 
  dwState.l
  dwStateMask.l 
  szInfo.b[256] 
  StructureUnion 
  uTimeout.l 
  uVersion.l 
  EndStructureUnion 
  szInfoTitle.b[64]
  dwInfoFlags.l
EndStructure 
 Structure NOTIFYICONDATA_XP Extends NOTIFYICONDATA_2K
   guid.GUID
 EndStructure 
 
Procedure SysTrayIconBalloonEx(Tray, WindowID, Title.s, Message.s, TimeOut.l, TypeIcon) 
; Tray     - идентификатор значка в трее
; WindowID - Системный идентификатор окна
; Title    - текст в заголовке баллона
; Message  - текст в баллоне
; TimeOut  - Время (в миллисекундах) отображения баллона
; TypeIcon - тип значка #NIIF_NONE #NIIF_INFO #NIIF_WARNING #NIIF_ERROR #NIIF_USER
  
  Protected nid.NOTIFYICONDATA_2K
  
  If OSVersion() >= #PB_OS_Windows_XP
    nid\cbSize = #NOTIFYICONDATA_V3_SIZE
  ElseIf OSVersion() >= #PB_OS_Windows_2000
    nid\cbSize = #NOTIFYICONDATA_V2_SIZE
  Else
    ProcedureReturn #False
  EndIf
  
  nid\uVersion = #NOTIFYICON_VERSION
  Shell_NotifyIcon_(#NIM_SETVERSION, @nid)
  
  nid\uID         = Tray
  nid\hwnd        = WindowID
  nid\dwInfoFlags = TypeIcon
  nid\uFlags      = #NIF_INFO
  nid\uTimeout    = timeOut
  
  nid\dwState = #NIS_SHAREDICON
  
  PokeS(@nid\szInfo, message, 256) 
  PokeS(@nid\szInfoTitle, title, 64)
  
  ProcedureReturn Shell_NotifyIcon_(#NIM_MODIFY, @nid) 
  
EndProcedure
;}
;{СОЗДАЕМ ИЗОБРАЖЕНИЕ ОКНА
  CreateImage(#IMAGE_head, w_width, w_height)
  If StartDrawing(ImageOutput(#IMAGE_head))
        Box(0,0, w_width, w_height, RGB(10,10,10))
        Box(2,25,w_width-4,w_height-29, RGB(255, 255, 255))
        DrawText(7,5, "ОКНО",RGB(179,184,178))
        StopDrawing()
      EndIf
      ;}
;{КАРТИНКА ТРЕЯ
    CreateImage(#icon1, 16, 16)
     If StartDrawing(ImageOutput(#icon1))
        Box(0,0, 16, 16, RGB(10,10,10))
        Box(1,1,14,14, RGB(250, 250, 250))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(4, 0, "X", RGB(10,10,10))
        StopDrawing()
      EndIf  
;}
;{СОЗДАЕМ ИЗОБРАЖЕНИЕ ДЛЯ ГЛАВНОГО ОКНА(фон)
  CreateImage(#IMAGE_fon, w_width-4, w_height-27)
  If StartDrawing(ImageOutput(#IMAGE_fon))
        Box(0,0, w_width-4, w_height-27, RGB(179,184,178))
        StopDrawing()
      EndIf
;}      
;{СОЗДАЕМ ИЗОБРАЖЕНИЕ ДЛЯ КНОПКИ Х
  CreateImage(#IMAGE_X, 23, 23)
  If StartDrawing(ImageOutput(#IMAGE_X))
    Box(0,0, 23, 23, RGB(179,184,178))
    Box(2,2, 19, 19, RGB(10,10,10))
DrawText(7,4, "X",RGB(179,184,178))
        StopDrawing()
      EndIf
      ;}
 ;{ФОН МЕНЮ  
 CreateImage(#win_head_img, 200, 84)
  If StartDrawing(ImageOutput(#win_head_img))
        Box(0,0, 200, 84, RGB(10,10,10))
        Box(2,2,196,80, RGB(50, 50, 50))
        StopDrawing()
  EndIf
 ;}
;{КНОПКА МЕНЮ 0
  CreateImage(#menu_0_img, 196, 26)
  If StartDrawing(ImageOutput(#menu_0_img))
    Box(0,0, 196, 26, RGB(219,219,219))
    Box(2,2, 192, 22, RGB(10,10,10))
    DrawText(7,4, "Показать окно",RGB(219,219,219))
    StopDrawing()
  EndIf
  ;}  
  ;{КНОПКА МЕНЮ 1
  CreateImage(#menu_1_img, 196, 26)
  If StartDrawing(ImageOutput(#menu_1_img))
    Box(0,0, 196, 26, RGB(219,219,219))
    Box(2,2, 192, 22, RGB(10,10,10))
    DrawText(7,4, "Скрыть окно",RGB(219,219,219))
    StopDrawing()
  EndIf
  ;} 
    ;{КНОПКА МЕНЮ 2
  CreateImage(#menu_2_img, 196, 26)
  If StartDrawing(ImageOutput(#menu_2_img))
    Box(0,0, 196, 26, RGB(219,219,219))
    Box(2,2, 192, 22, RGB(10,10,10))
    DrawText(7,4, "Выход",RGB(219,219,219))
    StopDrawing()
  EndIf
;} 
  
      
Procedure IsMouseOver(wnd) ; Определяем находится ли курсор мышки в пределах заданного окна (гаджета)
GetWindowRect_(wnd,re.RECT)  
GetCursorPos_(pt.POINT) 
Result = PtInRect_(re,pt\x|(pt\y<<32))  
ProcedureReturn Result 
EndProcedure
;ВСПЛЫВАЩЕЕ МЕНЮ
Procedure Pop_Menu()
  ;DisableWindow(#window,1)
 
OpenWindow(#win_pop,100,100, 200,84, "", #WS_POPUP|#PB_Window_Invisible)
  PosWinInfo(#win_pop) ; Перемещаем окно над трей
    ShowWindow_(WindowID(#win_pop), #SW_HIDE)   ;убираем кнопку на панели задач
    SetWindowLong_(WindowID(#win_pop), #GWL_EXSTYLE, #WS_EX_TOOLWINDOW);
    ShowWindow_(WindowID(#win_pop), #SW_SHOW);
    ImageGadget(#win_head, 0, 0, 200, 84, ImageID(#win_head_img)):DisableGadget(#win_head,1)
    ImageGadget(#menu0, 2, 2, 196, 26, ImageID(#menu_0_img))
    ImageGadget(#menu1, 2, 29, 196, 26, ImageID(#menu_1_img))
    ImageGadget(#menu2, 2, 56, 196, 26, ImageID(#menu_2_img))
    HideWindow(#win_pop,#False)   
    HideWindow(#win_pop, 1):HideWindow(#win_pop, 0)
  EndProcedure
;ОСНОВНОЕ ОКНО
Procedure OpenWindowAPP()
  hWnd  = OpenWindow(#window,100,100, w_width,w_height, "ОКНО", #WS_POPUP|#PB_Window_Invisible|#PB_Window_ScreenCentered)
     ;убираем c панели задач
    ShowWindow_(WindowID(#window), #SW_HIDE)
    SetWindowLong_(WindowID(#window), #GWL_EXSTYLE, #WS_EX_TOOLWINDOW)
    ShowWindow_(WindowID(#window), #SW_SHOW)
    ;//////////
  ImageGadget(#IMAGE_GADGET_1, 0, 0, w_width, w_height, ImageID(#IMAGE_head)):DisableGadget(#IMAGE_GADGET_1,1)
  ImageGadget(#IMAGE_GADGET_2, 2, 25, w_width-4, w_height-27, ImageID(#IMAGE_fon)):DisableGadget(#IMAGE_GADGET_2,1)
  ImageGadget(#IMAGE_GADGET_X, w_width-24, 1, 23, 23, ImageID(#IMAGE_X))
    Image = ImageID(#icon1)
    TrayId=AddSysTrayIcon(#TrayText, WindowID(#window),Image) ; Отображаем иконку в трее
    SysTrayIconToolTip(#TrayText, "ОКНО")
    HideWindow(#window, 1):HideWindow(#window, 0)
    HideWindow(#window,#False)
    EndProcedure
  OpenWindowAPP()
Repeat
    Event=WaitWindowEvent() ; текущее событие
    Type=EventType() ; тип события
    Menu=EventMenu() ; ИД меню
     ;{ПЕРЕМЕЩЕНИЕ ОКНА
If Event=#WM_LBUTTONDOWN
If move = 1
      SendMessage_(WindowID(#window),#WM_NCLBUTTONDOWN, #HTCAPTION,0)
EndIf 
EndIf
 
If Event=#WM_MOUSEMOVE
If IsMouseOver(GadgetID(#IMAGE_GADGET_2)) Or IsMouseOver(GadgetID(#IMAGE_GADGET_X))
      move = 0
      Else 
      move = 1
EndIf
  EndIf  
;}     
    ;{ Отображаем всплывающее меню при щелчке правой кнопкой мышки по иконке в трее
      If Event=#PB_Event_SysTray And Type=#PB_EventType_RightClick  
            Pop_Menu()
      EndIf
;{ОБРАБОТКА СОБЫТИЙ ВСПЛЫВАЮЩЕГО МЕНЮ ПРИ НАЖАТИИ
       If EventGadget()=#menu0
                  HideWindow(#window, 0)   ; Отобразили окно 
                  HideWindow(#win_pop, 1)  ; спрятали меню
                  Debug "клик Показать окно"
                 EndIf  
        If EventGadget()=#menu1
                  HideWindow(#window, 1)  ; спрятали окно 
                  HideWindow(#win_pop, 1) ; спрятали меню
                   Debug "клик Скрыть окно"
        EndIf
       If EventGadget()=#menu2
                   Debug "клик ВЫХОД - закрыть окно"
                   Break 
       EndIf
   ;}
   ;}  
   ;{Скрытие меню при клике
   If Type=#PB_EventType_LeftClick
     If IsWindow(#win_pop)=1
       If MouseX()<WindowX(#win_pop) Or MouseX()>WindowX(#win_pop)+w_width Or MouseY()<WindowY(#win_pop) Or MouseY()>WindowY(#win_pop)+w_height
         Debug "HIDE"
           HideWindow(#win_pop, 1)
        EndIf   
     EndIf
   EndIf
;}
;{ЗАКРЫТИЕ ОКНА
    If EventGadget()=#IMAGE_GADGET_X
      If EventType()=#PB_EventType_LeftClick
             Debug "клик X - закрыть окно"
             Break
              
       EndIf  
EndIf
 
;}      
  ForEver
  End
Добавлено через 12 часов 46 минут
Всем спасибо, проблему решил
Добавил процедуру
PureBasic
1
2
3
4
5
6
7
8
9
10
11
12
  Procedure TimerMouse() ; Процедура вызывается по таймеру
  Temp.POINT
  GetCursorPos_(@Temp)  ; Текущая позиция курсора мышки относительно экрана
  ;SetGadgetText(1,"Y =  "+Str(Temp\y))
  ;SetGadgetText(2,"X =  "+Str(Temp\x))
  
  If GetAsyncKeyState_(#VK_LBUTTON) ; Нажата левая кнопка мышки
click=1
  Else
click=0
  EndIf
EndProcedure
И при открытии окна меню
PureBasic
1
SetTimer_(WindowID(0), 2, 40, @TimerMouse() )
А это в обработчике событий
PureBasic
1
2
3
4
5
6
7
8
   ;{Скрытие меню при клике
  If click=1
     If win_pop=1
        Debug "HIDE"
        HideWindow(#win_pop, 1)
        win_pop=0
     EndIf
  EndIf
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.04.2017, 12:27
Помогаю со студенческими работами здесь

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

Меню в трее
Добрый день. Требуется сделать меню с трее, например как у антивируса Avast. Ниже скрин.

Меню в трее
Как сделать чтобы при нажатии на иконку в трее показывалось мини меню?

Обработка меню иконки в трее
Вот код создания меню для иконки программы в трее: if (lParam == WM_RBUTTONDOWN) { SetForegroundWindow(hWnd); POINT mouse; ...

Работа с контекстным меню в Трее
Добрый день! При нажатии правой кнопки мыши на иконку своего приложения я вызываю контекстное меню, но если я в нем ни чего не выберу и...


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru