We help IT Professionals succeed at work.

Retrieve data from a 3rd party window application ( VB6.0 500 POINTS )

KingSencat
KingSencat asked
on
473 Views
Last Modified: 2013-12-25
I have a code to retrieve a  text from a 3rd party application and then bring back to my vb project, i use winspector to find the handle to the window and to the text, however i need to get onother text too but i can't find the class name for this text.

This is an example i use to get the text1: ( IS 100% WORKING)

Dim nHwnd As Long
Dim nEditHwnd As Long, mainContainerHwnd As Long
Dim nText As String * 256
 nHwnd = FindWindow(vbNullString, inspector1windowname.Caption)
mainContainerHwnd = FindWindowEx(nHwnd, 0&, "#32770", vbNullString)
nEditHwnd = FindWindowEx(mainContainerHwnd, 0&, "Static", vbNullString)
 
SendMessageSTRING nEditHwnd, WM_GETTEXT, 256, nText
 
nextaction1.Caption = nText
end sub
'' end of code

the second text i need to get is the following

3rdparty window :

Players: 4          '<== this is the text i need to get back to my vb project

Now in winspector what i can see is this :

#32770: "Players"

.. for some reason its doesnt display the 4 so if i try to get the players i will just get the text players and not Players: 4

What i have to do to get the number of the players?

thanks to all!
Comment
Watch Question

The four is almost definitely part of a different control. If this third party application is just a GUI then see if you can get the id of a separate control which contains the 4. It may even have a z order that is below the other control you were hooking.

The other possibility is that if this third party application is graphics based, the 4 might be rendered graphically, not as text, or rendered as text in an OpenGL/Flash/some other graphics platform window, and so you cannot retrieve the contents as text.

A good way of testing it is instead of WM_GETTEXT, use WM_SETTEXT, and set it to "MyText" or something. You should see "Players" get replaced with "MyText" - but if the ": 4" is still there, then you can be sure that you're hooking the wrong control.

Author

Commented:
The four is almost definitely part of a different control. If this third party application is just a GUI then see if you can get the id of a separate control which contains the 4. It may even have a z order that is below the other control you were hooking.

-- I have checked right now doest have a z order.

The other possibility is that if this third party application is graphics based, the 4 might be rendered graphically, not as text, or rendered as text in an OpenGL/Flash/some other graphics platform window, and so you cannot retrieve the contents as text.

--Maybe your right here but there but i am sure is exist a way to identify an image, just like the spam bots doing with the captcha. How they do that? is that possible to do it with visual basic ?

A good way of testing it is instead of WM_GETTEXT, use WM_SETTEXT, and set it to "MyText" or something. You should see "Players" get replaced with "MyText" - but if the ": 4" is still there, then you can be sure that you're hooking the wrong control.

-- here i understand what you want me to do just to try to replace the players to see if also 4 is replaced
, i have try but i am not sure what i am doing wrong please look at this screenshot and to my attached code which first i try just to GET THE TEXT "PLAYERS" i get an empty msgbox

url:
http://img381.imageshack.us/my.php?image=screenshot2aa8.png

thanks

Dim nHwnd As Long
Dim nEditHwnd As Long, mainContainerHwnd As Long, mainbla As Long, mainbla2 As Long, mainbla3 As Long, mainbla4 As Long, mainbla5 As Long
Dim nText As String * 256
 nHwnd = FindWindow(vbNullString, "Online Hold'em Inspector 2.44d1")
mainContainerHwnd = FindWindowEx(nHwnd, 0&, "#32770", vbNullString)
mainbla = FindWindowEx(mainContainerHwnd, 0&, "Static", vbNullString)
mainbla2 = FindWindowEx(mainbla, 0&, "Static", vbNullString)
mainbla3 = FindWindowEx(mainbla2, 0&, "Static", vbNullString)
mainbla4 = FindWindowEx(mainbla3, 0&, "#32770", vbNullString)
mainbla5 = FindWindowEx(mainbla4, 0&, "#32770", vbNullString)
nEditHwnd = FindWindowEx(mainbla5, 0&, "#32770", vbNullString)
 
SendMessageSTRING nEditHwnd, WM_GETTEXT, 256, nText
 
MsgBox nText

Open in new window

You're looking at the wrong control.
#32770 is not the players: 3 label, it's the caption for the Tab "Players" between "Stats" and "Simulator". the players label is somewhere else.

Author

Commented:
Can you please put me the correct code to test?
I can't, because you're using the wrong control. #32770 is referring to the wrong control, like I said. You need to use your winspector tool to find out what the right control number is. I can't do that for you. I don't have the poker game or winspector.

