Windows未公开函数揭密——之一
什么是未公开函数? 
       对于Windows的API函数调用相信大家已经不会陌生了。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      [email protected]    
 
  |