Reading listbox items from 3rd party application - excel

I am struggling to get listbox items from a 3rd party application. cant find away to get the list items from the listbox, have search for a week and have not find any solution.
Is there anyone that have a clue what to do.
Update!!
I struggle to get the verbose information form the listbox, shown in picture 3, red marking. When i use LB_GETTEXT i only get the first row. Is there a way to get all lines from the multi-line listbox item?
Some one up for this challenge :)
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal
lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal
hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String)
As LongPtr
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal
hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Sub windows_API_Test()
Const LB_GETCOUNT = &H18B
Const LB_GETTOPINDEX = &H18E
Const LB_GETTEXTLEN = &H18A
Const LB_GETTEXT = &H189
Do
DoEvents
Main_window = FindWindow(vbNullString, "Select passes to be exported")
Listbox_window = FindWindowEx(Main_window, 0&, "Listbox", vbNullString)
Loop Until Listbox_window > 0
numberofindex = SendMessage(Listbox_window, LB_GETCOUNT, 0, ByVal 0&)
TopIndex = SendMessage(Listbox_window, LB_GETTOPINDEX, 0, 0)
For i = TopIndex To numberofindex - 1
textcount = SendMessage(Listbox_window, LB_GETTEXTLEN, i, 0)
'space for null terminating string '\0' will be automatically added by VB
buffer$ = Space$(textcount)
' pass string byval not byref
' also make sure that lParam of SendMessage is declared as ANY
Call SendMessage(Listbox_window, LB_GETTEXT, i, ByVal buffer$)
Debug.Print buffer$
Next i
End Sub
Info from Spy++
Listbox from 3rd party application
How to get information circled in red?

Related

An issue, within Excel since the current Office 365, crashes the whole application

I'm facing an issue in Excel from Office365. Since the switch to the current Excel 365, the code below no longer works as soon as the callback function is packed into a separate module.
The code (it's pure sample code) is in a module. Sub doAction() is executed with F5. A timer is created, waits for 1150 ms and then the timer is deleted again. The timer calls TimerCallback and about 10 messages appear in the immediate window.
Here is the sample code:
Option Explicit
Public Const cCallbackIntervall = 100
Public Declare PtrSafe Function SetTimer Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr, _
ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
​
Public Declare PtrSafe Function KillTimer Lib "user32" ( _
ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr) As Long​
Public Declare PtrSafe Function GetTickCount _
Lib "kernel32" Alias "GetTickCount64" () As LongLong​
Public Sub waitMilliseconds(lPeriod As Long)
Dim lTickcount As LongLong
lTickcount = GetTickCount
Do While GetTickCount - lTickcount < lPeriod
DoEvents
Loop​
End Sub
Public Sub TimerCallback(ByVal hWnd As LongPtr, ByVal uMsg As LongPtr, _
ByVal wParam As LongPtr, ByVal lParam As LongPtr)
On Error Resume Next
Debug.Print "Huhu " & Str(Timer)​
End Sub
Sub doAction()
Dim lTimer As LongPtr
Debug.Print
lTimer = SetTimer(0, 0, cCallbackIntervall, AddressOf TimerCallback)
waitMilliseconds (1150)
lTimer = KillTimer(0, lTimer)​
End Sub
As soon as the TimerCallback procedure is packed into its own module, the entire Excel crashes.
Has anyone an idea of ​​the reasons why?

Cannot change excel icon in taskbar with vba

I am using the following code to change word icon in windows taskbar from the usual word icon to an icon I have made.
But it doesn't work...only changes the small icon on the top-left corner of the application or userform.(not the taskbar)
I tried solution on the web including this link(
how to change the Excel Icon in Taskbar while loading,
Cannot change excel icon (in taskbar) with vba) and searched on stackoverflow.com but it couldn't help.
I am using Windows 10 & word 2010(I also tried this code on excel but it was same.)
I hope someone can help....
#If VBA7 And Win64 Then
Private Declare PtrSafe Function ExtractIconA Lib "shell32.dll" _
(ByVal hInst As LongPtr, _
ByVal lpszExeFileName As String, _
ByVal nIconIndex As Long) As LongPtr
Private Declare PtrSafe Function SendMessageA Lib "user32" _
(ByVal hwnd As LongPtr, _
ByVal wMsg As Long, _
ByVal wParam As LongPtr, _
ByVal lParam As LongPtr) As LongPtr
Declare PtrSafe Function GetActiveWindow32 Lib "user32" Alias "GetActiveWindow" () As Long
Private Const ICON_SMALL As LongPtr = 0&
Private Const ICON_BIG As LongPtr = 1&
Dim hwndIcon As LongPtr
#Else
Declare Function GetActiveWindow32 Lib "user32" Alias "GetActiveWindow" () As Integer
Declare Function SendMessage32 Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function ExtractIcon32 Lib "shell32.dll" Alias "ExtractIconA" (ByVal hInst As Long, ByVal lpszExeFileName As String, ByVal nIconIndex As Long) As Long
Private Const ICON_SMALL As Long = 0&
Private Const ICON_BIG As Long = 1&
Dim hwndIcon As Long
#End If
Private Const WM_SETICON As Long = &H80
Public Sub ChangeApplicationIcon()
bigIcon_Path = ThisDocument.path & "\DataDontTouch\Icon\32X32B32.ico"
smallIcon_Path = ThisDocument.path & "\DataDontTouch\Icon\16X16B32.ico"
bigIcon = ExtractIconA(0, bigIcon_Path, 0)
smallIcon = ExtractIconA(0, smallIcon_Path, 0)
SendMessageA GetActiveWindow32(), &H80, 0&, smallIcon
SendMessageA GetActiveWindow32(), &H80, 1&, bigIcon
ActiveWindow.Caption = "Fast.exe"
End Sub

Changing background color for Status Bar of Excel

I'm using Excel 2016 (Office Theme:Colorful) and unfortunately when I write some code with a user defined text for displaying in status bar, the status bar changes its background color to dark green instead of remaining in vbButtonFace (&H8000000F). The result is an unreadable status bar text message, considered that the font color remains dark grey as expected.
I know it directly can't be done by VBA (please, don't suggest to me of changing Office theme... it's not an option!)
Googling around I found some code which uses API functions SendMessage and GetSysColor calls that I rearranged as follow:
#If VBA7 Then
Public Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
Public Declare PtrSafe Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
#Else
Public Private 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 Declare Function GetSysColor Lib "user32" (ByVal nIndex As Long) As Long
#End If
Private Const CCM_FIRST As Long = &H2000 'Common Control Messages
Private Const CCM_SETBKCOLOR As Long = (CCM_FIRST + 1)
Private Const PBM_SETBKCOLOR As Long = CCM_SETBKCOLOR 'Progress Bar Messages
Private Const COLOR_BTNFACE = &H8000000F
#If VBA7 Then
Public Sub SetStatusBackColour(hwndStatBar As LongPtr, ByVal clrref As Long)
Call SendMessage(hwndStatBar, PBM_SETBKCOLOR, 0&, ByVal clrref)
End Sub
#Else
Public Sub SetStatusBackColour(hwndStatBar As Long, ByVal clrref As Long)
Call SendMessage(hwndStatBar, PBM_SETBKCOLOR, 0&, ByVal clrref)
End Sub
#End If
Public Function EvalCol(ByVal inCol As Long) As Long ' Returns the RGB of a long colour value (System colour aware)
If ((inCol And &HFFFFFF00) = &H80000000) Then EvalCol = GetSysColor(inCol And &HFF) Else EvalCol = inCol
End Function
Private Sub Test()
Call SetStatusBackColour(StatusBar1.hwnd, EvalCol(vbButtonFace))
'Call SetStatusBackColour(StatusBar1.hwnd, COLOR_BTNFACE) 'without GetSysColor API function call
End Sub
Now the problem is... How can I find the hwnd of the Excel Status Bar?
Obviously, if this approach doesn't apply anymore or a different approach can be used instead, please tell me!
You may work around this issue by updating screen before setting the value of status bar then turning it back to False.
For example:
Application.ScreenUpdating = True
Application.StatusBar = "Transferring Records: " & I & " of " & X & " completed..."
Application.ScreenUpdating = False

minimize window driver selenium excel vba

I have searched a lot for a way to minimize the window of the driver in selenium for excel vba. I have found ways for Java and python and tried to adopt them but all my tries failed
I just found a way to maximize the window using
bot.Window.Maximize
But when trying to use Minimize I got an error
Again I am searching for excel vba as for selenium ...
Thanks advanced for help
AFAIK there is no method for this in VBA implementation (there is in Python for example). There are a number of ways to manipulate size and position e.g.
bot.Window.SetSize 0, 0
Or you can run headless
bot.AddArgument "--headless"
You might also try to:
1) Emulate Windows Key + Down
2) Write a javscript function that performs window.minimize() and async execute off the parent window
3) Capture your target co-ordinates by generating a GetWindowPlacement call along with implementing your own WINDOWPLACEMENT struct. Looks like gets ugly fast.
See also:
Getting the size of a minimized window
Driver.Window.SetSize 0, 0
just made the window smaller, without minimizing the browser to the taskbar.
How to use GetWindowPlacement in selenium vba?
'for vb6
Private Type POINTAPI
x As Long
y As Long
End Type
Private Type RECT
Left As Long
Top As Long
Right As Long
Bottom As Long
End Type
Private Type WINDOWPLACEMENT
Length As Long
flags As Long
showCmd As Long
ptMinPosition As POINTAPI
ptMaxPosition As POINTAPI
rcNormalPosition As RECT
End Type
Private Declare Function GetWindowPlacement Lib "user32" (ByVal hwnd As Long, lpwndpl As WINDOWPLACEMENT) As Long
Private Sub Command1_Click()
Dim wp As WINDOWPLACEMENT
wp.Length = Len(wp)
GetWindowPlacement targetHandle, wp
End Sub
Minimize window by windows API
This is a workaround for Selenium VBA not having a working minimize window option.
''compiler constants
#If VBA7 Then
Public Declare PtrSafe Function ShowWindow Lib "user32" (ByVal hwnd As LongPtr, ByVal nCmdShow As Long) As Boolean
Public Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
#Else
Public Declare Function ShowWindow Lib "USER32" (ByVal hwnd As Long, ByVal nCmdShow As Long) As Boolean
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 FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
#End If
Dim hwnd As Long
Dim Botwindowtitle As String
bot.Start
Botwindowtitle = bot.Window.Title
hwnd = GetAllWindowHandles(Botwindowtitle)
Call ShowWindow(hwnd, 7) 'Show the window minimized (SW_SHOWMINNOACTIVE = 7) http://www.jasinskionline.com/windowsapi/ref/s/showwindow.html
bot.Get "https://www.google.com/"
Private Function GetAllWindowHandles(partialName As String) As Long
Dim hwnd As Long, lngRet As Long
Dim strText As String
Dim hWndTemp As Long
hwnd = FindWindowEx(0&, 0&, vbNullString, vbNullString)
Do While hwnd <> 0
strText = String$(100, Chr$(0))
lngRet = GetWindowText(hwnd, strText, 100)
If InStr(1, strText, partialName, vbTextCompare) > 0 Then
Debug.Print "Window Handle:" & hwnd & vbNewLine & _
"Window title:" & Left$(strText, lngRet) & vbNewLine & _
"----------------------"
hWndTemp = hwnd
GetAllWindowHandles = hWndTemp
End If
'~~> Find next window
hwnd = FindWindowEx(0&, hwnd, vbNullString, vbNullString)
Loop
End Function

