Avatar of KingSencat
KingSencat
 asked on

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

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!
Visual Basic Classic

Avatar of undefined
Last Comment
c0ldfyr3

8/22/2022 - Mon
alainbryden

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.
KingSencat

ASKER
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

alainbryden

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.
Experts Exchange is like having an extremely knowledgeable team sitting and waiting for your call. Couldn't do my job half as well as I do without it!
James Murphy
KingSencat

ASKER
Can you please put me the correct code to test?
alainbryden

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.
KingSencat

ASKER
I have uploaded the screenshot of holdem inspector in my first post, dont you see it?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
KingSencat

ASKER
from the screenshot i upload you can't tell see and tell me what i have to modify ?
alainbryden

Click the + next to "Simulator" -_-
KingSencat

ASKER
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
alainbryden

Nope it's not in there. Looks like your winspector can't identify the labels you're looking for.
c0ldfyr3

The Players label isn't inside the "Simulator" frame though it's on the parent...
alainbryden

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.
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
c0ldfyr3

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

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

thanks to all
c0ldfyr3

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

I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck
KingSencat

ASKER
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
KingSencat

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

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?
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
KingSencat

ASKER
how do i call getwindow rect? any example would be very helpfull
c0ldfyr3

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

KingSencat

ASKER
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.
Your help has saved me hundreds of hours of internet surfing.
fblack61
ASKER CERTIFIED SOLUTION
c0ldfyr3

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.