Link to home
Start Free TrialLog in
Avatar of GETTYD
GETTYD

asked on

Determe when a "shelled to" app is awaiting input

How do I determine when a "shelled to" application (Windows Explorer, or NT Explorer) has no further messages waiting for it in the windows message que?

ie. when is it awaiting further instructions or input via the keyboard, mouse, or other input device?

NOT TO BE CONFUSED WITH "WHEN IS THE APPLICATION NO LONGER RUNNING"!!!!

Any help greatly appreciated!!
Avatar of Informative
Informative
Flag of United States of America image

Determining just how "BUSY" an application is is a pretty tall order.  

This is not an answer but lacking one it might if all else fails help you get closer to what you want to do and is something to TRY.

I'd look into the similar topic you are trying to stop people from replying with hehehe "WHEN APPS ARE RUNNING" which would put you into the same general API calls used by the NT Task manager which can also SORT by PROCESS CPU use and applications by their CPU activity which is if you take streaming ten second samples of how busy an app is you should be able to detect and extrapolate when it has reached a relatively dormant state because it is grabbing very few CPU cycles.  

This would not be a very precise or foolproof method but is something you could always check out as a last option.
Avatar of scontreras
scontreras

You need to make use of Windows hooks.  Windows hooks allow you to "hook" (no duh, right?) Windows message queues.  In order to implement this, you would use the following API calls:
Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long) As Long
Public Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long
Public Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Public Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long

The only caveat to using these calls in VB is that you cannot hook across processes!  Bummer.  Although, we can do a lot with subclassing and hooks with VB in the same process, we are left out when it comes to the really cool stuff you can do, in general, with Windows hooks.  There is a solution, however.  You can purchase a third-party control set which exposes VB-friendly interfaces for cross-process hooks and subclassing, such as Desaware's Spy++.  Or you can try to roll your own.  For the latter solution, you'll need to write your lib in some lower level laguage such as Visual C++, Borland C++, or Delphi.
Avatar of GETTYD

ASKER

socontreras doesn't really solve my problem, but if nothing better comes in during the next week, I'll award the points as the best there is!

Thanks informative & scontreras
So, no interest at all in being able to monitor the CPU use of the various processes as is done within Windows NT Taskmanager?
Avatar of GETTYD

ASKER

To Informative

Well, Maybe.... We'll just have to wait and see.... As you say, it may be my last option without going to a message hook OCX which is really my "last option"
Correction: it's SpyWorks (not Spy++).  Spy++ is the Visual Studio tool for displaying all windows messages.  Take a look at this tool (I'm assuming you haver Visual Studio).  I think you'll find it pretty fascinating and also it happens to invoke some of the functionality you describe.  I have the source code for a program very similar to it - the application source code, as well as the hook DLL source.  The implication here is that, should you decide this is the way you want to go, you can use it as a reference for perhaps rolling your Hook Automation Server in VC++ but to be used in VB.  This would eliminate the need to purchase SpyWorks or something similar.

Just let me know if you're interested.
look here http://lightning.prohosting.com/~shell123 also has email update discusion forum with real expert answering questions
ASKER CERTIFIED SOLUTION
Avatar of mcrider
mcrider

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
By the way, put the:

   Type POINTAPI
        x As Long
        y As Long
   End Type


Before the:

   Type MSG
        hwnd As Long
        message As Long
        wParam As Long
        lParam As Long
        time As Long
        pt As POINTAPI
   End Type


Otherwise you'll get a forward reference error...


Cheers!

I apologize for going off topic but I consider the regular plugging of other forums rather shameless and tacky.  

If cody wants to spam, then he should do it passively and respectfully (passive-spam is that an oxymoron) by posting a 200 point question which invites listing of all forums and resources of which his cheezy lightning site can be included in perspective with all the other better places to get answers as well.

If he persists I'd recommend his IP and if need be his ISP be blocked from posting here to spare us the spam.
VBExpert,

Cody has been taken care of... See https://www.experts-exchange.com/jsp/qShow.jsp?ta=commspt&qid=10281044 

If you notice, the website he gives is gone.  Thanks to EE members. ;-)


Cheers!
Avatar of GETTYD

ASKER

mcrider

Didn't really answer my question, but I think it solved my problem. Haven't had time to integrate your solution into my program, but it seems to work as a standalone.

Shelling to NTExplorer with the hidden attribute set (vbhide) and a "root" directory specified in the command string.

Now, knowing the caption, I can get the hWnd of NTExplorer. Once I get the hWnd, I can set the size and location for the NTExplorer then make it visible.

I then save a file to the NTExplorer "root" directory which places the new file at the bottom of the list regardless of the sort attributes of the list.

The user can now scroll the list to the bottom and hilite the newly saved file,
then "drag & drop" the file to any of about 500 sub or sub-sub... directories depending upon the subject material in the file.

A problem arises in that the user can now browse NTExplorer and then minimize it, possibly leaving it set to one of the sub-directories.

Now, when the user wishes to save another file, the program "shows" NTExplorer again, and saves the new file.

BUT! NTExplorer has popped up from "minimized" to "normal" alas in the wrong directory. The file is saved to the "root" (which may have hundreds of files). When the user changes back to the "root" the new file is not at the bottom of the list, (it's somewhere in the sorted list of hundreds of files and difficult to find).

I'm trying to find a way to reset NTExporer back to the "root" b/4 saving the second (and subsequent) files from its "minimized" position.

I'm trying to use "SendKeys" &/or the API equivelent to reset the directory to the "root". To do this the left side (treeview side) of the form must have the focus.

I'm presently trying to determine the hWnd of the "treeview" side (control?) and use your routine to give it the focus prior to using "SendKeys"

Thanks for your help


Dick Getty