Get list of installed network card - vb6

I want to fill the combo box with all the installed network adapter name using visual basic 6.0. Is there any way to do so? I also want to know how to add, edit and delete the value of registry?

Simplest way would be to shell out to the ipconfig command, redirect the output to a file, and then parse the file. There are many implementations of a function usually called "ShellAndWait()". I've taken one I had squirreled away - it might not be the best, but it works.
Option Explicit
Private Declare Function CloseHandle Lib "Kernel32.dll" ( _
ByVal hHandle As Long _
) As Long
Private Declare Function OpenProcess Lib "Kernel32.dll" ( _
ByVal dwDesiredAccess As Long, _
ByVal bInheritHandle As Long, _
ByVal dwProcessId As Long _
) As Long
Private Declare Function WaitForSingleObject Lib "Kernel32.dll" ( _
ByVal hHandle As Long, _
ByVal dwMilliseconds As Long _
) As Long
Private Const INFINITE As Long = -1&
Private Const SYNCHRONIZE As Long = &H100000
Private Sub Form_Load()
Dim oNetworkAdapters As VBA.Collection
Dim vNetworkAdapter As Variant
Set oNetworkAdapters = GetNetworkAdapters()
cmbNICs.Clear
For Each vNetworkAdapter In oNetworkAdapters
cmbNICs.AddItem vNetworkAdapter
Next vNetworkAdapter
End Sub
Public Function GetNetworkAdapters() As VBA.Collection
Dim sTempFileName As String
Dim nFileNo As Integer
Dim sLine As String
Dim oNetworkAdapters As VBA.Collection
Set oNetworkAdapters = New VBA.Collection
sTempFileName = Environ$("TEMP") & "\VBTmp" & Format$(Now, "yyyymmddhhnnss")
If ShellAndWait("cmd.exe /c ipconfig > """ & sTempFileName & """", vbHide) Then
nFileNo = FreeFile
Open sTempFileName For Input As #nFileNo
Do Until EOF(nFileNo)
Line Input #nFileNo, sLine
If Len(sLine) > 0 Then
If sLine Like "*:" Then
If Not sLine Like " *:" Then
oNetworkAdapters.Add sLine
End If
End If
End If
Loop
Close #nFileNo
Kill sTempFileName
End If
Set GetNetworkAdapters = oNetworkAdapters
End Function
' Start the indicated program and wait for it to finish, hiding while we wait.
Public Function ShellAndWait(ByRef in_sProgramName As String, _
ByVal in_enmWindowStyle As VbAppWinStyle) As Boolean
Dim nProcessId As Long
Dim hProcess As Long
' Start the program.
On Error GoTo ShellError
nProcessId = Shell(in_sProgramName, in_enmWindowStyle)
On Error GoTo 0
DoEvents
' Wait for the program to finish.
' Get the process handle.
hProcess = OpenProcess(SYNCHRONIZE, 0, nProcessId)
If hProcess <> 0 Then
WaitForSingleObject hProcess, INFINITE
CloseHandle hProcess
End If
ShellAndWait = True
Exit Function
ShellError:
MsgBox "Error starting task '" & in_sProgramName & "'" & vbCrLf & Err.Description, vbOKOnly Or vbExclamation, "Error"
End Function

Here is the simple code that will detect all Ethernet and wireless adaptors
NetworkInterface slectedNic;
IEnumerable<NetworkInterface> nics = NetworkInterface.GetAllNetworkInterfaces().Where(network => network.OperationalStatus == OperationalStatus.Up && (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet || network.NetworkInterfaceType == NetworkInterfaceType.Wireless80211));
foreach (NetworkInterface item in nics)
{
cmbAdptors.Items.Add(item);
}
but if u want to detect only active wireless adaptor
change
.Where(network => network.OperationalStatus == OperationalStatus.Up && (network.NetworkInterfaceType == NetworkInterfaceType.Ethernet || network.NetworkInterfaceType == NetworkInterfaceType.Wireless80211));
to
.Where(network => network.OperationalStatus == OperationalStatus.Up && network.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)

Related

Get output from command line in VB6

i am using this .Cls file and a command using 7zip to extract specific file from a zip.
my single file gets extracted how ever i need to add if statement to se if my file was found so that i can exit sub it can this piece of code be modifed to add own code
DOSOutputs.cls
Option Explicit
Private Declare Function PeekMessage Lib "user32" Alias "PeekMessageA" (lpMsg As MsgType, ByVal hWnd As Long, ByVal wMsgFilterMin As Long, ByVal wMsgFilterMax As Long, ByVal wRemoveMsg As Long) As Long
Private Declare Function TranslateMessage Lib "user32" (ByRef lpMsg As Any) As Long
Private Declare Function DispatchMessage Lib "user32" Alias "DispatchMessageW" (ByRef lpMsg As Any) As Long
Private Type POINTAPI
x As Long
Y As Long
End Type
Private Type MsgType
hWnd As Long
message As Long
wParam As Long
lParam As Long
Time As Long
pt As POINTAPI
End Type
Private Const PM_NOREMOVE As Long = 0&
Private Const PM_REMOVE As Long = 1&
'
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
'The CreatePipe function creates an anonymous pipe,
'and returns handles to the read and write ends of the pipe.
Private Declare Function CreatePipe Lib "kernel32" ( _
phReadPipe As Long, _
phWritePipe As Long, _
lpPipeAttributes As Any, _
ByVal nSize As Long) As Long
'Used to read the the pipe filled by the process create
'with the CretaProcessA function
Private Declare Function ReadFile Lib "kernel32" ( _
ByVal hFile As Long, _
ByVal lpBuffer As String, _
ByVal nNumberOfBytesToRead As Long, _
lpNumberOfBytesRead As Long, _
ByVal lpOverlapped As Any) As Long
'Structure used by the CreateProcessA function
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type
'Structure used by the CreateProcessA function
Private Type STARTUPINFO
cb As Long
lpReserved As Long
lpDesktop As Long
lpTitle As Long
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
'Structure used by the CreateProcessA function
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessID As Long
dwThreadID As Long
End Type
'This function launch the the commend and return the relative process
'into the PRECESS_INFORMATION structure
Private Declare Function CreateProcessA Lib "kernel32" ( _
ByVal lpApplicationName As Long, _
ByVal lpCommandLine As String, _
lpProcessAttributes As SECURITY_ATTRIBUTES, _
lpThreadAttributes As SECURITY_ATTRIBUTES, _
ByVal bInheritHandles As Long, _
ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, _
ByVal lpCurrentDirectory As Long, _
lpStartupInfo As STARTUPINFO, _
lpProcessInformation As PROCESS_INFORMATION) As Long
'Close opened handle
Private Declare Function CloseHandle Lib "kernel32" ( _
ByVal hHandle As Long) As Long
'Consts for the above functions
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const STARTF_USESTDHANDLES = &H100&
Private Const STARTF_USESHOWWINDOW = &H1
Private mCommand As String 'Private variable for the CommandLine property
Private mOutputs As String 'Private variable for the ReadOnly Outputs property
'Event that notify the temporary buffer to the object
Public Event ReceiveOutputs(CommandOutputs As String)
'This property set and get the DOS command line
'It's possible to set this property directly from the
'parameter of the ExecuteCommand method
Public Property Let CommandLine(DOSCommand As String)
mCommand = DOSCommand
End Property
Public Property Get CommandLine() As String
CommandLine = mCommand
End Property
'This property ReadOnly get the complete output after
'a command execution
Public Property Get Outputs()
Outputs = mOutputs
End Property
Public Function ExecuteCommand(Optional CommandLine As String) As String
Dim proc As PROCESS_INFORMATION 'Process info filled by CreateProcessA
Dim ret As Long 'long variable for get the return value of the
'API functions
Dim start As STARTUPINFO 'StartUp Info passed to the CreateProceeeA
'function
Dim sa As SECURITY_ATTRIBUTES 'Security Attributes passeed to the
'CreateProcessA function
Dim hReadPipe As Long 'Read Pipe handle created by CreatePipe
Dim hWritePipe As Long 'Write Pite handle created by CreatePipe
Dim lngBytesread As Long 'Amount of byte read from the Read Pipe handle
Dim strBuff As String * 256 'String buffer reading the Pipe
'if the parameter is not empty update the CommandLine property
If Len(CommandLine) > 0 Then
mCommand = CommandLine
End If
'if the command line is empty then exit whit a error message
If Len(mCommand) = 0 Then
MsgBox "Command Line empty", vbCritical
Exit Function
End If
'Create the Pipe
sa.nLength = Len(sa)
sa.bInheritHandle = 1&
sa.lpSecurityDescriptor = 0&
ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
If ret = 0 Then
'If an error occur during the Pipe creation exit
MsgBox "CreatePipe failed. Error: " & Err.LastDllError, vbCritical
Exit Function
End If
'Launch the command line application
start.cb = Len(start)
start.dwFlags = STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW
'set the StdOutput and the StdError output to the same Write Pipe handle
start.hStdOutput = hWritePipe
start.hStdError = hWritePipe
'Execute the command
ret& = CreateProcessA(0&, mCommand, sa, sa, 1&, _
NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
If ret <> 1 Then
'if the command is not found ....
MsgBox "File or command not found", vbCritical
Exit Function
End If
'Now We can ... must close the hWritePipe
ret = CloseHandle(hWritePipe)
mOutputs = ""
'Read the ReadPipe handle
Do
ret = ReadFile(hReadPipe, strBuff, 256, lngBytesread, 0&)
mOutputs = mOutputs & Left(strBuff, lngBytesread)
'Send data to the object via ReceiveOutputs event
RaiseEvent ReceiveOutputs(Left(strBuff, lngBytesread))
'Pause 0.02
FastDoEvents
Loop While ret <> 0
'Close the opened handles
ret = CloseHandle(proc.hProcess)
ret = CloseHandle(proc.hThread)
ret = CloseHandle(hReadPipe)
'Return the Outputs property with the entire DOS output
ExecuteCommand = mOutputs
End Function
Public Sub FastDoEvents()
Dim uMsg As MsgType
'
Do While PeekMessage(uMsg, 0&, 0&, 0&, PM_REMOVE) ' Reads and deletes message from queue.
TranslateMessage uMsg ' Translates virtual-key messages into character messages.
DispatchMessage uMsg ' Dispatches a message to a window procedure.
Loop
End Sub
form1
Private WithEvents objDOS As DOSOutputs
Private Sub Form_Load()
Set objDOS = New DOSOutputs
End Sub
button command
Private Sub Command22_Click()
On Error Resume Next
On Error GoTo errore
objDOS.CommandLine = text6.text
objDOS.ExecuteCommand
'If objDOS.Outputs = "41_gfx7.rom " Then
'Text1.Text = Text1.Text & objDOS.Outputs & vbNewLine
'End If
Exit Sub
errore:
MsgBox (Err.Description & " - " & Err.Source & " - " & CStr(Err.Number))
End Sub
text6.text has
"C:\Program Files (x86)\7-Zip\7z" x "C:\Users\sarah\Downloads\MAME\MAME_2010_full_nonmerged_romsets\roms\*.zip" -o"C:\Users\sarah\Desktop\rom test\New folder (2)\" *41_gfx7.rom -y
so now am trying to get the status from output using if statement to se if 41_gfx7.rom was found so that i can exit the scan or sub as there is no need to scan further.
or maybe if you can help add better one it will be great,once the string is found exit sub it
Private Sub Command1_Click()
Dim objShell As New WshShell
Dim objExecObject As WshExec
Dim strText As String
Set objExecObject = objShell.Exec(Text6.Text)
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadLine()
If InStr(strText, "Reply") > 0 Then
Debug.Print "Reply received: " & strText
Exit Do
End If
Loop
End Sub
text6 is my command
ok update
"C:\Program Files (x86)\7-Zip\7z" x "C:\Users\sarah\Downloads\MAME\MAME_2010_full_nonmerged_romsets\roms\*.zip" -o"C:\Users\sarah\Desktop\rom test\New folder (2)\" *41_gfx7.rom -y
i need to add list to this command according to https://sevenzip.osdn.jp/chm/cmdline/commands/list.htm so that file names gets displayed in output data
The following Microsoft article describes two methods that read the output of a command: WSH: Running Programs
The simplest uses the StdOut property of the WshExec object:
Set objShell = WScript.CreateObject("WScript.Shell")
Set objExecObject = objShell.Exec("cmd /c ping -n 3 -w 1000 157.59.0.1")
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadLine()
If Instr(strText, "Reply") > 0 Then
Wscript.Echo "Reply received."
Exit Do
End If
Loop
You can replace the ping command here with your 7z command and read StdOut to see what your command returned.
Since you are doing this in VB6, you can add a reference (Projects menu > References) to Windows Script Host Object Model library and instantiate the objects with the proper types directly:
Dim objShell As New WshShell
Dim objExecObject As WshExec
Dim strText As String
Set objExecObject = objShell.Exec("cmd /c ping -n 3 -w 1000 127.0.0.1")
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadLine()
If InStr(strText, "Reply") > 0 Then
Debug.Print "Reply received: " & strText
Exit Do
End If
Loop
With this approach you don't need the DOSCommand.cls, you can simply use the WshShell object for all your operations.
Your Command22_Click would look like this:
Private Sub Command22_Click()
On Error GoTo errore
Dim objShell As New WshShell
Dim objExecObject As WshExec
Dim strText As String
Set objExecObject = objShell.Exec(text6.Text)
Do While Not objExecObject.StdOut.AtEndOfStream
strText = objExecObject.StdOut.ReadLine()
' Parse the text your 7z command returned here
If InStr(strText, "41_gfx7.rom") > 0 Then
Text1.Text = Text1.Text & strText & vbCrLf
Exit Do
End If
Loop
Exit Sub
errore:
MsgBox (Err.Description & " - " & Err.Source & " - " & CStr(Err.Number))
End Sub

Killing Previous Instance of VB6 Application

I've searched around for the proper way to kill a previous Instance of a VB6 application to no avail. If our main service dies, we need to terminate the previous instance of the running application and then, when the service comes back up only the new instance should be loaded. I am trying to exit this code in the following function:
Private Sub g_cServerInterface_FatalError(Error As enSvrReturns, ErrorString As String)
Dim sMsg As String
Dim result As VbMsgBoxResult
m_bFatalError = True
UnFreeze
If m_cLanguageText Is Nothing Then
GoTo TheEnd 'Form not yet loaded - not yet logged on
End If
' m_NumFatalErrors = m_NumFatalErrors + 1
' If m_NumFatalErrors > 5 Then
' Functions.DevInfo "Unable to restart Manitou.", g_cLangText_General
' End
' End If
If Error <> SVRERR_NOT_CONNECTED Or RunningInDebugger() Then
sMsg = g_cLangText_General.GetText("A system error has occurred")
If ErrorString <> "" Then
sMsg = sMsg & ":" & vbCrLf & vbCrLf & ErrorString & vbCrLf & vbCrLf
Else
sMsg = sMsg & ". "
End If
sMsg = sMsg & g_cLangText_General.GetText("Press OK to attempt to restart or Cancel to quit.")
result = DevAskOkCancel(sMsg, Nothing)
Else
' Since we've been disconnected, attempt immediately to reconnect
result = vbOK
End If
If (result = vbOK) Then
On Local Error Resume Next
If InStr(g_CommandLine, "-U") = 0 Then
g_CommandLine = g_CommandLine & " -U" & g_cUser.id
End If
If InStr(g_CommandLine, "-P") = 0 Then
g_CommandLine = g_CommandLine & " -P" & g_cUser.Password
End If
Shell App.Path & "\" & App.EXEName & " " & g_CommandLine & " -X", vbNormalFocus
DoEvents
End If
TheEnd:
If (Not RunningInDebugger()) Then
' Running as compiled executable
' Specifies the exit code for the process, and for all threads that
' are terminated as a result of this call. Use the GetExitCodeProcess
' function to retrieve the process's exit value. Use the GetExitCodeThread
' function to retrieve a thread's exit value.
CoUninitialize
ExitProcess 0
Else
' Running from the IDE
End
End If
End Sub
Note that I added the CoUninitialize and ExitProcess 0 API calls to this. How can I correctly terminate the previously loaded instance when the service comes back up? thanks Larry
Private Declare Function FindWindow Lib "user32" _
Alias "FindWindowA" (ByVal lpClassName As String, _
ByVal lpWindowName As String) As Long
Private Declare Function PostMessage Lib "user32" _
Alias "PostMessageA" (ByVal hwnd As Long, _
ByVal wMsg As Long, _
ByVal wParam As Long, _
lParam As Any) As Long
Private Const WM_CLOSE = &H10
Private Sub Form_Load()
Dim strCap As String
Dim lngHwnd As Long
Dim lngRet As Long
strCap = Me.Caption
Me.Caption = "*" & strCap
lngHwnd = FindWindow(ByVal vbNullString, ByVal strCap)
If lngHwnd <> 0 Then
PostMessage lngHwnd, WM_CLOSE, 0&, 0&
End If
Me.Caption = strCap
End Sub

Convert from \Device\HarddiskVolume1 to C: in vb6

Is there any way to convert from \Device\HarddiskVolume1\programfile\explorer.exe to C:\programfile\explorer.exe in visual basic 6?
thanks
Try this
Option Explicit
Private Declare Function QueryDosDevice Lib "kernel32" Alias "QueryDosDeviceA" (ByVal lpDeviceName As String, ByVal lpTargetPath As String, ByVal ucchMax As Long) As Long
Private Sub Command1_Click()
Debug.Print pvReplaceDevice("\Device\HarddiskVolume1\aaa.txt")
End Sub
Private Function pvReplaceDevice(sPath As String) As String
Dim sDrive As String
Dim sDevice As String
Dim lIdx As Long
For lIdx = 0 To 25
sDrive = Chr$(65 + lIdx) & ":"
sDevice = Space(1000)
If QueryDosDevice(sDrive, sDevice, Len(sDevice)) <> 0 Then
sDevice = Left$(sDevice, InStr(sDevice, Chr$(0)) - 1)
' Debug.Print sDrive; "="; sDevice
If LCase$(Left$(sPath, Len(sDevice))) = LCase$(sDevice) Then
pvReplaceDevice = sDrive & Mid$(sPath, Len(sDevice) + 1)
Exit Function
End If
End If
Next
pvReplaceDevice = sPath
End Function
If you want an efficient use of API functions, create a class - "DiskDevice"
Option Explicit
Private Declare Function GetLogicalDriveStrings Lib "Kernel32" Alias "GetLogicalDriveStringsW" ( _
ByVal nBufferLength As Long, _
ByVal lpBuffer As Long _
) As Long
Private Declare Function QueryDosDevice Lib "Kernel32.dll" Alias "QueryDosDeviceW" ( _
ByVal lpDeviceName As Long, _
ByVal lpTargetPath As Long, _
ByVal ucchMax As Long _
) As Long
Private m_colDrivesKeyedByDevice As VBA.Collection
Private Sub Class_Initialize()
Dim sDriveStrings As String
Dim vasDriveStrings As Variant
Dim nIndex As Long
Dim sDrive As String
' Allocate max size buffer [A-Z]:\\\0 and retrieve all drives on the system.
sDriveStrings = Space$(105)
GetLogicalDriveStrings 1000, StrPtr(sDriveStrings)
' Split over the null chars between each substring.
vasDriveStrings = Split(sDriveStrings, vbNullChar)
Set m_colDrivesKeyedByDevice = New VBA.Collection
' Iterate through each drive string (escaping later if any item is null string).
For nIndex = 0 To UBound(vasDriveStrings)
sDrive = Left$(vasDriveStrings(nIndex), 2) ' Ignore the backslash.
If Len(sDrive) = 0 Then
Exit For
End If
' Create mapping from Drive => Device
m_colDrivesKeyedByDevice.Add sDrive, GetDeviceForDrive(sDrive)
Next nIndex
End Sub
' Retrieve the device string \device\XXXXXX for the drive X:
Private Function GetDeviceForDrive(ByRef the_sDrive As String)
Const knBufferLen As Long = 1000
Dim sBuffer As String
Dim nRet As Long
sBuffer = Space$(knBufferLen)
nRet = QueryDosDevice(StrPtr(the_sDrive), StrPtr(sBuffer), knBufferLen)
GetDeviceForDrive = Left$(sBuffer, nRet - 2) ' Ignore 2 terminating null chars.
End Function
Public Function GetFilePathFromDevicePath(ByRef the_sDevicePath As String) As String
Dim nPosSecondBackslash As Long
Dim nPosThirdBackslash As Long
Dim sDevice As String
Dim sDisk As String
' Path is always \Device\<device>\path1\path2\etc. Just get everything before the third backslash.
nPosSecondBackslash = InStr(2, the_sDevicePath, "\")
nPosThirdBackslash = InStr(nPosSecondBackslash + 1, the_sDevicePath, "\")
sDevice = Left(the_sDevicePath, nPosThirdBackslash - 1)
sDisk = m_colDrivesKeyedByDevice.Item(sDevice) ' Lookup
' Reassemble, this time with disk.
GetFilePathFromDevicePath = sDisk & Mid$(the_sDevicePath, nPosThirdBackslash)
End Function
Now, you use code like:
Set m_oDiskDevice = New DiskDevice
...
sMyPath = m_oDiskDevice.GetFilePathFromDevicePath("\Device\HarddiskVolume1\programfile\explorer.exe")
That way you don't have to call the API functions multiple times - you just do a collection lookup.

How can I stop Excel workbook flicker on automation open?

I'm using GetObject with a workbook path to either create a new or grab an existing Excel instance. If it's grabbing an existing user-created instance, the application window is visible; if the workbook path in question is closed, it will open and hide, but not before it flickers on the screen. Application.ScreenUpdating does not help with this.
I don't think I can use the Win32Api call LockWindowUpdate, because I don't know whether I'm getting or creating before the file is open. Is there some other VBA-friendly way (i.e. WinAPI) to freeze the screen long enough to get the object?
EDIT: Just to clarify, because the first answer suggests using the Application object... These are the steps to reproduce this behavior.
1. Open Excel--make sure you're only running one instance--save and close the default workbook. Excel window now visible but "empty"
2. Open Powerpoint or Word, insert a module, add the following code
Public Sub Open_SomeWorkbook()
Dim MyObj As Object
Set MyObj = GetObject("C:\temp\MyFlickerbook.xlsx")
'uncomment the next line to see the workbook again'
'MyObj.Parent.Windows(MyObj.Name).Visible = True'
'here's how you work with the application object... after the fact'
Debug.Print MyObj.Parent.Version
End Sub
Note the flicker as Excel opens the file in the existing instance, and then hides it... because it's automation
Note also, however, that there is no application object to work with, until the flickering is done. This is why I'm looking for some larger API method to "freeze" the screen.
Try,
Application.VBE.MainWindow.Visible = False
If that doesn't work try
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal ClassName As String, ByVal WindowName As String) As Long
Private Declare Function LockWindowUpdate Lib "user32" _
(ByVal hWndLock As Long) As Long
Sub EliminateScreenFlicker()
Dim VBEHwnd As Long
On Error GoTo ErrH:
Application.VBE.MainWindow.Visible = False
VBEHwnd = FindWindow("wndclass_desked_gsk", _
Application.VBE.MainWindow.Caption)
If VBEHwnd Then
LockWindowUpdate VBEHwnd
End If
'''''''''''''''''''''''''
' your code here
'''''''''''''''''''''''''
Application.VBE.MainWindow.Visible = False
ErrH:
LockWindowUpdate 0&
End Sub
Both found here Eliminating Screen Flicker During VBProject Code
Ok you didn't mention multiple instances... [1. Open Excel--make sure you're only running one instance] :)
How about something like this.....
Public Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" _
(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare PtrSafe Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Public Declare PtrSafe Function ShowWindow Lib "user32" (ByVal lHwnd As Long, _
ByVal lCmdShow As Long) As Boolean
Public Declare PtrSafe Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
Sub GetWindowHandle()
Const SW_HIDE As Long = 0
Const SW_SHOW As Long = 5
Const SW_MINIMIZE As Long = 2
Const SW_MAXIMIZE As Long = 3
'Const C_WINDOW_CLASS = "XLMAIN"
Const C_WINDOW_CLASS = vbNullString
Const C_FILE_NAME = "Microsoft Excel - Flickerbook.xlsx"
'Const C_FILE_NAME = vbNullString
Dim xlHwnd As Long
xlHwnd = FindWindow(lpClassName:=C_WINDOW_CLASS, _
lpWindowName:=C_FILE_NAME)
'Debug.Print xlHwnd
if xlHwnd = 0 then
Dim MyObj As Object
Dim objExcel As Excel.Application
Set objExcel = GetObject(, "Excel.Application")
objExcel.ScreenUpdating = False
Set MyObj = GetObject("C:\temp\MyFlickerbook.xlsx")
'uncomment the next line to see the workbook again'
'MyObj.Parent.Windows(MyObj.Name).Visible = True
'here's how you work with the application object... after the fact'
Debug.Print MyObj.Parent.Version
MyObj.Close
objExcel.ScreenUpdating = True
else
'Either HIDE/SHOW or MINIMIZE/MAXIMISE
ShowWindow xlHwnd, SW_HIDE
Set MyObj = GetObject("C:\temp\MyFlickerbook.xlsx")
'manage MyObj
ShowWindow xlHwnd, SW_SHOW
'Or LockWindowUpdate then Unlock
LockWindowUpdate xlHwnd
Set MyObj = GetObject("C:\temp\MyFlickerbook.xlsx")
'manage MyObj
LockWindowUpdate 0
end if
' 'Get Window Name
' Dim strWindowTitle As String
' strWindowTitle = Space(260) ' We must allocate a buffer for the GetWindowText function
' Call GetWindowText(xlHwnd, strWindowTitle, 260)
' debug.print (strWindowTitle)
End Sub
I ended up basically ditching GetObject, because it wasn't granular enough, and wrote my own flickerless opener, with some inspiration from osknows and great code samples from here and here. Thought I would share it in case others found it useful. First the complete module
'looping through, parent and child (see also callbacks for lpEnumFunc)
Private Declare Function EnumWindows Lib "user32.dll" (ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
Private Declare Function EnumChildWindows Lib "user32.dll" (ByVal hWndParent As Long, _
ByVal lpEnumFunc As Long, _
ByVal lParam As Long) As Long
'title of window
Private Declare Function GetWindowTextLength Lib "user32.dll" Alias "GetWindowTextLengthA" (ByVal hWnd As Long) As Long
Private Declare Function GetWindowText Lib "user32.dll" Alias "GetWindowTextA" (ByVal hWnd As Long, _
ByVal lpString As String, _
ByVal cch As Long) As Long
'class of window object
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" (ByVal hWnd As Long, _
ByVal lpClassName As String, _
ByVal nMaxCount As Long) As Long
'control window display
Private Declare Function ShowWindow Lib "user32" (ByVal lHwnd As Long, _
ByVal lCmdShow As Long) As Boolean
Private Declare Function BringWindowToTop Lib "user32" (ByVal hWnd As Long) As Long
Private Declare Function SetFocus Lib "user32" (ByVal hWnd As Long) As Long
Public Enum swcShowWindowCmd
swcHide = 0
swcNormal = 1
swcMinimized = 2 'but activated
swcMaximized = 3
swcNormalNoActivate = 4
swcShow = 5
swcMinimize = 6 'activates next
swcMinimizeNoActivate = 7
swcShowNoActive = 8
swcRestore = 9
swcShowDefault = 10
swcForceMinimized = 11
End Enum
'get application object using accessibility
Private Declare Function AccessibleObjectFromWindow Lib "oleacc" (ByVal hWnd As Long, _
ByVal dwId As Long, _
ByRef riid As GUID, _
ByRef ppvObject As Object) _
As Long
Private Declare Function IIDFromString Lib "ole32" (ByVal lpsz As Long, _
ByRef lpiid As GUID) As Long
'Const defined in winuser.h
Private Const OBJID_NATIVEOM As Long = &HFFFFFFF0
'IDispath pointer to native object model
Private Const Guid_Excel As String = "{00020400-0000-0000-C000-000000000046}"
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
'class names to search by (Excel, in this example, is XLMAIN)
Private mstrAppClass As String
'title (a.k.a. pathless filename) to search for
Private mstrFindTitle As String
'resulting handle outputs - "default" app instance and child with object
Private mlngFirstHwnd As Long
Private mlngChildHwnd As Long
'------
'replacement GetObject
'------
Public Function GetExcelWbk(pstrFullName As String, _
Optional pbleShow As Boolean = False, _
Optional pbleWasOpenOutput As Boolean) As Object
Dim XLApp As Object
Dim xlWbk As Object
Dim strWbkNameOnly As String
Set XLApp = GetExcelAppForWbkPath(pstrFullName, pbleWasOpenOutput)
'other stuff can be done here if the app needs to be prepared for the load
If pbleWasOpenOutput = False Then
'load it, without flicker, if you plan to show it
If pbleShow = False Then
XLApp.ScreenUpdating = False
End If
Set xlWbk = XLApp.Workbooks.Open(pstrFullName)
Else
'get it by its (pathless, if saved) name
strWbkNameOnly = PathOrFileNm("FileNm", pstrFullName)
Set xlWbk = XLApp.Workbooks(strWbkNameOnly)
End If
Set GetExcelWbk = xlWbk
Set xlWbk = Nothing
Set XLApp = Nothing
End Function
Private Function GetExcelAppForWbkPath(pstrFullName As String, _
pbleWbkWasOpenOutput As Boolean, _
Optional pbleLoadAddIns As Boolean = True) As Object
Dim XLApp As Object
Dim bleAppRunning As Boolean
Dim lngHwnd As Long
'get a handle, and determine whether it's for a workbook or an app instance
lngHwnd = WbkOrFirstAppHandle(pstrFullName, pbleWbkWasOpenOutput)
'if a handle came back, at least one instance of Excel is running
'(this isnt' particularly useful; just check XLApp.Visible when you're done getting/opening;
'if it's a hidden instance, it wasn't running)
bleAppRunning = (lngHwnd > 0)
'get an app instance.
Set XLApp = GetAppForHwnd(lngHwnd, pbleWbkWasOpenOutput, pbleLoadAddIns)
Set GetExcelAppForWbkPath = XLApp
Set XLApp = Nothing
Exit Function
End Function
Private Function WbkOrFirstAppHandle(pstrFullName As String, _
pbleIsChildWindowOutput As Boolean) As Long
Dim retval As Long
'defaults
mstrAppClass = "XLMAIN"
mstrFindTitle = PathOrFileNm("FileNm", pstrFullName)
mlngFirstHwnd = 0
mlngChildHwnd = 0
'find
retval = EnumWindows(AddressOf EnumWindowsProc, 0)
If mlngChildHwnd > 0 Then
pbleIsChildWindowOutput = True
WbkOrFirstAppHandle = mlngChildHwnd
Else
WbkOrFirstAppHandle = mlngFirstHwnd
End If
'clear
mstrAppClass = ""
mstrFindTitle = ""
mlngFirstHwnd = 0
mlngChildHwnd = 0
End Function
Private Function GetAppForHwnd(plngHWnd As Long, _
pbleIsChild As Boolean, _
pbleLoadAddIns As Boolean) As Object
On Error GoTo HandleError
Dim XLApp As Object
Dim AI As Object
If plngHWnd > 0 Then
If pbleIsChild = True Then
'get the parent instance using accessibility
Set XLApp = GetExcelAppForHwnd(plngHWnd)
Else
'get the "default" instance
Set XLApp = GetObject(, "Excel.Application")
End If
Else
'no Excel running
Set XLApp = CreateObject("Excel.Application")
If pbleLoadAddIns = True Then
'explicitly reload add-ins (automation doesn't)
For Each AI In XLApp.AddIns
If AI.Installed Then
AI.Installed = False
AI.Installed = True
End If
Next AI
End If
End If
Set GetAppForHwnd = XLApp
Set AI = Nothing
Set XLApp = Nothing
Exit Function
End Function
'------
'API wrappers and utilities
'------
Public Function uWindowClass(ByVal hWnd As Long) As String
Dim strBuffer As String
Dim retval As Long
strBuffer = Space(256)
retval = GetClassName(hWnd, strBuffer, 255)
uWindowClass = Left(strBuffer, retval)
End Function
Public Function uWindowTitle(ByVal hWnd As Long) As String
Dim lngLen As Long
Dim strBuffer As String
Dim retval As Long
lngLen = GetWindowTextLength(hWnd) + 1
If lngLen > 1 Then
'title found - pad buffer
strBuffer = Space(lngLen)
'...get titlebar text
retval = GetWindowText(hWnd, strBuffer, lngLen)
uWindowTitle = Left(strBuffer, lngLen - 1)
End If
End Function
Public Sub uShowWindow(ByVal hWnd As Long, _
Optional pShowType As swcShowWindowCmd = swcRestore)
Dim retval As Long
retval = ShowWindow(hWnd, pShowType)
Select Case pShowType
Case swcMaximized, swcNormal, swcRestore, swcShow
BringWindowToTop hWnd
SetFocus hWnd
End Select
End Sub
Private Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Dim strThisClass As String
Dim strThisTitle As String
Dim retval As Long
Dim bleMatch As Boolean
'mlngWinCounter = mlngWinCounter + 1
'type of window is all you need for parent
strThisClass = uWindowClass(hWnd)
bleMatch = (strThisClass = mstrAppClass)
If bleMatch = True Then
strThisTitle = uWindowTitle(hWnd)
'Debug.Print "Window #"; mlngWinCounter; " : ";
'Debug.Print strThisTitle; "(" & strThisClass & ") " & hWnd
If mlngFirstHwnd = 0 Then mlngFirstHwnd = hWnd
'mlngChildWinCounter 0
retval = EnumChildWindows(hWnd, AddressOf EnumChildProc, 0)
If mlngChildHwnd > 0 Then
'If mbleFindAll = False And mlngChildHwnd > 0 Then
'stop EnumWindows by setting result to 0
EnumWindowsProc = 0
Else
EnumWindowsProc = 1
End If
Else
EnumWindowsProc = 1
End If
End Function
Private Function EnumChildProc(ByVal hWnd As Long, ByVal lParam As Long) As Long
Dim strThisClass As String
Dim strThisTitle As String
Dim retval As Long
Dim bleMatch As Boolean
strThisClass = uWindowClass(hWnd)
strThisTitle = uWindowTitle(hWnd)
If Len(mstrFindTitle) > 0 Then
bleMatch = (strThisTitle = mstrFindTitle)
Else
bleMatch = True
End If
If bleMatch = True Then
mlngChildHwnd = hWnd
EnumChildProc = 0
Else
EnumChildProc = 1
End If
End Function
Public Function GetExcelAppForHwnd(pChildHwnd As Long) As Object
Dim o As Object
Dim g As GUID
Dim retval As Long
'for child objects only, e.g. must use a loaded workbook to get its parent Excel.Application
'make a valid GUID type
retval = IIDFromString(StrPtr(Guid_Excel), g)
'get
retval = AccessibleObjectFromWindow(pChildHwnd, OBJID_NATIVEOM, g, o)
If retval >= 0 Then
Set GetExcelAppForHwnd = o.Application
End If
End Function
Public Function PathOrFileNm(pstrPathOrFileNm As String, _
pstrFileNmWithPath As String)
On Error GoTo HandleError
Dim i As Integer
Dim j As Integer
Dim strChar As String
If Len(pstrFileNmWithPath) > 0 Then
i = InStrRev(pstrFileNmWithPath, "\")
If i = 0 Then
i = InStrRev(pstrFileNmWithPath, "/")
End If
If i > 0 Then
Select Case pstrPathOrFileNm
Case "Path"
PathOrFileNm = Left(pstrFileNmWithPath, i - 1)
Case "FileNm"
PathOrFileNm = Mid(pstrFileNmWithPath, i + 1)
End Select
ElseIf pstrPathOrFileNm = "FileNm" Then
PathOrFileNm = pstrFileNmWithPath
End If
End If
End Function
And then some sample/test code.
Public Sub Test_GetExcelWbk()
Dim MyXLApp As Object
Dim MyXLWbk As Object
Dim bleXLWasRunning As Boolean
Dim bleWasOpen As Boolean
Const TESTPATH As String = "C:\temp\MyFlickerbook.xlsx"
Const SHOWONLOAD As Boolean = False
Set MyXLWbk = GetExcelWbk(TESTPATH, SHOWONLOAD, bleWasOpen)
If Not (MyXLWbk Is Nothing) Then
Set MyXLApp = MyXLWbk.Parent
bleXLWasRunning = MyXLApp.Visible
If SHOWONLOAD = False Then
If MsgBox("Show " & TESTPATH & "?", vbOKCancel) = vbOK Then
MyXLApp.Visible = True
MyXLApp.Windows(MyXLWbk.Name).Visible = True
End If
End If
If bleWasOpen = False Then
If MsgBox("Close " & TESTPATH & "?", vbOKCancel) = vbOK Then
MyXLWbk.Close SaveChanges:=False
If bleXLWasRunning = False Then
MyXLApp.Quit
End If
End If
End If
End If
Set MyXLWbk = Nothing
Set MyXLApp = Nothing
End Sub
Hope someone else finds this useful.

vb6 - how to get the remote computer name based on the given IP address

how can i get the remote computer name based on a given IP Address in vb6? Is there any way that i can list out a list of computers linked to current computer?
If reverse DNS lookup does what you want this might help. This example simplifies the processing of the DNS results, but should get you started and may be enough:
Option Explicit
Private Const DNS_TYPE_PTR = &HC
Private Const DNS_QUERY_STANDARD = &H0
Private Const DnsFreeRecordListDeep = 1&
Private Enum DNS_STATUS
ERROR_BAD_IP_FORMAT = -3&
ERROR_NO_PTR_RETURNED = -2&
ERROR_NO_RR_RETURNED = -1&
DNS_STATUS_SUCCESS = 0&
End Enum
Private Type VBDnsRecord
pNext As Long
pName As Long
wType As Integer
wDataLength As Integer
Flags As Long
dwTTL As Long
dwReserved As Long
prt As Long
others(9) As Long
End Type
Private Declare Function DnsQuery Lib "Dnsapi" Alias "DnsQuery_A" ( _
ByVal Name As String, _
ByVal wType As Integer, _
ByVal Options As Long, _
ByRef aipServers As Any, _
ByRef ppQueryResultsSet As Long, _
ByVal pReserved As Long) As Long
Private Declare Function DnsRecordListFree Lib "Dnsapi" ( _
ByVal pDnsRecord As Long, _
ByVal DnsFreeRecordListDeep As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
ByRef pTo As Any, _
ByRef uFrom As Any, _
ByVal lSize As Long)
Private Declare Function StrCopyA Lib "kernel32" Alias "lstrcpyA" ( _
ByVal retval As String, _
ByVal PTR As Long) As Long
Private Declare Function StrLenA Lib "kernel32" Alias "lstrlenA" ( _
ByVal PTR As Long) As Long
Public Function IP2HostName(ByVal IP As String, ByRef HostName As String) As Long
Dim Octets() As String
Dim OctX As Long
Dim NumPart As Long
Dim BadIP As Boolean
Dim lngDNSRec As Long
Dim Record As VBDnsRecord
Dim Length As Long
'Returns DNS_STATUS Enum values, otherwise a DNS system error code.
IP = Trim$(IP)
If Len(IP) = 0 Then IP2HostName = ERROR_BAD_IP_FORMAT: Exit Function
Octets = Split(IP, ".")
If UBound(Octets) <> 3 Then IP2HostName = ERROR_BAD_IP_FORMAT: Exit Function
For OctX = 0 To 3
If IsNumeric(Octets(OctX)) Then
NumPart = CInt(Octets(OctX))
If 0 <= NumPart And NumPart <= 255 Then
Octets(OctX) = CStr(NumPart)
Else
BadIP = True
Exit For
End If
Else
BadIP = True
Exit For
End If
Next
If BadIP Then IP2HostName = ERROR_BAD_IP_FORMAT: Exit Function
IP = Octets(3) & "." & Octets(2) & "." & Octets(1) & "." & Octets(0) & ".IN-ADDR.ARPA"
IP2HostName = DnsQuery(IP, DNS_TYPE_PTR, DNS_QUERY_STANDARD, ByVal 0, lngDNSRec, 0)
If IP2HostName = DNS_STATUS_SUCCESS Then
If lngDNSRec <> 0 Then
CopyMemory Record, ByVal lngDNSRec, LenB(Record)
With Record
If .wType = DNS_TYPE_PTR Then
Length = StrLenA(.prt)
HostName = String$(Length, 0)
StrCopyA HostName, .prt
Else
IP2HostName = ERROR_NO_PTR_RETURNED
End If
End With
DnsRecordListFree lngDNSRec, DnsFreeRecordListDeep
Else
IP2HostName = ERROR_NO_RR_RETURNED
End If
'Else
'Return with DNS error code.
End If
End Function
Note however it does not handle NetBIOS names.
According to this Microsoft support article, the standard GetHostByAddr() functions should do it. Unfortunately, I can't find any examples of how to do a GetHostByAddr call in VB6, but perhaps someone else can help with that part. Alternately, you could run a commandline tool like nslookup:
bensonk#hunter ~/Desktop/cont $ nslookup 64.34.119.12
Server: 208.67.222.222
Address: 208.67.222.222#53
Non-authoritative answer:
12.119.34.64.in-addr.arpa name = stackoverflow.com.
That example was run on a linux machine, but the same command will work fine on windows.
MOST SIMPLE TECHNIQUE EVER
To send computer name ,
Do this:
Create a textbox,
Change its multiline property to true.
After that, in the text property of that textbox, write this:
echo %computername% >> C:\temp.txt
then, using Fileinput, input the textfile and input the textfile C:\temp.txt.
If you want to use this for sending over winsock or LAN, Send the text box text using winsock1.sendata
Done

Resources