Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Where is my string going in Win32::API ?

by John M. Dlugosz (Monsignor)
on Jul 03, 2001 at 06:11 UTC ( [id://93396]=perlquestion: print w/replies, xml ) Need Help??

John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Puzzle me this, Oh Wise Monks:

The following piece of code gets, changes one character, and sets a window's label using the Wide system calls and UTF16-LE strings.

sub change_text { use bytes; my $s= 'x'x256; $getTextF->Call ($handle, $s, 128); # substr ($s,46,2, "\x22\x21"); #substr ($s,40,2, "\x22\x21"); $setTextF->Call ($handle, $s); $s =~ tr/\0 /.-/; print $s; }
The tr// at the end is to make it print out usefully on an 8-bit console. I can see where the 0's are and that all the chars are properly LE with the ASCII code in the first byte and 0 in the second, and my new 16-bit character is properly aligned.

If I un-comment one of the substr lines, the new character does indeed appear in the window, but the string is truncated! How much is truncated seems to vary with the exact string! Maybe 5 chars in one case. That's even if the substr took place at the very first position.

When dumping my string via print, I can see that it is put together correctly, every byte where it belongs.

So I'm wondering what might be making the system call quit early? Are strings discontiguous in memory and this is now two fragments?

If I Get the text out again, I see that bytes have actually been deleted, and stuff after it moved up, not just truncated by getting the length wrong. The Win32 calls take nul-terminated input, so the Set stops when it sees \0\0 in the buffer. Yet the value of $s is unaltered after I call Set, but Get again implies that Set deleted a few bytes before passing it along to the actual OS call.

Is this strange or what? I'm totally mystified.

Full program follows.

—John

${^WIDE_SYSTEM_CALLS}= 1; use strict; use Win32::GUI; use Win32::API; my $s= "This is a TM symbol =>x"; my $setTextF= new Win32::API:: ('user32.dll', 'SetWindowTextW', ['N',' +P'], 'N') or die; my $getTextF= new Win32::API:: ('user32.dll', 'GetWindowTextW', ['N',' +P','N'], 'N') or die; my $window = Win32::GUI::Window->new ( -width => 400, # Set the width -height => 200, # Set the height -text => "Hello World Title", # Set the title -name => "window1", # Set the name (used for event handlers) ); my $font = Win32::GUI::Font->new ( -size => 20, # Set the size (in points) -name => "Comic Sans MS", # Name of the font ); my $lable = $window->AddLabel( -text => $s, # Set the text in the label -font => $font, # Set the font -foreground => [0, 0, 255], # Set the color of the text -name => 'text1' ); my $handle= $window->{text1}{-handle}; print $handle; $window->Show (); change_text(); sub window1_Terminate { return -1; # Return -1 to end the event loop } sub change_text { use bytes; my $s= 'x'x256; $getTextF->Call ($handle, $s, 128); substr ($s,46,2, "\x22\x21"); #substr ($s,40,2, "\x22\x21"); $setTextF->Call ($handle, $s); $s =~ tr/\0 /.-/; print "$s\n"; $getTextF->Call ($handle, $s, 128); $s =~ tr/\0 /.-/; print $s; }

Replies are listed 'Best First'.
(tye)Re: Where is my string going in Win32::API ?
by tye (Sage) on Jul 03, 2001 at 08:56 UTC

    The only thing that makes some sense to me is that someone is converting your string to UTF-8 and using the character count as the byte count when converting back to UNICODE/UTF-16.

    Removing Win32::GUI from the picture, I don't see your problem (but I also see \x22\x21 as just a block). So I suspect that Win32::GUI is interfering with the processing of the window title. Try setting the title of a window that is not under Win32::GUI control for comparison.

            - tye (but my friends call me "Tye")
      With only 1 char in the non-ASCII range, the length difference between bytes and chars, if UTF8 encoded, is 2. That's not what I'm seeing.

      Try a window not under its control: good idea, but a lot of effort to create a window using Win32::API to call the underlying routines. But I'll try something like that, later.

      —John

Re: Where is my string going in Win32::API ?
by jplindstrom (Monsignor) on Jul 03, 2001 at 15:58 UTC
    This may not be useful in your particular case, but you can change the title bar of a Win32::GUI window with:
    $window->Text("New title")
    Does that "solve" your problem?

    /J

      No, because the point of my experiment is to suppliment Win32::GUI text routines with something that will handle Unicode. Setting the text in the framework turned it into 3 UTF bytes as indivial 8-bit characters—it does not respect the ${^WIDE_SYSTEM_CALLS} setting.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://93396]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (2)
As of 2024-04-20 15:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found