none
how to use SendMessage to delete item listview in External program RRS feed

  • Question

  • hi guys..

    i need my app edit External program and delete item from her listview

    see this proof

    this External program i need my app edit it runtime and delete this item Eagle using SendMesage function


    Sunday, June 25, 2017 2:17 AM

All replies

  • You get the ListView handle, then
    GetWindowThreadProcessId()
    OpenProcess()
    VirtualAllocEx()

    You loop on items (SendMessage() with LVM_GETITEMCOUNT) by getting their text by filling a LVITEM structure then
    WriteProcessMemory()
    SendMessage() with LVM_GETITEMW
    ReadProcessMemory()

    when you find your item, you call SendMessage() with LVM_DELETEITEM

    I just tested it on Windows 10 with those declarations:

    <DllImport("User32", SetLastError:=True)>
    Public Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As Int32) As UInteger
    End Function
    
    <DllImport("User32", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function
    
    <DllImport("User32", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function FindWindowEx(ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
    End Function
    
    Const SYNCHRONIZE As Integer = (&H100000)
    Const STANDARD_RIGHTS_REQUIRED As Integer = (&HF0000)
    
    Const PROCESS_VM_OPERATION As Integer = (&H8)
    Const PROCESS_VM_READ As Integer = (&H10)
    Const PROCESS_VM_WRITE As Integer = (&H20)
    Const PROCESS_DUP_HANDLE As Integer = (&H40)
    Const PROCESS_CREATE_PROCESS As Integer = (&H80)
    Const PROCESS_SET_QUOTA As Integer = (&H100)
    Const PROCESS_SET_INFORMATION As Integer = (&H200)
    Const PROCESS_QUERY_INFORMATION As Integer = (&H400)
    Const PROCESS_SUSPEND_RESUME As Integer = (&H800)
    Const PROCESS_QUERY_LIMITED_INFORMATION As Integer = (&H1000)
    Const PROCESS_SET_LIMITED_INFORMATION As Integer = (&H2000)
    Const PROCESS_ALL_ACCESS As Integer = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFFF)
    
    <DllImport("kernel32.dll")>
    Public Shared Function OpenProcess(dwDesiredAccess As UInteger, bInheritHandle As Boolean, dwProcessId As Integer) As IntPtr
    End Function
    
    
    <DllImport("kernel32.dll")>
    Private Shared Function CloseHandle(hObject As IntPtr) As [Boolean]
    End Function
    
    
    <DllImport("User32.dll", EntryPoint:="SendMessageW", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function
    
    Public Const MEM_COMMIT = &H1000
    Public Const MEM_RESERVE = &H2000
    Public Const MEM_DECOMMIT = &H4000
    Public Const MEM_RELEASE = &H8000
    Public Const MEM_FREE = &H10000
    
    Public Const PAGE_NOACCESS = &H1
    Public Const PAGE_READONLY = &H2
    Public Const PAGE_READWRITE = &H4
    Public Const PAGE_WRITECOPY = &H8
    
    <DllImport("Kernel32", SetLastError:=True)>
    Public Shared Function VirtualAllocEx(hProcess As IntPtr, address As IntPtr, size As UIntPtr, allocationType As Integer, protect As Integer) As IntPtr
    End Function
    
    <DllImport("Kernel32", SetLastError:=True)>
    Public Shared Function VirtualFreeEx(MhProcess As IntPtr, address As IntPtr, size As UIntPtr, allocationType As Integer) As Boolean
    End Function
    
     <DllImport("kernel32.dll")>
    Public Shared Function WriteProcessMemory(hProcess As IntPtr, lpBaseAddress As IntPtr, lpBuffer As IntPtr, nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
    End Function
    <DllImport("kernel32.dll")>
    Public Shared Function ReadProcessMemory(hProcess As IntPtr, lpBaseAddress As IntPtr, lpBuffer As IntPtr, nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
    End Function
    
    <StructLayoutAttribute(LayoutKind.Sequential)>
    Public Structure LVITEM
        Public mask As Integer
        Public iItem As Integer
        Public iSubItem As Integer
        Public state As Integer
        Public stateMask As Integer
        Public pszText As IntPtr
        Public cchTextMax As Integer
        Public iImage As Integer
        Public lParam As IntPtr
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
    End Structure
    
    Public Const LVM_FIRST = &H1000
    Public Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
    Public Const LVM_GETITEMTEXTA = (LVM_FIRST + 45)
    Public Const LVM_GETITEMTEXTW = (LVM_FIRST + 115)
    Public Const LVM_DELETEITEM = (LVM_FIRST + 8)
    Public Const LVM_GETITEMA = (LVM_FIRST + 5)
    Public Const LVM_GETITEMW = (LVM_FIRST + 75)


    Sunday, June 25, 2017 6:56 AM
  • Somebody has made a whole thread about like you who ask so many of this kind of questions.

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/6d0d3696-9445-4afd-8da2-5718dded2568/so-many-potential-malicious-questions?forum=vbgeneral


    Success
    Cor


    Sunday, June 25, 2017 8:56 AM
  • You get the ListView handle, then
    GetWindowThreadProcessId()
    OpenProcess()
    VirtualAllocEx()

    You loop on items (SendMessage() with LVM_GETITEMCOUNT) by getting their text by filling a LVITEM structure then
    WriteProcessMemory()
    SendMessage() with LVM_GETITEMW
    ReadProcessMemory()

    when you find your item, you call SendMessage() with LVM_DELETEITEM

    I just tested it on Windows 10 with those declarations:

    <DllImport("User32", SetLastError:=True)>
    Public Shared Function GetWindowThreadProcessId(hWnd As IntPtr, ByRef lpdwProcessId As Int32) As UInteger
    End Function
    
    <DllImport("User32", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function
    
    <DllImport("User32", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function FindWindowEx(ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
    End Function
    
    Const SYNCHRONIZE As Integer = (&H100000)
    Const STANDARD_RIGHTS_REQUIRED As Integer = (&HF0000)
    
    Const PROCESS_VM_OPERATION As Integer = (&H8)
    Const PROCESS_VM_READ As Integer = (&H10)
    Const PROCESS_VM_WRITE As Integer = (&H20)
    Const PROCESS_DUP_HANDLE As Integer = (&H40)
    Const PROCESS_CREATE_PROCESS As Integer = (&H80)
    Const PROCESS_SET_QUOTA As Integer = (&H100)
    Const PROCESS_SET_INFORMATION As Integer = (&H200)
    Const PROCESS_QUERY_INFORMATION As Integer = (&H400)
    Const PROCESS_SUSPEND_RESUME As Integer = (&H800)
    Const PROCESS_QUERY_LIMITED_INFORMATION As Integer = (&H1000)
    Const PROCESS_SET_LIMITED_INFORMATION As Integer = (&H2000)
    Const PROCESS_ALL_ACCESS As Integer = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFFF)
    
    <DllImport("kernel32.dll")>
    Public Shared Function OpenProcess(dwDesiredAccess As UInteger, bInheritHandle As Boolean, dwProcessId As Integer) As IntPtr
    End Function
    
    
    <DllImport("kernel32.dll")>
    Private Shared Function CloseHandle(hObject As IntPtr) As [Boolean]
    End Function
    
    
    <DllImport("User32.dll", EntryPoint:="SendMessageW", SetLastError:=True, CharSet:=CharSet.Auto)>
    Public Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Integer, ByVal lParam As IntPtr) As Integer
    End Function
    
    Public Const MEM_COMMIT = &H1000
    Public Const MEM_RESERVE = &H2000
    Public Const MEM_DECOMMIT = &H4000
    Public Const MEM_RELEASE = &H8000
    Public Const MEM_FREE = &H10000
    
    Public Const PAGE_NOACCESS = &H1
    Public Const PAGE_READONLY = &H2
    Public Const PAGE_READWRITE = &H4
    Public Const PAGE_WRITECOPY = &H8
    
    <DllImport("Kernel32", SetLastError:=True)>
    Public Shared Function VirtualAllocEx(hProcess As IntPtr, address As IntPtr, size As UIntPtr, allocationType As Integer, protect As Integer) As IntPtr
    End Function
    
    <DllImport("Kernel32", SetLastError:=True)>
    Public Shared Function VirtualFreeEx(MhProcess As IntPtr, address As IntPtr, size As UIntPtr, allocationType As Integer) As Boolean
    End Function
    
     <DllImport("kernel32.dll")>
    Public Shared Function WriteProcessMemory(hProcess As IntPtr, lpBaseAddress As IntPtr, lpBuffer As IntPtr, nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
    End Function
    <DllImport("kernel32.dll")>
    Public Shared Function ReadProcessMemory(hProcess As IntPtr, lpBaseAddress As IntPtr, lpBuffer As IntPtr, nSize As Integer, ByRef vNumberOfBytesRead As UInteger) As Boolean
    End Function
    
    <StructLayoutAttribute(LayoutKind.Sequential)>
    Public Structure LVITEM
        Public mask As Integer
        Public iItem As Integer
        Public iSubItem As Integer
        Public state As Integer
        Public stateMask As Integer
        Public pszText As IntPtr
        Public cchTextMax As Integer
        Public iImage As Integer
        Public lParam As IntPtr
        Public iIndent As Integer
        Public iGroupId As Integer
        Public cColumns As Integer
        Public puColumns As IntPtr
    End Structure
    
    Public Const LVM_FIRST = &H1000
    Public Const LVM_GETITEMCOUNT = (LVM_FIRST + 4)
    Public Const LVM_GETITEMTEXTA = (LVM_FIRST + 45)
    Public Const LVM_GETITEMTEXTW = (LVM_FIRST + 115)
    Public Const LVM_DELETEITEM = (LVM_FIRST + 8)
    Public Const LVM_GETITEMA = (LVM_FIRST + 5)
    Public Const LVM_GETITEMW = (LVM_FIRST + 75)


    bro please can you complete your code how to use it idk :/
    Sunday, June 25, 2017 7:04 PM
  • For example :

    Public Shared Function ListViewFindItem(hWnd As IntPtr, sItemText As String) As Integer
        Dim nReturn = -1
        Dim pid As Integer
        GetWindowThreadProcessId(hWnd, pid)
        Dim hProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_QUERY_INFORMATION, False, pid)
        If (hProcess) Then
            Dim nNbItems As Integer = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0)
            Dim pPointer As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
    
            For nItem As Integer = 0 To nNbItems - 1
                Dim lvItem As LVITEM = New LVITEM()
                Dim sStringBuffer As Byte() = New Byte(255) {}
    
                lvItem.mask = 1
                lvItem.iItem = nItem
                lvItem.cchTextMax = sStringBuffer.Length
                lvItem.pszText = pPointer
    
                Dim nNbBytesRead As UInteger = 0
                Dim pLVI As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(LVITEM)))
                Marshal.StructureToPtr(lvItem, pLVI, False)
                If (WriteProcessMemory(hProcess, pPointer, pLVI, Marshal.SizeOf(GetType(LVITEM)), nNbBytesRead)) Then
                    SendMessage(hWnd, LVM_GETITEMW, nItem, pPointer)
                    ReadProcessMemory(hProcess, pPointer, Marshal.UnsafeAddrOfPinnedArrayElement(sStringBuffer, 0), sStringBuffer.Length, nNbBytesRead)
    
                    Dim sItemTextUnicode As String = Encoding.Unicode.GetString(sStringBuffer, 0, nNbBytesRead)
                    Dim nEndText As Integer = sItemTextUnicode.IndexOf(ControlChars.NullChar & ControlChars.NullChar)
                    Dim sFindItemText = sItemTextUnicode.Substring(0, nEndText)
    
                    If (sFindItemText = sItemText) Then
                        nReturn = nItem
                        Marshal.FreeHGlobal(pLVI)
                        Exit For
                    End If
                End If
                Marshal.FreeHGlobal(pLVI)
            Next
    
            VirtualFreeEx(hProcess, pPointer, 0, MEM_RELEASE)
            CloseHandle(hProcess)
        Else
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error())
        End If
        Return nReturn
    End Function

    Dim nItem As Integer = ListViewFindItem(hWnd, "Eagle")
    If (nItem <> -1) Then
        SendMessage(hWnd, LVM_DELETEITEM, nItem, 0)
    End If


    • Edited by Castorix31 Sunday, June 25, 2017 7:59 PM
    Sunday, June 25, 2017 7:54 PM
  • For example :

    Public Shared Function ListViewFindItem(hWnd As IntPtr, sItemText As String) As Integer
        Dim nReturn = -1
        Dim pid As Integer
        GetWindowThreadProcessId(hWnd, pid)
        Dim hProcess As IntPtr = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE Or PROCESS_QUERY_INFORMATION, False, pid)
        If (hProcess) Then
            Dim nNbItems As Integer = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0)
            Dim pPointer As IntPtr = VirtualAllocEx(hProcess, IntPtr.Zero, 260, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
    
            For nItem As Integer = 0 To nNbItems - 1
                Dim lvItem As LVITEM = New LVITEM()
                Dim sStringBuffer As Byte() = New Byte(255) {}
    
                lvItem.mask = 1
                lvItem.iItem = nItem
                lvItem.cchTextMax = sStringBuffer.Length
                lvItem.pszText = pPointer
    
                Dim nNbBytesRead As UInteger = 0
                Dim pLVI As IntPtr = Marshal.AllocHGlobal(Marshal.SizeOf(GetType(LVITEM)))
                Marshal.StructureToPtr(lvItem, pLVI, False)
                If (WriteProcessMemory(hProcess, pPointer, pLVI, Marshal.SizeOf(GetType(LVITEM)), nNbBytesRead)) Then
                    SendMessage(hWnd, LVM_GETITEMW, nItem, pPointer)
                    ReadProcessMemory(hProcess, pPointer, Marshal.UnsafeAddrOfPinnedArrayElement(sStringBuffer, 0), sStringBuffer.Length, nNbBytesRead)
    
                    Dim sItemTextUnicode As String = Encoding.Unicode.GetString(sStringBuffer, 0, nNbBytesRead)
                    Dim nEndText As Integer = sItemTextUnicode.IndexOf(ControlChars.NullChar & ControlChars.NullChar)
                    Dim sFindItemText = sItemTextUnicode.Substring(0, nEndText)
    
                    If (sFindItemText = sItemText) Then
                        nReturn = nItem
                        Marshal.FreeHGlobal(pLVI)
                        Exit For
                    End If
                End If
                Marshal.FreeHGlobal(pLVI)
            Next
    
            VirtualFreeEx(hProcess, pPointer, 0, MEM_RELEASE)
            CloseHandle(hProcess)
        Else
            Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error())
        End If
        Return nReturn
    End Function

    Dim nItem As Integer = ListViewFindItem(hWnd, "Eagle")
    If (nItem <> -1) Then
        SendMessage(hWnd, LVM_DELETEITEM, nItem, 0)
    End If


    i have error bro how can i fix it?? what should i write in

    Dim nItem As Integer = ListViewFindItem(hWnd, "Eagle")
    If (nItem <> -1) Then
        SendMessage(hWnd, LVM_DELETEITEM, nItem, 0)
    End If

    ListViewFindItem(hWnd

    and

    SendMessage(hWnd

    hWnd of what?? Listview or my project??

    see the error

    Monday, June 26, 2017 8:58 AM
  • i writed

            Dim hwnd As IntPtr
            hwnd = FindWindow(vbNullString, "EaGLE") ' WindowTitle
            Dim nItem As Integer = ListViewFindItem(hwnd, "Eagle") 'ItemText in Listview
            If (nItem <> -1) Then
                SendMessage(hwnd, LVM_DELETEITEM, nItem, 0)
            End If

    also not work

    Monday, June 26, 2017 9:04 AM
  • Your sample is wrong because hWnd must be the ListView handle.

    I did not write the code to find this hWnd, because I don't know the hierarchy of your windows (see with Spy++)

    I tested on one of my Listview samples with FindWindow() and GetWindow() with GW_CHILD

    because I know that the ListView is the only child of my window.

    Otherwise, use EnumChildWindows() with GetClassName() then String().Contains("SysListView32") to find the ListView handle.


    • Edited by Castorix31 Monday, June 26, 2017 9:22 AM
    Monday, June 26, 2017 9:21 AM
  • just tell me how can i get hWnd of listview like this

    Monday, June 26, 2017 9:28 AM
  • See the hierarchy of windows.

    In my sample :

    I use (because there is only 1 child, the ListView) :

    Dim hWnd As IntPtr = FindWindow(Nothing, "Caption")
    hWnd = GetWindow(hWnd, GW_CHILD)

    Monday, June 26, 2017 9:37 AM
  • See the hierarchy of windows.

    In my sample :

    I use (because there is only 1 child, the ListView) :

    Dim hWnd As IntPtr = FindWindow(Nothing, "Caption")
    hWnd = GetWindow(hWnd, GW_CHILD)

    what is GetWindow?? and GW_CHILD ??

    Monday, June 26, 2017 10:28 AM
  • what is GetWindow?? and GW_CHILD ??

    You can find them with Google...

    Const GW_HWNDFIRST As Integer = 0
    Const GW_HWNDLAST As Integer = 1
    Const GW_HWNDNEXT As Integer = 2
    Const GW_HWNDPREV As Integer = 3
    Const GW_OWNER As Integer = 4
    Const GW_CHILD As Integer = 5
    Const GW_ENABLEDPOPUP As Integer = 6
    Const GW_MAX As Integer = 6
    
    <DllImport("User32", SetLastError:=True)>
        Public Shared Function GetWindow(hwnd As IntPtr, uCmd As UInteger) As IntPtr
        End Function

    Monday, June 26, 2017 10:36 AM
  • my code is true or false??

      Private Declare Function GetWindow Lib "user32" (ByVal hwnd _
        As Long, ByVal wCmd As Long) As Long
        Private Const GW_CHILD = 5

    but now work!!

    see my app

    Monday, June 26, 2017 10:39 AM
  • i tired not wotk pfff i need just get hwnd of listview howwwwwww

    Monday, June 26, 2017 10:48 AM
  • Then you must use several times

    hWnd = GetWindow(hWnd, GW_CHILD)

    to get the SysListView32...

    Monday, June 26, 2017 10:49 AM
  • Then you must use several times

    hWnd = GetWindow(hWnd, GW_CHILD)

    to get the SysListView32...


    not get ListView hWnd


    Monday, June 26, 2017 11:00 AM
  • I don't see where you used GetWindow() several times to get each child window until you get the Listview in the hierarchy that you posted

    • Edited by Castorix31 Monday, June 26, 2017 11:17 AM
    Monday, June 26, 2017 11:17 AM
  • I don't see where you used GetWindow() several times to get each child window until you get the Listview in the hierarchy that you posted

    i'm very sorry bro but i'm very stupid idk how to get hWnd this Listview please help me

    Monday, June 26, 2017 5:22 PM
  • The best method is with EnumChildWindows() if there are several windows,
    but from your screencopy :

    // Main window
    Dim hWnd As IntPtr = FindWindow(Nothing, "ZED")
    // SysTabControl32
    hWnd = GetWindow(hWnd, GW_CHILD)
    // "Capture Window"
    hWnd = GetWindow(hWnd, GW_CHILD)
    // SysListView32
    hWnd = GetWindow(hWnd, GW_CHILD)

    (of course ListViewFindItem(hWnd, "Eagle") won't work in this sample, with "Ahmed" in first column...)

    Also it may not work if 32-bit <=> 64-bit


    • Edited by Castorix31 Monday, June 26, 2017 5:43 PM
    Monday, June 26, 2017 5:38 PM
  • The best method is with EnumChildWindows() if there are several windows,
    but from your screencopy :

    // Main window
    Dim hWnd As IntPtr = FindWindow(Nothing, "ZED")
    // SysTabControl32
    hWnd = GetWindow(hWnd, GW_CHILD)
    // "Capture Window"
    hWnd = GetWindow(hWnd, GW_CHILD)
    // SysListView32
    hWnd = GetWindow(hWnd, GW_CHILD)

    (of course ListViewFindItem(hWnd, "Eagle") won't work in this sample, with "Ahmed" in first column...)

    Also it may not work if 32-bit <=> 64-bit


    oh bro you are legend vb.net last question how can i make my app delete second item not first

    like this proof i need check item in second subitems

    Monday, June 26, 2017 7:42 PM
  • and i have other question why i can't edit listview if the external programm running as admin

    i running my app with admin and not delete item listview why??

    Monday, June 26, 2017 7:48 PM
  • I don't see where you used GetWindow() several times to get each child window until you get the Listview in the hierarchy that you posted

    i'm very sorry bro but i'm very stupid idk how to get hWnd this Listview please help me

     If this is being used for a ListView that is on another one of your applications,  then you are going about this the wrong way.  You should use one form or another of a interprocess communication to communicate directly between the two applications.  You would just send a message to the other application which contains the data it needs to delete the item(s) from it's ListView and any underlying data collections.

     I also would not recommend doing this on an application that is not yours either.  Even if you succeed in deleting the item from it's ListView,  and assuming it is a well written program,  it will have an internal collection of data which is only being displayed in the ListView,  not stored in the ListView.  The real data would still be there internally,  you would just be removing the displayed item from the ListView but,  not from the internal data collection.


    If you say it can`t be done then i`ll try it

    Monday, June 26, 2017 7:48 PM
  •  how can i make my app delete second item not first

    like this proof i need check item in second subitems

    Just add

    lvItem.iSubItem = 1

    in ListViewFindItem()

    to read the text of the second column

    Monday, June 26, 2017 8:41 PM
  •  how can i make my app delete second item not first

    like this proof i need check item in second subitems

    Just add

    lvItem.iSubItem = 1

    in ListViewFindItem()

    to read the text of the second column

    and i have other question why i can't edit listview if the external programm running as admin

    i running my app with admin and not delete item listview why??

    Tuesday, June 27, 2017 1:18 AM
  • and i have other question why i can't edit listview if the external programm running as admin

    i running my app with admin and not delete item listview why??

    LVM_DELETEITEM works for me on Windows 10, only if both applications are 32-bit or 64-bit

    (for example, if I compile as x64, it won't delete an item in a ListView from a 32-bit application)

    Tuesday, June 27, 2017 4:51 AM
  • I would modify the external application for inter-process communication so you can send a message to have it remove a particular item from the ListView. If the external app is not yours and is from a third-party then you have no business attempting to modify it in this way and any anti-malware or anti-virus app may block the operation.


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Tuesday, June 27, 2017 12:23 PM