브라우저에서 드래그 한 다음 Ctrl+C를 눌러 클립보드에 저장한 후,
WYSIWYG 에디터에서 Ctrl+V를 눌러 뿌려보면 태그가 그대로 적용된 것이 보인다.
이것은 클립보드의 또 다른 형태를 이용한 버전이다.
기본적인 CF_TEXT와 함께 HTML Format의 데이터도 저장된다.


클립보드 HTML Format에 대한 정보 : http://msdn.microsoft.com/en-us/library/aa767917(VS.85).aspx



클립보드의 HTML Format은 아래와 같은 형태를 지닌다.
아래 전부의 내용이 클립보드 안에 들어간다.
나누자면,
노르스름한게 헤더같은 존재고
나머지 하얀색이 HTML 내용이며,
<!--StartFragment--> 와 <!--EndFragment--> 사이가 뽑아낼 내용이다.
자세한 내용은 위의 링크를 봐도 알 수 있고 숫자로 계산을 때려봐도 대충 감은 온다.
Version:0.9
StartHTML:71
EndHTML:170
StartFragment:140
EndFragment:160
StartSelection:140
EndSelection:160
<!DOCTYPE>
<HTML>
<HEAD>
<TITLE>The HTML Clipboard</TITLE>
<BASE HREF="http://sample/specs"> 
</HEAD>
<BODY>
<!--StartFragment -->
<P>The Fragment</P>
<!--EndFragment -->
</BODY>
</HTML>






아쉽게도 델파이에서 사용하는 ClipBoard 객체엔 CF_HTML 이 정의되어 있지 않다.
직접 정의해서 사용하는 수 밖에 없다.
아래에 CF_HTML 형태로 클립보드에 저장하고, CF_HTML 형태로 저장된 클립보드 내용을 가져오는 함수를 남긴다.
존내 짜증나는건 브라우저마다 위치계산하기가 애매하다는 것이다.
제대로 돌아가게 만들려면 반드시 다시 보고 연구해야 한다.
Chrome이 제일 편하고 짱인듯...

  (함수 두개 달랑 있는 소스파일)





클립보드에 CF_HTML 형태로 저장하기

주의!
일단은 급한 필요에 의해 IE, FireFox, Chrome 브라우저에 <img src="ImagePath"> 형태로 뿌릴 수 있는 것만 구현했다.
다른 긴 태그들의 연속이나,
한글이나 기타 사항을 넣으려면 UTF8 관련된 인코딩 삽질을 해야한다.


  1. // 클립보드에 CF_HTML 형태로 입력
  2. // _____________________________________________________________________________
  3. procedure SetClipBoardHTML(s: String);
  4. const
  5.   START_FRAGMENT='<!--StartFragment-->';
  6.   END_FRAGMENT  ='<!--EndFragment-->';
  7.  
  8. var
  9.   gMem: HGLOBAL;
  10.   pBytes: PByteArray;
  11.   i: Integer;
  12.   tmpStr: String;
  13.   LBuffer: TBytes;
  14.  
  15. begin
  16.   // HTML Format에 맞게 세팅
  17.   tmpStr:='Version:1.0'+#13#10;
  18.   tmpStr:=tmpStr+'StartHTML:~~~~~~~~'+#13#10;
  19.   tmpStr:=tmpStr+'EndHTML:########'+#13#10;
  20.   tmpStr:=tmpStr+'StartFragment:~~~~~~~~'+#13#10;
  21.   tmpStr:=tmpStr+'EndFragment:########'+#13#10;
  22.   tmpStr:=tmpStr+'<html><body>'+#13#10;
  23.   tmpStr:=tmpStr+'<!--StartFragment-->'+s+'<!--EndFragment-->'+#13#10;
  24.   tmpStr:=StringReplace(tmpStr, '~~~~~~~~', Format('%.08d', [Pos('<html', tmpStr)-1]), [rfReplaceAll]);
  25.   tmpStr:=StringReplace(tmpStr, '########', Format('%.08d', [Pos(END_FRAGMENT, tmpStr)+Length(END_FRAGMENT)]), [rfReplaceAll]);
  26.  
  27.   // 버퍼에 복사
  28.   SetLength(LBuffer, Length(tmpStr)+1);
  29.   for i:=0 to Length(tmpStr) do LBuffer[i]:=Byte(tmpStr[i+1]);
  30.  
  31.   // 클립보드용 버퍼에 복사
  32.   gMem:=GlobalAlloc(GHND, Length(LBuffer)*2);
  33.   pBytes:=GlobalLock(gMem);
  34.   try
  35.     for i:=0 to Length(LBuffer)+1 do pBytes[i]:=LBuffer[i];
  36.   finally
  37.     GlobalUnlock(gMem);
  38.   end;
  39.  
  40.   // 클립보드에 쓰기
  41.   OpenClipBoard(0);
  42.   EmptyClipBoard;
  43.   SetClipBoardData(RegisterClipBoardFormat('HTML Format'), gMem);
  44.   CloseClipBoard;
  45. end;





클립보드에 CF_HTML 형태로 들어있는 데이터를 가져오기

주의!
자동으로 헤더를 자르고 태그만 남기는 로직은 없다.
필요하다면 직접 대가리를 잘라야 한다.

  1. // 클립보드의 CF_HTML 포맷데이터 가져오기
  2. // _____________________________________________________________________________
  3. function GetClipBoardHTML: String;
  4. var
  5.   gMem: HGLOBAL;
  6.   pBytes: PByteArray;
  7.   lenBuffer: DWORD;
  8.   i: Integer;
  9.   CF_HTML: UINT;
  10.  
  11. begin
  12.   Result:='';
  13.  
  14.   // CF_HTML 등록
  15.   CF_HTML:=RegisterClipboardFormat('HTML Format');
  16.  
  17.   // 클립보드를 열어 CF_HTML 데이터가 있으면 읽어와서 반환
      OpenClipBoard(0);
  18.   if ClipBoard.HasFormat(CF_HTML) then begin
  19.     gMem:=GetClipboardData(CF_HTML);
  20.     pBytes:=GlobalLock(gMem);
  21.     try
  22.       lenBuffer:=Length(PChar(pBytes))*2;
  23.       SetLength(Result, lenBuffer);
  24.       for i:=0 to lenBuffer do Result[i+1]:=Chr(pBytes[i]);
  25.       Result:=TEncoding.UTF8.GetString(TBytes(pBytes), 0, lenBuffer);
  26.     finally
  27.       GlobalUnlock(gMem);
  28.     end;
  29.   end;
  30.   CloseClipBoard;
  31. end;












Posted by bloodguy
,