Что нового

[Элементы GUI] При восстановлении окна из трея нажатия на кнопки не обрабатываются

Skortyak

Новичок
Сообщения
5
Репутация
0
Здравствуйте!
Может похожая тема уже была, но поиск по форуму уже третий день "временно отключен" :(.
Пишу скрипт, который создает окно с пользовательскими кнопками и сворачивает его в трей. При запуске второго экземпляра скрипта требуется развернуть это окно из трея. С помощью функций WinSetState и WinActivate окно разворачивается - но нажатия на кнопки не обрабатываются. Если же развернуть окно из трея мышкой - все работает.
Как развернуть полноценное окно из трея вторым запущенным экземпляром скрипта?
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>
 
If _Singleton("MyWindow", 1) = 0 Then
	$oGUI = WinGetHandle("[TITLE:MyWindow; CLASS:AutoIt v3 GUI]")
	MsgBox(4096, "Внимание", "Текущий скрипт уже запущен. ID: " & $oGUI)
	WinSetState("MyWindow", "", @SW_SHOW)
	WinSetState("MyWindow", "", @SW_RESTORE)
	WinActivate("MyWindow")
	Exit
EndIf

Opt("TrayMenuMode", 1 + 2)
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)

$hGUI = GUICreate("MyWindow", 200, 300, -1, -1, $WS_CAPTION + $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "_MinimizeTray")

$ShowButton = GUICtrlCreateButton(" Button", 5, 100, 190, 40, $BS_MULTILINE)
GUICtrlSetImage($ShowButton, "shell32.dll", 274)
GUICtrlSetOnEvent($ShowButton, "_Button")

$CloseButton = GUICtrlCreateButton("Выход", 120, 250, 75, 45)
GUICtrlSetImage($CloseButton, "shell32.dll", 221)
GUICtrlSetOnEvent($CloseButton, "_Exit")

TrayCreateItem("Восстановить")
TrayItemSetOnEvent(-1, "_RestoreTray")
TrayCreateItem("")
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
TraySetOnEvent(-8, "_RestoreTray")
TraySetClick(16)

TraySetState(1)

While 1
	Sleep(10)
WEnd

Func _MinimizeTray()
	GUISetState(@SW_HIDE, $hGUI)
EndFunc   ;==>_MinimizeTray

Func _RestoreTray()
	GUISetState(@SW_SHOW, $hGUI)
	GUISetState(@SW_RESTORE, $hGUI)
EndFunc   ;==>_RestoreTray

Func _Button()
	MsgBox(4096, "Button", "Нажата кнопка Button")
EndFunc   ;==>_Button

Func _Exit()
	Exit
EndFunc   ;==>_Exit
 

InnI

AutoIT Гуру
Сообщения
4,922
Репутация
1,432
Skortyak
Вероятно, после получения команды
Код:
GUISetState(@SW_HIDE)
GUI перестаёт обрабатывать сообщения от элементов, до получения
Код:
GUISetState(@SW_SHOW)
(во всяком случае мои эксперименты приводят именно к такому выводу)
Код:
GUICreate("Test Window")
$btn = GUICtrlCreateButton("Exit", 10, 10)

; GUISetState() ; кнопка работает
WinSetState("Test Window", "", @SW_SHOW) ; кнопка не работает

Do
Until GUIGetMsg() = $btn

Варианты решения:
1. При первом запуске отобразить GUI через GUISetState(), после чего пользоваться только WinSetState().
2. Обрабатывать сообщение WM_SHOWWINDOW и отображать GUI через GUISetState()
Код:
GUIRegisterMsg(0x0018, "WM_SHOWWINDOW")

Func WM_SHOWWINDOW($hWnd, $iMsg, $wParam, $lParam)
  If $wParam Then GUISetState(@SW_SHOW)
EndFunc
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
может не стоит вызывать окно? просто обратить внимание пользователя что программа запущена и вызвать ее можно из трея
 
Автор
S

Skortyak

Новичок
Сообщения
5
Репутация
0
To InnI - вариант №1 работает, но при первом запуске появляется окно, которое сразу-же сворачивается.
С вариантом № 2 так и не смог разобраться/понять, и решил "забить" на него (в любом случае с этим способом будет усложнение скрипта).

To joiner - это, конечно, самый простой способ, но хочется сделать "КРАСИВО"

В принципе вариант №1 от InnI вполне рабочий, но хотелось бы найти способ без появляющегося окна и без излишнего увеличения/усложнения скрипта.
 
A

Alofa

Гость
Skortyak сказал(а):
В принципе вариант №1 от InnI вполне рабочий, но хотелось бы найти способ без появляющегося окна и без излишнего увеличения/усложнения скрипта.
А если проявить немного смекалки?
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>

Global $hGUI = WinGetHandle("[TITLE:MyWindow;CLASS:AutoIt v3 GUI]")
 
