27.4 API中的函数指针

Posted VB.Net

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了27.4 API中的函数指针相关的知识,希望对你有一定的参考价值。

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。

有时候在API中还有函数作为参数的时候,例如EnumWindows,它的作用枚举所有的窗口。其C原型为:

BOOL EnumWindows(

  WNDENUMPROC lpEnumFunc,

  LPARAM lParam

);

MSDN对于参数lpEnumFunc的解释是:

Long pointer to an application-defined callback function.

亦即指向函数的长指针。其实看lpEnumFunc这个参数也可以获得一些信息:lp说明是长指针,Func说明是函数。参数lpEnumFunc指向的函数有一个比较固定的写法:

BOOL CALLBACK EnumWindowsProc(

  HWND hwnd,

  LPARAM lParam

);

参数hwnd事实上是输出的窗口的Handle(句柄),MSDN的解释:

[out] Handle to a top-level window.

可以看到[out],说明是输出的。

EnumWindowsProc中的参数lParam和EnumWindows中的参数lParam一致。

EnumWindowsProc有点像是VB中的事件,Out的参数是给事件内代码使用的。

【例 27A.4【项目:code27A-004】修改窗口的标题。

在以下代码中,先是使用EnumWindows枚举所有窗口的句柄,然后使用GetWindowText获得窗口标题,最后使用SetWindowText修改窗口的标题。

    Structure windowInfo
        Dim hwnd As IntPtr
        Dim title As String
    End Structure
    Dim lstWindowInfo As List(Of windowInfo)

    Private Delegate Function EnuCallBack(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
    Private Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As EnuCallBack, ByVal lParam As Integer) As Integer

    Private Declare Auto Function GetWindowText Lib "user32" (ByVal hWnd As IntPtr, ByVal lpClassName As Text.StringBuilder, ByVal nMaxCount As Integer) As Integer
    Private Declare Auto Function SetWindowText Lib "user32" (ByVal hWnd As IntPtr, lpString As String) As Boolean

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        lstWindowInfo.Clear()
        Try
            Dim getWindows As New EnuCallBack(AddressOf EnumWindowProc)
            Call EnumWindows(getWindows, 0)
            Call showTitle()
        Catch ex As Exception

        End Try
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        lstWindowInfo = New List(Of windowInfo)
    End Sub

    '将窗口标题显示到ListView中
    Private Sub showTitle()
        For i As Integer = 0 To lstWindowInfo.Count - 1
            Dim lviTitle As New ListViewItem(lstWindowInfo(i).hwnd)
            lviTitle.SubItems.Add(lstWindowInfo(i).title)
            lvTitle.Items.Add(lviTitle)
        Next
    End Sub

    '回调函数
    Private Function EnumWindowProc(ByVal hwnd As Integer, ByVal lParam As Integer) As Boolean
        Dim sTitle As New Text.StringBuilder(255)
        Dim lenTitle As Integer
        Dim wininfo As windowInfo

        Try
            'GetWindowText通过传递的参数hwnd获得标题
            lenTitle = GetWindowText(hwnd, sTitle, 255)
            '如果标题不为空,保存窗口句柄、标题到wininfo结构,然后增加到List中
            If sTitle.ToString <> "" Then
                wininfo.hwnd = hwnd
                wininfo.title = sTitle.ToString
                lstWindowInfo.Add(wininfo)
            End If
        Catch ex As Exception
            '出错则取消继续调用
            EnumWindowProc = False
            Exit Function
        End Try
        '必须为True,继续调用
        EnumWindowProc = True
    End Function

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        If lvTitle.SelectedItems.Count < 1 Then Exit Sub
        Dim pos As Integer = lvTitle.SelectedIndices(0)
        Dim selHwnd As IntPtr
        selHwnd = lstWindowInfo(pos).hwnd
        '通过窗口句柄修改窗口标题
        Call SetWindowText(selHwnd, "自定义标题")

    End Sub

运行结果如下图所示:

图27A-4 修改记事本的标题

由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。

学习更多vb.net知识,请参看vb.net 教程 目录

以上是关于27.4 API中的函数指针的主要内容,如果未能解决你的问题,请参考以下文章

27.3 API中的结构

函数指针使用演示样例(參考Linux-内核代码)

27.5 API中类型的变通使用

27.5 API中类型的变通使用

27.2 API函数的类型

Android JNI编程——C语言指针的初步认识指针变量互换两个数函数返回多个值