How to get event if my window is covered

Just starting out? Need help? Post your questions and find answers here.
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

How to get event if my window is covered

Post 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.
Image
User avatar
chi
Addict
Addict
Posts: 1087
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

Re: How to get event if my window is covered

Post by chi »

Et cetera is my worst enemy
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to get event if my window is covered

Post 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.
Image
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: How to get event if my window is covered

Post 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
Egypt my love
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to get event if my window is covered

Post 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.
Image
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: How to get event if my window is covered

Post 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
Last edited by breeze4me on Thu Mar 03, 2022 1:18 am, edited 5 times in total.
BarryG
Addict
Addict
Posts: 4128
Joined: Thu Apr 18, 2019 8:17 am

Re: How to get event if my window is covered

Post 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.
User avatar
JHPJHP
Addict
Addict
Posts: 2251
Joined: Sat Oct 09, 2010 3:47 am

Re: How to get event if my window is covered

Post 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.
Last edited by JHPJHP on Thu Mar 03, 2022 1:04 pm, edited 1 time in total.

If you're not investing in yourself, you're falling behind.

My PureBasic StuffFREE STUFF, Scripts & Programs.
My PureBasic Forum ➤ Questions, Requests & Comments.
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to get event if my window is covered

Post 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.
Image
BarryG
Addict
Addict
Posts: 4128
Joined: Thu Apr 18, 2019 8:17 am

Re: How to get event if my window is covered

Post 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?
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to get event if my window is covered

Post 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
Image
BarryG
Addict
Addict
Posts: 4128
Joined: Thu Apr 18, 2019 8:17 am

Re: How to get event if my window is covered

Post 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?
User avatar
Lord
Addict
Addict
Posts: 900
Joined: Tue May 26, 2009 2:11 pm

Re: How to get event if my window is covered

Post by Lord »

It looks like this:
https://ibb.co/7RdSbHZ
Image
BarryG
Addict
Addict
Posts: 4128
Joined: Thu Apr 18, 2019 8:17 am

Re: How to get event if my window is covered

Post 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
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: How to get event if my window is covered

Post 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:
Post Reply