If $hGUI Then
    MsgBox(4096, "Внимание", "Текущий скрипт уже запущен. ID: " & $hGUI)
    _RestoreTray()
    Exit
EndIf

Opt("TrayMenuMode", 1 + 2)
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)

$hGUI = GUICreate("MyWindow", 200, 300, @DesktopWidth, @DesktopHeight, $WS_CAPTION + $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "_MinimizeTray")

$ShowButton = GUICtrlCreateButton(" Button", 5, 100, 190, 40, $BS_MULTILINE)
GUICtrlSetImage($ShowButton, "shell32.dll", 274)
GUICtrlSetOnEvent($ShowButton, "_Button")

$CloseButton = GUICtrlCreateButton("Выход", 120, 250, 75, 45)
GUICtrlSetImage($CloseButton, "shell32.dll", 221)
GUICtrlSetOnEvent($CloseButton, "_Exit")

TrayCreateItem("Восстановить")
TrayItemSetOnEvent(-1, "_RestoreTray")
TrayCreateItem("")
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
TraySetOnEvent(-8, "_RestoreTray")
TraySetClick(16)

; --------------------
GUISetState()
_MinimizeTray()
WinMove($hGUI, '', (@DesktopWidth - 200)/2, (@DesktopHeight - 300)/2)
; --------------------

While Sleep(100)
WEnd

Func _MinimizeTray()
	WinSetState($hGUI, '', @SW_HIDE)
EndFunc   ;==>_MinimizeTray

Func _RestoreTray()
	WinSetState($hGUI, '', @SW_SHOW)
EndFunc   ;==>_RestoreTray

Func _Button()
    MsgBox(4096, "Button", "Нажата кнопка Button")
EndFunc   ;==>_Button

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Что касается "излишнего увеличения/усложнения скрипта", то в вашем случае лучше применить GUI режим MessageLoop.
 
Автор
S

Skortyak

Новичок
Сообщения
5
Репутация
0
Alofa сказал(а):
А если проявить немного смекалки?
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>

Global $hGUI = WinGetHandle("[TITLE:MyWindow;CLASS:AutoIt v3 GUI]")
 
If $hGUI Then
    MsgBox(4096, "Внимание", "Текущий скрипт уже запущен. ID: " & $hGUI)
    _RestoreTray()
    Exit
EndIf

Opt("TrayMenuMode", 1 + 2)
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)

$hGUI = GUICreate("MyWindow", 200, 300, @DesktopWidth, @DesktopHeight, $WS_CAPTION + $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "_MinimizeTray")

$ShowButton = GUICtrlCreateButton(" Button", 5, 100, 190, 40, $BS_MULTILINE)
GUICtrlSetImage($ShowButton, "shell32.dll", 274)
GUICtrlSetOnEvent($ShowButton, "_Button")

$CloseButton = GUICtrlCreateButton("Выход", 120, 250, 75, 45)
GUICtrlSetImage($CloseButton, "shell32.dll", 221)
GUICtrlSetOnEvent($CloseButton, "_Exit")

TrayCreateItem("Восстановить")
TrayItemSetOnEvent(-1, "_RestoreTray")
TrayCreateItem("")
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
TraySetOnEvent(-8, "_RestoreTray")
TraySetClick(16)

; --------------------
GUISetState()
_MinimizeTray()
WinMove($hGUI, '', (@DesktopWidth - 200)/2, (@DesktopHeight - 300)/2)
; --------------------

While Sleep(100)
WEnd

Func _MinimizeTray()
	WinSetState($hGUI, '', @SW_HIDE)
EndFunc   ;==>_MinimizeTray

Func _RestoreTray()
	WinSetState($hGUI, '', @SW_SHOW)
EndFunc   ;==>_RestoreTray

Func _Button()
    MsgBox(4096, "Button", "Нажата кнопка Button")
EndFunc   ;==>_Button

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Что касается "излишнего увеличения/усложнения скрипта", то в вашем случае лучше применить GUI режим MessageLoop.
Вариант со смекалкой подойдет, спасибо! Единственный минус - если у пользователя будет стоять справа второй монитор с бОльшим разрешением (что маловероятно), окошко появляется на нем.
 
Автор
S

Skortyak

Новичок
Сообщения
5
Репутация
0
Только сейчас обратил внимание, что если при таком варианте
InnI сказал(а):
1. При первом запуске отобразить GUI через GUISetState(), после чего пользоваться только WinSetState().
развернуть окно из трея мышкой, то сначала отрисовывается само окно, и только потом (с довольно большой задержкой) - кнопки.
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
Skortyak [?]
С вариантом № 2 так и не смог разобраться/понять, и решил "забить" на него (в любом случае с этим способом будет усложнение скрипта).
ничего сложного

Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>

