Close Message With No Title

Started by Jeremy Whilde, November 04, 2015, 07:45:37 AM

Previous topic - Next topic

Jeremy Whilde

I need to monitor for and close a specific message if it appears, problem is the window for the message has no title text.

I ran up RoboScripter and also a few other windows detective type apps to see what was visible but only seems to be the Class of the main container of the message window.

I have managed to close the window like this:

AddExtender("wwctl44i.dll")
sMyText = ""
window1=cWndByWndSpec("#32770","ActSage",2,2,65535)
;Message("Handle", window1)
ControlHandle=cWndByID(window1,65535)
;Message("ControlHandle", ControlHandle)
;sMyText = cgetedittext(ControlHandle)
;Message("Text", sMyText)
cSetFocus(ControlHandle)
SendKey("!+{F4}")   ; Close message


Now the first problem is how to monitor in the background for this window. If I either just fire this code and leave it to wait for the message window or put it in a while loop it will sit using 25% CPU because it does not get passed the Window1 line, I guess the ActSage module only runs when the error message is created.

Can anyone think if there is any way to wait for some indication the message has been displayed? It has no title text it does have a class "#32770" unfortunately this is not unique and is used by other apps such as RoboScripter as an example.

There is some text in the message window  but this is in a child control which although can be targeted does not really help as to get this you still need to look for the parent message container window, which only seems to exist when the message is created so the above problem still exists.

The second issue is the main application ACT! that hosts this message is produced now by a new manufacturer "SwiftPage" so using window1=cWndByWndSpec("#32770","ActSage",2,2,65535) is almost certainly going to fail on the SwiftCall version or Act! as opposed to Sage ACT!

Have attached data file on the message window I am trying to manage.

Any ideas?

Thanks JW

td

One common approach to this problem is a while loop with a TimeDelay.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Jeremy Whilde

Tony

I cannot use a while loop as the script does not get past the line window1=cWndByWndSpec("#32770","ActSage",2,2,65535) and this is the only way I have been able to detect the presence of the message window. Like I said I guess the ActSage module only runs when the message that I need to close is displayed. The issue is how do I find/use an alternative to the following:

window1=cWndByWndSpec("#32770","ActSage",2,2,65535)
ControlHandle=cWndByID(window1,65535)

As this just sit's using 25% cpu until the error message is displayed. So it stops on the first line so a while loop cannot be used. The issue is how to detect the message window some other way? See the original post and attached file.

Thanks JW

td

You can still use a while loop.  You just need to trap the error using the ErrorMode and LastError functions.  You either pause the script with a call to TimeDelay and retry or continue processing based on the error state.  The cWndByWndSpec function itself retries many times but it pauses for a brief period between each attempt to give up CPU time to other processes.

There are other more convoluted ways to accomplish what your script is attempting to do but you should probably give the above a shot first as it is the simplest to implement.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Actually, you don't even need to use ErrorMode.  cWndByWndSpec does not error if the window can't be found so all you need to do is check the return value.  When it's 0 you know the window isn't present and you will know to call TimeDelay before trying again.

Also note that cWndByWndSpec uses minimal CPU (less than maybe 12% on most systems) before quickly returning with either a handle or zero.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

Since you know your error dialogue's module name and assuming that module is an exe that only exists when your dialog is displaying, you can also use the AppExist function with the flag parameter to 1. Your script would only call cWndByWndSpec when AppExist returned @True.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

Jeremy Whilde

Tony

OK thanks for the explanations but as I indicated originally there is some sort of issue or problem at the window1 line maybe some issue with cWndByWndSpec. I too would expect this to returns zero (0), if the specified window is not found, so something like the following should and does work for Notepad:

AddExtender("wwctl44i.dll")
sMyText = ""
While @True
   If IsKeyDown(@Shift) then break   
   window1=cWndByWndSpec("Notepad","notepad",2,15,1025)
   If Window1 <> 0
      cSetFocus(window1)
      SendKey("!+{F4}")
   Endif
   TimeDelay(1)   
EndWhile
Exit


However the version below for the window I need to manage does not work, the script is stuck at the window1 line taking 25% CPU!

AddExtender("wwctl44i.dll")
sMyText = ""
While @True
   If IsKeyDown(@Shift) then break   
   window1=cWndByWndSpec("#32770","ActSage",2,2,65535)
   If Window1 <> 0
      ControlHandle=cWndByID(window1,65535)
      cSetFocus(ControlHandle)
      SendKey("!+{F4}")
      ;Sendkeysto("Lookup Contacts", "!+{F4}")
   Endif
   TimeDelay(1)   
EndWhile

Any further ideas?

Thanks JW

Jeremy Whilde

I would also add that although the script stops at the cWndByWndSpec if the target window does appear the rest of the script runs OK.

Thanks JW

td

Your script should not hang on  cWndByWndSpec .  It will process for some time because the class you are looking for can have a lot of instances.  This is because you likely have a lot of control bar popup  windows that use the same dialogue class which is common.    As to the CPU usage, I can't get anywhere new that value on any system I tested on which all have quad core CPUs.  I can only assume you have a slower and/or older system.  You may also have corrupt performance counters that is causing your system to hang but that usually (not always) causes the function to error.

That said, I think the cWndByWndSpec function could use a few enhancements to make it a little more flexible.

The process of window identification can sometimes also be accomplished using dotNet classes with WinBatch CLR hosting.   However, it can be a bit of a bear to write only to find out that the Windows involved do not support the required interfaces.

If your dialogue is running in it's own thread or process, you could also consider writing a script to just find and the killing that process or thread.

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

td

The Control Manger extender has been updated with the new cSetWndSpecRetry function.  The cSetWndSpecRetry function gives you more control over the behavior of the cGetWndByWndSpec and cWndByWndSpecName  functions. 

"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade