WSHでクリップボードを扱う その2 2012-09-14 (Fri) 23:30

WSHでクリップボードを扱うのに、IEオブジェクトを使う以外の方法を模索していたところ、
C++のサンプルコードを発見。
そのサンプルではクリップボードを扱うのに WindowsのAPIを使用しているようだ。

JScriptからWindowsのAPIが呼び出せないか調べてみたところ、
SFC mini なるツールを導入すれば可能らしい。

こちらは「VBScript,JScriptでWin32APIの使用を補助するためのツール」ということで、
HPにサンプルも豊富に掲載されていて意外と簡単に扱えそうだ。
JScriptでWindowsのAPIが使えれば今後も何かと便利そうなので早速導入。

で、WSHでクリップボードを扱う その1のサンプルをAPIを使用して書き換えてみる。

	var GMEM_MOVEABLE = 0x2;
var GMEM_ZEROINIT = 0x40;
var GHND = (GMEM_MOVEABLE | GMEM_ZEROINIT);
var CF_TEXT = 1;

function getClipboard(){
var rtn = '';
var Win32API = new ActiveXObject('SfcMini.DynaCall');
function IsSjisLeadByte(x){
return ((x >= 0x81 && x <= 0x9f) || (x >= 0xE0 && x <= 0xFC))?true:false;
}
Win32API.LoadLibraries('user32','kernel32');
if(!Win32API.OpenClipboard(0)){
return '';
}
var hMem = Win32API.GetClipboardData(CF_TEXT);
if(hMem){
var data = new ActiveXObject('SfcMini.Structure');
var chek = new ActiveXObject('SfcMini.Structure');
chek('code','Byte','dummy','String*4');
data('str', 'String*4');
var ptr = Win32API.GlobalLock(hMem);
if(!ptr){
Win32API.CloseClipboard();
return '';
}
var lenB = Win32API.lstrlen(ptr);
for(var i = 0; i < lenB; i++){
Win32API.lstrcpyn(chek, ptr + i, 2);
if(IsSjisLeadByte(chek.code))
Win32API.lstrcpyn(data, ptr + (i++), 3);
else
Win32API.lstrcpyn(data, ptr + i, 2);
rtn += data.str;
}
Win32API.GlobalUnlock(hMem);
}
Win32API.CloseClipboard();
return rtn;
}
function setClipboard(str){
var Win32API = new ActiveXObject('SfcMini.DynaCall');
Win32API.LoadLibraries('user32','kernel32');

var hMem = Win32API.GlobalAlloc(GHND, Win32API.lstrlen(str) + 4);
if(!hMem){
return false;
}
var ptr = Win32API.GlobalLock(hMem);
if(!ptr){
Win32API.GlobalFree(hMem);
return false;
}
Win32API.lstrcpy(ptr, str);
Win32API.GlobalUnlock(hMem);
if(!Win32API.OpenClipboard(0)){
return false;
}
Win32API.EmptyClipboard();
Win32API.SetClipboardData(CF_TEXT, hMem);
Win32API.GlobalFree(hMem);
Win32API.CloseClipboard();
return true;
}
setClipboard("Hello& World!!!");
WScript.Echo(getClipboard());

◎ポイント
APIで取得したクリップボードのデータをJScriptの変数に取り込むために SFC miniの String構造体を使用しているのだが、どうやら 1024 * 128 - 1 バイトまでしか扱えない(*1)らしいので、無条件にクリップボードのデータサイズ分 String構造体の領域を確保して一発コピーでは済ませられない。

そこで、分割してコピーしなくてはいけないわけだが、分割した際の切れ目がたまたま 2バイト文字の1バイト目だと JScriptの変数に追加したときに何らかの補正が行われるためか文字化けが発生してしまうようだ。

仕方なく1バイトずつ文字コードをチェックして2バイト文字がぶった切れないようにしているのだが、他に何か簡単にJScriptの変数に取り込む方法はないものか?
一発コピーできれば文字コードのチェックとかしなくていいのに。



取り敢えずはこれで IEオブジェクトを使う方法での問題も発生しないようなのでよしとしておこう。

ちなみに文字コードについては SJISを想定している。

(*1) String構造体の最大サイズ
関連記事

コメントの投稿

管理者にだけ表示を許可する

注意事項
基本的にこのブログはブログ主の備忘録です。

ブログの内容にはブログ主の主観や時には正確でない情報が含まれていることもあります。書いてある内容がすべての環境にあてはまることを保証するものでもありません。
また過去の記事の情報はそれが参照された時点では既に陳腐化していることもあります。

その辺をご理解の上で当ブログ内に書いてあることを試す場合は自己責任でお願いします。

万一何らかの損害が生じても責任は持てませんのであしからず!

記事内容の誤りの指摘、疑問点の回答などコメント頂けると助かります。
カレンダー
02 | 2017/03 | 03
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -
ブログ内検索
カラーコードチェッカ
カラーコードの確認
入力例) #ffffff | blue
カテゴリ
最新記事
最新コメント
最新トラックバック
リンク
ブロとも申請フォーム

この人とブロともになる

メールフォーム

名前:
メール:
件名:
本文: