Results 1 to 18 of 18

Thread: Extracting an image from an external application

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Extracting an image from an external application

    Hey folks,

    I'm hoping someone can provide me with some help in regards to this, here's a quick overview of what I'm doing:

    I'm using user32.dll API on a 2 second timer to detect which window is open, FindWindow(), once I've found the window I'm looking for, I use FindWindowEx() to get the child window of the previously found one.

    So I've got my window which contains 2 items. An image, and an Input box.

    2 questions (Minor, and Major)

    Minor: Is there a better way to monitor when a particular window opens?

    Major: How would I extract the image that is held on the form? And then insert text into the input box?

    Note: The image is variable - it's polled from a website.

    Thanks for any help you can provide :-)

  2. #2
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    Is the window you are looking for generated by a 3rd party app? If so, I can't think of a better way to monitor. If the window is generated by your app - there are much better ways.

    Is the window you are looking for, a web browser window?

    Is the image by any chance a Captcha?
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  3. #3

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Yes, this image is a captcha and before anyone jumps on it, I'm not trying to write a spam bot or anything along those lines.

    No, the window is not an internet explorer instance. It's an internal application at my workplace, with only 2 controls on the visible (Child) window.

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Yeah, the window is generated by a 3rd party app, and no it's not a web browser.

    It's an internal application that show's only a picture and a text box for input. Oh, and a button to submit.

    You could call it a captcha I suppose, but they're basically images of words without all the distortion, which is why I can use OCR on it with a near 100% success rate.

    Thanks :-)

  5. #5
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    You can find the child window of the picture box control, and then do a screen grab of the area covered by the child window.

    As for sending text to the text box control, that topic has been discussed on the forum many times before. If you go to the Advanced Search, and search within the vb.net forum you should be able to find those threads.
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Excuse my ignorance, but how on earth would I detect the child window of the picture window?

    If you could just point me in the direction of something that would accomplish this for me, or even the functions I'd need, I'd be appreciated

    Thanks

    Edit - Also, how would I do a screen grab of a particular area? I know I'll be able to find the offsets by the location of the window, but what would be the API/Function I'd use to get a copy of a specific area?
    Last edited by HeWhoWas; Aug 18th, 2009 at 06:48 AM.

  7. #7
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    To get the child window, you use FindWindowEx, just as you have described in your first post. The picture box is a child window of the main application.

    There are a lot of threads on screen capture on this forum. For example, this one has working code:
    http://www.vbforums.com/showthread.php?t=574859

    Or, you can look in the code bank:
    http://www.vbforums.com/showthread.php?t=385497
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  8. #8

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    So each element on the page is a child window of that window? Would there be a way to navigate via the name of it, or is there some way of getting a constant yet unique identifier for it?

    Just trying to clarify.

  9. #9
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    Quote Originally Posted by HeWhoWas View Post
    So each element on the page is a child window of that window? Would there be a way to navigate via the name of it, or is there some way of getting a constant yet unique identifier for it?

    Just trying to clarify.
    Searching for the child window belonging to the control can be tricky.

    First, you must have a way of identifying the child window you want (handle, title etc). You need to find the application window you want (using FindWindow), then go through all the child windows in there (using FindWindowEx). If your control is nested within other controls (eg. it is within a container control), you need to get the child windows of that container control window etc. When you find the child window that matches the identification criteria - you have found your picturebox.

    See the following threads:
    http://www.vbforums.com/showthread.php?t=568052
    http://www.vbforums.com/showthread.php?t=567473
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  10. #10

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Re-edited. Apparantly I wasn't stupid.

    When I use the data type Long to store the hwnd, I get a massive numberm and I can locate the correct child window. However the Easy Screen Capture Class you pointed me towards is expecting an IntPtr to reference the handle. Here's some code with comments to help you visualise this, if you need it.

    Code:
     Private Sub tmrWindowFind_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tmrWindowFind.Tick
            Dim hwnd As IntPtr
            Dim wnd2 As IntPtr
            Dim Img As Image
            Dim SC As New ScreenShot.ScreenCapture
    
            hwnd = General.FindWindow(vbNullString, "Challenge") 'This stores the hwnd of the window as a short number. About 6 - 8 digits long.
            If hwnd <> 0 Then 
                tmrWindowFind.Stop()
                wnd2 = FindWindowEx(hwnd, vbNull, vbNull, vbNull) 'This returns 0
                wnd2 = FindWindowEx(hwnd, wnd2, vbNull, vbNull) 'This should be the correct one, but again, it returns 0
                Img = SC.CaptureWindow(wnd2)
                Img.Save("C:\tmp.jpeg", System.Drawing.Imaging.ImageFormat.Jpeg)
    And I'm declaring the API functions as such:

    Code:
        Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
          (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    
        Public Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
        (ByVal hWnd1 As IntPtr, ByVal hWnd2 As IntPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr
    Last edited by HeWhoWas; Aug 20th, 2009 at 11:25 AM.

  11. #11

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Sorry, reposted my post.

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    Ok, I don't see how people have been using this function with Integers as the data type. Even taking code straight out of the code bank and modifying only the name of the window I'm looking for, I get an error because the number is way too large to be in an Integer or IntPtr.

    What's going on? :-(

    Edit - Is there any way to check the hwnd of the window? Outside of code I mean. Also, this is the average hwnd I'm receiving using data type long: 1305670057984
    Last edited by HeWhoWas; Aug 20th, 2009 at 09:46 PM.

  13. #13

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    ...do API calls to FindWindow and FindWindowEx require Administrator privileges?

  14. #14
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    Quote Originally Posted by HeWhoWas View Post
    ...do API calls to FindWindow and FindWindowEx require Administrator privileges?
    Not that I know of.

    The VB.net Integer class is equivalent to the Long type in VB6, so you should replace all references to Long with Integer (or to be more precise, you can use Int32 if you compile for 32-bit Windows).
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  15. #15
    Hyperactive Member Runesmith's Avatar
    Join Date
    Oct 2008
    Posts
    399

    Re: Extracting an image from an external application

    Quote Originally Posted by HeWhoWas View Post
    ... modifying only the name of the window I'm looking for...
    If you know the name of the window (I mean, all or part of the title bar text), you can use a "pure" .net method to get the window handle without calling FindWindow API.

    I have been using this method ever since I found it on this forum:
    Code:
    Private Function FindWinHandle() As Integer
            For Each p As System.Diagnostics.Process In System.Diagnostics.Process.GetProcesses
                If Not p.MainWindowHandle.ToInt32 = 0 AndAlso Not p.ProcessName = "explorer" Then
    
                    If p.MainWindowTitle.ToLower.Contains("part of window title here") Then
                        FindWinHandle = p.MainWindowHandle.ToInt32
                        Return FindWinHandle
                    End If
    
                End If
            Next
    End Function
    You will still need to use FindWindowEx to get to the controls inside, though.

    This thread gives examples of how to declare FindWindow and FindWindowEx and to get handles of controls within the main window, using NotePad as an example:
    http://www.pinvoke.net/default.aspx/user32.FindWindow
    Last edited by Runesmith; Aug 21st, 2009 at 02:10 AM.
    Runesmith

    The key to getting the right answer is asking the right question

    I just realized: good health is merely the slowest possible rate at which one can die

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    If hwnd is an Integer datatype, then why does the Easy Screen Capture class ask for an IntPtr? or will it implicitly cast it?

    Ok, it doesn't cast from Integer to IntPtr. And If the Long and Integer variable types are the same, why is it that when I declare hwnd as a long, I get a number > 10 long, while Integer gives me one around 5?
    Last edited by HeWhoWas; Aug 21st, 2009 at 02:40 AM.

  17. #17
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Extracting an image from an external application

    IntPtr is used to store handles and pointers in VB. Any API function that returns a handle or a pointer can be declared in VB to return either an Integer or an IntPtr. Either will work fine. If you then want to call a method that takes an IntPtr as an argument it would make sense for you to declare your API function to return an IntPtr.

    That said, it's easy to convert between Integer and IntPtr. The IntPtr structure has a constructor that takes an Integer as an argument and it also has a ToInt32 method that returns an Integer, so you can go either way.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  18. #18

    Thread Starter
    Junior Member
    Join Date
    Aug 2009
    Posts
    30

    Re: Extracting an image from an external application

    I just realised that I have been staring at a piece of code that shows me exactly what you described there. Let me test, then I'll be happy to mark this topic as resolved, finally :-)

    It worked! But....I didn't realise that the window had to be visible to the user for this function to work. Is there any way to get a shot of a particular control, without having the window containing it visible?
    Last edited by HeWhoWas; Aug 21st, 2009 at 04:06 AM.

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