|
-
Feb 22nd, 2010, 10:40 PM
#1
Thread Starter
Lively Member
Save to and replay from function keys? (Macro)
How can I make it so when I type something into a text box and click save, it will put the text into one of the function keys at the top row of my keyboard and then be able to push that key to automatically type whatever I saved?
-
Feb 22nd, 2010, 11:05 PM
#2
Frenzied Member
Re: Save to and replay from function keys? (Macro)
If this is within your program, you can create a menu item, or several menu items and assign the keyboard shortcuts to those menu items, the somevariable = text1.text...
Good Luck
Option Explicit should not be an Option!
-
Feb 23rd, 2010, 05:46 PM
#3
Thread Starter
Lively Member
Re: Save to and replay from function keys? (Macro)
Could you better explain that please?
-
Feb 23rd, 2010, 07:48 PM
#4
Re: Save to and replay from function keys? (Macro)
One of the questions asked, which would better focus the replies... Will this functionality just be used in your application or is it suppose to work on any window/application that has the focus?
-
Feb 23rd, 2010, 07:52 PM
#5
Thread Starter
Lively Member
Re: Save to and replay from function keys? (Macro)
It's supposed to work in any application. The user will type anything into a text box and check a box if they want it enabled, then save the settings. After saving, the user will be able to press the corresponding function key (F1-F11) and whatever they typed will be automatically typed out for them.
I managed to find out how to assign functions to the F keys, but I still have some problems.
1) I can't manage to print the text in the specified text box into the currently selected text area in the current open program.
2) When I press the desired F key, the original function still performs. (Example: I press F10 to print "test10", but it still highlights the top menu (File, Edit, ect.)
3) I can't figure out how to type out the text. Right now, all I have is "Print text10.text" and it prints "test10" on the background of my application in a single column. How can I get it to actually type out into a text box?
I have some more problems. Within this application, I give the user two check boxes for options. The first is whether or not the F key is being overridden. The second is to include the enter key. If the auto-enter box isn't checked, I want it to just type out the text as if the user did. If it is checked, I want it to type out the text and emulate a press of the enter key. How might this be accomplished?
The current code I have for each F key is as follows:
Code:
If Check19.Value = 1 Then 'If checked
If KeyCode = vbKeyF10 Then 'If F10 is pressed
Print Text10.Text 'Print what is in #10 text box
End If
End If
Last edited by cs475x; Feb 23rd, 2010 at 08:33 PM.
-
Feb 23rd, 2010, 08:45 PM
#6
Re: Save to and replay from function keys? (Macro)
Well, here's an idea.
1. Use RegisterHotKey (examples exist on this forum) to assign hotkey(s) to your application.
2. When the hotkey is pressed, you can try sending the text one of several ways
:: SendKeys - not recommended
:: SendInput - last resort in this case
:: SendMessage with WM_SetText - preferred if it works well
:: SetWindowText - basically calls SendMessage; so if one works the other may as well
For the last two options above, you will need an hWnd...
Here is how you might get the active window when your hotkey is received. There's a nice api to use called GetFocus but it only works for the thread that calls the API. There's also a neat hack by attaching one thread to another process' thread; thereby allowing GetFocus to return the child window in the foreground window that has the focus. It's just a tad complicated, so I've included it below.
Call GetTargetHwnd() function to return the actual window handle that has the current keyboard focus.
Code:
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function AttachThreadInput Lib "user32.dll" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function GetFocusAPI Lib "user32.dll" Alias "GetFocus" () As Long
Private Function GetTargetHwnd() As Long
Dim tgtParent As Long
Dim tgtThread As Long
Dim myThread As Long
tgtParent = GetForegroundWindow()
myThread = App.ThreadID()
tgtThread = GetWindowThreadProcessId(tgtParent, ByVal 0&)
If myThread <> tgtThread Then
AttachThreadInput myThread, tgtThread, 1& ' join threads
End If
GetTargetHwnd = GetFocusAPI
If myThread <> tgtThread Then
AttachThreadInput myThread, tgtThread, 0& ' release
End If
End Function
-
Feb 23rd, 2010, 09:09 PM
#7
Re: Save to and replay from function keys? (Macro)
 Originally Posted by cs475x
It's supposed to work in any application. The user will type anything into a text box and check a box if they want it enabled, then save the settings. After saving, the user will be able to press the corresponding function key (F1-F11) and whatever they typed will be automatically typed out for them.
See my previous reply too. Your trapping of function keys won't work if another application has the focus; so if this is to be system-wide, foreget about using KeyPress and KeyDown events.
 Originally Posted by cs475x
