Option Explicit
Private Const WM_USER As Long = &H400
Private Const TB_BUTTONCOUNT As Long = (WM_USER + 24)
Private Const TB_GETBUTTON As Long = (WM_USER + 23)
Private Const MEM_COMMIT As Long = &H1000
Private Const MEM_RELEASE As Long = &H8000
Private Const PAGE_READWRITE As Long = &H4
Private Const WM_LBUTTONDOWN As Long = &H201
Private Const WM_LBUTTONUP As Long = &H202
Private Const PROCESS_QUERY_INFORMATION As Long = (&H400)
Private Const PROCESS_ALL_ACCESS As Long = &H1F0FFF
Private Type TTBButton
iBitmap As Long
idCommand As Long
fsState As Byte
fsStyle As Byte
bReserved(0 To 1) As Byte
dwData As Long
iString As Long
End Type
Private Type TRAYDATA
hwnd As Long
uID As Long
uCallbackMessage As Long
Reserved(0 To 1) As Long
hIcon As Long
End Type
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32.dll" (ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function PostMessage Lib "user32.dll" Alias "PostMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function VirtualAllocEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpBaseAddress As Any, ByRef lpBuffer As Any, ByVal nSize As Long, ByRef lpNumberOfBytesWritten As Long) As Long
Private Declare Function VirtualFreeEx Lib "kernel32.dll" (ByVal hProcess As Long, ByRef lpAddress As Any, ByRef dwSize As Long, ByVal dwFreeType As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Function TrayToolbarWnd() As Long
Dim hTB As Long
hTB = FindWindow("Shell_TrayWnd", vbNullString)
If hTB <> 0 Then
hTB = FindWindowEx(hTB, 0, "TrayNotifyWnd", vbNullString)
If hTB <> 0 Then
hTB = FindWindowEx(hTB, 0, "SysPager", vbNullString)
If hTB <> 0 Then hTB = FindWindowEx(hTB, 0, "ToolbarWindow32", vbNullString)
End If
End If
TrayToolbarWnd = hTB
End Function
Sub VietnameseOff()
Dim nCount As Long, k As Long, sTip As String
Dim tb As TTBButton, tray As TRAYDATA, r As Long
Dim pid As Long, pMemory As Long, hTB As Long, hProcess As Long, BytesRead As Long
hTB = TrayToolbarWnd
GetWindowThreadProcessId hTB, pid
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, pid)
If hProcess = 0 Then Exit Sub
nCount = SendMessage(hTB, TB_BUTTONCOUNT, 0, 0)
pMemory = VirtualAllocEx(hProcess, ByVal 0, ByVal 1024, MEM_COMMIT, PAGE_READWRITE)
For k = 0 To nCount - 1
SendMessage hTB, TB_GETBUTTON, k, pMemory
ReadProcessMemory hProcess, ByVal pMemory, tb, LenB(tb), BytesRead
ReadProcessMemory hProcess, ByVal tb.dwData, tray, LenB(tray), BytesRead
sTip = String(1024, Chr(0))
ReadProcessMemory hProcess, ByVal tb.iString, ByVal StrPtr(sTip), 1024, BytesRead
sTip = Left(sTip, InStr(1, sTip, Chr(0)) - 1)
If sTip = "Click to turn off Vietnamese mode" Then
PostMessage tray.hwnd, tray.uCallbackMessage, tray.uID, WM_LBUTTONDOWN
PostMessage tray.hwnd, tray.uCallbackMessage, tray.uID, WM_LBUTTONUP
End If
Next k
VirtualFreeEx hProcess, pMemory, 0, MEM_RELEASE
CloseHandle hProcess
End Sub