If _Singleton("MyWindow", 1) = 0 Then
    $oGUI = WinGetHandle("[TITLE:MyWindow; CLASS:AutoIt v3 GUI]")
    MsgBox(4096, "Внимание", "Текущий скрипт уже запущен. ID: " & $oGUI)
    WinSetState("MyWindow", "", @SW_SHOW)
    WinSetState("MyWindow", "", @SW_RESTORE)
    WinActivate("MyWindow")
    Exit
EndIf

Opt("TrayMenuMode", 1 + 2)
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)

$hGUI = GUICreate("MyWindow", 200, 300, -1, -1, $WS_CAPTION + $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "_MinimizeTray")

$ShowButton = GUICtrlCreateButton(" Button", 5, 100, 190, 40, $BS_MULTILINE)
GUICtrlSetImage($ShowButton, "shell32.dll", 274)
GUICtrlSetOnEvent($ShowButton, "_Button")

$CloseButton = GUICtrlCreateButton("Выход", 120, 250, 75, 45)
GUICtrlSetImage($CloseButton, "shell32.dll", 221)
GUICtrlSetOnEvent($CloseButton, "_Exit")

TrayCreateItem("Восстановить")
TrayItemSetOnEvent(-1, "_RestoreTray")
TrayCreateItem("")
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
TraySetOnEvent(-8, "_RestoreTray")
TraySetClick(16)

TraySetState(1)
GUISetState(@SW_HIDE, $hGUI)
GUIRegisterMsg(0x0018, "WM_SHOWWINDOW")
While 1
    Sleep(10)
WEnd
Func WM_SHOWWINDOW($hWnd, $iMsg, $wParam, $lParam)
  If $wParam Then GUISetState(@SW_SHOW)
EndFunc

Func _MinimizeTray()
    GUISetState(@SW_HIDE, $hGUI)
EndFunc   ;==>_MinimizeTray

Func _RestoreTray()
    GUISetState(@SW_SHOW, $hGUI)
EndFunc   ;==>_RestoreTray

Func _Button()
    MsgBox(4096, "Button", "Нажата кнопка Button")
EndFunc   ;==>_Button

Func _Exit()
    Exit
EndFunc   ;==>_Exit
 
Автор
S

Skortyak

Новичок
Сообщения
5
Репутация
0
joiner сказал(а):
ничего сложного
Код:
#NoTrayIcon
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiButton.au3>
#include <Misc.au3>

If _Singleton("MyWindow", 1) = 0 Then
    $oGUI = WinGetHandle("[TITLE:MyWindow; CLASS:AutoIt v3 GUI]")
    MsgBox(4096, "Внимание", "Текущий скрипт уже запущен. ID: " & $oGUI)
    WinSetState("MyWindow", "", @SW_SHOW)
    WinSetState("MyWindow", "", @SW_RESTORE)
    WinActivate("MyWindow")
    Exit
EndIf

Opt("TrayMenuMode", 1 + 2)
Opt("GUIOnEventMode", 1)
Opt("TrayOnEventMode", 1)

$hGUI = GUICreate("MyWindow", 200, 300, -1, -1, $WS_CAPTION + $WS_SYSMENU)
GUISetOnEvent($GUI_EVENT_CLOSE, "_MinimizeTray")

$ShowButton = GUICtrlCreateButton(" Button", 5, 100, 190, 40, $BS_MULTILINE)
GUICtrlSetImage($ShowButton, "shell32.dll", 274)
GUICtrlSetOnEvent($ShowButton, "_Button")

$CloseButton = GUICtrlCreateButton("Выход", 120, 250, 75, 45)
GUICtrlSetImage($CloseButton, "shell32.dll", 221)
GUICtrlSetOnEvent($CloseButton, "_Exit")

TrayCreateItem("Восстановить")
TrayItemSetOnEvent(-1, "_RestoreTray")
TrayCreateItem("")
TrayCreateItem("Выход")
TrayItemSetOnEvent(-1, "_Exit")
TraySetOnEvent(-8, "_RestoreTray")
TraySetClick(16)

TraySetState(1)
GUISetState(@SW_HIDE, $hGUI)
GUIRegisterMsg(0x0018, "WM_SHOWWINDOW")
While 1
    Sleep(10)
WEnd
Func WM_SHOWWINDOW($hWnd, $iMsg, $wParam, $lParam)
  If $wParam Then GUISetState(@SW_SHOW)
EndFunc

Func _MinimizeTray()
    GUISetState(@SW_HIDE, $hGUI)
EndFunc   ;==>_MinimizeTray

Func _RestoreTray()
    GUISetState(@SW_SHOW, $hGUI)
EndFunc   ;==>_RestoreTray

Func _Button()
    MsgBox(4096, "Button", "Нажата кнопка Button")
EndFunc   ;==>_Button

Func _Exit()
    Exit
EndFunc   ;==>_Exit

СПАСИБО !!!
Теперь понял, как эти сообщения обрабатывать. А то в справке к GUIRegisterMsg новичку трудно разобраться.
 
Верх