Popup window when the cursor is at the edge of the screen (?)
Posted: Tue Mar 14, 2023 3:52 pm
I have a working code on AutoIt3. I converted it to PureBasic and can't get the code to work.
The meaning is the following:
Creates a transparent window at the edge of the screen, 1 pixel wide at full length. The window can be created from any of the 4 sides. When I hover over this transparent window, the WM_NCHITTEST event comes. It creates a popup window and checks every 400 milliseconds that the cursor is within the popup window. As soon as the cursor leaves the window, then after 400 milliseconds, the code for smoothly increasing transparency is executed until it becomes invisible and then the window is hidden.
At the moment WM_NCHITTEST is called all the time and I don't understand why. If I take another example with WM_NCHITTEST, then it can be seen that events only come when the cursor is over the window.
The meaning is the following:
Creates a transparent window at the edge of the screen, 1 pixel wide at full length. The window can be created from any of the 4 sides. When I hover over this transparent window, the WM_NCHITTEST event comes. It creates a popup window and checks every 400 milliseconds that the cursor is within the popup window. As soon as the cursor leaves the window, then after 400 milliseconds, the code for smoothly increasing transparency is executed until it becomes invisible and then the window is hidden.
At the moment WM_NCHITTEST is called all the time and I don't understand why. If I take another example with WM_NCHITTEST, then it can be seen that events only come when the cursor is over the window.
Code: Select all
EnableExplicit
#Win_tr = 0
#Window = 1
#Timer = 0
Global Point.POINT
Global DesktopWidth, DesktopHeight
Global hGUI, hGUI_tr
Global ww, hh, i, ifTimer = 1
Declare WM_NCHITTEST(hWnd, Msg, wParam, lParam)
Declare DelayGui()
ExamineDesktops()
DesktopWidth = DesktopWidth(0)
DesktopHeight = DesktopHeight(0)
ww = 99
hh = 600
; создаём прозрачное окно шириной 1 писсель справа, чтобы реагировать при наведении выши на него
; hGUI_tr = OpenWindow(#Win_tr, DesktopWidth - 1, 0, 1, DesktopHeight, "", #PB_Window_BorderLess)
hGUI_tr = OpenWindow(#Win_tr, 0, 0, 1, DesktopHeight, "", #PB_Window_BorderLess)
SetWindowLongPtr_(hGUI_tr,#GWL_EXSTYLE,GetWindowLongPtr_(hGUI_tr,#GWL_EXSTYLE) | #WS_EX_TOOLWINDOW | #WS_EX_TOPMOST | #WS_EX_LAYERED)
StickyWindow(#Win_tr, #True)
SetWindowColor(#Win_tr, 0)
SetLayeredWindowAttributes_(hGUI_tr, 0, 1, 3)
; hGUI = OpenWindow(#Window, 0, 0, ww, hh, "", #PB_Window_SystemMenu | #WS_POPUP | #WS_THICKFRAME | #WS_SIZEBOX)
; всплывающее окно
hGUI = OpenWindow(#Window, DesktopWidth - 140, 80, 95, 400, "", #PB_Window_SystemMenu | #PB_Window_BorderLess | #PB_Window_SizeGadget)
SetWindowLongPtr_(hGUI,#GWL_EXSTYLE,GetWindowLongPtr_(hGUI,#GWL_EXSTYLE) | #WS_EX_TOOLWINDOW | #WS_EX_TOPMOST | #WS_EX_LAYERED)
SetLayeredWindowAttributes_(hGUI, 0, 255, 2)
; StickyWindow(#Window, #True)
; Delay(200)
; For i = 245 To 1 Step -14
; SetLayeredWindowAttributes_(hGUI, 0, i, 2)
; Delay(10)
; Next
HideWindow(#Window, #True)
SetWindowCallback(@WM_NCHITTEST(), #Win_tr)
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
If EventTimer() = #Timer
; ifTimer = 0
DelayGui()
EndIf
Case #PB_Event_CloseWindow
CloseWindow(#Window)
CloseWindow(#Win_tr)
End
EndSelect
ForEver
; Эта функция должна выполнятся только если курсор в окне
Procedure WM_NCHITTEST(hWnd, Msg, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents, i, X, Y
Protected yClient = lParam >> 16
Protected xClient = lParam & $FFF
If yClient
; If hWnd = hGui_tr
; If Not BitAnd(WinGetState(Gui$), 2) ; если окно не отображается, то
If GetActiveWindow() <> #Window
HideWindow(#Window, #False)
For i = 1 To 255 Step 7
SetLayeredWindowAttributes_(hGUI, 0, i, 3)
Delay(10)
Next
Else
HideWindow(#Window, #False)
EndIf
; If ifTimer
AddWindowTimer(#Window, #Timer, 400)
; ifTimer = 0
; Debug 1
; EndIf
; переместить прозрачное окно за пределы экрана
ResizeWindow(#Win_tr , DesktopWidth + 2 , #PB_Ignore, #PB_Ignore , #PB_Ignore)
; ProcedureReturn
EndIf
; EndIf
ProcedureReturn Result
EndProcedure
; Функция вызывается пока курсор находится в окне
Procedure DelayGui()
Protected i
GetCursorPos_(@Point)
; Debug Point\x
; Debug Point\y
; если Х-координата курсора больше ширины экрана, то
If Point\x >= DesktopWidth - 1
ProcedureReturn
EndIf
; Protected WinW = WindowWidth(#Window)
; Protected WinH = WindowHeight(#Window)
Protected WinX = WindowX(#Window)
Protected WinY = WindowY(#Window)
; Если курсор внутри окна, то выпрыгиваем не разрегистрируя таймер
If Point\x >= WinX And Point\x <= WinX + WindowWidth(#Window) And Point\y >= WinY And Point\y <= WinY + WindowHeight(#Window)
ProcedureReturn
EndIf
; скрываем окно разрегистрируя таймер
Delay(600)
For i = 245 To 1 Step -7
SetLayeredWindowAttributes_(hGUI, 0, i, 3)
Delay(10)
Next
HideWindow(#Window, #True)
; убираем окно за пределы экрана
ResizeWindow(#Win_tr , DesktopWidth - 1, #PB_Ignore, #PB_Ignore , #PB_Ignore)
RemoveWindowTimer(#Window, #Timer)
; ifTimer = 1
EndProcedure