Sign in to follow this  
Followers 0
JohnBailey

Detect if a Window is Flashing

22 posts in this topic

How do I detect if a window is flashing. WinGetState() does not have a return for this.

Example:

Local $currentActiveHwnd = WinGetHandle('')
Local $PID = Run('notepad.exe')
Local $WinTitle = 'Untitled - Notepad'
WinWait($WinTitle)
WinActivate($currentActiveHwnd)
Local $winHwnd = WinGetHandle($WinTitle)
_API_FlashWindow($winHwnd, False)

Func _API_FlashWindow($hWnd, $fInvert=True)
  Local $aResult

  $aResult = DllCall("User32.dll", "int", "FlashWindow", "hwnd", $hWnd, "int", $fInvert)
  Return $aResult[0] <> 0
EndFunc

A decision is a powerful thing

Share this post


Link to post
Share on other sites



Interesting and thank you. However, not exactly what I'm looking for. There is potential (like on my machine) for this to be very inaccurate since it is using PixelSearch (I didn't even think about that - not a bad idea). On machine, I have a double-sized tool bar thus it doesn't find the Taskbar button for a window, instead it sees an icon and thinks that it's not it ... at least I think that's what it's seeing. It may be seeing the Taskbar Window's Button's Icon.

Any other ideas?

BTW: Good find! I didn't even see that in my search - google or AIv3forumsearch


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Here is a visual basic script to trigger the flashing:

http://www.visualbasic.happycodings.com/Other/code23.html

I would assume you would just need to reverse engineer it to find the window(s) tagged to flash.

NICE! Great idea and find! I'll look through it and post my findings here.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Revised..

maybe change "@DesktopHeight - 30" to "@DesktopHeight - 60" for the "dual" taskbar

; Detect Window Flashing in TaskBar

; Author Rizo & Valuater
; This is Rizo's one-and-only post

$XP_Orange = 0xE47B09

Run_Notepad_Demo()

While 1

    $coord = PixelSearch(0, @DesktopHeight - 30, @DesktopWidth, @DesktopHeight, $XP_Orange, 10, 10)

    If Not @error Then
        TrayTip("Location", "X and Y are:" & $coord[0] & "," & $coord[1], 5) ; notification
        MouseClick("left", $coord[0], $coord[1], 1, 0) ; brings Flashing Window Active
        ExitLoop
    EndIf

    Sleep(100)
WEnd


Func Run_Notepad_Demo()
    If Not WinExists("Untitled - ") Then
        Run("Notepad.exe", "", @SW_MINIMIZE)
    EndIf

    WinWait("Untitled - ")

    ; flashes the window 4 times with a break in between each one of 1/2 second
    WinFlash("Untitled - ", "", 4, 500)
EndFunc   ;==>Run_Demo

8)

Edited by Valuater

NEWHeader1.png

Share this post


Link to post
Share on other sites

you can just use WinFlash()

Revised..

maybe change "@DesktopHeight - 30" to "@DesktopHeight - 60" for the "dual" taskbar

8)

Good idea on the using 60 for the "dual taskbar." However, the biggest problem with that is the inaccuracy. I cannot specify which window to watch for/listen to.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Sounds like a pain in the arse really... I mean, the first thought that comes to mind:

1. Loop

2. WinList

3. Collect visible wins only

4. Set window hook to each visible window

5. Get request to match flash value

6. Repeat loop

Off the top of my head, can't even think of how to keep checking the incoming messages or if you're allowed to hook more than one window at a time.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Sounds like a pain in the arse really... I mean, the first thought that comes to mind:

1. Loop

2. WinList

3. Collect visible wins only

4. Set window hook to each visible window

5. Get request to match flash value

6. Repeat loop

Off the top of my head, can't even think of how to keep checking the incoming messages or if you're allowed to hook more than one window at a time.

haha agreed it does. I was searching MSDN thinking that there's got to be a function or something on there. This obviously is not an unusual question as several have asked it on this forum and I've found other forums with a thread/post involving this question, but this forum is the only one with people actually attempting to resolve it. Like I said, I would think MSDN would have something on it. Maybe it's well guarded <_<

Anyone know a MSDN or dllcall method?


A decision is a powerful thing

Share this post


Link to post
Share on other sites

5. Get request to match flash value

How do I do just that part?


A decision is a powerful thing

Share this post


Link to post
Share on other sites

How do I do just that part?

Find the windows message style I suppose. I don't even know if flash is a standard style to be honest. I didn't even know we had the function until the other day. (Not something I would use personally, as it annoys the crap out of me when other progs do it).

http://msdn2.microsoft.com/en-us/library/ms674884.aspx

http://msdn2.microsoft.com/en-us/library/ms674887.aspx

May be a good place to start.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

Find the windows message style I suppose. I don't even know if flash is a standard style to be honest. I didn't even know we had the function until the other day. (Not something I would use personally, as it annoys the crap out of me when other progs do it).

