HiroCom777さんの
VBdeJW !!で公開されているJwwClipControlを参考にして、
JWWのクリップボードのデータを読み込んでみました。
基本的な構造としては、
起点の座標+グループ毎の縮尺+各データに
なっているようです。
まず、クリップボードからTStreamにデータを取り出します。
uses Clipbrd;
procedure TForm1.Button1Click(Sender: TObject);
var
Data: THandle;
DataPtr: Pointer;
MemStream: TMemoryStream;
I: Integer;
FormatID: Integer;
FormatName: array [0..MAX_PATH] of Char;
ID: word;
F: Boolean;
begin
F := False;
ID := 0;
for I := 0 to ClipBoard.FormatCount - 1 do
begin
FormatID:= ClipBoard.Formats[I];
GetClipBoardFormatName(FormatID, FormatName, SizeOf(FormatName));
if FormatName = 'Jw_win' then
begin
F := True;
ID := FormatID;
Break;
end;
end;
if not F then Exit;
ClipBoard.Open;
Data := ClipBoard.GetAsHandle(ID);
if Data = 0 then Exit;
DataPtr := GlobalLock(Data);
if DataPtr = nil then Exit;
MemStream := TMemoryStream.Create;
try
MemStream.WriteBuffer(DataPtr^, GlobalSize(Data));
MemStream.Position := 0;
JwwPasteFromClipboard(TStream(MemStream));
Drawdata;
finally
MemStream.Free;
GlobalUnLock(Data);
ClipBoard.Close;
end;
end;
次にTStreamから各データを取得します。この部分については、jwwunitのjwwRead関数を
参考にしています。というかそのままに近いので今回は、線データのみ取得させています。
// クリップボードのデータを取得する。
procedure JwwPasteFromClipboard(Stream: TStream);
var
I,J,K: Integer;
dw: DWORD;
db: Double;
S: String;
wd: Word;
bt: Byte;
JWWList: TJWWList;
SenCount: Integer;
DSen: CDataSen;
orgX,orgY: Double;
scale: array[0..15] of Double;
Size,Cnt: Integer;
Dummy: array[0..150] of Byte;
function StringRead(n:Integer): String;
var
I: Integer;
cc: char;
begin
Result := '';
for I:=0 to n-1 do
begin
Stream.ReadBuffer(cc,1);
Result := Result + cc;
end;
end;
begin
Stream.Position := 0;
Size := Stream.Size;
Cnt := High(JWWSen);
// 基準点
Stream.ReadBuffer(orgX,SizeOf(Double));
Stream.ReadBuffer(orgY,SizeOf(Double));
// レイヤグループの縮尺
for I := 0 to 15 do
Stream.ReadBuffer(scale[I],SizeOf(Double));
JWWList := TJWWList.Create;
try
Stream.ReadBuffer(wd,SizeOf(wd));
if wd = $FFFF then
begin
Stream.ReadBuffer(dw,SizeOf(dw));
J := dw;
end else
J := wd;
SetLength(JWWSen,Cnt+J);
SenCount := Cnt;
I := 1;
while Stream.Position <= Size do
begin
Stream.ReadBuffer(wd,2);
case wd of
$0000: Break;
$FFFF: begin
Stream.ReadBuffer(wd,2);
Stream.ReadBuffer(wd,2);
S := StringRead(wd);
JWWList.AddItem(I,S);
J := I;
Inc(I);
end;
$FF7F: begin
Stream.ReadBuffer(dw,4);
J := dw and $7FFFFFFF;
end;
$7FFF: begin
Stream.ReadBuffer(dw,4);
J := dw and $7FFFFFFF;
end;
else begin
if (wd and $8000) <> 0 then
J := wd and $7FFF else J := 0;
end;
end;
S := JWWList.NoByItem[J].CDataString;
if S = 'CDataList' then
begin
Stream.ReadBuffer(Dummy,28);
Stream.ReadBuffer(bt,1);
if bt <> $FF then
StringRead(bt)
else
begin
Stream.ReadBuffer(wd,2);
StringRead(wd)
end;
Stream.ReadBuffer(wd,2);
if wd = $FFFF then
Stream.ReadBuffer(dw,4);
end;
if S = 'CDataSen' then
begin
Stream.ReadBuffer(dw,4);
DSen.Root.m_lGroup:=dw;
Stream.ReadBuffer(bt,1);
DSen.Root.m_nPenStyle:=bt;
Stream.ReadBuffer(wd,2);
DSen.Root.m_nPenColor:=wd;
Stream.ReadBuffer(wd,2);
DSen.Root.m_nPenWidth:=wd;
Stream.ReadBuffer(wd,2);
DSen.Root.m_nLayer:=wd;
Stream.ReadBuffer(wd,2);
DSen.Root.m_nGLayer:=wd;
Stream.ReadBuffer(wd,2);
DSen.Root.m_sFlg:=wd;
Stream.ReadBuffer(db,8);
DSen.m_start_x := db;
Stream.ReadBuffer(db,8);
DSen.m_start_y := db;
Stream.ReadBuffer(db,8);
DSen.m_end_x := db;
Stream.ReadBuffer(db,8);
DSen.m_end_y := db;
JWWSen[SenCount] := DSen;
Inc(SenCount);
end;
if S = 'CDataEnko' then
begin
Stream.ReadBuffer(Dummy,75);
end;
if S = 'CDataTen' then
begin
Stream.ReadBuffer(dw,4);
Stream.ReadBuffer(bt,1);
Stream.ReadBuffer(Dummy,30);
if bt = 100 then
Stream.ReadBuffer(Dummy,20);
end;
if S = 'CDataMoji' then
begin
Stream.ReadBuffer(Dummy,83);
Stream.ReadBuffer(bt,1);
if bt <> $FF then
StringRead(bt)
else
begin
Stream.ReadBuffer(wd,2);
StringRead(wd);
end;
Stream.ReadBuffer(bt,1);
if bt <> $FF then
StringRead(bt)
else
begin
Stream.ReadBuffer(wd,2);
StringRead(wd);
end;
end;
if S = 'CDataSolid' then
begin
Stream.ReadBuffer(dw,4);
Stream.ReadBuffer(bt,1);
Stream.ReadBuffer(wd,2);
Stream.ReadBuffer(Dummy,72);
if wd = 10 then
Stream.ReadBuffer(Dummy,4);
end;
if S = 'CDataBlock' then
begin
Stream.ReadBuffer(Dummy,59);
end;
if S = 'CDataSunpou' then
begin
Stream.ReadBuffer(Dummy,145);
Stream.ReadBuffer(bt,1);
if bt <> $FF then
Stream.ReadBuffer(Dummy,1)
else
Stream.ReadBuffer(Dummy,2);
Stream.ReadBuffer(bt,1);
if bt <> $FF then
Stream.ReadBuffer(Dummy,1)
else
Stream.ReadBuffer(Dummy,2);
Stream.ReadBuffer(wd,2);
Stream.ReadBuffer(Dummy,94);
for K := 0 to 3 do
begin
Stream.ReadBuffer(dw,4);
Stream.ReadBuffer(bt,1);
Stream.ReadBuffer(Dummy,30);
if bt = 100 then
Stream.ReadBuffer(Dummy,20);
end;
end;
if S <> '' then Inc(I);
S:='';
end;
SetLength(JWWSen,SenCount);
finally
JWWList.Free;
end;
end;
上記のコードを
JWWファイルの超簡易表示 その3で
試して頂くとデータが追加されているのがわかります。ただ、貼り付ける位置の座標やレイヤは元データのままなので、実際に使う場合には
その辺りを処理する必要があります。
今回は、メモリ上で処理していますが、クリップボードからTFileStreamでファイルに書き出して、
そこから読み込むというのもいいかも知れませんね。
VBdeJW !!
http://www.h7.dion.ne.jp/~hirocom/VBdeJW/
Peter's Room
jww data read & save unit Ver1.3β
http://www5b.biglobe.ne.jp/~peter/index.html
AFsoft WebSite
CAD作ろ!
http://afsoft.jp/