[RESOLVED] How can I Run "Copy" Command/Function Outside of Program/Form?-VBForums
Results 1 to 16 of 16

Thread: [RESOLVED] How can I Run "Copy" Command/Function Outside of Program/Form?

  1. #1

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Resolved [RESOLVED] How can I Run "Copy" Command/Function Outside of Program/Form?

    Looking for a way, to run, the equivalent of "Ctrl+C" using my own VB program. Essentially the reason I am doing this is because the program I am trying to write is a converter, and the plan is to have it use "Ctrl+F" instead of "Ctrl+C". It would copy whatever is highlighted, check if it is a number if it is convert it to another number and paste it back to where it was copied from.

    I will figure the rest out later, for now I am just looking for a way to copy selected text using a pre-specified shortcut key combination such as "Ctrl+F" from any window in any program. Heck it can even store the copied text in the regular clipboard, I just don't want to use Ctrl+C to do the copying.

    If I need to explain better please say so, and as always any help, suggestions ideas, links etc is very much appreciated.

    Thanks in advance.

  2. #2
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,192

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    What type of application is the 3rd party program: website, word, other(exe, pdf, etc.)?

  3. #3

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    It can be anything, word, excel, chrome, notepad, pdf etc. I'm thinking the way to do it might be to call the Ctrl+C keyboard combination or emulate it?

  4. #4
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,192

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    That would certainly be your easiest bet:
    1. Set focus to the 3rd party program
    2. Use sendkeys to send control + f
    3. Use sendkeys to send control + c
    4. Check to make sure that text was found by checking if the clipboard's text is not empty
    5. If the clipboard's text is not empty then get it by calling the clipboard's GetText

  5. #5

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Perhaps I should not have chosen "Ctrl+F" as my keyboard combo. Let us use"ctrl+Q" instead. (That way there is no confusion to the 'Find" feature Ctrl+F usually does)

    So I need to select some text somewhere on a random window in a random program, and hit Ctrl+Q, once hit it will copy the selected text into the clipboard, convert it (using a math equation I'll input later, and re-paste the new converted value exactly where it was originally converted from.

    You thik setting focus on the third party window still applys in the same way?

  6. #6
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,258

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    To be honest, what you're asking for is a global keyboard hook. I'm not sure VB is the best language for this. I'm not saying VB can't do it, but it's likely to be outside the bounds of what the .NET framework can do. It's going to be deeper at a lower level. I'd think that C/C++ would be a much better candidate.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  7. #7

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Shoot, I was hoping this wasn't the case. I can post what I have:

    Code:
       Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    
            If m.Msg = WM_HOTKEY Then                
                Debug.WriteLine(m.Msg.ToString & ":" & m.WParam.ToString & ":" & m.LParam.ToString)
    
                keybd_event(Keys.LControlKey, 0, 0, 0) 'key down
                keybd_event(Keys.A, 0, 0, 67) 'key down
                keybd_event(Keys.A, 0, &H2, 67) 'key up
                keybd_event(Keys.LControlKey, 0, &H2, 0) 'keyup
    
                'CONVERSION CODE FOLLOWED BY PASTING CODE WOULD GO HERE
    
    
            End If
            MyBase.WndProc(m) 
    
        End Sub
    I got the majority of this off of somewhere I forget where, but it isn't my original code just for disclaimer purposes. It will recognize that I have hit a keyboard combo even outside the program, but it wont run the copy function.

  8. #8
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,192

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Try breaking my steps down into code:
    1.Set focus to the 3rd party program
    You do this by first starting the process using System.Diagnostics.Process.Start and then using the BringWindowToTop API:
    Code:
    Dim notepad As Process = Process.Start("notepad.exe")
    BringWindowToTop(notepad.Handle)
    2.Use sendkeys to send control + f
    You will have to use the SendKeys.Send method to send the keys, only because control is a special key(^) it'll look a little strange:
    Code:
    SendKeys.Send("^(f)")
    3.Use sendkeys to send control + c
    Do the same thing for control + c that you did for control + f:
    Code:
    SendKeys.Send("^(c)")
    4.Check to make sure that text was found by checking if the clipboard's text is not empty
    For this step, use a conditional statement to make sure it's not empty by using the Clipboard.ContainsText method:
    Code:
    If Clipboard.ContainsText Then
    5.If the clipboard's text is not empty then get it by calling the clipboard's GetText
    Very simple, in the conditional statement's true condition display the text using the Clipboard.GetText method:
    Code:
    If Clipboard.ContainsText Then
        MessageBox.Show(Cliboard.GetText)
    End If
    Or you could simplify it by using the If short-circuit:
    Code:
    MessageBox.Show(If(Clipboard.ContainsText, Clipboard.GetText, "Nothing Copied."))

  9. #9
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,258

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    dday - I think you're missing the point... he's not trying SEND Ctrl+F ... he wants to use Ctrl+F (or Q, or Z, or T, or what ever) FROM ANY application... as a global hotkey. So let's say he has Word open, selects some text, presses Ctrl+Q ... it should find the selected text, copy it to the clipboard, process it, then paste the new value right back into the same spot.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  10. #10
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Location
    South Louisiana
    Posts
    9,192

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Ohhh.... Yeah I did misunderstand that. I was under the assumption that he wanted to find text on a 3rd party application and copy the text if anything was found. I don't know how that could even be done... I'll have to bow out of this one.

  11. #11
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,258

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    IT can be done with a global keyboard hotkey handler... for which I question the use of VB for since it seems like it would be a lower level kind of issue.

    Back to the OP, so what DOES that code do? You mention what it doesn't do, which is fine, but what does it do?

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  12. #12

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Alrighty, I figured this out:
    Code:
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    
    
            If m.Msg = WM_HOTKEY Then
                Debug.WriteLine(m.Msg.ToString & ":" & m.WParam.ToString & ":" & m.LParam.ToString)
                SendKeys.Send("^(c)")
    
                If IsNumeric(Clipboard.GetText) Then
                    valHolder3 = Clipboard.GetText
                    valHolder3 = valHolder3 / 25.4
                    Clipboard.SetText(valHolder3)
                    SendKeys.Send("^(v)")
                End If
    
            End If
            MyBase.WndProc(m)
    
        End Sub
    
        Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            Call UnregisterHotKey(Me.Handle, 9)
        End Sub
    
        Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            Call RegisterHotKey(Me.Handle.ToInt32, 0, &H2, 70)
    
        End Sub
    That's all of the code, including the copy and paste functionality and the hot-key functionality. Just in case anyone else ever comes across this. Now there may be a better way to accomplish this but this is what I came up with.

  13. #13
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,246

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    I wouldn't involve the clipboard or use sendkeys if I didn't have to. This is my idea, Register the hotkey, when hotkey is detected get handle of the foreground app, with that we get the handle of the control that has focus on the app. I'm not sure how you check if a control is an edit control so I just check to see if its classname has the word "edit" in it. , I then take the external text & convert to a decimal, add 1.1 to it and send it back to the control as a string...

    Code:
    Imports System.Runtime.InteropServices
    Imports System.Text
    
    Public Class Form1
    
        Private Const hotKey1 As Integer = 100 ' Our hot key ID
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            ' Register our hot key, (Control + Q)
            If Not RegisterHotKey(Me.Handle, hotKey1, fsModifier.CONTROL Or fsModifier.NOREPEAT, CUInt(Keys.Q)) Then
                MessageBox.Show("RegisterHotKey 'Control+Q' failed!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Asterisk)
            End If
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
            ' UnRegister our hot key
            UnregisterHotKey(Me.Handle, hotKey1)
        End Sub
    
        ' watch for messages ( i.e. our hot-key)
        Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
            If m.Msg = WM_HOTKEY Then
                Dim id As Int32 = m.WParam.ToInt32
                If id = hotKey1 Then  ' Control + Q detected
                    ' Get handle of the Foreground app.
                    Dim hWndParent As IntPtr = GetForegroundWindow()
                    ' check handle is not me, or zero
                    If hWndParent <> IntPtr.Zero AndAlso hWndParent <> Me.Handle Then
                        ' get handle of child control that has focus
                        Dim hWndFocusChild = hWndWithFocus(hWndParent)
                        ' only read/write text if the control has "edit" in the classname.
                        If Get_ClassName(hWndFocusChild).ToLower.Contains("edit") Then
                            ' convert the text to decimal value
                            Dim value As Decimal
                            Decimal.TryParse(GetText(hWndFocusChild), value)
                            ' add 1.1 to the value.
                            value += 1.1D
                            ' set external control Text to the value as a string.
                            SendMessage(hWndFocusChild, WM_SETTEXT, 0, value.ToString)
                        End If
                    End If
                End If
            End If
            ' proc all msgs.
            MyBase.WndProc(m)
        End Sub
    
    #Region "API"
        Private Const WM_HOTKEY As Int32 = &H312
        Private Enum fsModifier As UInt32
            NONE = &H0
            ALT = &H1
            CONTROL = &H2
            SHIFT = &H4
            WIN = &H8
            NOREPEAT = &H4000
        End Enum
        <DllImport("User32.dll")> _
        Private Shared Function RegisterHotKey(ByVal hwnd As IntPtr, ByVal id As Int32, ByVal fsModifiers As UInt32, ByVal vk As UInt32) As Boolean
        End Function
        <DllImport("User32.dll")> _
        Private Shared Function UnregisterHotKey(ByVal hwnd As IntPtr, ByVal id As Int32) As Boolean
        End Function
    
        <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
        Private Shared Sub GetClassName(ByVal hWnd As System.IntPtr, ByVal lpClassName As StringBuilder, ByVal nMaxCount As Integer)
        End Sub
        <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>
        Private Shared Function GetForegroundWindow() As IntPtr
        End Function
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As IntPtr) As UInt32
        End Function
        <DllImport("user32.dll")> _
        Private Shared Function AttachThreadInput(ByVal idAttach As UInt32, ByVal idAttachTo As UInt32, ByVal fAttach As Boolean) As Boolean
        End Function
        <DllImport("kernel32.dll")> _
        Private Shared Function GetCurrentThreadId() As UInt32
        End Function
        <DllImport("user32.dll", SetLastError:=True)> _
        Private Shared Function GetFocus() As IntPtr
        End Function
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
        Private Shared Function GetWindowText(ByVal hwnd As IntPtr, ByVal lpString As StringBuilder, ByVal cch As Integer) As Integer
        End Function
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
        Private Shared Function GetWindowTextLength(ByVal hwnd As IntPtr) As Integer
        End Function
    
        Private Function Get_ClassName(ByVal hWnd As IntPtr) As String
            Dim sb As New StringBuilder(256)
            GetClassName(hWnd, sb, 256)
            Return sb.ToString
        End Function
    
        Private Function hWndWithFocus(hWnd As IntPtr) As IntPtr
            Dim hFocus As IntPtr
            Dim foreThread As UInt32 = GetWindowThreadProcessId(hWnd, IntPtr.Zero)
            Dim appThread As UInt32 = GetCurrentThreadId()
            If foreThread <> appThread Then
                AttachThreadInput(foreThread, appThread, True)
                hFocus = GetFocus()
                AttachThreadInput(foreThread, appThread, False)
            End If
            Return hFocus
        End Function
    
        Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As String) As Integer
        Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
        Private Const WM_SETTEXT As Integer = &HC    
        Private Const WM_GETTEXT As Integer = &HD
        Private Const WM_GETTEXTLENGTH As Integer = &HE
        
        Private Function GetText(ByVal WindowHandle As IntPtr) As String
            Dim TextLen As Integer = SendMessage(WindowHandle, WM_GETTEXTLENGTH, 0, 0) + 1
            Dim Buffer As String = New String(" "c, TextLen)
            SendMessage(WindowHandle, WM_GETTEXT, TextLen, Buffer)
            Buffer = Buffer.Substring(0, Buffer.IndexOf(Chr(0)))
            Return Buffer
        End Function
    
    #End Region
    
    End Class
    Last edited by Edgemeal; Apr 17th, 2015 at 02:15 PM. Reason: minor code & comment changes

  14. #14

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    I'm looking at what you have supplied and it makes sense code wise, but I am unsure of why I would do that? Any chance you can clear up why it'd be better to do it that way?

  15. #15
    VB For Fun Edgemeal's Avatar
    Join Date
    Sep 2006
    Location
    WindowFromPoint
    Posts
    4,246

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    Quote Originally Posted by TomToms View Post
    I'm looking at what you have supplied and it makes sense code wise, but I am unsure of why I would do that? Any chance you can clear up why it'd be better to do it that way?
    Just that I've seen problems with the clipboard when attempting to read and write to it too often or too fast, so I'm wary to use it like that, plus I don't like the idea of apps overwriting whatever I currently have stored on the clipboard.

  16. #16

    Thread Starter
    Member
    Join Date
    Sep 2014
    Posts
    58

    Re: How can I Run "Copy" Command/Function Outside of Program/Form?

    @Edgemeal, my originally posted solution works sometimes but not always, the solution you gave seems to work flawlessly, and quicker. Thank-you.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width

Survey posted by VBForums.