中文:
FWH:修正 MDICHILD + Resource Dialog + TGET 中文輸入法亂碼
這個 bug 存在許多年了,一直沒有解決!
今天透過 AI 解決了這個問題!
English:
FWH: Fix Chinese IME garble on MDICHILD + Resource Dialog + TGET
This bug has existed for many years and was never fixed.
Today it was finally solved with the help of AI!
https://www4.zzz.com.tw/phpBB3/viewtopic.php?f=2&t=379
patch_isdialogmessage.c
/*
* Smart IsDialogMessage:
* FW_SetUnicode(.T.) -> IsDialogMessageW (fixes Unicode modeless CJK IME)
* FW_SetUnicode(.F.) -> real IsDialogMessageA (ANSI/Big5 modeless must stay A)
*
* FWH message loop always imports IsDialogMessageA; we IAT-hook it.
*/
#include <Windows.h>
#include <hbapi.h>
#include "hbinit.h"
#ifndef _WIN64
#ifndef IMAGE_ORDINAL_FLAG32
#define IMAGE_ORDINAL_FLAG32 IMAGE_ORDINAL_FLAG
#endif
BOOL FW_GetUnicode( void );
typedef BOOL ( WINAPI * PFN_IsDialogMessageA )( HWND, LPMSG );
static PFN_IsDialogMessageA s_pRealIsDialogMessageA = NULL;
static BOOL WINAPI FW_IsDialogMessageDispatch( HWND hDlg, LPMSG lpMsg )
{
if( FW_GetUnicode() )
return IsDialogMessageW( hDlg, lpMsg );
if( s_pRealIsDialogMessageA )
return s_pRealIsDialogMessageA( hDlg, lpMsg );
return IsDialogMessageA( hDlg, lpMsg );
}
static BOOL PatchIAT( HMODULE hMod, const char * cDll, const char * cFunc, PROC pNew )
{
PIMAGE_DOS_HEADER pDos;
PIMAGE_NT_HEADERS pNt;
PIMAGE_IMPORT_DESCRIPTOR pImp;
DWORD nImpRva;
if( ! hMod )
return FALSE;
pDos = (PIMAGE_DOS_HEADER) hMod;
if( pDos->e_magic != IMAGE_DOS_SIGNATURE )
return FALSE;
pNt = (PIMAGE_NT_HEADERS)( (BYTE *) hMod + pDos->e_lfanew );
if( pNt->Signature != IMAGE_NT_SIGNATURE )
return FALSE;
nImpRva = pNt->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress;
if( ! nImpRva )
return FALSE;
pImp = (PIMAGE_IMPORT_DESCRIPTOR)( (BYTE *) hMod + nImpRva );
for( ; pImp->Name; pImp++ )
{
char * cName = (char *)( (BYTE *) hMod + pImp->Name );
PIMAGE_THUNK_DATA pThunk;
PIMAGE_THUNK_DATA pOrig;
DWORD nOrigRva;
if( lstrcmpiA( cName, cDll ) != 0 )
continue;
nOrigRva = pImp->OriginalFirstThunk ? pImp->OriginalFirstThunk : pImp->FirstThunk;
pOrig = (PIMAGE_THUNK_DATA)( (BYTE *) hMod + nOrigRva );
pThunk = (PIMAGE_THUNK_DATA)( (BYTE *) hMod + pImp->FirstThunk );
for( ; pOrig->u1.AddressOfData; pOrig++, pThunk++ )
{
PIMAGE_IMPORT_BY_NAME pBy;
DWORD dwOld;
if( pOrig->u1.Ordinal & IMAGE_ORDINAL_FLAG32 )
continue;
pBy = (PIMAGE_IMPORT_BY_NAME)( (BYTE *) hMod + pOrig->u1.AddressOfData );
if( lstrcmpA( (char *) pBy->Name, cFunc ) != 0 )
continue;
if( VirtualProtect( &pThunk->u1.Function, sizeof( PROC ),
PAGE_READWRITE, &dwOld ) )
{
pThunk->u1.Function = (ULONG_PTR) pNew;
VirtualProtect( &pThunk->u1.Function, sizeof( PROC ), dwOld, &dwOld );
return TRUE;
}
}
}
return FALSE;
}
static void fw_patch_isdlg( void )
{
HMODULE hUser;
HMODULE hExe;
if( s_pRealIsDialogMessageA == NULL )
{
hUser = GetModuleHandleA( "user32.dll" );
if( hUser )
s_pRealIsDialogMessageA =
( PFN_IsDialogMessageA ) GetProcAddress( hUser, "IsDialogMessageA" );
}
hExe = GetModuleHandleA( NULL );
PatchIAT( hExe, "USER32.dll", "IsDialogMessageA",
(PROC) FW_IsDialogMessageDispatch );
PatchIAT( hExe, "user32.dll", "IsDialogMessageA",
(PROC) FW_IsDialogMessageDispatch );
}
HB_CALL_ON_STARTUP_BEGIN( _fw_patch_isdialogmessage )
fw_patch_isdlg();
HB_CALL_ON_STARTUP_END( _fw_patch_isdialogmessage )
#if defined( HB_PRAGMA_STARTUP )
#pragma startup _fw_patch_isdialogmessage
#elif defined( HB_DATASEG_STARTUP )
#define HB_DATASEG_BODY HB_DATASEG_FUNC( _fw_patch_isdialogmessage )
#include "hbiniseg.h"
#endif
HB_FUNC( FW_PATCHISDIALOGMESSAGE )
{
fw_patch_isdlg();
hb_retl( TRUE );
}
#endif /* !_WIN64 */your main.prg
HB_CDPSELECT( "UTF8" )
FW_SetUnicode( .T. )
FW_PatchIsDialogMessage()fix window.prg ::Link()
if lSubClass
// add:2026.09.23: 解決 folder 內的 tget 無法輸入中文字問題.
//::nOldProc = XXChangeProc( ::hWnd, nAt, ::lxUnicode )
// FW Unicode: always Unicode subclass so WM_CHAR delivers full codepoints
// (Resource ANSI EDITTEXT otherwise LOBYTE-truncates Chinese to -:,f).
::nOldProc = XXChangeProc( ::hWnd, nAt,;
IsWindowUnicode( ::hWnd ) .or. FW_SetUnicode() )
endifWeChat ID: ssbbstw