I must say I was surprised when I couldn't find any posts similar to this (I think the question was answered but no solution). I would be keen to get this up nad running as
others may benifit too.
Thanks for your inputs on this Joacim, I appreciate it .
Through sheer determination I revisited the above APIs' - SUCCESS!
In short, and NO Sub-Classing, I used:
SetForeGroundWindow(myApps hWnd)
GetNextWindow(myApps hWnd, GW_HWNDNEXT)
SetForeGroundWindow(retval of GetNextWindow)
Viola....
Clicking the SysTray Icon takes the focus, SetForegroundWindow ensures myApp is ready for GetNext,
then capture the Next hWnd,
Now set the focus back to the losing apps Window......
I will post the entire app in the .Net Forum once done.
I want to keep this un-resolved, as I would like feedback on a Global (Sub-Classed) method
using the WM_ACTIVEAPP as M$ states it should work.
At this stage many, many thanks to Joacim for his persistance
I've been playing with this code under VB6 for a while. The method as spelled out in the .Net forum doesn't work in VB6 since the "Next Window" is not the one we are looking for. I find that I have to first iterate through all the "tooltips_class32" windows first.
In addition, once we find the top level window we can't just send a WM_COPY message to that window since we really want the Textbox child of that window. I've been testing on Notepad and EditPadPro. Here is what I've found works so far.
Like you, I didn't get the WM_APPACTIVATE code to work, but I think I can so I'll keep working on it.
Also I never liked the Word dialog box so I'll adapt my spellchecker to this code. It is in my "RichtextBox Tricks and Tips" thread. That code brings up a context menu with spelling suggestions rather than that ugly Word Box.
Another thought I had was instead of using a task tray icon to activate we could install a global keyboard hook and look for a hot-key. This way we would already have the handle to the edit window.
@moeur, even though I really like the way you where thinking in the above solotion there is a huge problem in that logic... The problem itself is well known, using GetWindow in a loop can freeze your app if a user happens to close a window while the loop is running... Even the MSDN Library tells you to not use this approach (and I'm quoting)
An application that calls GetWindow to perform this task [read EnumWindows] (in a loop) risks being caught in an infinite loop or referencing a handle to a window that has been destroyed.
It's simple enough to put a counter in the loop that exits the loop on too many iterations. In either case you have to work through the windows to get to the one you want.
All I'm saying ís that you should use EnumWindows instead. You can apply your logic in the callback procedure just as well... Please remember: I liked your logic
Some more comments on this:
WM_APPACTIVATE is not going to work for the task tray icon method because what you'd have to subclass would be the tray.
The method I posted above is still kind of flaky since sometimes there are other windows besides tooltips_class32 windows between your window and the previous window. For instance I've seen a window with a class name "WorkerW".
This method also does not work for things like the VBForums edit box.
I have come up with a robust solution to this problem.
Whenever a top-level window is activated, a global message is sent that can be trapped with a global WH_SHELL hook. If we keep track of which program was activated last, then when our icon is clicked, we have all the info we need.
Instead of having to set a global WH_SHELL hook (which would require C++) we can instead use an API function that Penagate mentioned in another thread called RegisterShellHookWindow. This function directs all shell messages to our window procedure so we just have to subclass our own window.
To set up this functionality, you do something like this
In this code, I use my subclasser class (clsSubClass) and taskicon OCX control (NotifyIcon) but you can do it any way you would like. Once this is done we will receive the shell messages in our window procedure.
What we want to do is keep track of the last window that was activated, so in the window procedure
Now the only thing left to do is allow the user to start the spell checking by left clicking on the system tray icon that we added. In this code I call a CheckSpelling function that checks the spelling of the text on the clipboard and returns the corrected results to the clipboard.
ok so if u have the text that u need to copy allready selected u can copy it to clipboard with sendkeys.send("{^c}') then u can retrieve it with clipboard.gettext how this is what you are looking for