http://msdn2.microsoft.com/en-us/library/ms674884.aspx

http://msdn2.microsoft.com/en-us/library/ms674887.aspx

May be a good place to start.

I'll keep looking around. Basically what's going on is I have a program that flashes ( I didn't create the program) when msgs occur. I don't want it to keep flashing. I want it to flash once or twice and then do as GTalk does turns a different color (the Flash-orange color). I to specifically do it for the program that flashes when msgs occurs, but I also would like to know how to do this in general.

Smoke_n, I agree though the flashing annoys me too, which is why I'm trying to figure this out. I'm surprised there isn't an easy way of determining this or a post method already one that is specific to a window.

Thanks gang!!!! I'll keep looking.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

Not sure if it's a good idea but anyways...

(requires CallBack UDF)

#include "DllCallBack.au3"
; No comments on this one. If you dont know whats happening just ignore it.
Global $pWinFlash, $vWinFlash_Jmp, $vWinFlash_Original

$pStub_WinFlash = _DllCallBack("_Stub_WinFlash", "ptr")
$hUser32 = DllCall("kernel32.dll", "ptr", "LoadLibrary", "str", "user32.dll")
$pWinFlash = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", $hUser32[0], "str", "FlashWindowEx")
$vWinFlash_Original = DllStructCreate("ubyte[7]")
DllStructSetData($vWinFlash_Original, 1, DllStructGetData(DllStructCreate("ubyte[7]", $pWinFlash[0]), 1))
$vWinFlash_Jmp = DllStructCreate("ubyte[1];ptr;ubyte[2]")
DllStructSetData($vWinFlash_Jmp, 1, Binary("0xB8"))
DllStructSetData($vWinFlash_Jmp, 2, $pStub_WinFlash)
DllStructSetData($vWinFlash_Jmp, 3, Binary("0xFFE0"))
DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Jmp), "dword", 7, "long_ptr", 0)

;lets test our hook:

Run("notepad","",@SW_MINIMIZE)
WinWait("Untitled - Notepad")
WinFlash("Untitled - Notepad", "", 3, 500)


Func _Stub_WinFlash($pFLASHWINFO)
    $tFLASHWINFO = DllStructCreate("uint;hwnd;dword;uint;dword", $pFLASHWINFO)
    ConsoleWrite("-----------" & @CRLF & _
                    "Flashing Window Detected: " & @CRLF & _
                    "handle = " & DllStructGetData($tFLASHWINFO, 2) & @CRLF & _
                    "flags = " & DllStructGetData($tFLASHWINFO, 3) & @CRLF & _
                    "count = " & DllStructGetData($tFLASHWINFO, 4) & @CRLF & _
                    "timeout = " & DllStructGetData($tFLASHWINFO, 5) & @CRLF & _
                    "-----------" & @CRLF)
    DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Original), "dword", 7, "long_ptr", 0)
    DllCall("user32.dll", "int", "FlashWindowEx", "ptr", $pFLASHWINFO)
    DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Jmp), "dword", 7, "long_ptr", 0)
    Return 1
EndFunc
Edited by Siao

"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Not sure if it's a good idea posting this, but anyways.

(requires CallBack UDF)

code...
SUCKER!!! You totally discovered it!! THANK YOU!!! <_<:)

Incredible! That DllCallBack is so powerful (I wish I understood it more). Could you comment any of that? I know Piccaso didn't comment on any of it nor did you, but at least where can I learn about what's going on (I don't just want to keep using this stuff without knowing what's going on).

Thanks again GANG!

If anyone else comes up with another idea, please let us know.

The only bummer about this method is that Globals must be used :D While that's not horrible, I get nervous :P

Revision with Example

#include <DllCallBack.au3>
#include <A3LWinAPI.au3>


Global $pWinFlash, $vWinFlash_Jmp, $vWinFlash_Original; Required


Run("notepad","",@SW_MINIMIZE)
Local $winTitle = "Untitled - Notepad"
WinWait("Untitled - Notepad")
Global $WatchForHwnd = WinGetHandle("[Title:Untitled - Notepad]")
_WatchFlashingWinInit()
Sleep(1000*Random(3,8,1));Timer
;~ WinFlash($WatchForHwnd, "",10, 200); Doesn't work for some reason
_API_FlashWindow($WatchForHwnd)
While 1
    Sleep(10)
WEnd

Func _WatchFlashingWinInit()
; No comments on this one. If you dont know whats happening just ignore it.
    
    $pStub_WinFlash = _DllCallBack("_WatchFlashingWinInit_Stub_WinFlash", "ptr")
    $hUser32 = DllCall("kernel32.dll", "ptr", "LoadLibrary", "str", "user32.dll")
    $pWinFlash = DllCall("kernel32.dll", "ptr", "GetProcAddress", "ptr", $hUser32[0], "str", "FlashWindowEx")
    $vWinFlash_Original = DllStructCreate("ubyte[7]")
    DllStructSetData($vWinFlash_Original, 1, DllStructGetData(DllStructCreate("ubyte[7]", $pWinFlash[0]), 1))
    $vWinFlash_Jmp = DllStructCreate("ubyte[1];ptr;ubyte[2]")
    DllStructSetData($vWinFlash_Jmp, 1, Binary("0xB8"))
    DllStructSetData($vWinFlash_Jmp, 2, $pStub_WinFlash)
    DllStructSetData($vWinFlash_Jmp, 3, Binary("0xFFE0"))
    DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Jmp), "dword", 7, "long_ptr", 0)
