Извлечение текста из Hwnd и освобождение выделенного пространства памяти - PullRequest
0 голосов
/ 14 января 2019

Я новичок в VB.Net. Я пришел с VB6 и VBA, поэтому я все еще учусь. Я пытаюсь очистить пространство памяти, когда я получаю текст, используя мою функцию GetWinTxt (). Я не уверен, правильно ли я освобождаю пространство памяти или нет. Я исследовал MSDN и множество других сайтов, в том числе этот, пытаясь узнать об этом, и я нахожу это несколько запутанным. Эта функция будет использоваться часто, и я не хочу утечки памяти. Кажется, что он работает нормально, потому что нет никаких кодов ошибок, но может кто-то с большим знанием, пожалуйста, скажите мне, правильно ли я делаю? Также я должен использовать Marshal.DestroyStructure (), прежде чем использовать Marshal.FreeHGlobal ()? И если так, как бы я использовал это в моем коде ниже?

Option Explicit On
Imports System.Runtime.InteropServices

Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
End Function

<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr
End Function

Friend Const WM_GETTEXT = &HD
Friend Const WM_GETTEXTLENGTH = &HE

Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
    Dim Hwnd As IntPtr = FindWindow(Nothing, "Untitled - Notepad") 'notepad parent win
    Dim Handle As IntPtr = FindWindowEx(Hwnd, IntPtr.Zero, "Edit", Nothing) 'notepad edit area
    MsgBox(Lf.GetWinTxt(Handle))'Lf is my class name
End Sub

Friend Function GetWinTxt(hwnd As IntPtr) As String
    Dim TextLen As Integer = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1
    Dim WinHandle As IntPtr = Marshal.AllocHGlobal(TextLen)
    Call SendMessage(hwnd, WM_GETTEXT, TextLen, WinHandle)
    Dim txt As String = Marshal.PtrToStringUni(WinHandle)
    GetWinTxt = txt
    Dim ByteString(TextLen) As Byte ' the next 3 lines are what i'm not sure if i'm doing it right or not
    Marshal.Copy(WinHandle, ByteString, 0, TextLen)
    Marshal.FreeHGlobal(txt) 
End Function

РЕДАКТИРОВАННЫЙ ФИНАЛЬНЫЙ КОД:

Public Function GetWinTxt(hwnd As IntPtr) As String
    Dim TextLen As IntPtr = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0) + 1
    Dim f As Integer = TextLen
    Winhandle = Marshal.AllocHGlobal(f)
    Call SendMessage(hwnd, WM_GETTEXT, f, Winhandle)
    Dim txt As String = Marshal.PtrToStringUni(Winhandle)
    Return txt
    Try
        Dim ByteString(f) As Byte
        Marshal.Copy(Winhandle, ByteString, 0, f)
        Marshal.FreeHGlobal(Winhandle)
    Catch ex As Exception
        Return ""
        Debug.Print(ex.Message)
    End Try
End Function

1 Ответ

0 голосов
/ 15 января 2019

Ответ отрицательный, если только вы не вызываете метод, подобный Marshal. StructureToPtr().

Вы должны использовать аналог любого метода, который вы использовали для его распределения. Маршал. Разрушить структуру освободит все подструктуры, на которые указывает блок неуправляемой памяти. Но у тебя нет никакой структуры.

Кроме того, вы вызываете Dim WinHandle As IntPtr = Marshal.AllocHGlobal(TextLen) Выделяет память из неуправляемой памяти процесса на WinHandle, затем освобождает другую, Marshal.FreeHGlobal(txt). Это приведет к утечке памяти. попробуйте изменить его на Marshal.FreeHGlobal(WinHandle).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...