VB.net Code to Programatically Populate Address Fields in UPS Worldship
Posted: January 16th, 2009 | Author: jriggs | Filed under: .net | Tags: .net, usps | No Comments »This code represents a full 8 hour day of coding. I’m posting it here as a debt of gratitude to all those on the forums who have donated their time helping out people like me. If this code helps you please let me know in the comments.
Option Explicit On Imports System.Runtime.InteropServices Imports System.text Public Module upscode Dim sShipInt As IntPtr Dim bExit As Boolean = False Dim bSub As Boolean = False Dim ipName, ipAddr1, ipZip, ipCity, ipState, ipState2, ipCountry, ipPhone, ipEmail As IntPtr Dim bName, bAddr1, bZip, bCity, bState, bCountry, bPhone, bEmail As Boolean Dim iCountryCbo As Integer Dim iStateCbo As Integer Private Const WM_SETTEXT As Long = &HC Private Const CB_SETCURSEL As Long = &H14E Private Const CB_FINDSTRING As Long = &H14C Private Const WM_SETFOCUS As Long = &H7 Private Const SW_RESTORE As Long = 9 _ Private Function FindWindow( _ ByVal lpClassName As String, _ ByVal lpWindowName As String) As IntPtr End Function _ Private Function FindWindowEx(ByVal hwndParent As IntPtr, ByVal hwndChildAfter As IntPtr, _ ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr End Function _ Private Sub GetClassName(ByVal hWnd As System.IntPtr, _ ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer) End Sub _ Private Function GetWindowTextLength(ByVal hWnd As IntPtr) As Integer End Function _ Private Function GetWindowText(ByVal hwnd As IntPtr, _ ByVal lpString As StringBuilder, _ ByVal cch As Integer) As Integer End Function _ Private Function SendMessageByString(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _ ByVal lParam As String) As IntPtr End Function ' _ 'Private Function SendMessage(ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, _ ' ByVal lParam As String) As IntPtr 'End Function _ Private Function SetForegroundWindow(ByVal hwnd As IntPtr) As Boolean End Function ' _ 'Private Function SetActiveWindow(ByVal hwnd As IntPtr) As Boolean ' End Function _ Private Function ShowWindow(ByVal handle As IntPtr, ByVal nCmd As Int32) As Boolean End Function Public Function GetChildHandle(ByVal parent As IntPtr, ByVal className As String) As IntPtr Dim child As IntPtr = FindWindowEx(parent, IntPtr.Zero, className, Nothing) Return child End Function 'use spy++ to locate window names and classes: start->all programs->visual staudio 2005->visual studio tools->spy++ 'windows (labels/textboxes/forms) are nested so loop through them looking for the intptr assigned to textboxes we 'want to change - these are dynamic Public Function InsertToWorldship(ByVal sFirstName As String, ByVal sLastName As String, ByVal sAddr1 As String, _ ByVal sAddr2 As String, ByVal sCity As String, ByVal sState As String, _ ByVal sZip As String, ByVal sCountry As String, ByVal sEmail As String) As Boolean bExit = False bSub = False Dim parent As IntPtr = FindWindow("UOFUPSOnlineOffice32", "UPS WorldShip") Dim child As IntPtr = GetChildHandle(parent, "MDIClient") If CLng(child) = 0 Then MessageBox.Show("Could not locate UPS Worldship Process", "Exit") Exit Function End If 'at this point the class name becomes dynamic, so loop until finding the next known static handle ' Ship To ' RecurseWindows(CLng(child), ) bExit = False bSub = True RecurseWindows(CLng(sShipInt), ) If sCountry.Substring(0, 3) = "USA" Then sCountry = "United States" End If ShowWindow(parent, SW_RESTORE) SendMessageByString(ipName, WM_SETTEXT, CInt(IntPtr.Zero), sFirstName & " " & sLastName) SendMessageByString(ipAddr1, WM_SETTEXT, CInt(IntPtr.Zero), sAddr1 & " " & sAddr2) iCountryCbo = CInt(SendMessageByString(ipCountry, CB_FINDSTRING, -1, sCountry)) ' SetForegroundWindow(ipCountry) SendMessageByString(ipCountry, CB_SETCURSEL, iCountryCbo, "0") Threading.Thread.Sleep(100) ' SetForegroundWindow(ipZip) ' Threading.Thread.Sleep(100) SetForegroundWindow(ipZip) ' Threading.Thread.Sleep(100) 'SetActiveWindow(ipZip) ' SendMessageByString(ipZip, WM_SETTEXT, IntPtr.Zero, CInt(sZip) & "- ") ' SetActiveWindow(ipZip) Threading.Thread.Sleep(200) SendKeys.SendWait(sZip) ' SendMessageByString(ipCity, WM_SETTEXT, CInt(IntPtr.Zero), sCity) ' SendMessageByString(ipState2, WM_SETTEXT, IntPtr.Zero, "Blah") iStateCbo = CInt(SendMessageByString(ipState, CB_FINDSTRING, -1, sState)) SendMessageByString(ipState, CB_SETCURSEL, iStateCbo, "0") ' SendMessageByString(ipPhone, WM_SETTEXT, IntPtr.Zero, "1234567890") SendMessageByString(ipEmail, WM_SETTEXT, CInt(IntPtr.Zero), sEmail) End Function Public Sub RecurseWindows(Optional ByVal Parent_hWnd As Long = 0, Optional ByVal Level As Long = 0) If bExit = True Then Exit Sub End If If CBool(Parent_hWnd) Then Dim tLen As Long, sbWindowText As New System.Text.StringBuilder sbWindowText.Append(Space(260)) 'MAX_PATH tLen = GetWindowTextLength(CType(Parent_hWnd, IntPtr)) GetWindowText(CType(Parent_hWnd, IntPtr), sbWindowText, sbWindowText.Length) If bSub = True Then AssignIntPtr(CType(Parent_hWnd, IntPtr), sbWindowText.ToString) End If If bSub = False Then If sbWindowText.ToString = " Ship To " Then sShipInt = CType(Parent_hWnd, IntPtr) bExit = True End If End If End If Dim Child_hWnd As Long Child_hWnd = CLng(FindWindowEx(CType(Parent_hWnd, IntPtr), CType(0, IntPtr), vbNullString, vbNullString)) Do While CBool(Child_hWnd) RecurseWindows(Child_hWnd, Level + 1) Child_hWnd = CLng(FindWindowEx(CType(Parent_hWnd, IntPtr), CType(Child_hWnd, IntPtr), vbNullString, vbNullString)) Loop End Sub Private Sub AssignIntPtr(ByVal Parent_hWnd As IntPtr, ByVal Text As String) 'the text we are actually looking for here is the label that precedes the text/combobox we want to change, so 'set a flag and next time through the loop assign the intptr If bName = True Then ipName = Parent_hWnd bName = False End If If bAddr1 = True Then ipAddr1 = Parent_hWnd bAddr1 = False End If If bZip = True Then ipZip = Parent_hWnd bZip = False End If If bCity = True Then ipCity = Parent_hWnd bCity = False End If If ipState.ToInt64 > 0 AndAlso ipState2 = IntPtr.Zero Then ipState2 = Parent_hWnd End If '2nd stated text box - used if country<>USA If bState = True Then ipState = Parent_hWnd bState = False End If If bCountry = True Then ipCountry = Parent_hWnd bCountry = False End If If bPhone = True Then ipPhone = Parent_hWnd bPhone = False End If If bEmail = True Then ipEmail = Parent_hWnd bEmail = False End If If Text.ToString = "Company or &Name:" Then bName = True End If If Text.ToString = "Addre&ss 1:" Then bAddr1 = True End If If Text.ToString = "Posta&l Code:" Then bZip = True End If If Text.ToString = "&City or Town:" Then bCity = True End If If Text.ToString = "State/Pr^&ovince/County:" Then bState = True End If If Text.ToString = "Countr&y/Territory:" Then bCountry = True End If If Text.ToString = "Tele&phone:" Then bPhone = True End If If Text.ToString = "E-&mail Address:" Then bEmail = True End If End Sub End Module