|
-
Sep 11th, 2005, 05:49 PM
#1
Global Hook
Hi All,
How can I return the selected (highlighted) word/text from any given application?
Eg. I select a word in Excel (or Outlook, Access, Visio etc) and upon a click of a Button, I MsgBox the word.
I'm gussing a global (system wide) hook of some kind.
Cheers.
-
Sep 11th, 2005, 06:16 PM
#2
Re: Global Hook
Hmmmm... If I understand your question correctly you work in one application and select something in that and then you want to click a button in another app and that should know what you have selected in the app you worked in just before you clicked the button... Is this correct?
-
Sep 11th, 2005, 06:22 PM
#3
Re: Global Hook
You can set up OLE to connect two apps.
I have a sample that I can post.
-
Sep 11th, 2005, 07:03 PM
#4
-
Sep 11th, 2005, 07:16 PM
#5
Re: Global Hook
Well, nothing is impossible but there are a few things that are very hard to do. Just think about it.... Let's say I have made a little application that has 3 text boxes and a treeview and also a listview (or whatever). Now I've set the HideSelection property to false on all of these controls which means you can select text in 3 different textboxes one treeview and in one listview. Now I click on your icon in the Systray and I want it to return what ever I've selected in my program.... Which is 5 different things.... So your app should return what????
-
Sep 11th, 2005, 07:27 PM
#6
Re: Global Hook
Point taken.
I can work on that. The trouble is getting just anything returned.
-
Sep 11th, 2005, 07:32 PM
#7
Re: Global Hook
For what its worth, its a Spell Checker that runs in the SysTray.
I can select a word that I suspect is wrong, currently by copying it to the ClipBoard and dbl click my Icon (in the SysTray), the word is checked against M$Word SpellChecker().
The corrected word (if relavent) is then placed onto the ClipBoard for insertion.
This is all up and running quite well. I just wanted to go one step further, and cut out the inital manual copy step. Therefore, select the suspect word, have the Spell Check check the slected word....
-
Sep 12th, 2005, 06:42 AM
#8
Re: Global Hook
This might be a bit hard to figure out. You could try to monitor which window and control currently has focus and when your icon is clicked send WM_COPY to that window. However all applications you might be able to copy text from doesn't respond to the WM_COPY message, but many does. All edit fields and combo boxes react on this message.
-
Sep 12th, 2005, 07:15 AM
#9
Re: Global Hook
To find out what window has the cursor / focus in it use GetGUIThreadInfo API.
-
Sep 12th, 2005, 10:36 PM
#10
Re: Global Hook
Thanks Guys.
@ Merrion, I'm checking that out
-
Sep 14th, 2005, 10:27 PM
#11
Re: Global Hook
Unfortunatly, when you click the SysTray, the (current) App losses focus (being the selected text).
However, when you give focus back to the App, the (previously) selected text is re-shown slected. That said, Windows therefore must know (all the time) what text IS selected (whether the App has the focus or not).
Is there a way then to query 'Windows' for the given App (passing the the Handle of the App in question)?
Cheers.
-
Sep 15th, 2005, 03:00 AM
#12
Re: Global Hook
When an application gains focus it gets a wm_activateapp message.
In this message the wParam is the thread handle of the application that is losing the focus. Pass this handle to GetGUIThreadInfo and you can find out which window in the application that just lost the focus was the one with the input focus.
-
Sep 18th, 2005, 03:56 PM
#13
Re: Global Hook
Thanks Merrion 
Ok, what I will attempt to do is capture the losing focus app's HWnd, re-focus to that app, (hopefully the selected text will now be re-selected (since getting back the focus))
then use WM_COPY.....
-
Sep 18th, 2005, 05:46 PM
#14
Re: Global Hook
Ok, To begin (intercepting the WM_ACTIVEAPP message) I'm using the following to no avail. The wParam is either a 0 or 1 depending on whether my App has the focus or not:
VB Code:
Option Explicit
'Module
Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long
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 Const WM_ACTIVATEAPP = &H1C
Public Const GWL_WNDPROC = (-4)
Dim PrevProc As Long
Public Sub HookForm(frmObj As Form)
PrevProc = SetWindowLong(frmObj.hwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub
Public Sub UnHookForm(F As Form)
SetWindowLong F.hwnd, GWL_WNDPROC, PrevProc
End Sub
Public Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
WindowProc = CallWindowProc(PrevProc, hwnd, uMsg, wParam, lParam)
If uMsg = WM_ACTIVATEAPP Then
Form1.Caption = wParam
End If
End Function
VB Code:
Option Explicit
'Form1
Private Sub Form_Load()
HookForm Me
End Sub
Private Sub Form_Unload(Cancel As Integer)
UnHookForm Me
End Sub
-
Sep 18th, 2005, 05:58 PM
#15
-
Sep 18th, 2005, 06:03 PM
#16
Re: Global Hook
Yeah, that's because the wParam contains the activation flag (was your application, or rather your window activated or not) while the lParam contains the the thread ID of the application that lost the activtion, or gained the activation, depending on the value you've got in the wParam parameter.
-
Sep 18th, 2005, 06:17 PM
#17
Re: Global Hook
Hi Manavo11, unfortunatly I wouldn't know what will be the active window (as it could be many)
Joacim, Hi, I tried getting the Thread ID using the lParam, but it is the same for all apps ecept mine. I think I'm using the Sub-Class correct - does it work for you?
Cheers,
-
Sep 18th, 2005, 06:28 PM
#18
Re: Global Hook
The problem might be that when the user clicks on your icon in the system tray, the lParam will show the thread that had the focus before which in this case would have been the taskbar itself....
-
Sep 18th, 2005, 06:35 PM
#19
Re: Global Hook
At this stage I am still testing in the IDE, no SysTray icon at this stage. I working on the assumption from Merrion's post that when my app recieves the focus, I can check for the Hwnd that had the focus. I guess that by intercepting the WMessage (when my app gets the foocus), that I can check on of the params, in particular the param that has the leaving apps Hwnd....
Cheers,
-
Sep 18th, 2005, 07:03 PM
#20
Re: Global Hook
OK, when you subclass your Form and check for the WM_ACTIVATEAPP message you will get that every time your Form either lose or gain focus from another thread. So this will sort of work like the GotFocus event for a Form with the difference that the message is sent when your Form gain or lose focus from another application. So the wParam argument will tell you if your Form has gained or lost focus to another thread. While lParam will tell you the the thread ID that lost or gained focus.
The problem here is that lParam is the thread ID and not the hWnd of the app that lost/gained focus.
-
Sep 18th, 2005, 07:11 PM
#21
Frenzied Member
Re: Global Hook
very intersting question, since i am using my bro user for few question i know that my brother had worked with Babylon.
Babylon is a Dictionary you underlin the word on and app and click on the the wheel button on your mouse and the app will that the word and give you definition. if this thread had not been solved untill my bro comes i can ask him for help
-
Sep 18th, 2005, 07:46 PM
#22
Re: Global Hook
 Originally Posted by Joacim Andersson
The problem here is that lParam is the thread ID and not the hWnd of the app that lost/gained focus.
Concur. The problem was I wasn't seeing the reulst until I gave the focus to my App, then minimised it - then the ID changed based on the App that had the focus.
Testing to see if the ID's are relavent when my app gets the focus.
-
Sep 18th, 2005, 07:57 PM
#23
Re: Global Hook
Ok, further to my last; why I see the (correct TreadID) result when I minimise, is that once I minimise, the previous app gets back the focus hence the lParam change. This dosn't work
when my app gets the focus, as it is the current tread.
I have unsuccessfully tried different WM_ constants in order to capture the losing focus app ID once my Apps sub-class is envoked.
-
Sep 19th, 2005, 03:45 PM
#24
Re: Global Hook
*bump*
-
Sep 19th, 2005, 04:08 PM
#25
Re: Global Hook
When your app regains focus you should get the thread id from the application that lost focus... at least that is what the MSDN Library states. Maybe you need to subclass the ThunderRT6Main window (this window is called ThunderMain when you run the app from the IDE) instead of your Form. VB creates this window as the parent for all other windows in your application. It's not visible but gains the messages before your Form does. You can get the handle to this window via a call to GetWindow, just pass the hWnd of your Form and the GW_OWNER relationship flag.
-
Sep 19th, 2005, 04:17 PM
#26
Re: Global Hook
G'Day Joacim 
I to thought I could get the ThreadID when my app gets the Focus of the losing apps.
The only way I could get that to work was when I minimised my app - it seems that
the ID was received when the focus was going back to the original losing app....
That said, I't dosn't help with my goal as I need the losing apps ID when mine gets the focus (as your aware).
I will try a demo with regard to the VB's ThunderRT6Main. 
Thanks again,
-
Sep 19th, 2005, 04:37 PM
#27
Re: Global Hook
Bugger! Yeilds the same result (works only when you minimise).
-
Sep 19th, 2005, 04:57 PM
#28
Re: Global Hook
This is from MSDN:
WM_ACTIVATEAPP Notification
--------------------------------------------------------------------------------
The WM_ACTIVATEAPP message is sent when a window belonging to a different application than the active window is about to be activated. The message is sent to the application whose window is being activated and to the application whose window is being deactivated.
A window receives this message through its WindowProc function.
Syntax
WM_ACTIVATEAPP
WPARAM wParam
LPARAM lParam;
Parameters
wParam
Specifies whether the window is being activated or deactivated. This parameter is TRUE if the window is being activated; it is FALSE if the window is being deactivated.
lParam
Specifies a thread identifier (a DWORD). If the wParam parameter is TRUE, lParam is the identifier of the thread that owns the window being deactivated. If wParam is FALSE, lParam is the identifier of the thread that owns the window being activated.
Return Value
If an application processes this message, it should return zero.
Notification Requirements
Minimum DLL Version None
Header Declared in Winuser.h, include Windows.h
Minimum operating systems Windows 95, Windows NT 3.1
See Also
Windows Overview, WM_ACTIVATE
Should work..........................
-
Sep 19th, 2005, 05:14 PM
#29
Re: Global Hook
Why not try something simplier... Like using SendKeys "%{tab}" (Alt+Tab) to set focus back to the previous application?
-
Sep 19th, 2005, 05:17 PM
#30
Re: Global Hook
hehe, just wanted to avoid any SendKey issues 
(But, I'm knocking it up now)
-
Sep 19th, 2005, 05:31 PM
#31
Re: Global Hook
Oh bloody hell. SendKeys dosn't want to work from a SysTray Icon (in VB.Net), from a Form Click it's fine (both VB6 and .Net)
-
Sep 19th, 2005, 05:35 PM
#32
Re: Global Hook
Oh yes it will work if you first makes sure you call SetForegroundWindow and pass the hWnd of your Form (even if it isn't visible).
-
Sep 19th, 2005, 05:39 PM
#33
Re: Global Hook
Okey dokey... trying now
-
Sep 19th, 2005, 06:39 PM
#34
Re: Global Hook
[crying] Its a catch 22. If I use SendKeys, I must use SetForgroundWindow - then I cant copy the text using SedKeys my app nolonger has the Focus. So, I tried to use GetActiveWindow to be used with say SendMessage (for a Copy), but that too wont work
as my app has the ActiveWindow due to SetForground........ waaahhhhhhh[/still crying - pulling hair]
-
Sep 20th, 2005, 03:52 PM
#35
-
Sep 20th, 2005, 04:03 PM
#36
Re: Global Hook
I've actually lost you Bruce... If you've sent Alt+Tab the previous window will have focus so just try to send WM_COPY to the active window and check if the clipboard content changed. If so bring up your window and do your magic....
-
Sep 20th, 2005, 04:12 PM
#37
Re: Global Hook
Hi Joacim,
The GetActiveWindow didn't work post SetForgroundWindow. However, I didn't test WM_COPY - will try.
-
Sep 20th, 2005, 04:21 PM
#38
Re: Global Hook
What I meant is that after you have made a call to GetActiveWindow you should be able to send Alt+Tab. GetActiveWindow will only work if you own the thread of the active window, and since you've alt+tabbed to another process it should fail. If you want the handle of the active window that belongs to another thread you should use GetForegroundWindow instead.
-
Sep 20th, 2005, 04:30 PM
#39
Re: Global Hook
Understood
-
Sep 20th, 2005, 04:34 PM
#40
Re: Global Hook
But as merrion pointed out you should use the GetGUIThreadInfo API function to get the handle of the control owning the user input...
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|