Page 1 of 2

How to get event if my window is covered

Posted: Wed Mar 02, 2022 11:19 am
by Lord
Hi!

Is there a way to detect that my window isn't still the top most window
(partly or complete covered by another window)? I knowthat my window
is a foreground window by comparing GetForegroundWindow_() with
WindowID(#myWindow), but I need some kind of trigger to get informed
when another window is moved and covers my window.

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 12:48 pm
by chi

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 2:42 pm
by Lord
Hi chi!

Thank you for your reply.
The solutions your link points to are not what I'm looking for.

A little demo code for what I have:

Code: Select all

; Inspired by:
; Simple transparent sticky reminder message by OgreVorbis
; https://www.purebasic.fr/english/viewtopic.php?p=578302

EnableExplicit

Enumeration
#MainWindow 
#DummyWindow
#InfoWindow
EndEnumeration

#ColorKey= $FFFFFF
Define TheMessage.s
Define Event.i

Procedure MoveText()
  ResizeWindow(#InfoWindow, WindowX(#MainWindow)+8, WindowY(#MainWindow)+28, #PB_Ignore, #PB_Ignore)
EndProcedure
Procedure InfoKeyHandler()
  Static WindowState=0
  WindowState=1-WindowState
  HideWindow(#InfoWindow, WindowState)
  SetActiveWindow(#MainWindow)
EndProcedure

OpenWindow(#MainWindow, 10, 10, 120, 120,"")

OpenWindow(#DummyWindow, 0, 0, 1,1, "Dummy", #PB_Window_Invisible)
OpenWindow(#InfoWindow, 0, 0, 128, 32, "Info", #PB_Window_BorderLess | #PB_Window_ScreenCentered, WindowID(#DummyWindow))
SetWindowColor(#DummyWindow, #colorkey)
SetWindowColor(#InfoWindow, #colorkey)
SetWindowLong_(WindowID(#InfoWindow), #GWL_EXSTYLE, #WS_EX_LAYERED | #WS_EX_TOPMOST)
SetLayeredWindowAttributes_(WindowID(#InfoWindow), #colorkey, 100, #LWA_COLORKEY)
StickyWindow(#InfoWindow, #True)

TheMessage = "Scale 4:1"
TextGadget(0, 0, 0, 80, 20, TheMessage)
SetGadgetColor(0, #PB_Gadget_FrontColor, #Red)
SetGadgetColor(0, #PB_Gadget_BackColor, #colorkey)
MoveText()
BindEvent(#PB_Event_MoveWindow, @MoveText())

AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Space, 1)
InfoKeyHandler()
BindEvent(#PB_Event_Menu, @infoKeyHandler())

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
II would like to have an instant event if another window
(partly) covers my window.
Otherwise the text is showing up in the covering window.
Just start the code and turn the text on by hitting space
then move any other window over my little windwo and
you will see what I mean.

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 3:11 pm
by RASHAD
Adapt the next snippet for your need

Code: Select all

OpenWindow(0, 100, 100, 300, 200, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
AddWindowTimer(0,125,5000)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Quit = 1 
      
    Case #PB_Event_Timer
      If GetForegroundWindow_() <> WindowID(0)
        SendMessage_(#HWND_BROADCAST, #WM_SYSCOMMAND, #SC_HOTKEY, WindowID(0))
      EndIf           

  EndSelect
Until Quit = 1

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 4:59 pm
by Lord
Hi RASHAD!

Thank you for your answer.
Your snippet doesn't really help in my case.
It's not about bringing my window in front of another window.
I just want to detect wether another window is (partially)
covering my window or not.
My window can stay in background.

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 9:39 pm
by breeze4me
As far as I know, there is no such event.
Instead, how about this way?

Edit: a bug fixed.

Code: Select all

; Inspired by:
; Simple transparent sticky reminder message by OgreVorbis
; https://www.purebasic.fr/english/viewtopic.php?p=578302

EnableExplicit

Enumeration
#MainWindow 
#DummyWindow
#InfoWindow
EndEnumeration

#ColorKey= $FFFFFF
Define TheMessage.s
Define Event.i

Procedure MoveText()
  ResizeWindow(#InfoWindow, WindowX(#MainWindow)+8, WindowY(#MainWindow)+28, #PB_Ignore, #PB_Ignore)
  
  ;added lines
  SetWindowPos_(WindowID(#InfoWindow), #HWND_TOP, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED | #SWP_NOACTIVATE)
  SetWindowPos_(WindowID(#MainWindow), WindowID(#InfoWindow), 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED)
EndProcedure

Procedure InfoKeyHandler()
  Static WindowState=0
  WindowState=1-WindowState
  HideWindow(#InfoWindow, WindowState)
  SetActiveWindow(#MainWindow)
EndProcedure


Procedure MyWindowCallback(WindowID, Message, WParam, LParam)
  Protected Result = #PB_ProcessPureBasicEvents
  
  If Message = #WM_ACTIVATE Or Message = #WM_MOVE ;Or Message = #WM_SETCURSOR Or Message = #WM_ACTIVATEAPP
    MoveText()
  EndIf
  
  If Message = #WM_WINDOWPOSCHANGED
    SetWindowPos_(WindowID(#InfoWindow), #HWND_TOP, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED | #SWP_NOACTIVATE)
  EndIf
  
  ProcedureReturn Result
EndProcedure


OpenWindow(#MainWindow, 10, 10, 120, 120,"")

OpenWindow(#DummyWindow, 0, 0, 1,1, "Dummy", #PB_Window_Invisible)
OpenWindow(#InfoWindow, 0, 0, 128, 32, "Info", #PB_Window_BorderLess | #PB_Window_ScreenCentered, WindowID(#DummyWindow))
SetWindowColor(#DummyWindow, #colorkey)
SetWindowColor(#InfoWindow, #colorkey)
SetWindowLong_(WindowID(#InfoWindow), #GWL_EXSTYLE, #WS_EX_LAYERED)           ;unnecessary #WS_EX_TOPMOST
SetLayeredWindowAttributes_(WindowID(#InfoWindow), #colorkey, 100, #LWA_COLORKEY)
;StickyWindow(#InfoWindow, #True)    ;remove

TheMessage = "Scale 4:1"
TextGadget(0, 0, 0, 80, 20, TheMessage)
SetGadgetColor(0, #PB_Gadget_FrontColor, #Red)
SetGadgetColor(0, #PB_Gadget_BackColor, #colorkey)
MoveText()

;BindEvent(#PB_Event_MoveWindow, @MoveText())         ;remove
SetWindowCallback(@MyWindowCallback(), #MainWindow)   ;added line

AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Space, 1)
InfoKeyHandler()
BindEvent(#PB_Event_Menu, @infoKeyHandler())

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver


Old version.

Code: Select all

; Inspired by:
; Simple transparent sticky reminder message by OgreVorbis
; https://www.purebasic.fr/english/viewtopic.php?p=578302

EnableExplicit

Enumeration
#MainWindow 
#DummyWindow
#InfoWindow
EndEnumeration

#ColorKey= $FFFFFF
Define TheMessage.s
Define Event.i

Procedure MoveText()
  ResizeWindow(#InfoWindow, WindowX(#MainWindow)+8, WindowY(#MainWindow)+28, #PB_Ignore, #PB_Ignore)
  
  ;added lines.
  SetWindowPos_(WindowID(#InfoWindow), #HWND_TOP, 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED | #SWP_NOACTIVATE)
  SetWindowPos_(WindowID(#MainWindow), WindowID(#InfoWindow), 0, 0, 0, 0, #SWP_NOSIZE | #SWP_NOMOVE | #SWP_FRAMECHANGED)
  
EndProcedure

Procedure InfoKeyHandler()
  Static WindowState=0
  WindowState=1-WindowState
  HideWindow(#InfoWindow, WindowState)
  SetActiveWindow(#MainWindow)
EndProcedure

OpenWindow(#MainWindow, 10, 10, 120, 120,"")

OpenWindow(#DummyWindow, 0, 0, 1,1, "Dummy", #PB_Window_Invisible)
OpenWindow(#InfoWindow, 0, 0, 128, 32, "Info", #PB_Window_BorderLess | #PB_Window_ScreenCentered, WindowID(#DummyWindow))
SetWindowColor(#DummyWindow, #colorkey)
SetWindowColor(#InfoWindow, #colorkey)
SetWindowLong_(WindowID(#InfoWindow), #GWL_EXSTYLE, #WS_EX_LAYERED | #WS_EX_TOPMOST)
SetLayeredWindowAttributes_(WindowID(#InfoWindow), #colorkey, 100, #LWA_COLORKEY)
;StickyWindow(#InfoWindow, #True)    ;remove

TheMessage = "Scale 4:1"
TextGadget(0, 0, 0, 80, 20, TheMessage)
SetGadgetColor(0, #PB_Gadget_FrontColor, #Red)
SetGadgetColor(0, #PB_Gadget_BackColor, #colorkey)
MoveText()

;BindEvent(#PB_Event_MoveWindow, @MoveText())
BindEvent(#PB_Event_MoveWindow, @MoveText(), #MainWindow)      ;explicitly designating the target window
BindEvent(#PB_Event_ActivateWindow, @MoveText(), #MainWindow)  ;added line


AddKeyboardShortcut(#MainWindow, #PB_Shortcut_Space, 1)
InfoKeyHandler()
BindEvent(#PB_Event_Menu, @infoKeyHandler())

Repeat
  Event = WaitWindowEvent()
  Select Event
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver

Re: How to get event if my window is covered

Posted: Wed Mar 02, 2022 9:48 pm
by BarryG
Lord wrote: Wed Mar 02, 2022 2:42 pmI would like to have an instant event if another window (partly) covers my window.
Chi's code does exactly that. Edit his code to have a lower timeout instead of 3 seconds and to not bring your covered window to the front, and then it does just what you asked.

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 2:31 am
by JHPJHP
Hi Lord,

See Windows Services & Other Stuff\Other_Stuff\OtherStuff\WindowOverlapped.pb

This example will list the title of any visible window that overlaps the main PureBasic Window.

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 9:50 am
by Lord
Hi breeze4me, BarryG and JHPJHP!

Thanks for your answers to all of you.
I tried all of your recommendations.
Still, a timer based solution is not the wanted way.
I go with "Old Version" by breeze4me as it almost gives the wanted behaviour.

So again thank you to all of you. Case closed.

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 11:35 am
by BarryG
Lord wrote: Thu Mar 03, 2022 9:50 amI go with "Old Version" by breeze4me as it almost gives the wanted behaviour.
It does? I can cover it with another window and it doesn't do anything. All it does (and even the bug-fixed version) is open a small blank window that literally does nothing?

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 12:15 pm
by Lord
BarryG wrote: Thu Mar 03, 2022 11:35 am ...
It does? I can cover it with another window and it doesn't do anything. All it does (and even the bug-fixed version) is open a small blank window that literally does nothing?
Just press space bar to see "TheMassage" ;-) .
In my version, the text "Scale 4:1" is visible when my window is covered by another.
I tried to find a way to detect if another window covered or left my window so that I could turn text off and on.
But with your version I can live with. :D

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 12:35 pm
by BarryG
Sorry, but I really don't get this at all. When I press Space to show the text, the text still gets covered by other windows? Is it not supposed to?

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 1:15 pm
by Lord
It looks like this:
https://ibb.co/7RdSbHZ

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 9:44 pm
by BarryG
Okay, it doesn't do that here on Win 10 - the text gets covered by other windows. Maybe it's a Win 7 vs Win 10 thing?

Image

Re: How to get event if my window is covered

Posted: Thu Mar 03, 2022 11:42 pm
by breeze4me
Image
(This is the result of executing Lord's code)

Lord: "What the... , it's so ugly! The layered window is visible above another window, so when my window is covered with another window, I should turn off the text. Is there an event like that?"

breeze4me: "No such event. Instead, I suggest changing the z-order of the topmost-level layered window so that it does not become topmost-level."
Image
"Here is the result."

Lord: "That's good. I will adopt that method."


It's the whole story. So BarryG, you'd better have a cup of coffee and think again. :mrgreen: :twisted: