Hi Antonio,
Subject: Regression in is2byteansi() (fwunicode.c) breaks ANSI CP1254 (Turkish) GET input β shows "?" β June 2026 build
Environment
- FiveWin: FWH 26.xx (June 2026 build), 32-bit, MSVC
- Harbour 3.2.0dev
- Legacy non-Unicode application: startup calls HB_CDPSELECT( "TRWIN" ) and FW_SetUnicode( .F. ). All data is single-byte Windows-1254 (Turkish). We do not use UTF-8.
Symptom / my question
After updating FiveWin, typing Turkish characters (Ε Δ Δ± Δ° Ε Δ Γ§ ΓΆ ΓΌ β¦) into ordinary GET fields displays ? instead of the character. The same application + source worked correctly with the previous FWH build. What is the supported way to run a non-Unicode CP1254 (TRWIN) application with the new FWH so that ANSI Turkish input is preserved?
Root cause I found
is2byteansi() in source/winapi/fwunicode.c was rewritten. For the Western/Central-European single-byte codepages (CP1250β1258, which includes CP1254 Turkish) the new code now returns:
if ( iCP >= 1250 && iCP <= 1258 )
{
return ( FW_GetUnicode() ? FALSE : TRUE );
}Because our app runs FW_SetUnicode(.F.), FW_GetUnicode() is false, so for CP1254 it now returns TRUE.
The previous FWH version special-cased only Thai (CP874) and returned FALSE for every other codepage (including CP1254):
BOOL is2byteansi( unsigned char c1, unsigned char c2 )
{
if ( ( ( fwCDP == 0 ) ? GetACP() : fwCDP ) == 874 )
{
if ( c1 >= 161 && c1 <= 251 )
return ( ( c2 == 0 ) || ( c2 >= 161 && c2 <= 251 ) );
}
return FALSE;
}This return-value flip changes how isutf8() classifies legacy CP1254 text, and the result is the ? shown in GET fields for Turkish characters. Our stored data is genuine single-byte CP1254 (verified at byte level, e.g. Δ Γ Ε Δ° Γ Γ Δ ΓΌ Ε β D0 DC DE DD D6 C7 F0 FC FE, one byte per character, LENGTH() == CHAR_LENGTH(), no 0x3F).
Workaround I applied (without rebuilding the FWH library)
I added a small C unit to the application that re-defines is2byteansi() with the old behavior, compiled with C linkage and linked before FiveHC32.lib; with /FORCE:MULTIPLE the linker binds every call (including the library's own isutf8()) to my version (LNK4006: _is2byteansi already defined β¦; second definition ignored):
#include <windows.h>
extern "C" int is2byteansi( unsigned char c1, unsigned char c2 )
{
if ( GetACP() == 874 ) /* Thai only, as in old FWH */
{
if ( c1 >= 161 && c1 <= 251 )
return ( ( c2 == 0 ) || ( c2 >= 161 && c2 <= 251 ) );
}
return 0; /* CP1254 & others: FALSE */
}This restores correct Turkish input.
Questions to you
- Is the new is2byteansi() behavior (returning TRUE for CP1250β1258 when FW_SetUnicode(.F.)) intended for non-Unicode apps, or is the ? an unintended regression?
- For a legacy ANSI CP1254 / TRWIN application that does not use UTF-8, what is the recommended configuration with the new FWH (e.g. a documented FW_SetCDP() / FW_SetUnicode() combination) to get the previous correct behavior without patching is2byteansi()?
Hakan ONEMLI
Harbour & MSVC 2022 & FWH 23.06