Author

Commented:
I have uploaded the screenshot of holdem inspector in my first post, dont you see it?

Author

Commented:
from the screenshot i upload you can't tell see and tell me what i have to modify ?
Click the + next to "Simulator" -_-

Author

Commented:
Nope it's not in there. Looks like your winspector can't identify the labels you're looking for.
Top Expert 2008

Commented:
The Players label isn't inside the "Simulator" frame though it's on the parent...
It isn't on the parent either. I went through all of the visible controls that winspector captured and was able to attribute each to a visible control, but the three white labels superimposed on the tab bar do not appear on it. This seems like a sketchy application to begin with.
Top Expert 2008

Commented:
If all came to all, you could screen shot that area using window rects and ocr to see how many players there are :)

Author

Commented:
c0ldfyr3: nice solution but how i do that? :D

thanks to all
Top Expert 2008

Commented:
Ok well to start with you need to use GetWindowRect API to get the co-ordinates of the window on the screen, then trail and error to locate the X & Y co-ordinates of the Players label inside that Rect and call the function RectangleShot in the module attached, I think you need to divide co ords by Screen.TwipsPerPixel to get correct X & Y positions at this point.

Now find a good OCR app from somewhere, I've added some links below. You're only working with numbers that are always in the same font so it should be easy.

http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=35987&lngWId=1
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=48585&lngWId=1
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=43642&lngWId=1
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=32191&lngWId=1
http://www.pscode.com/vb/scripts/ShowCode.asp?txtCodeId=52555&lngWId=1
Option Explicit
Private Declare Function GetSystemPaletteEntries Lib "gdi32" (ByVal hDc As Long, ByVal wStartIndex As Long, ByVal wNumEntries As Long, lpPaletteEntries As PALETTEENTRY) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDc As Long) As Long
Private Declare Function SetWindowPos Lib "user32" (ByVal hwnd As Long, ByVal hWndInsertAfter As Long, ByVal X As Long, ByVal Y As Long, ByVal cx As Long, ByVal cy As Long, ByVal wFlags As Long) As Long
Private Declare Function WindowFromPoint Lib "user32" (ByVal xPoint As Long, ByVal yPoint As Long) As Long
Private Declare Function GetCursorPos Lib "user32" (lpPoint As PointAPI) As Long
Private Declare Function RealizePalette Lib "gdi32" (ByVal hDc As Long) As Long
Private Declare Function SelectObject Lib "gdi32" (ByVal hDc As Long, ByVal hObject As Long) As Long
Private Declare Function GetWindowRect Lib "user32" (ByVal hwnd As Long, lpRect As RECT) As Long
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Function DrawFocusRect Lib "user32" (ByVal hDc As Long, lpRect As RECT) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" (ByVal hDc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function CreatePalette Lib "gdi32" (lpLogPalette As LOGPALETTE) As Long
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function SelectPalette Lib "gdi32" (ByVal hDc As Long, ByVal hPalette As Long, ByVal bForceBackground As Long) As Long
Private Declare Function GetWindowDC Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
Private Declare Function SendMessageLong Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Private Declare Function GetParent Lib "user32" (ByVal hwnd As Long) As Long
Private Declare Function GetDesktopWindow Lib "user32" () As Long
Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal hDc As Long, ByVal iCapabilitiy As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hDc As Long) As Long
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDc As Long) As Long
Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As GUID, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
Private Const VK_MENU = &H12
Private Const VK_SNAPSHOT = &H2C
Private Const KEYEVENTF_KEYUP = &H2
Private Const WM_COMMAND = &H111
Private Const RASTERCAPS As Long = 38
Private Const RC_PALETTE As Long = &H100
Private Const SIZEPALETTE As Long = 104
Private Type GUID
   Data1 As Long
   Data2 As Integer
   Data3 As Integer
   Data4(7) As Byte
End Type
Private Type PointAPI
        X As Long
        Y As Long
End Type
Private Type PicBmp
   Size As Long
   Type As Long
   hBmp As Long
   hPal As Long
   Reserved As Long
End Type
Private Type PALETTEENTRY
        peRed As Byte
        peGreen As Byte
        peBlue As Byte
        peFlags As Byte
End Type
Private Type LOGPALETTE
        palVersion As Integer
        palNumEntries As Integer
        palPalEntry(255) As PALETTEENTRY