EndFunc


Func _WatchFlashingWinInit_Stub_WinFlash($pFLASHWINFO)
    $tFLASHWINFO = DllStructCreate("uint;hwnd;dword;uint;dword", $pFLASHWINFO)
    ConsoleWrite("-----------" & @CRLF & _
                    "Flashing Window Detected:" & @CRLF & _
                    "handle = " & DllStructGetData($tFLASHWINFO, 2) & @CRLF & _
                    "flags = " & DllStructGetData($tFLASHWINFO, 3) & @CRLF & _
                    "count = " & DllStructGetData($tFLASHWINFO, 4) & @CRLF & _
                    "timeout = " & DllStructGetData($tFLASHWINFO, 5) & @CRLF & _
                    "WinTitle = " & WinGetTitle(HWnd(DllStructGetData($tFLASHWINFO, 2))) & @CRLF & _
                    "-----------" & @CRLF)
    Local $_winHandle = HWnd(DllStructGetData($tFLASHWINFO, 2))
    Local $_winTitle = WinGetTitle(HWnd(DllStructGetData($tFLASHWINFO, 2)))
    If $_winHandle = $WatchForHwnd Then
        _API_FlashWindow($_winHandle, True)
        TrayTip('Did It','Yes',3)
    EndIf
    DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Original), "dword", 7, "long_ptr", 0)
    DllCall("user32.dll", "int", "FlashWindowEx", "ptr", $pFLASHWINFO)
    DllCall("kernel32.dll", "int", "WriteProcessMemory", "ptr", -1, "ptr", $pWinFlash[0], "ptr", DllStructGetPtr($vWinFlash_Jmp), "dword", 7, "long_ptr", 0)
    Return 1
EndFunc

Comments please! :)

There are issues too:

[*] WinFlash will not work with this method.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

CRUD! One thing about that is it only works if the Window is flashing too, not just the Taskbar Button <_< blast! close guys but still better than the previous methods in my opinion.


A decision is a powerful thing

Share this post


Link to post
Share on other sites

There's also pretty blunt polling approach...

Monitor script, which keeps turning off window flashing for specified window and checks the return value (0 if window wasn't flashing):

While 1
    If  _Flash("Untitled - Notepad") <> 0 Then
        MsgBox(0, '', 'Window Flashed')
        ExitLoop
    EndIf
    Sleep(100)
WEnd

Func _Flash($win)
    If WinActive($win) Then Return 0
    $tFLASHWINFO = DllStructCreate("uint;hwnd;dword;uint;dword")
    DllStructSetData($tFLASHWINFO, 1, 20)
    DllStructSetData($tFLASHWINFO, 2, WinGetHandle($win))
    $a = DllCall("user32.dll", "int", "FlashWindowEx", "ptr", DllStructGetPtr($tFLASHWINFO))
    Return $a[0]
EndFunc

Then from other script do a WinFlash("Untitled - Notepad")...


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Nice work Siao... as usual.


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

There's also pretty blunt polling approach...

Monitor script, which keeps turning off window flashing for specified window and checks the return value (0 if window wasn't flashing):

Then from other script do a WinFlash("Untitled - Notepad")...

Saio,

That did it! I don't understand why that worked on QIP (the program that flashes) and the other one doesn't though. Do you know of any reason that there might be?

Thank you Thank you Thank you!! I agree with Smoke_n, NICE WORK This has been a really interesting learning process!

Everyone

Thanks everyone for the help and input!

"Bug": When I click menu items in QIP, the window is detected as Flashing <_< It seems to be the only program that does this too.

Update:

I'm finding the info I need for the Taskbar Buttons. I'll post my findings here.

Edited by JohnBailey

A decision is a powerful thing

Share this post


Link to post
Share on other sites

Although I am still researching Taskbar button manipulation and will post my findings, this is a powerful solution to the problem. If needed I have a working example of stopping a window from flashing. I know others posted methods here, but for some reason this is the ONLY method that works a 100% (so far) of the time especially for the msging app that's been flashing.

http://www.autoitscript.com/forum/index.php?showtopic=56536

Stay tuned <_<


A decision is a powerful thing

Share this post


Link to post
Share on other sites

Yea... I was going to dig up this topic and post the link to that hooker topic, but then opted for taking a nap instead... <_< Good that you found it and it works for you.

Manipulating taskbar buttons is pretty easy with Auto3Lib's Toolbar wrappers.


"be smart, drink your wine"

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0