{*******************************************************} { } { Tocsg.Clipboard } { } { Copyright (C) 2019 kku } { } {*******************************************************} unit Tocsg.Clipboard; // 잠깐 만들던건.. 여기 Tocsg.Clipboard_Old interface uses System.SysUtils, Vcl.Clipbrd, Winapi.Windows, Winapi.Messages, System.Classes; //const // arrCbImgFormat: array [0..26] of DWORD = ( // CF_DIB, CF_DIBV5, CF_BITMAP, // // 윈도우 기본 캡쳐 시 사용되는 이미지 포맷 25_0306 16:31:21 kku // 491661, 49350, 50384, 50209, 48171, // // 엑셀 셀 복사 시 사용하는 이미지 포맷 // 16, // // 엑셀, 파워포인트에서 사용하는 이미지 포맷 // 49718, // // 파워포인트에서 사용하는 이미지 포맷 // 50706, 49350, 49523, 49161, 50707, 49348, // 49171, 49431, 50703, 49436, 50152, 49166, // 49349, 49935, 49360, 49298, 14 // ); // 클립보드 수행시 뜨는 포맷 목록들 //Text //Debug Output: OnDrawClipboard() - FormatCount : 4 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(0) : 13 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(1) : 16 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(2) : 1 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(3) : 7 Process kku Assister.exe (4708) //Capture //Debug Output: OnDrawClipboard() - FormatCount : 3 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(0) : 2 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(1) : 8 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(2) : 17 Process kku Assister.exe (4708) //File //Debug Output: OnDrawClipboard() - FormatCount : 11 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(0) : 49161 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(1) : 49359 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(2) : 50043 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(3) : 50044 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(4) : 49439 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(5) : 49414 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(6) : 49463 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(7) : 15 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(8) : 49158 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(9) : 49159 Process kku Assister.exe (4708) //Debug Output: OnDrawClipboard() - Format(10) : 49171 Process kku Assister.exe (4708) type // AllocateHWnd사용으로 thread에서 사용주의 TDrawClipboard = class; TNotifyClipboard = procedure(Sender: TDrawClipboard) of object; TDrawClipboard = class(TClipboard) private hWnd_: HWND; hNextCBWnd_, hAllocHWND_: HWND; bReseting_: Boolean; procedure WndProc(var msg: TMessage); override; protected evDrawCB_: TNotifyClipboard; procedure SetDrawCBEvent(evDrawCB: TNotifyClipboard); procedure process_WM_CHANGECBCHAIN(var msg: TMessage); procedure process_WM_DRAWCLIPBOARD(var msg: TMessage); // procedure process_WM_CLIPBOARDUPDATE(var msg: TMessage); public Constructor Create(h: HWND = 0); Destructor Destroy; override; procedure Stop; procedure Reset; property OnDrawClipboard: TNotifyClipboard read evDrawCB_ write SetDrawCBEvent; property NextCBWnd: HWND read hNextCBWnd_ write hNextCBWnd_; end; TClipboardHelper = class helper for TClipboard public function GetSize: Integer; end; function CopyToClipboard(const S: String; bDoClear: Boolean): Boolean; function ClearClipboard(bImageOnly: Boolean = false): Boolean; function OpenCloseClipboardTest: Boolean; function IsClipboardEmpty: Boolean; function GetClipboardSize: Integer; function GetClipboardHandles: String; var CF_HTML: DWORD; CF_BS1Empty: DWORD; { Clipboard has 8 Formats. 49161 = DataObject 49268 = Shell IDList Array 15 = CF_hDrop 49158 = FileName 49159 = FileNameW 49389 = Preferred DropEffect 49380 = Shell Object Offsets 49171 = Ole Private Data } implementation uses Vcl.Forms, Tocsg.Exception, Tocsg.Trace, Tocsg.Safe, Vcl.Graphics, System.Generics.Collections, Tocsg.Strings; { TDrawClipboard } Constructor TDrawClipboard.Create(h: HWND = 0); begin Inherited Create; hWnd_ := h; bReseting_ := false; hAllocHWND_ := 0; Reset; // hAllocHWND_ := AllocateHWnd(WndProc); // ASSERT(AddClipboardFormatListener(hAllocHWND_) = true); end; Destructor TDrawClipboard.Destroy; begin Stop; // RemoveClipboardFormatListener(hAllocHWND_); // DeallocateHWnd(hAllocHWND_); // hAllocHWND_ := 0; Inherited; end; procedure TDrawClipboard.Stop; begin if hAllocHWND_ <> 0 then begin if hNextCBWnd_ <> 0 then begin ChangeClipboardChain(hAllocHWND_, hNextCBWnd_); hNextCBWnd_ := 0; end; DeallocateHWnd(hAllocHWND_); hAllocHWND_ := 0; end else if hWnd_ <> 0 then begin if hNextCBWnd_ <> 0 then begin ChangeClipboardChain(hWnd_, hNextCBWnd_); hNextCBWnd_ := 0; end; end; end; procedure TDrawClipboard.Reset; begin // bReseting_ := true; // 초기화 할때 재감지 되도록 다시 롤백 24_0716 18:06:45 kku try Stop; if hWnd_ <> 0 then begin hNextCBWnd_ := SetClipboardViewer(hWnd_); end else begin hAllocHWND_ := AllocateHWnd(WndProc); hNextCBWnd_ := SetClipboardViewer(hAllocHWND_); end; finally bReseting_ := false; end; end; procedure TDrawClipboard.SetDrawCBEvent(evDrawCB: TNotifyClipboard); begin if @evDrawCB_ <> @evDrawCB then evDrawCB_ := evDrawCB; end; procedure TDrawClipboard.WndProc(var msg: TMessage); begin case msg.Msg of WM_CHANGECBCHAIN : process_WM_CHANGECBCHAIN(msg); WM_DRAWCLIPBOARD : process_WM_DRAWCLIPBOARD(msg); // WM_CLIPBOARDUPDATE : process_WM_CLIPBOARDUPDATE(msg); else msg.Result := DefWindowProc(hAllocHWND_, msg.Msg, msg.WParam, msg.LParam); end; end; procedure TDrawClipboard.process_WM_CHANGECBCHAIN(var msg: TMessage); begin with TWMChangeCBChain(msg) do begin if (Remove = hNextCBWnd_) then hNextCBWnd_ := Next else if hNextCBWnd_ <> 0 then SendMessage(hNextCBWnd_, WM_CHANGECBCHAIN, Remove, Next); end; end; procedure TDrawClipboard.process_WM_DRAWCLIPBOARD(var msg: TMessage); begin if bReseting_ then exit; // msg as TWMDrawClipboard if Assigned(evDrawCB_) then evDrawCB_(Self); if hNextCBWnd_ <> 0 then SendMessage(hNextCBWnd_, msg.Msg, msg.WParam, msg.LParam); // SendMessage(hNextCBWnd_, WM_DRAWCLIPBOARD, 0, 0); end; //procedure TDrawClipboard.process_WM_CLIPBOARDUPDATE(var msg: TMessage); //begin // if Assigned(evDrawCB_) then // evDrawCB_(Self); //end; { // 클립보드에 CF_HTML 형태로 입력 // _____________________________________________________________________________ procedure SetClipBoardHTML(s: String); const START_FRAGMENT=''; END_FRAGMENT =''; var gMem: HGLOBAL; pBytes: PByteArray; i: Integer; tmpStr: String; LBuffer: TBytes; begin // HTML Format에 맞게 세팅 tmpStr:='Version:1.0'+#13#10; tmpStr:=tmpStr+'StartHTML:~~~~~~~~'+#13#10; tmpStr:=tmpStr+'EndHTML:########'+#13#10; tmpStr:=tmpStr+'StartFragment:~~~~~~~~'+#13#10; tmpStr:=tmpStr+'EndFragment:########'+#13#10; tmpStr:=tmpStr+'
'+#13#10; tmpStr:=tmpStr+''+s+''+#13#10; tmpStr:=StringReplace(tmpStr, '~~~~~~~~', Format('%.08d', [Pos(' 0 then Result := GlobalSize(Data); finally if Data <> 0 then GlobalUnlock(Data); Close; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. GetSize()'); end; end; { Function } function OpenAndClearClipboard: Boolean; begin Result := OpenClipboard(0); if Result then EmptyClipboard; end; function CopyToClipboard(const S: String; bDoClear: Boolean): Boolean; var nDataSize, nBufferSize: Integer; hData: HGLOBAL; pData: Pointer; begin nDataSize := Length(S) * 2; if nDataSize > 0 then begin if bDoClear then begin if not OpenAndClearClipboard then begin Result := false; exit; end; end; nBufferSize := nDataSize + 2; hData := GlobalAlloc(GMEM_MOVEABLE or GMEM_DDESHARE, nBufferSize); if hData <> 0 then begin pData := GlobalLock(hData); if pData <> nil then begin Move(S[1], pData^, nBufferSize); GlobalUnlock(hData); SetClipboardData(CF_UNICODETEXT, hData); end; end; if bDoClear then CloseClipboard; end; Result := True; end; procedure RemoveClipboardImageFormat; type PCbEnt = ^TCbEnt; TCbEnt = record uType: UINT; pData: Pointer; nSize: Integer; end; var uFormat: UINT; CbTxtFmtList: TList