End Type
Private Const SWP_NOMOVE = 2
Private Const SWP_NOSIZE = 1
Private Const flags = SWP_NOMOVE Or SWP_NOSIZE
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Dim LaTop As Integer, R As RECT
Dim WinOver As Long, WinOld As Long
Public Function CaptureWindow(ByVal hWndSrc As Long, ByVal Client As Boolean, ByVal LeftSrc As Long, ByVal TopSrc As Long, ByVal WidthSrc As Long, ByVal HeightSrc As Long) As Picture
    Dim hDcMemory As Long
    Dim hBmp As Long
    Dim hBmpPrev As Long
    Dim R As Long
    Dim hdcSrc As Long
    Dim hPal As Long
    Dim hPalPrev As Long
    Dim RasterCapsScrn As Long
    Dim HasPaletteScrn As Long
    Dim PaletteSizeScrn As Long
    Dim LogPal As LOGPALETTE
    If Client Then
        hdcSrc = GetDC(hWndSrc) ' Get device context for client area.
    Else
        hdcSrc = GetWindowDC(hWndSrc) ' Get device context for entire window.
    End If
    ' Create a memory device context for the copy process.
    hDcMemory = CreateCompatibleDC(hdcSrc)
    ' Create a bitmap and place it in the memory DC.
    hBmp = CreateCompatibleBitmap(hdcSrc, WidthSrc, HeightSrc)
    hBmpPrev = SelectObject(hDcMemory, hBmp)
    ' Get screen properties.
    RasterCapsScrn = GetDeviceCaps(hdcSrc, RASTERCAPS) ' Raster
                                                       ' capabilities.
    HasPaletteScrn = RasterCapsScrn And RC_PALETTE       ' Palette
                                                        ' support.
    PaletteSizeScrn = GetDeviceCaps(hdcSrc, SIZEPALETTE) ' Size of
                                                        ' palette.
 
   ' If the screen has a palette make a copy and realize it.
    If HasPaletteScrn And (PaletteSizeScrn = 256) Then
        ' Create a copy of the system palette.
        LogPal.palVersion = &H300
        LogPal.palNumEntries = 256
        R = GetSystemPaletteEntries(hdcSrc, 0, 256, LogPal.palPalEntry(0))
        hPal = CreatePalette(LogPal)
        Stop
        ' Select the new palette into the memory DC and realize it.
        hPalPrev = SelectPalette(hDcMemory, hPal, 0)
        R = RealizePalette(hDcMemory)
    End If
 
    ' Copy the on-screen image into the memory DC.
    R = BitBlt(hDcMemory, 0, 0, WidthSrc, HeightSrc, hdcSrc, LeftSrc, TopSrc, vbSrcCopy)
    ' Remove the new copy of the  on-screen image.
    hBmp = SelectObject(hDcMemory, hBmpPrev)
    ' If the screen has a palette get back the palette that was
   ' selected in previously.
    If HasPaletteScrn And (PaletteSizeScrn = 256) Then
        hPal = SelectPalette(hDcMemory, hPalPrev, 0)
    End If
    ' Release the device context resources back to the system.
    R = DeleteDC(hDcMemory)
    R = ReleaseDC(hWndSrc, hdcSrc)
    ' Call CreateBitmapPicture to create a picture object from the
    ' bitmap and palette handles. Then return the resulting picture
    ' object.
    'Set CaptureWindow = CreateBitmapPicture(hBmp , hPal)
    'GetIconHandle (hWnd)
    Set CaptureWindow = CreateBitmapPicture(hBmp, hPal)
End Function
Public Function CreateBitmapPicture(ByVal hBmp As Long, ByVal hPal As Long) As Picture
  Dim R As Long
 
   Dim pic As PicBmp
   ' IPicture requires a reference to "Standard OLE Types."
   Dim IPic As IPicture
   Dim IID_IDispatch As GUID
 
   ' Fill in with IDispatch Interface ID.
   With IID_IDispatch
      .Data1 = &H20400
      .Data4(0) = &HC0
      .Data4(7) = &H46
   End With
 
   ' Fill Pic with necessary parts.
   With pic
      .Size = Len(pic)          ' Length of structure.
      .Type = vbPicTypeBitmap   ' Type of Picture (bitmap).
      .hBmp = hBmp              ' Handle to bitmap.
      .hPal = hPal              ' Handle to palette (may be null).
   End With
 
   ' Create Picture object.
   R = OleCreatePictureIndirect(pic, IID_IDispatch, 1, IPic)
 
   ' Return the new Picture object.
   Set CreateBitmapPicture = IPic
End Function
 
Public Sub RectangleShot(StartX As Integer, StartY As Integer, endx As Integer, endy As Integer, oPicBox As Picture)
    Dim WinOver                     As Long
    Dim C                           As PointAPI
    Dim WWidth                      As Integer
    Dim WS                          As RECT
    Dim PictureThis                 As StdPicture
    Dim WHeight                     As Integer
    Dim PathOfFile                  As String
    Dim TmpData                     As Variant
    Dim TmpForm                     As Integer
    PathOfFile = FixPath(App.Path)
    DoEvents
    TmpForm = GetClipForm
    TmpData = Clipboard.GetData
    Clipboard.Clear
    Set PictureThis = CaptureScreen
    WWidth = endx - StartX
    If WWidth < 0 Then WWidth = WWidth * -1
    WHeight = endy - StartY
    If WHeight < 0 Then WHeight = WHeight * -1
    If endy < StartY Then SwapThem endy, StartY
    If endx < StartX Then SwapThem endx, StartX
    oPicBox.Parent.ScaleMode = 3
    oPicBox = LoadPicture()
    oPicBox.Width = (WWidth)
    oPicBox.Height = (WHeight)
    DoEvents
    oPicBox.PaintPicture PictureThis, 0, 0, WWidth, WHeight, StartX, StartY, WWidth, WHeight
    oPicBox.Picture = oPicBox.Image
    If Len(Dir("C:\Selection_Screen_Shot.bmp")) > 0 Then Kill ("C:\Selection_Screen_Shot.bmp")
    Call SavePicture(oPicBox.Image, "C:\Selection_Screen_Shot.bmp")
    Set PictureThis = LoadPicture("")
    Call ShellExecute(FrmMain.hwnd, "open", PathOfFile & "Selection_Screen_Shot.bmp", vbNullString, vbNullString, 3)
    WinOver = 0
    WinOld = 0
    R.Left = 0
    R.Right = 0
    R.Top = 0
    R.Bottom = 0
    DoEvents
    Call Clipboard.Clear
End Sub
 
Private Function GetClipForm() As Integer
    If Clipboard.GetFormat(&HBF00) = True Then
        GetClipForm = &HBF00
    ElseIf Clipboard.GetFormat(1) = True Then
        GetClipForm = 1
    ElseIf Clipboard.GetFormat(2) = True Then
        GetClipForm = 2
    ElseIf Clipboard.GetFormat(3) = True Then
        GetClipForm = 3
    ElseIf Clipboard.GetFormat(8) = True Then
        GetClipForm = 8
    ElseIf Clipboard.GetFormat(9) = True Then
        GetClipForm = 9
    End If
End Function
 
Public Function CaptureScreen() As Picture
    Dim hWndScreen As Long
    hWndScreen = GetDesktopWindow()
    Set CaptureScreen = CaptureWindow(hWndScreen, False, 0, 0, Screen.Width \ Screen.TwipsPerPixelX, Screen.Height \ Screen.TwipsPerPixelY)
End Function

Open in new window

Author

Commented:
i find a good OCR program and i test it with the players number font and its recognize the number. I put the attached code into a module. Now what i have to put in my form?

thanks

Author

Commented:
c0ldfyr3: Hey it has been 2 days since your last comment, any ideas how to start with the screenshot thing?
Top Expert 2008

Commented:
I gave you everything you need above... Call the GetWindowRect to get the X, Y, Height and Width of the entire window, and then 'guess' inside that area where the location of that Players box is, trial and error is the fastest way of finding it.

Once you've done that, the RectangleShot function takes Start X & Y and End X & Y co-ords for taking a screen shot of a certain area of the screen which you are going to give it, then you need to use one of the OCR applications I pasted links to to read in the character you've taken a screen shot of.

Which part don't you understand and I have elaborate?

Author

Commented:
how do i call getwindow rect? any example would be very helpfull
Top Expert 2008

Commented:
API Text Viewer comes free with VB :P
Public Type RECT
        Left As Long
        Top As Long
        Right As Long
        Bottom As Long
End Type
 
Public Declare Function GetWindowRect Lib "user32" Alias "GetWindowRect" (ByVal hwnd As Long, lpRect As RECT) As Long
 
' ... '
 
Dim rRECT     As RECT
Dim lRc       As Long
lRc = GetWindowRect( nHwnd, rRECT )

Open in new window

Author

Commented:
ok , i put in a module the first code you give me, now in my form i will call the above code you just paste, but where do i put the window title name? , i dont understand.
Top Expert 2008
Commented:
This one is on us!
(Get your first solution completely free - no credit card required)
UNLOCK SOLUTION
Unlock the solution to this question.
Join our community and discover your potential

Experts Exchange is the only place where you can interact directly with leading experts in the technology field. Become a member today and access the collective knowledge of thousands of technology experts.

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.