Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

WinAPI Help (GetWindowText, GetWindowTextLength, GetClassName) 1

Status
Not open for further replies.

dllCoRupT626

Programmer
Oct 15, 2002
12
0
0
US
Right to the point... I'm trying to List all of the Top LvL Window's, Everything works fine until it try's to get the ClassName of the Window and the Window Text (Title Bar).

This is all in a module:

'Declare's


Public Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Integer

Public Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Integer

Public Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Integer

Public Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, ByVal lParam As Integer) As Boolean

'Function's


Public Function fGetTopLvLWindowsEnumProc(hWnd As Long, ByVal lParam As Long) As Boolean
Dim tmpWinLen, tmpClassLen As Long
On Error GoTo error_Handler

If topWindowNames(1) <> &quot;¬ÑÉÑáѦÖÑä¬&quot; Then
ReDim Preserve topWindowNames((UBound(topWindowNames) + 1))
End If
If topWindowClassNames(1) <> &quot;¬ÑÉÑáѦÖÑä¬&quot; Then
ReDim Preserve topWindowClassNames((UBound(topWindowClassNames) + 1))
End If
If topWindowHandles(1) <> 0 Then
ReDim Preserve topWindowHandles((UBound(topWindowHandles) + 1))
End If

tmpWinLen = GetWindowTextLength(hWnd)
Call GetWindowText(hWnd, topWindowNames(UBound(topWindowNames)), tmpWinLen + 1)
topWindowHandles(UBound(topWindowHandles)) = hWnd
tmpClassLen = GetClassName(hWnd, topWindowClassNames(UBound(topWindowClassNames)), 151)

If topWindowNames(UBound(topWindowNames)) = &quot;&quot; Then topWindowNames(UBound(topWindowNames)) = &quot;No-Name&quot;
frmMain.View1.ListItems.Add , , hWnd
frmMain.View1.ListItems.Item(I).SubItems(1) = topWindowClassNames(UBound(topWindowClassNames))
frmMain.View1.ListItems.Item(I).SubItems(2) = topWindowNames(UBound(topWindowNames))
I = I + 1

fGetTopLvLWindowsEnumProc = True 'Tell's EnumWindows to continue
Exit Function

error_Handler:
fGetTopLvLWindowsEnumProc = False 'Tell's EnumWindows to stop
End Function

Public Function fGetTopLvLWindows() As Boolean
On Error GoTo error_Handler

fGetTopLvLWindows = True
ReDim topWindowNames(1) 'Clear's the array
ReDim topWindowClassNames(1) 'Clear's the array
ReDim topWindowHandles(1) 'Clear's the array
topWindowNames(1) = &quot;¬ÑÉÑáѦÖÑä¬&quot;
topWindowClassNames(1) = &quot;¬ÑÉÑáѦÖÑä¬&quot;
topWindowHandles(1) = 0

I = 1
frmMain.View1.ColumnHeaders.Add , , &quot;Handle&quot;, ((frmMain.View1.Width / 3) - 110)
frmMain.View1.ColumnHeaders.Add , , &quot;Class Name&quot;, ((frmMain.View1.Width / 3) - 110)
frmMain.View1.ColumnHeaders.Add , , &quot;Window&quot;, ((frmMain.View1.Width / 3) - 110)

EnumWindows AddressOf fGetTopLvLWindowsEnumProc, False

Exit Function

error_Handler:
fGetTopLvLWindows = False
End Function


topWindowHandles, topWindowNames, and topWindowClassNames are all dimed at the start of the program

'
Public topWindowHandles() As Long
Public topWindowNames() As String
Public topWindowClassNames() As String
'

fGetTopLvLWindows() is called at Form_Load

Everything actually work's but GetClassName put's NULL in topWindowClassNames(UBound(topWindowClassNames)) even though i put nMaxCount to 151, GetWindowText put's NULL in topWindowNames(UBound(topWindowNames)) to, and GetWindowTextLength Return's 0.

That never change's :(
And i know the Handle to the window is right cause i checked it with another program.

Plz help
 
Sorry to double post, I stoped it before i thought it went through, To make changes.
 