Close folder opened through Explorer.exe

It's a bit of a silly question, but how do you close a folder through Excel VBA ? Below the code to opening it,
Shell "Explorer.exe \\sharepoint.com#SSL\DavWWWRoot\sites\folder", vbMinimizedFocus
This solution with the process ID unfortunately does not work.
The following code loops through all opened Explorer windows. So you can use that to match against the LocationURL and get the window handle hWnd and use Windows API SendMessage to close the window.
Option Explicit
'for 64-bit Excel use
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Long) As LongPtr
'for 32-bit Excel use
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
Const WM_SYSCOMMAND = &H112
Const SC_CLOSE = &HF060
Public Sub CloseWindowExample()
Dim sh As Object
Set sh = CreateObject("shell.application")
Dim w As Variant
For Each w In sh.Windows
'print all locations in the intermediate window
Debug.Print w.LocationURL
' select correct shell window by LocationURL
If w.LocationURL = "file://sharepoint.com#SSL/DavWWWRoot/sites/folder" Then
SendMessage w.hWnd, WM_SYSCOMMAND, SC_CLOSE, 0
End If
Next w
End Sub
Note that the LocationURL path begins with file:// and that all backslashes \ in the path are converted to slashes / as shown in the example.
To make it compatible with both 64 and 32 bit Excel you can use
#If VBA7 Then
Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Long) As LongPtr
#Else
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
(ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
#End If
Note that one of these will be marked in red as compile error but the code will still run.

Resources