unit cwcells;

interface

uses classes,windows,SysUtils,clipbrd,convImages;

type
 TCWFormat=(cfNone,cfCell,cfContent,cfView,cfImage);

 CWCell = record
  left,top:DWORD;
  width,height:DWORD;
  fileName,flagName:PChar;
  padding:byte;
 end;

 TCWCellDirector = class(TObject)
 private
  procedure saveCell(stream:TMemoryStream;inf:TImageInfo);
  function loadCell(stream:TMemoryStream):TImageInfo;
 public
  constructor create();
  class function getClipFormat():TCWFormat;
  function loadCellPart():TImageInfo;
  function loadCellParts():TStrings;
  function loadCellContent():TStrings;
  procedure saveCellView(list:TStrings);
  procedure saveCellPart(inf:TImageInfo);
  procedure saveCellParts(list:TStrings);
  procedure saveContent(list:TStrings);
 end;


implementation
var
CLIP_CWCELL:DWORD;
CLIP_CONTENT:DWORD;
CLIP_CWVIEW:DWORD;

constructor TCWCellDirector.create();
begin
 inherited;
end;

class function TCWCellDirector.getClipFormat():TCWFormat;
begin
 if Clipboard.HasFormat(CLIP_CWCELL)then result:=cfCell
 else if Clipboard.HasFormat(CLIP_CONTENT)then result:=cfContent
 else result:=cfNone;
end;

procedure TCWCellDirector.saveCell(stream:TMemoryStream;inf:TImageInfo);
var
 len,value:DWORD;
 sValue:PChar;
 bValue:byte;
begin
  value:=inf.posInf.x;
  stream.WriteBuffer(value,sizeof(DWORD));
  value:=inf.posInf.y;
  stream.WriteBuffer(value,sizeof(DWORD));
  value:=inf.posInf.w+40000;
  stream.WriteBuffer(value,sizeof(DWORD));
  value:=inf.posInf.h;

  stream.WriteBuffer(value,sizeof(DWORD));
  sValue:=PChar(inf.fileName);
  len:=Length(sValue)+1;
  stream.WriteBuffer(len,sizeof(DWORD));
  stream.WriteBuffer(sValue^,len);

  bValue:=Byte(inf.posInf.trans);
  stream.WriteBuffer(bValue,sizeof(byte));

  sValue:=PChar(inf.flagName); //セル描画のフラグ
  len:=Length(sValue)+1;
  stream.WriteBuffer(len,sizeof(DWORD));
  stream.WriteBuffer(sValue^,len);

  bValue:=0;   //無意味と思われるデータ
  stream.WriteBuffer(bValue,sizeof(byte));
end;

function TCWCellDirector.loadCell(stream:TMemoryStream):TImageInfo;
var
  hBuf:THandle;
  buffer:pointer;
  value,len:Integer;
  sValue:PChar;
  bValue:byte;
begin
  result:=TImageInfo.Create();
 try
  stream.ReadBuffer(Value,sizeof(DWORD));
  result.posInf.x:=value;

  stream.ReadBuffer(Value,sizeof(DWORD));
  result.posInf.y:=value;

  stream.ReadBuffer(Value,sizeof(DWORD));
  result.posInf.w:=value-40000;

  stream.ReadBuffer(Value,sizeof(DWORD));
  result.posInf.h:=value;


  stream.ReadBuffer(len,sizeof(DWORD));
  getMem(sValue,len+1);
  stream.ReadBuffer(sValue^,len);
  result.fileName:=sValue;

  stream.ReadBuffer(bValue,sizeof(byte));
  result.posInf.trans:=boolean(bValue);

  stream.ReadBuffer(len,sizeof(DWORD));
  getMem(sValue,len+1);
  stream.ReadBuffer(sValue^,len);
  result.flagName:=sValue;
 finally

 end;

end;

function TCWCellDirector.loadCellPart():TImageInfo;
var
  stream:TMemoryStream;
  hBuf:THandle;
  buffer:pointer;
  value,len:Integer;
  sValue:PChar;
  bValue:byte;
