Skip to content

Commit 9cd6e2a

Browse files
committed
v0.3.1
1 parent 5165e13 commit 9cd6e2a

5 files changed

Lines changed: 66 additions & 15 deletions

File tree

Changes

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
Revision history for Win32API::Console
22

3+
0.3.1 2025-12-02
4+
- Add limitations to POD
5+
- Fix tests with CP_UTF8, use alternative code page for old systems
6+
37
0.3.0 2025-12-01
48
- Add Get/SetConsoleScreenBufferInfoEx functions
59
- Fix use of 'S' instead of 's' for COORD and SMALL_RECT

lib/Win32API/Console.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use version;
2020

2121
# version '...'
2222
our $version = '0.10';
23-
our $VERSION = 'v0.3.0';
23+
our $VERSION = 'v0.3.1';
2424
$VERSION = eval $VERSION;
2525

2626
# authority '...'

lib/Win32API/Console.pod

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ this module was created, which uses most of the XS functions of
1414
L<Win32::Console>, but also provides additional ones (e.g., for wide char
1515
support).
1616

17-
Further details can be found in the included PM or directly at MSDN. The API
17+
Further details can be found in the source code or directly at MSDN. The API
1818
interface was modeled on the classic Windows API, so that the original
1919
documentation from Microsoft can be used in most cases.
2020

21-
=head1 FUNCTIONS
21+
=head1 SUBROUTINES
2222

2323
Many Windows API functions exist in multiple variants that differ by the
2424
character encoding they expect. The naming convention typically uses suffixes:
@@ -75,8 +75,11 @@ Example:
7575
use utf8;
7676
FunctionName("Text");
7777

78-
B<Note>: The wrapper provides a compatibility layer, but depends on the
79-
internal XS compilation settings of L<Win32::Console>.
78+
B<Note>: The wrapper provides a compatibility layer, but its behavior depends
79+
on the internal XS build configuration of L<Win32::Console>.
80+
81+
Please also refer to the Windows-specific L</CAVEATS> section for important
82+
details when using these wrapper functions.
8083

8184
=back
8285

@@ -2137,6 +2140,33 @@ Constants for L</GetStdHandle> and L</SetStdHandle>
21372140

21382141
All of the above.
21392142

2143+
=head1 CAVEATS
2144+
2145+
Not all functions listed here are supported on every version of Windows.
2146+
Where possible, the platform support is detected, and if there are limitations,
2147+
a Windows error code (C<$^E>) is set accordingly. In some cases, a workaround
2148+
is available to circumvent these limitations. Please refer to the official
2149+
MSDN documentation to verify whether a specific function is supported on your
2150+
Windows version.
2151+
2152+
=head2 Known limitations
2153+
2154+
On Windows 7 and 8, C<WideCharToMultiByte> with C<CP_UTF8> sometimes returns
2155+
incorrect results when the system locale is not UTF-8. This is a platform
2156+
limitation, not an issue in the Perl code. Typical symptoms include corrupted
2157+
characters (e.g., double-encoded UTF-8 sequences).
2158+
2159+
L<MSDN - WideCharToMultiByte function|https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-widechartomultibyte>:
2160+
2161+
UTF-8 (CP_UTF8) is supported starting with Windows XP, but full support for
2162+
UTF-8 as a system locale was added in later versions of Windows 10
2163+
2164+
L<MSDN - Unicode in the Windows API|https://learn.microsoft.com/en-us/windows/win32/intl/unicode-in-the-windows-api>:
2165+
2166+
Prior to Windows 10 version 1903, UTF-8 was not available as a system code
2167+
page. Applications using CP_UTF8 may experience inconsistent behavior if the
2168+
system locale is not UTF-8.
2169+
21402170
=head1 REQUIRES
21412171

21422172
L<Exporter>

t/00-begin.t

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ terms as the Perl 5 programming language system itself.
2424
use 5.014;
2525
use warnings;
2626

27+
use Win32;
2728
use Test::More;
2829

2930
sub UNICODE () {
@@ -103,10 +104,11 @@ sub banner {
103104
diag( ' ' );
104105
diag( '# ' x 36 );
105106
diag( ' ' );
106-
diag( " OS: $^O" );
107-
diag( " PERL: $]" );
108-
diag( " UNICODE: ", UNICODE ? "detected" : "not detected" );
109-
diag( " MANUAL_TESTS: ", MANUAL_TESTS ? "enabled" : "not enabled" );
107+
diag( " OS: $^O" );
108+
diag( " PERL: $]" );
109+
diag( " CP: ", Win32::GetConsoleOutputCP() );
110+
diag( " UNICODE: ", UNICODE ? "detected" : "not detected" );
111+
diag( " MANUAL_TESTS: ", MANUAL_TESTS ? "enabled" : "not enabled" );
110112
diag( ' ' );
111113
diag( '# ' x 36 );
112114
}

t/02-helper.t

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use utf8;
44

55
use Test::More tests => 6;
66
require bytes;
7+
use version;
78

89
BEGIN {
910
use_ok 'Win32';
@@ -14,6 +15,7 @@ BEGIN {
1415

1516
BEGIN { subtest "Import private helper's" => sub {
1617
can_ok('Win32API::Console' =>
18+
'CP_ACP',
1719
'CP_UTF8',
1820
'ERROR_SUCCESS',
1921
'ERROR_INVALID_HANDLE',
@@ -28,6 +30,7 @@ BEGIN { subtest "Import private helper's" => sub {
2830
'__HRESULT_FROM_WIN32',
2931
);
3032
no warnings;
33+
*CP_ACP = Win32API::Console->can('CP_ACP');
3134
*CP_UTF8 = Win32API::Console->can('CP_UTF8');
3235
*ERROR_SUCCESS = Win32API::Console->can('ERROR_SUCCESS');
3336
*ERROR_INVALID_HANDLE = Win32API::Console->can('ERROR_INVALID_HANDLE');
@@ -42,6 +45,7 @@ BEGIN { subtest "Import private helper's" => sub {
4245
*__HRESULT_FROM_WIN32 = Win32API::Console->can('__HRESULT_FROM_WIN32');
4346
}}
4447

48+
my $os;
4549
subtest 'GetOSVersion' => sub {
4650
my $id = GetOSVersion();
4751
diag "$^E" if $^E;
@@ -51,23 +55,34 @@ subtest 'GetOSVersion' => sub {
5155
diag "$^E" if $^E;
5256
cmp_ok(@ver, '>=', 5, 'GetOSVersion() array context');
5357
note join(", " => @ver);
58+
$os = version->declare(sprintf('v%2$d.%3$d.%4$d', @ver));
5459
};
5560

5661
subtest 'WideCharToMultiByte and back' => sub {
57-
my $original = "Viele Grüße";
62+
my ($cp, $original);
63+
if ($os < v10.0.1903) {
64+
# Before Windows 10, there was no native UTF-8 system locale.
65+
$cp = CP_ACP;
66+
$original = "Hello";
67+
}
68+
else {
69+
# Starting with Windows 10 (1903), there is beta support for UTF-8.
70+
$cp = CP_UTF8;
71+
$original = "Viele Grüße";
72+
}
5873

59-
# Convert multibyte to wide string (UTF-8 codepage)
60-
my $wide = MultiByteToWideChar($original, CP_UTF8);
74+
# Convert multibyte to wide string
75+
my $wide = MultiByteToWideChar($original, $cp);
6176
ok(defined $wide, 'MultiByteToWideChar returned a value');
6277
ok($wide, 'wide string is not empty');
6378

6479
# Convert back to multibyte string
65-
my $mb = WideCharToMultiByte($wide, CP_UTF8);
80+
my $mb = WideCharToMultiByte($wide, $cp);
6681
ok(defined $mb, 'WideCharToMultiByte returned a value');
6782
ok($mb, 'Multibyte string is not empty');
6883
is(
69-
bytes::substr($original, 0),
70-
bytes::substr($mb, 0),
84+
bytes::substr($mb, 0),
85+
bytes::substr($original, 0),
7186
'Round-trip conversion preserved string'
7287
);
7388
};

0 commit comments

Comments
 (0)