Access中已用MessageBoxW实现Unicode MsgBox,求模拟Unicode InputBox的方法
实现支持Unicode的InputBox替代方案
Great job getting the Unicode-friendly MsgBoxW working! For a Unicode-compatible input box equivalent, you'll need to roll your own using Windows API calls (since there's no direct InputBoxW exposed like MessageBoxW). Here's a complete VBA implementation that mimics the native InputBox behavior while fully supporting Unicode characters:
Full VBA Code
Private Declare PtrSafe Function DialogBoxParamW Lib "User32" (ByVal hInstance As LongPtr, ByVal lpTemplateName As LongPtr, ByVal hWndParent As LongPtr, ByVal lpDialogFunc As LongPtr, ByVal dwInitParam As LongPtr) As Integer Private Declare PtrSafe Function EndDialog Lib "User32" (ByVal hDlg As LongPtr, ByVal nResult As Integer) As Boolean Private Declare PtrSafe Function GetDlgItem Lib "User32" (ByVal hDlg As LongPtr, ByVal nIDDlgItem As Integer) As LongPtr Private Declare PtrSafe Function SetWindowTextW Lib "User32" (ByVal hWnd As LongPtr, ByVal lpString As LongPtr) As Boolean Private Declare PtrSafe Function GetWindowTextLengthW Lib "User32" (ByVal hWnd As LongPtr) As Integer Private Declare PtrSafe Function GetWindowTextW Lib "User32" (ByVal hWnd As LongPtr, ByVal lpString As LongPtr, ByVal nMaxCount As Integer) As Integer Private Declare PtrSafe Function GetModuleHandleW Lib "Kernel32" (ByVal lpModuleName As LongPtr) As LongPtr Private Const IDC_INPUT As Integer = 1001 Private Const IDOK As Integer = 1 Private Const IDCANCEL As Integer = 2 Private DialogTitle As String Private DialogPrompt As String Private DefaultText As String Private InputBoxResult As String Private Function InputBoxDialogProc(ByVal hDlg As LongPtr, ByVal uMsg As Integer, ByVal wParam As LongPtr, ByVal lParam As LongPtr) As Integer Dim inputHandle As LongPtr Dim textLength As Integer Dim inputBuffer As String Select Case uMsg Case &H100 ' WM_INITDIALOG: Initialize dialog when created ' Set dialog title and prompt text SetWindowTextW hDlg, StrPtr(DialogTitle) SetWindowTextW GetDlgItem(hDlg, &HFFFF), StrPtr(DialogPrompt) ' Static text control uses default ID -1 ' Populate default text in input box inputHandle = GetDlgItem(hDlg, IDC_INPUT) SetWindowTextW inputHandle, StrPtr(DefaultText) InputBoxDialogProc = 1 Case &H111 ' WM_COMMAND: Handle button clicks Select Case wParam Case IDOK ' Retrieve input text from the edit control textLength = GetWindowTextLengthW(GetDlgItem(hDlg, IDC_INPUT)) + 1 inputBuffer = String(textLength, vbNullChar) GetWindowTextW GetDlgItem(hDlg, IDC_INPUT), StrPtr(inputBuffer), textLength InputBoxResult = Left$(inputBuffer, textLength - 1) EndDialog hDlg, IDOK InputBoxDialogProc = 1 Case IDCANCEL ' User canceled, return empty string InputBoxResult = "" EndDialog hDlg, IDCANCEL InputBoxDialogProc = 1 End Select Case Else InputBoxDialogProc = 0 End Select End Function Public Function InputBoxW(Prompt As String, Optional Title As String = "Microsoft Access", Optional Default As String = "") As String Dim hInstance As LongPtr Dim dialogTemplate() As Byte ' Define a minimal Unicode dialog template matching native InputBox layout dialogTemplate = _ &H0& & &H0& & _ ' Style: WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_MODALFRAME &H100& & &H100& & _ ' Position: x=256, y=256 &H200& & &H100& & _ ' Size: width=512, height=256 &H0& & &H0& & _ ' Menu: none, Class: none StrPtr("") & _ ' Title (set dynamically) &H0& & &H0& & _ ' Font: default ' Static prompt text control &H0& & &H0& & _ ' Style: WS_CHILD | WS_VISIBLE | SS_LEFT &H10& & &H10& & _ ' Position: x=16, y=16 &H1E0& & &H20& & _ ' Size: width=480, height=32 &HFFFF& & &H0& & _ ' ID: -1 (default static control), Class: none StrPtr("") & _ ' Text (set dynamically) &H0& & _ ' End of control ' Edit input control &H500000& & &H0& & _ ' Style: WS_CHILD | WS_VISIBLE | ES_LEFT | WS_BORDER | WS_TABSTOP &H10& & &H40& & _ ' Position: x=16, y=64 &H1E0& & &H20& & _ ' Size: width=480, height=32 &H3E9& & &H0& & _ ' ID: 1001 (IDC_INPUT), Class: none StrPtr("") & _ ' Text (set dynamically) &H0& & _ ' End of control ' OK button &H500000& & &H0& & _ ' Style: WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON | WS_TABSTOP &H10& & &H70& & _ ' Position: x=16, y=112 &H80& & &H20& & _ ' Size: width=128, height=32 &H1& & &H0& & _ ' ID: 1 (IDOK), Class: none StrPtr("OK") & _ ' Text &H0& & _ ' End of control ' Cancel button &H500000& & &H0& & _ ' Style: WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP &H100& & &H70& & _ ' Position: x=256, y=112 &H80& & &H20& & _ ' Size: width=128, height=32 &H2& & &H0& & _ ' ID: 2 (IDCANCEL), Class: none StrPtr("Cancel") & _ ' Text &H0& & _ ' End of control &H0& & &H0& ' End of template ' Store parameters for dialog proc DialogPrompt = Prompt DialogTitle = Title DefaultText = Default InputBoxResult = "" ' Get current module handle and launch dialog hInstance = GetModuleHandleW(0) DialogBoxParamW hInstance, VarPtr(dialogTemplate(0)), Application.hWndAccessApp, AddressOf InputBoxDialogProc, 0 ' Return user input (or empty string if canceled) InputBoxW = InputBoxResult End Function
How It Works
- Unicode Support: Uses
SetWindowTextWandGetWindowTextWexclusively to handle text, ensuring full Unicode compatibility (no garbled characters for non-ANSI scripts). - Native Look & Feel: The dialog template mimics the layout and behavior of Access's native
InputBox, so users won't notice a difference. - Familiar Parameters: The
InputBoxWfunction accepts the samePrompt,Title, andDefaultparameters as the built-inInputBox, making it a drop-in replacement.
To use it, just call it like you would the standard InputBox:
Dim userInput As String userInput = InputBoxW("请输入Unicode文本:", "Unicode输入框", "默认内容") If userInput <> "" Then MsgBoxW("你输入的是:" & userInput) End If
内容的提问来源于stack exchange,提问作者YellowLarry
相关产品推荐
相关产品推荐