begin
 stream := TMemoryStream.Create;
 result:=nil;
 try
  if Clipboard.HasFormat(CLIP_CWCELL) then
  begin
   result:=TImageInfo.create();
   ClipBoard.Open;
   hBuf := Clipboard.GetAsHandle(CLIP_CWCELL);
   buffer := GlobalLock(hBuf);
   stream.WriteBuffer(buffer^,GlobalSize(hBuf));
   GlobalUnlock(hBuf);
   Clipboard.Close;

   stream.Position :=0;

   stream.ReadBuffer(Value,sizeof(DWORD));
   result:=self.loadCell(stream);

  end;
  finally
    stream.Free;
  end;

end;

function TCWCellDirector.loadCellParts():TStrings;
var
  stream:TMemoryStream;
  hBuf:THandle;
  buffer:pointer;
  value,len,i:Integer;
  sValue:PChar;
  bValue:byte;
  inf:TImageInfo;
begin
 stream := TMemoryStream.Create;
 result:=TStringList.Create();
 try
  if Clipboard.HasFormat(CLIP_CWCELL) then
  begin
   ClipBoard.Open;
   hBuf := Clipboard.GetAsHandle(CLIP_CWCELL);
   buffer := GlobalLock(hBuf);
   stream.WriteBuffer(buffer^,GlobalSize(hBuf));
   GlobalUnlock(hBuf);
   Clipboard.Close;

   stream.Position :=0;
   stream.ReadBuffer(Value,sizeof(DWORD));

   for i:=0 to Value-1 do
   begin
    inf:=loadCell(stream);
    if(inf<>nil)then
    begin
     result.AddObject(IntToStr(i),inf);
   //  windows.MessageBox(0,PChar(IntToStr(result.Count)),'',MB_OK);
    end;
    stream.Position:=stream.Position+SizeOf(byte);
   end;

  end;
  finally
    stream.Free;
  end;

end;

function TCWCellDirector.loadCellContent():TStrings;
var
  stream:TMemoryStream;
  hBuf:THandle;
  buffer:pointer;
  value,len,i:Integer;
  smallValue:smallInt;
  sValue:PChar;
  bValue:byte;
  inf:TImageInfo;
begin
 stream := TMemoryStream.Create;
 result:=TStringList.Create();
 try
  if Clipboard.HasFormat(CLIP_CONTENT) then
  begin
   ClipBoard.Open;
   hBuf := Clipboard.GetAsHandle(CLIP_CONTENT);
   buffer := GlobalLock(hBuf);
   stream.WriteBuffer(buffer^,GlobalSize(hBuf));
   GlobalUnlock(hBuf);
   Clipboard.Close;

   stream.Position :=0;
   stream.ReadBuffer(smallValue,sizeof(smallInt));
   if(smallValue=$808)then
   begin
    stream.ReadBuffer(len,sizeof(DWORD));
    stream.Position:=stream.Position+len;
    stream.ReadBuffer(value,sizeof(DWORD));
    if(value=40000)then
    begin
     stream.ReadBuffer(value,sizeof(DWORD));

     for i:=0 to Value-1 do
     begin
      inf:=loadCell(stream);
      if(inf<>nil)then
      begin
       result.AddObject(IntToStr(i),inf);
      end;
      stream.Position:=stream.Position+SizeOf(byte);
     end;
    end
    else windows.MessageBox(0,'貼り付け不可','コピーするコンテントは１つでお願いします',MB_OK);
   end;

  end;
  finally
    stream.Free;
  end;

end;




procedure TCWCellDirector.saveCellPart(inf:TImageInfo);
var
 stream:TMemoryStream;
 value:Integer;
 buffer:Pointer;
 hBuf:THandle;
begin

 stream:=TMemoryStream.Create();
 try
  value:=1;
  stream.WriteBuffer(value,SizeOf(DWORD));
  saveCell(stream,TImageInfo(inf));
  stream.Position:=0;

  hBuf := GlobalAlloc(GHND,stream.Size);
  buffer:=GlobalLock(hBuf);
  stream.ReadBuffer(buffer^,stream.Size);

  Clipboard.Open;
  Clipboard.Clear;
  Clipboard.SetAsHandle(CLIP_CWCELL,hBuf);
  GlobalUnlock(hBuf);
  Clipboard.Close;
 finally
  stream.Free();
 end;

 inf.FreeEx();

end;

procedure TCWCellDirector.saveCellParts(list:TStrings);
var
 stream:TMemoryStream;
 value,i:Integer;
 buffer:Pointer;
 hBuf:THandle;
begin

 stream:=TMemoryStream.Create();
 try

  value:=list.Count;
  stream.WriteBuffer(value,SizeOf(DWORD));

  for i:=0 to list.Count-1 do
  begin
   saveCell(stream,TImageInfo(list.Objects[i]));
  end;

  stream.Position:=0;

  hBuf := GlobalAlloc(GHND,stream.Size);
  buffer:=GlobalLock(hBuf);
  stream.ReadBuffer(buffer^,stream.Size);


  Clipboard.Open;
  Clipboard.Clear;
  Clipboard.SetAsHandle(CLIP_CWCELL,hBuf);
  GlobalUnlock(hBuf);
  Clipboard.Close;
 finally
  stream.Free();
 end;


end;

procedure TCWCellDirector.saveContent(list:TStrings);
var
 stream:TMemoryStream;
 i,value:Integer;
 bValue:byte;
 buffer:Pointer;
 hBuf:THandle;
begin
 stream:=TMemoryStream.Create();

 try
  bValue:=$8;
  stream.WriteBuffer(bValue,SizeOf(byte));
  stream.WriteBuffer(bValue,SizeOf(byte));
  Value:=1;
  stream.WriteBuffer(value,SizeOf(DWORD));

  bValue:=0;
  stream.WriteBuffer(bValue,SizeOf(byte));

  value:=40000;
  stream.WriteBuffer(value,SizeOf(DWORD));

  value:=list.Count;
  stream.WriteBuffer(value,SizeOf(DWORD));

  for i:=0 to list.Count-1 do
  begin
   saveCell(stream,TImageInfo(list.Objects[i]));
  end;

  stream.Position:=0;

  hBuf := GlobalAlloc(GHND,stream.Size);
  buffer:=GlobalLock(hBuf);
  stream.ReadBuffer(buffer^,stream.Size);

  Clipboard.Open;
  Clipboard.Clear;
  Clipboard.SetAsHandle(CLIP_CONTENT,hBuf);
  GlobalUnlock(hBuf);
  Clipboard.Close;

 finally
  stream.Free();
 end;



end;

procedure TCWCellDirector.saveCellView(list:TStrings);
var
 stream:TMemoryStream;
 i,value,len:Integer;
 bValue:byte;
 buffer:Pointer;
 hBuf:THandle;
 text:PChar;
begin
 stream:=TMemoryStream.Create();

 try
  bValue:=$0;
  stream.WriteBuffer(bValue,SizeOf(byte));
  stream.WriteBuffer(bValue,SizeOf(byte));
  Value:=0;
  stream.WriteBuffer(value,SizeOf(DWORD));

  text:='新規エリア'+#0;
  len:=Length(text)+1;
  stream.WriteBuffer(len,SizeOf(DWORD));
  stream.WriteBuffer(text^,len);

  value:=40001;
  stream.WriteBuffer(value,SizeOf(DWORD));

  bValue:=$0;
  stream.WriteBuffer(bValue,SizeOf(byte));

  value:=0;
  stream.WriteBuffer(value,SizeOf(DWORD));
  stream.WriteBuffer(value,SizeOf(DWORD));

  value:=list.Count;
  stream.WriteBuffer(value,SizeOf(DWORD));

  for i:=0 to list.Count-1 do
  begin
   saveCell(stream,TImageInfo(list.Objects[i]));
  end;

  stream.Position:=0;

  hBuf := GlobalAlloc(GHND,stream.Size);
  buffer:=GlobalLock(hBuf);
  stream.ReadBuffer(buffer^,stream.Size);

  Clipboard.Open;
  Clipboard.Clear;
  Clipboard.SetAsHandle(CLIP_CWVIEW,hBuf);
  GlobalUnlock(hBuf);
  Clipboard.Close;

 finally
  stream.Free();
 end;



end;

Initialization
 CLIP_CWCELL:=RegisterClipboardFormat('CardWirthEditor Cell');
 CLIP_CONTENT:=RegisterClipboardFormat('CardWirthEditor Content');
 CLIP_CWVIEW:=RegisterClipboardFormat('CardWirthEditor View');
end.
