CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Mar 2010
    Posts
    3

    Need help with Macro: Copy selection from one app insert to another application!

    Hi
    I think this is an appropriate section to start this thread:

    I will put an application window that we all share called: "Map Network Drive" (see the pic). Found in My Computer, Tools, Map Network Drive...
    http://i49.tinypic.com/63srqe.jpg

    1.
    From this window, I would like to tab a specific amount of times (without using SendKeys) until I reach the text-area, right side of Folder.

    2.
    I would like to select and copy the manually typed text (in this case: "Wish to copy this selection").

    3.
    Then insert the text to a new Mail Item.
    I would like to insert the text without using (see bold:
    With OutlookMessage
    .body = storeddata
    End With

    /you may ask why, it's because, what if I insert the text to another application (that application wont have .body).


    Can you help me with this? I provide the initial code (with comments) I have for the whole macro.

    PS: Is it possible to force the macro to work in the background without getting interrupted or copying from / insert to, wrong application?. ---->
    Example of this problem occur when using sendkeys.
    Say you are using a lot of sendkeys command, and all of a sudden middle of the macro another window pops up. The sendkeys will instead tab, enter, write etc in that window instead... And that is not good.




    The initial part of the code:
    Code:
           Public Declare Function EnumWindows Lib "user32" _
       (ByVal lpEnumFunc As Long, _
        ByVal lParam As Long) As Long
     
    Public Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    
        
    Public Declare Function GetWindowThreadProcessId Lib "user32" _
        (ByVal hwnd As Long, _
         lpdwProcessId As Long) As Long
        
    Public Declare Function IsIconic Lib "user32" _
        (ByVal hwnd As Long) As Long
       
    Public Declare Function ShowWindow Lib "user32" _
        (ByVal hwnd As Long, _
         ByVal nCmdShow As Long) As Long
        
    Public Declare Function AttachThreadInput Lib "user32" _
        (ByVal idAttach As Long, _
         ByVal idAttachTo As Long, _
         ByVal fAttach As Long) As Long
        
    Public Declare Function GetForegroundWindow Lib "user32" _
        () As Long
       
    
    Public Declare Function SendMessageString Lib "user32" Alias "SendMessageA" _
    (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long
     
     
    Public Declare Function GetWindow Lib "user32" _
    (ByVal hwnd As Long, ByVal wCmd As Long) As Long
     
    Public Declare Function GetWindowTextLength Lib "user32" Alias "GetWindowTextLengthA" (ByVal hwnd As Long) As Long
     
    Public Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
     
    Public Declare Function SendMessage Lib "user32" Alias _
        "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
        ByVal wParam As Long, lParam As Any) As Long
        
    Public Const SW_RESTORE = 9
    Public Const SW_SHOW = 5
    Public Const WM_PASTE = &H302
    Public Const WM_COPY = &H301
    
    
    Public Type FindWindowParameters
     
        strTitle As String  'INPUT
        hwnd As Long        'OUTPUT
     
    End Type

    String/ Long /Object /etc values

    The next is our SUB code.
    See me comments in the code. Also, I cant get this part to work as intended. Macro doesn't select the text, the macro doesn't copy the text (tried with manually selecting text) and it doesnt paste the text to another textbox area.

    I really don't know how to write the code...

    Code:
    Sub GetStringValue()
    Dim lhwndparent As Long
    Dim CopyWord As String
        Dim MyData As New DataObject
        Set MyData = New DataObject
    Dim OutlookMessage As Object
    Dim oMailItem As MailItem 
    
    lhwndparent = FnSetForegroundWindow("Map Network Drive")
    JumpToPreviousControl (8) 'Tab the fields until we reach our textbox destination
    
    Call SendMessage(intRet, EM_SETSEL, 0&, 0&) ' I know this doesnt work  (tried with Notepad with unmarked text)
    
    CopyWord = SendMessage(lhwndparent, WM_COPY, 0&, 0&) 'This doesnt work either
    
    'Now creating a new mail item.
    Set OutlookMessage = CreateObject("Outlook.application").CreateItem(0)
    
    lhwndparent2 = FnSetForegroundWindow("Untitled*") 'this is the next application/window that I will insert my data.
    
    'store the text in the clipboard
        MyData.SetText CopyWord
        CopyWord = MyData.GetText
        MyData.PutInClipboard
        
        SendMessageString lhwndparent2 , WM_PASTE, 0, CopyWord   'here to insert our text in another application textbox area (in this case our mail item)
    
    End Sub
    Function to tab through textbox areas (I need a code that replaces SendKeys)

    Code:
    ' Jumps backward a specified number of times. Private Sub JumpToPreviousControl(ByVal times As Integer)
    Dim i As Integer
    For i = 1 To times
        SendKeys ("+{Tab}"), True
    Next
    End Sub

    Last is our FindWindow function

    Code:
    '
    Public Function FnFindWindowLike(strWindowTitle As String) As Long
     
        'We'll pass a custom structure in as the parameter to store our result...
        Dim Parameters As FindWindowParameters
        Parameters.strTitle = strWindowTitle ' Input parameter
     
        Call EnumWindows(AddressOf EnumWindowProc, VarPtr(Parameters))
       
        FnFindWindowLike = Parameters.hwnd
       
    End Function
     
    Private Function EnumWindowProc(ByVal hwnd As Long, _
                                   lParam As FindWindowParameters) As Long
      
       Dim strWindowTitle As String
     
       strWindowTitle = Space(260)
       Call GetWindowText(hwnd, strWindowTitle, 260)
       strWindowTitle = TrimNull(strWindowTitle) ' Remove extra null terminator
                                             
       If strWindowTitle Like lParam.strTitle Then
      
            lParam.hwnd = hwnd 'Store the result for later.
            EnumWindowProc = 0 'This will stop enumerating more windows
      
       End If
                              
       EnumWindowProc = 1
     
    End Function
     
    Private Function TrimNull(strNullTerminatedString As String)
     
        Dim lngPos As Long
     
        'Remove unnecessary null terminator
        lngPos = InStr(strNullTerminatedString, Chr$(0))
      
        If lngPos Then
            TrimNull = Left$(strNullTerminatedString, lngPos - 1)
        Else
            TrimNull = strNullTerminatedString
        End If
      
    End Function
     
     
     
    Public Function FnSetForegroundWindow(strWindowTitle As String) As Boolean
     
        Dim MyAppHWnd As Long
        Dim CurrentForegroundThreadID As Long
        Dim NewForegroundThreadID As Long
        Dim lngRetVal As Long
       
        Dim blnSuccessful As Boolean
       
        MyAppHWnd = FnFindWindowLike(strWindowTitle)
       
        If MyAppHWnd <> 0 Then
           
            'We've found the application window by the caption
                CurrentForegroundThreadID = GetWindowThreadProcessId(GetForegroundWindow(), ByVal 0&)
                NewForegroundThreadID = GetWindowThreadProcessId(MyAppHWnd, ByVal 0&)
       
            'AttachThreadInput is used to ensure SetForegroundWindow will work
            'even if our application isn't currently the foreground window
            '(e.g. an automated app running in the background)
                Call AttachThreadInput(CurrentForegroundThreadID, NewForegroundThreadID, True)
                lngRetVal = SetForegroundWindow(MyAppHWnd)
                Call AttachThreadInput(CurrentForegroundThreadID, NewForegroundThreadID, False)
               
            If lngRetVal <> 0 Then
           
                'Now that the window is active, let's restore it from the taskbar
                If IsIconic(MyAppHWnd) Then
                    Call ShowWindow(MyAppHWnd, SW_RESTORE)
                Else
                    Call ShowWindow(MyAppHWnd, SW_SHOW)
                End If
               
                blnSuccessful = True
           
            Else
           
                MsgBox "Found the window, but failed to bring it to the foreground!"
           
            End If
           
        Else
       
            'Failed to find the window caption
            'Therefore the app is probably closed.
            MsgBox "Application Window '" + strWindowTitle + "' not found!"
       
        End If
       
         FnSetForegroundWindow = blnSuccessful
       
    End Function

  2. #2
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Why send a network share location as an email anything? You're mixing apples and oranges with your sample.

    Be specific about what you want to do, FIRST.
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  3. #3
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Just overlooking the code you seem to obtain the hWnds of the windows you are using.
    To send keystrokes to a window you have the hWnd of, you can use the SendMessage() API
    SendMessage(TargethWnd, WM_KEYDOWN,keycode,0)
    There have been already some samples her, also you might look up SendMessage here:
    http://allapi.mentalis.org/apilist/apilist.php

  4. #4
    Join Date
    Mar 2010
    Posts
    3

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Quote Originally Posted by dglienna View Post
    Why send a network share location as an email anything? You're mixing apples and oranges with your sample.

    Be specific about what you want to do, FIRST.
    What I want is,

    If I open an application that I'm working with, has textbox area (just as the attached link), I want to be able to select the whole textbox area, store it as a string, and insert to another application.

    Map Network Drive was just an example. It contained a textbox area.

    Something is wrong with the code I wrote, it doesn't as intended...

  5. #5
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Yes. If you want to copy text from a TextBox or similar control you need to obtain the hWnd of the control.
    Use EnumChildWindows() to enumerate and obtain the hWnd of the windows of the controls.
    You ought to know (or find out) the name of the childwindow of the textbox you want.
    Then you use this hWnd in the copy and paste, or try to use SendMessage with WM_GETTEXT to get the contents of the textbox.
    EnumChildWindows() is as easy to use, as is the EnumWindows()

  6. #6
    Join Date
    Mar 2010
    Posts
    26

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Hi Groom

    I may be totally on a different wavelength but I do quite a bit of this stuff and it strikes me that the stuff you are copying from the "Map Network Drive" window is data that resides somewhere in the registry. Why don't you pull it from the registry and then parse it for the bit you need.

    This avoids launching the utility at all and obviates the need to perform tab strokes etc, which can always be troublesome.

    Finally could you save your data to a file on disk and include this in your email as an attachment.

    Just a thought.

  7. #7
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    You might not have noted, Mr. TurboBob, but the OP had already stated that the Network mapping was only an example, and that the target is copying text from atextbox or similar.

  8. #8
    Join Date
    Mar 2010
    Posts
    26

    Re: Need help with Macro: Copy selection from one app insert to another application!

    yeh but the box he is talking about is a drop down combo box, not a text box and you need to select an item from the list before you can apttempt to get the text from it. This is why he wants to send tab keys to it.

    I was just making an observation. It is perfectly easy to ignore it if I am "on the wrong wavelength".

  9. #9
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Sorry, no offence meant.
    I just wanted to pop back to the subject.
    The sending of Tab keys does not necessarily select an item in the combo box, although it might move to it from some other control... a system which is always based on starting with the focus at the same control. Obtaining the childwindow's hWnd, however, is not, because you always can address it then with the SendMessage() function, sending WM_SETFOCUS and WM_GETTEXT messages. Works with a combobox too, returning the text of the selected item.

  10. #10
    Join Date
    Mar 2010
    Posts
    26

    Re: Need help with Macro: Copy selection from one app insert to another application!

    This is a project that uses the functions that I use.

    It is developed in VB.Net 2008 and I am using Windows 7 which has quite a different UI than XP


    First open "Map Network Drive"

    Press the first button to get its hwnd. This uses the api call findwindow and assumes you know the complete caption.

    Press the next button to enumerate all of it's child windows. This uses a callback function to iterate through all the controls on the parent form (window).

    The TextBox (Combo) you are interested in has a class name "Edit" and is the only one with this
    class name - press the next button and the text box will show only the hwnd for this.
    The XP version may be different - you can find this out using SPY++ if you have it installed.

    The next button "Bring to Foreground" makes the parent the active window and the textbox/combo as the live data entry point (In Windows buttons textboxes and most controls are just windows with the all important hwnd)

    SendKeys down emulates a down keystroke to ensure the next line of text appears in the window (note I have to set the targert as foreground again as pressing this button makes my application the active window). I am using sendkeys but I am open to hearing a better way of doing it!

    Press "Gettext" copies the text and puts it in a textbox.

    Witrh regard to placing the data retrieved into an outlook message and mailing it I don't have a clue how to go about this but you seem to have this part covered.

    I hope this helps
    Attached Files Attached Files

  11. #11
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    Re: Need help with Macro: Copy selection from one app insert to another application!

    What has that got to do with VB6?
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

  12. #12
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Well, it seems to show the principle of operation of what the OP wanted.
    It should be no problem to translate into VB6, since the interesting parts are the use of the API calls to finally get the text.
    Although a direct VB6 solution would have been appreciated here, that might nevertheless help.

  13. #13
    Join Date
    Mar 2010
    Posts
    26

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Sorry Folks

    VB6 version
    Attached Files Attached Files

  14. #14
    Join Date
    Jul 2006
    Location
    Germany
    Posts
    3,725

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Not bad. Can't verify it working now because I'm sitting on a German OS computer, but looking over the code shows that everything is there. Should work perfectly.
    Good work.

  15. #15
    Join Date
    Mar 2010
    Posts
    3

    Re: Need help with Macro: Copy selection from one app insert to another application!

    Quote Originally Posted by TurboBob View Post
    Sorry Folks

    VB6 version

    Hi
    It does copy from Map Network Drive, but not from other applications.

    1. Say you open a PDF file, in the menu you select: File, Properties...
    2. This will open a new window: Document Properties.
    3. And let say this window "Document Properties" has text in the locked fields. The macro doesn't work on them...

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured