Windows未公开函数揭密——之一

    技术2022-05-11  80

    Windows未公开函数揭密——之一

    什么是未公开函数?

           对于WindowsAPI函数调用相信大家已经不会陌生了。API函数调用是通过在VB中定义和调用Windows动态连接库中的函数从而扩展VB程序的功能。API函数的定义和调用方法在微软的开发工具中都有详细的说明。

           那么什么是“未公开”函数呢?微软为了某种目的。对于一些封装在系统中的函数没有在任何开发文档提供任何函数说明和定义。而这些函数有很多都是很有用的。所幸的是一些有心之人对Windows系统动态连接库做了十分详细的分析,从而将这些未公开函数公开以供广大开发人员共享(我对他们的感激之情就象滔滔江水,绵绵不绝

           好了,废话少说,言归正传,这里首先向大家介绍的是Windows下未公开的关闭Windows的函数。在Windows API函数中虽然提供了ExitWindowsEx这样的API函数,但是在有一些程序中我们需要象一些程序安装完毕那样提示用户重新启动计算机或者不重新启动计算机。或者要在程序中弹出关闭系统对话框。要实现这些功能就要使用Windows未公开函数了。下面来看程序

    首先建立一个新的工程文件,在工程文件中加入一个Module文件。在Module文件中加入以下代码:

     

    Option Explicit

      

    Public bIsWinNT As Boolean

     

    '下面就是未公开的函数定义,注意在Alias之后没有使用函数的真正名字

    '而是用了函数编号,这是因为微软没有公开函数名

    Declare Function SHRestartSystemMB Lib "shell32" _

           Alias "#59" _

          (ByVal hOwner As Long, _

           ByVal sExtraPrompt As String, _

           ByVal uFlags As Long) As Long

    Declare Function SHShutDownDialog Lib "shell32" _

            Alias "#60" _

            (ByVal YourGuess As Long) As Long

     

    Declare Function GetVersionEx Lib "kernel32" _

            Alias "GetVersionExA" _

            (lpVersionInformation As OSVERSIONINFO) As Long

                                        

    Type OSVERSIONINFO

            dwOSVersionInfoSize As Long

            dwMajorVersion As Long

            dwMinorVersion As Long

            dwBuildNumber As Long

            dwPlatformId As Long

            szCSDVersion As String * 128

    End Type

      

    Public Const EWX_LOGOFF = 0

    Public Const EWX_SHUTDOWN = 1

    Public Const EWX_REBOOT = 2

    Public Const EWX_FORCE = 4

    Public Const EWX_POWEROFF = 8

    Public Const shrsExitNoDefPrompt = 1

    Public Const shrsRebootSystem = 2

      

    Const VER_PLATFORM_WIN32s = 0

    Const VER_PLATFORM_WIN32_WINDOWS = 1

    Const VER_PLATFORM_WIN32_NT = 2

      

    Declare Sub CopyMemory Lib "kernel32" _

            Alias "RtlMoveMemory" _

            (pDest As Any, _

            pSource As Any, _

            ByVal ByteLen As Long)

      

    Declare Function IsTextUnicode Lib "advapi32" _

            (lpBuffer As Any, _

            ByVal cb As Long, _

            lpi As Long) As Long

                                  

    Public Const IS_TEXT_UNICODE_ASCII16 = &H1

    Public Const IS_TEXT_UNICODE_REVERSE_ASCII16 = &H10

    Public Const IS_TEXT_UNICODE_STATISTICS = &H2

    Public Const IS_TEXT_UNICODE_REVERSE_STATISTICS = &H20

    Public Const IS_TEXT_UNICODE_CONTROLS = &H4

    Public Const IS_TEXT_UNICODE_REVERSE_CONTROLS = &H40

    Public Const IS_TEXT_UNICODE_SIGNATURE = &H8

    Public Const IS_TEXT_UNICODE_REVERSE_SIGNATURE = &H80

    Public Const IS_TEXT_UNICODE_ILLEGAL_CHARS = &H100

    Public Const IS_TEXT_UNICODE_ODD_LENGTH = &H200

    Public Const IS_TEXT_UNICODE_DBCS_LEADBYTE = &H400

    Public Const IS_TEXT_UNICODE_NULL_BYTES = &H1000

    Public Const IS_TEXT_UNICODE_UNICODE_MASK = &HF

    Public Const IS_TEXT_UNICODE_REVERSE_MASK = &HF0

    Public Const IS_TEXT_UNICODE_NOT_UNICODE_MASK = &HF00

    Public Const IS_TEXT_UNICODE_NOT_ASCII_MASK = &HF000

     

    Public Function IsWinNT() As Boolean

        Dim osvi As OSVERSIONINFO

        osvi.dwOSVersionInfoSize = Len(osvi)

        GetVersionEx osvi

        IsWinNT = (osvi.dwPlatformId = VER_PLATFORM_WIN32_NT)

    End Function

     

     

    Public Function CheckString(msg As String) As String

        If bIsWinNT Then

            CheckString = StrConv(msg, vbUnicode)

        Else: CheckString = msg

        End If

    End Function

     

     

    Public Function GetStrFromPtr(lpszStr As Long, nBytes As Integer) As String

        ReDim ab(nBytes) As Byte

       

        CopyMemory ab(0), ByVal lpszStr, nBytes

        GetStrFromPtr = GetStrFromBuffer(StrConv(ab(), vbUnicode))

    End Function

     

     

    Public Function GetStrFromBuffer(szStr As String) As String

        If IsUnicodeStr(szStr) Then szStr = StrConv(szStr, vbFromUnicode)

      

        If InStr(szStr, vbNullChar) Then

            GetStrFromBuffer = Left$(szStr, InStr(szStr, vbNullChar) - 1)

        Else: GetStrFromBuffer = szStr

        End If

    End Function

     

     

    Public Function IsUnicodeStr(sBuffer As String) As Boolean

        Dim dwRtnFlags As Long

       

        dwRtnFlags = IS_TEXT_UNICODE_UNICODE_MASK

        IsUnicodeStr = IsTextUnicode(ByVal sBuffer, Len(sBuffer), dwRtnFlags)

    End Function

     

           然后在Form1中加入一个ComboBox控件、两个CommandButton控件,然后在Form1的代码窗口中加入以下代码:

     

    Private Sub Command1_Click()

        Call SHShutDownDialog(0)

    End Sub

     

    Private Sub Command2_Click()

        Dim sPrompt As String

        Dim uFlag As Long

      

        Select Case Combo1.ListIndex

            Case -1: uFlag = Val(Combo1.Text)

            Case 0:  uFlag = shrsExitNoDefPrompt

            Case 1:  uFlag = shrsRebootSystem

        End Select

      

        If SHRestartSystemMB(hWnd, sPrompt, uFlag) = vbYes Then

        End If

    End Sub

     

    Private Sub Form_Load()

        bIsWinNT = IsWinNT()

       

        If bIsWinNT Then    'WinNT操作系统

            With Combo1

                .AddItem "0 - 关闭程序并以其它用户身份登陆"

                .AddItem "1 - 关闭计算机"

                .AddItem "2 - 重新启动计算机"

                .Text = ""

            End With

        Else   'Win95/98操作系统

            With Combo1

                .AddItem "1 - 关闭计算机"

                .AddItem "2 - 重新启动计算机"

                .Text = ""

            End With

       End If

       Command1.Caption = "关闭系统对话框"

       Command2.Caption = "关闭或重新启动计算机"

    End Sub

     

           运行程序,点击“关闭系统对话框”按钮就可以弹出关闭系统对话框。在Combo1中选择关闭系统、重新启动或者关闭程序并以其它用户身份登陆项再点击“关闭或重新启动计算机”按钮,系统就会弹出提示对话框提示是否执行相应的操作,点击“是”就可以执行了。

    E-Mail      vbcode@21cn.com 


    最新回复(0)