I managed to find out how to assign functions to the F keys, but I still have some problems.
1) I can't manage to print the text in the specified text box into the currently selected text area in the current open program.
2) When I press the desired F key, the original function still performs. (Example: I press F10 to print "test10", but it still highlights the top menu (File, Edit, ect.)
3) I can't figure out how to type out the text. Right now, all I have is "Print text10.text" and it prints "test10" on the background of my application in a single column. How can I get it to actually type out into a text box?
1) For your application: Text1.Text = MacroText
2) In the keydown event, remember to set the KeyCode to 0 to stop its functionality. If F10 still activates the menubar, the ReigsterHotKey or a keyboard hook should prevent that
3) Print is wrong. You don't use Print to assign values to a property. Print is used to draw text to a DC or file.
-
Feb 23rd, 2010, 09:19 PM
#8
Thread Starter
Lively Member
Re: Save to and replay from function keys? (Macro)
I have no idea how exactly to setup the registerhotkey to be honest.
Could you or someone else provide me the code needed to display the text of text1.text when F1 is pressed, text2.text when F2 is pressed and so on up until F11? I have been working on this for about 2 days now with a cold and I think I just used up all my brain power for the day...
-
Feb 23rd, 2010, 09:25 PM
#9
Re: Save to and replay from function keys? (Macro)
Untested, I'll leave that to you.
1. Ensure form's KeyPreview is set to True
2. Sample, untested code
Code:
Private Sub Form_KeyDown(KeyCode As Integer, Shift As Integer)
Select Case KeyCode
Case vbKeyF1 to vbKeyF11
' vbKeyF1 = 112, so simple math to get 112 = 1: KeyCode-111 = textbox number
YourTargetTextBox.Text = Me.Controls("Text" & CStr(KeyCode - 111)).Text
KeyCode = 0
End Select
End Sub
I am not going to give you the HotKey code, it is readily available on this forum and a simple search will pull up very good examples that you can simply copy & paste and use with little to no modifications.
P.S. That Me.Controls(....) line would be unnecessary if your 11 textboxes were arrayed/indexed, i..e, Text1(1), Text1(2), Text1(3), etc.
And again, this is a waste of time in my opinion if you are going to try to set this up to work system-wide. You will not be trapping keystrokes in your application if someone is using FireFox for example.
Edited: ^^ should have read: ... You will not be trapping keystrokes with Form/Control's KeyDown events in your application....
Oh, and I don't intentionally mean to sound rash/harsh; just an attempt to have you step back a moment and really think about what the goals are for this project of yours and whether or not they should be modified. It sounds like you don't have much experience and jumping into APIs may be a bit premature. SendKeys may work and requires no APIs, but RegisterHotKey is something I think you will need if you want your macro to be system-wide. I and many others would rather suggest to a newbie vs. doing the work for them (i.e., the statement about not giving you the hotkey code).
Last edited by LaVolpe; Feb 23rd, 2010 at 09:50 PM.
-
Feb 23rd, 2010, 09:52 PM
#10
Thread Starter
Lively Member
Re: Save to and replay from function keys? (Macro)
I used the code provided here, but it still only types out each textbox in the program, not in another program such as Notepad.
-
Feb 23rd, 2010, 10:11 PM
#11
Re: Save to and replay from function keys? (Macro)
That's because that post did not intend to send text to another application, it was intended to trap F1 in his own application among multiple forms.
In post #6 above I gave you the code you would need to determine which window has the keyboard focus. Only one window at a time can have the focus. So if someone is typing in NotePad, your app does not have the focus. If someone while in NotePad presses F2, your app won't know about it because your app does not have the focus.
By using hot keys, your app will be informed when that key is pressed. And once you are informed, you can determine which window has the focus and attempt to set the text.
Now there are some problems you will have to overcome and this is not what I would call a project for a beginner. It may prove difficult for you, but if you figure it out and do most of the work yourself, you will have learned quite a bit.
1. SendMessage using WM_SetText or using SetWindowText APIs replaces the text in the target window, it doesn't append
2. Using VB's SendKeys or SendInput API will send literal keystrokes, but both APIs are dumb, they do not target a specific window. If user changes focus to another app or another window while the keystrokes are being sent, those strokes are sent to the new focused window.
3. Using SendMessage with the WM_PASTE message could be a better choice overall. However, not all windows will process that message. Of course, you'd have to set text in the clipboard first.
4. RegisterHotKey per msdn documentation does not allow you to use a single key as a hotkey/macro. Read the documentation.
5. A global keyboard hook could resolve the single key issue, but I personally don't offer assistance with global hooks due to the high probability of their misuse/malicious use by others.
Last edited by LaVolpe; Feb 23rd, 2010 at 10:26 PM.
Reason: meant Post #6 vs #2 in 2nd para
-
Feb 23rd, 2010, 10:32 PM
#12
Re: Save to and replay from function keys? (Macro)
Here's a really short example, combining code from post #6 above and thoughts from previous post.
Note. Just an example for proof of concept. There is no hot key code. A timer is used to simulate receipt of a hot key.
1. In a new project, add a form with these controls. Use their default properties; don't change them.
Timer, command button
2. Copy and paste this code into the form
Code:
Option Explicit
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function AttachThreadInput Lib "user32.dll" (ByVal idAttach As Long, ByVal idAttachTo As Long, ByVal fAttach As Long) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function GetFocusAPI Lib "user32.dll" Alias "GetFocus" () As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const WM_PASTE As Long = &H302
Private Function GetTargetHwnd() As Long
Dim tgtParent As Long
Dim tgtThread As Long
Dim myThread As Long
tgtParent = GetForegroundWindow()
myThread = App.ThreadID()
tgtThread = GetWindowThreadProcessId(tgtParent, ByVal 0&)
If myThread <> tgtThread Then
AttachThreadInput myThread, tgtThread, 1&
End If
GetTargetHwnd = GetFocusAPI
If myThread <> tgtThread Then
AttachThreadInput myThread, tgtThread, 0&
End If
End Function
Private Sub Command1_Click()
Timer1.Interval = 5000
Timer1.Enabled = True
End Sub
Private Sub Timer1_Timer()
Timer1.Enabled = False
Clipboard.Clear
Clipboard.SetText "Hello World"
SendMessage GetTargetHwnd(), WM_PASTE, 0&, ByVal 0&
MsgBox "Sent the text"
End Sub
3. Now open notepad, place your cursor in it some where
4. Open the vb project and run it
5. Press the command button, then within 5 seconds, click on the notepad window so it has focus.
6. When the 5 seconds are up, the text will be pasted into notepad
Edited: Try it with other applications too. Again, WM_Paste may not be processed by all windows.
Last edited by LaVolpe; Feb 23rd, 2010 at 10:36 PM.
-
Feb 23rd, 2010, 11:35 PM
#13
Re: Save to and replay from function keys? (Macro)
Using the clipboard is as fast and safe, to have some fun, another method using WM_CHAR
put a textbox on a form, run it, we focus on a window, notepad, word, or any html editor and then press f10
Code:
Option Explicit
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type GUITHREADINFO
cbSize As Long
flags As Long
hwndActive As Long
hwndFocus As Long
hwndCapture As Long
hwndMenuOwner As Long
hwndMoveSize As Long
hwndCaret As Long
rcCaret As RECT
End Type
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type Msg
hwnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As POINTAPI
End Type
Private Declare Function GetGUIThreadInfo Lib "user32.dll" (ByVal idThread As Long, ByRef pgui As GUITHREADINFO) As Long
Private Declare Function GetForegroundWindow Lib "user32.dll" () As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function RegisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long, ByVal fsModifiers As Long, ByVal vk As Long) As Long
Private Declare Function UnregisterHotKey Lib "user32" (ByVal hwnd As Long, ByVal id As Long) As Long
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As Msg, ByVal hwnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Private Declare Function WaitMessage Lib "user32" () As Long
Private Const WM_CHAR As Long = &H102
Private Const WM_HOTKEY As Long = &H312
Private Const PM_REMOVE As Long = &H1
Private bCancel As Boolean
Private Sub ProcessMessages()
Dim Message As Msg
Dim HANDLE As Long
Do While Not bCancel
WaitMessage
If PeekMessage(Message, Me.hwnd, WM_HOTKEY, WM_HOTKEY, PM_REMOVE) Then
HANDLE = GetFocusHandle
If HANDLE <> 0 Then
SetWindowTextEx HANDLE, Text1.Text '<<<<<<<this line put the text in other aplication
End If
End If
DoEvents
Loop
End Sub
Public Function GetFocusHandle() As Long
Dim GTI As GUITHREADINFO
GTI.cbSize = Len(GTI)
GetGUIThreadInfo GetWindowThreadProcessId(GetForegroundWindow, 0), GTI
GetFocusHandle = GTI.hwndFocus
End Function
Private Function SetWindowTextEx(hwnd As Long, Text As String)
Dim i As Integer
Dim Key As Byte
For i = 1 To Len(Text)
Key = Asc(Mid(Text, i, 1))
If Key <> 10 Then
PostMessage hwnd, WM_CHAR, Key, 0&
End If
Next
End Function
Private Sub Command1_Click()
Timer1.Interval = 5000
End Sub
Private Sub Form_Load()
bCancel = False
Call RegisterHotKey(Me.hwnd, &HBFFF&, 0&, vbKeyF10)
Me.Show
ProcessMessages
End Sub
Private Sub Form_Unload(Cancel As Integer)
bCancel = True
Call UnregisterHotKey(Me.hwnd, &HBFFF&)
End Sub
es solo un ejemplo pero es mas conveniente utilizar sublcass para los hotkeys
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
|