:( that worked last nite, today when i ran it, when it called fGetTopLvLWindows() it gave me an error:
&quot; The instruction at &quot;0x0fc0106a&quot; referenced memory at &quot;0x003e01d4&quot;. The memory could not be &quot;read&quot;. &quot;

Someone help Please.
 
The declaration of
[tt]
Public Function fGetTopLvLWindowsEnumProc(hWnd As Long, ByVal lParam As Long) As Boolean
[/tt]
should be
[tt]
Public Function fGetTopLvLWindowsEnumProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
[/tt]
And you'll make your life a lot easier, IMO, if you use [tt]Option Explicit[/tt] and declare your variables. Even where you have tried to declare them, they are not doing what you think they are. For example:

Dim tmpWinLen, tmpClassLen As Long

is actually declaring tmpWinLen as a Variant, and not a Long as you probably thought. This is a trap that many of us who come from earlier Microsoft Basics have fallen into at one time or another.

Additionally, your program will error out immediately that you call:

frmMain.View1.ListItems.Item(I).SubItems(1) = topWindowClassNames(UBound(topWindowClassNames))

since I = 0, but ListItems start at 1

Your error trap doesn't give you any hint that this has occurred, it just terminates the enumeration.

Oh, and the API doesn't handle VB strings directly. It assumes that it has been passed a pointer to a block of memory that it can write into. VB handles the passing of the pointer for you, but you are normally expected to reserve the memory that it points to by either a) using a fixed length string (memory already reserved) or b) assigning a string to the string variable you are passing of the correct length.

So, here's a minor modification of your module which addresses the various points made above, whilst retaining as much of your own code as possible:
[tt]
Option Explicit

Public topWindowHandles() As Long
Public topWindowNames() As String
Public topWindowClassNames() As String

Public Declare Function GetClassName Lib &quot;user32.dll&quot; Alias &quot;GetClassNameA&quot; (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Integer

Public Declare Function GetWindowText Lib &quot;user32.dll&quot; Alias &quot;GetWindowTextA&quot; (ByVal hWnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Integer

Public Declare Function GetWindowTextLength Lib &quot;user32.dll&quot; Alias &quot;GetWindowTextLengthA&quot; (ByVal hWnd As Long) As Integer

Public Declare Function EnumWindows Lib &quot;user32.dll&quot; (ByVal lpEnumFunc As Long, ByVal lParam As Integer) As Boolean

'Function's


Public Function fGetTopLvLWindowsEnumProc(ByVal hWnd As Long, ByVal lParam As Long) As Boolean
Dim tmpWinLen As Long
Dim tmpClassLen As Long

On Error GoTo error_Handler
If topWindowNames(1) <> &quot;¬ÑÉÑáѦÖÑä¬&quot; Then
ReDim Preserve topWindowNames((UBound(topWindowNames) + 1))
End If
If topWindowClassNames(1) <> &quot;¬ÑÉÑáѦÖÑä¬&quot; Then
ReDim Preserve topWindowClassNames((UBound(topWindowClassNames) + 1))
End If
If topWindowHandles(1) <> 0 Then
ReDim Preserve topWindowHandles((UBound(topWindowHandles) + 1))
End If

tmpWinLen = GetWindowTextLength(hWnd)
topWindowNames(UBound(topWindowNames)) = Space(tmpWinLen)
Call GetWindowText(hWnd, topWindowNames(UBound(topWindowNames)), tmpWinLen + 1)
topWindowHandles(UBound(topWindowHandles)) = hWnd
topWindowClassNames(UBound(topWindowClassNames)) = Space(151)
tmpClassLen = GetClassName(hWnd, topWindowClassNames(UBound(topWindowClassNames)), 151)

If topWindowNames(UBound(topWindowNames)) = &quot;&quot; Then topWindowNames(UBound(topWindowNames)) = &quot;No-Name&quot;
frmMain.View1.ListItems.Add , , hWnd
frmMain.View1.ListItems(frmMain.View1.ListItems.Count).SubItems(1) = topWindowClassNames(UBound(topWindowClassNames))
frmMain.View1.ListItems(frmMain.View1.ListItems.Count).SubItems(2) = topWindowNames(UBound(topWindowNames))

fGetTopLvLWindowsEnumProc = True 'Tell's EnumWindows to continue
On Error GoTo 0
Exit Function

error_Handler:
Debug.Print Err.Description
fGetTopLvLWindowsEnumProc = False 'Tell's EnumWindows to stop
End Function

Public Function fGetTopLvLWindows() As Boolean
On Error GoTo error_Handler

fGetTopLvLWindows = True
ReDim topWindowNames(1) 'Clear's the array
ReDim topWindowClassNames(1) 'Clear's the array
ReDim topWindowHandles(1) 'Clear's the array
topWindowNames(1) = &quot;¬ÑÉÑáѦÖÑä¬&quot;
topWindowClassNames(1) = &quot;¬ÑÉÑáѦÖÑä¬&quot;
topWindowHandles(1) = 0

frmMain.View1.ColumnHeaders.Add , , &quot;Handle&quot;, ((frmMain.View1.Width / 3) - 110)
frmMain.View1.ColumnHeaders.Add , , &quot;Class Name&quot;, ((frmMain.View1.Width / 3) - 110)
frmMain.View1.ColumnHeaders.Add , , &quot;Window&quot;, ((frmMain.View1.Width / 3) - 110)

EnumWindows AddressOf fGetTopLvLWindowsEnumProc, False
On Error GoTo 0
Exit Function

error_Handler:
Debug.Print Err.Description
fGetTopLvLWindows = False
End Function
 
Thank's. I was reading one of your other post's when I saw this lol.

I have Option Explicit on all the time but i figured i didn't have to post that oh well.

I'm going to go try it out
 
btw frmMain.View1.ListItems.Item(I).SubItems(1) = topWindowClassNames(UBound(topWindowClassNames)) work's becuase I is set to 1 when fGetTopLvLWindows() is called.

And i just found out about ByVal, I've been using C++ i just jumped back to VB for this becuase of the Winsock control :)
 
Hey man it Work's, Thank's alot i've been trying to get that to work for so long now it's Pitiful.

Cya
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top