☆JWWのクリップボードを読み込んでみる。
HiroCom777さんのVBdeJW !!で公開されているJwwClipControlを参考にして、
JWWのクリップボードのデータを読み込んでみました。
基本的な構造としては、起点の座標+グループ毎の縮尺+各データに なっているようです。
まず、クリップボードからTStreamにデータを取り出します。
次にTStreamから各データを取得します。この部分については、jwwunitのjwwRead関数を 参考にしています。というかそのままに近いので今回は、線データのみ取得させています。
上記のコードを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/
基本的な構造としては、起点の座標+グループ毎の縮尺+各データに なっているようです。
まず、クリップボードから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/
| 固定リンク