Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

How to "Set" unicode text to Win32::Clipboard?

by Dr. Mu (Hermit)
on Apr 30, 2011 at 21:22 UTC ( #902257=perlquestion: print w/replies, xml ) Need Help??
Dr. Mu has asked for the wisdom of the Perl Monks concerning the following question:

I'm working on a program that interacts with another Windows program (an editor). It selects all of the text (possibly unicode) under one tab, copies it to the clipboard, retrieves it from the clipboard, adds some markup, then pastes the marked-up text back to the other program under a new tab via the clipboard. At least, that's what's supposed to happen. Here's a skeletal version of the Markup routine that simply echoes back to the clipboard the text that it reads. The prints are there to monitor the text conversions:
sub Markup { $textarea = (grep {IsWindowVisible($_)} (FindWindowLike($ide, unde +f, qr/Edit/, undef, undef)))[0]; SetForegroundWindow($textarea); SendKeys('^a^c{HOME}'); my $source = $clip->GetAs(CF_UNICODETEXT); print map {sprintf("%2.2X ", ord($_))} (split //, $source); print +"\n\n"; $source = Encode::decode("UTF16-LE", $source); print map {sprintf("%2.2X ", ord($_))} (split //, $source); print +"\n\n"; $source = Encode::encode("UTF16-LE", $source); print map {sprintf("%2.2X ", ord($_))} (split //, $source); print +"\n\n"; $clip->Set($source); SendKeys('^n^v') }
According to the routine's output, the conversions are done correctly. The problem occurs when trying to write the text back to the clipboard. It appears to be treated as a zero-terminated byte string, rather than UTF16-LE-encoded text. What appears to be needed is a SetAs method, but there is none. Is there any way I can signal that the text being written to the clipboard is supposed to be UTF16-LE and not ASCII?


Replies are listed 'Best First'.
Re: How to "Set" unicode text to Win32::Clipboard?
by Util (Priest) on Apr 30, 2011 at 22:34 UTC

    If my reading of Clipboard.xs in the Win32::Clipboard source is correct, then the module does *not* have any way to make Set() work as anything but CF_TEXT. The docs even explicitly say about CF_TEXT:

    this is the only format you can use to set clipboard data


    1. Submit a request via to add this functionality.
    2. Edit the source to make a SetAs() routine, by combining techniques from GetAs() and Set(). Don't forget to send a patch to Jan Dubois.
    3. Use Win32::API to directly access SetClipboardData(CF_UNICODETEXT, Data) and related APIs.
    4. Pay someone to do #2 or #3.

      Thanks, yes, I saw that in the doc about CF_TEXT; but the same doc also states that CF_UNICODETEXT is a constant that's "not recognized by Win32:Clipboard," which is untrue. So I was hoping the doc was wrong here, as well, and that there was an easy way around the issue.

      Options 2 and 3 are more than I care to dig into right now. But since I'm using Win32::GuiTest I might also look into using its WMSetText method to write the text directly to the textarea, instead of going through the clipboard. Wish me luck!

      Thanks again,

        Unfortunately, WMSetText doesn't work like I thought it would with the text in the edit window. However, I've been able to work around the problem by saving the marked-up text to a file and causing the other program to load that file, instead of going back through the clipboard. It's ugly (the open file dialog box flashes on momentarily -- yuck!), but it works.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://902257]
Approved by Corion
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (8)
As of 2017-06-29 11:36 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (660 votes). Check out past polls.