, , , WM_CLIPBOARDUPDATE - delphi, . .
:
(N.B. tecnique Windows Vista , WinAPI, . -
http://delphidabbler.com/articles?article=9)
type
TAddOrRemoveClipboardFormatListener = function (hWndNewViewer : HWND) : BOOL; stdcall;
var _isClipboardChangeRequired : boolean;
var _addClipboardFormatListener, _removeClipboardFormatListener : TAddOrRemoveClipboardFormatListener;
procedure TDM.DataModuleCreate(Sender: TObject);
begin
<...>
_addClipboardFormatListener := GetProcAddress(GetModuleHandle('user32.dll'), 'AddClipboardFormatListener');
_removeClipboardFormatListener := GetProcAddress(GetModuleHandle('user32.dll'), 'RemoveClipboardFormatListener');
if (Assigned(_addClipboardFormatListener) AND NOT _addClipboardFormatListener(Application.Handle)) then
begin
_isClipboardChangeRequired := false;
ShowMessage(' ! !' +
sLineBreak + ' (' + IntToStr(GetLastError()) + '): ' + SysErrorMessage(GetLastError()));
end
else
_isClipboardChangeRequired := true;
<...>
end;
procedure TDM.DataModuleDestroy(Sender: TObject);
begin
if Assigned(_removeClipboardFormatListener) then
_removeClipboardFormatListener(Application.Handle);
end;
procedure TDM.ApplicationEvents_ClipboardChangeMessage(var Msg: tagMSG; var Handled: Boolean);
const
WM_CLIPBOARDUPDATE = $031D;
MAX_CLIPBOARD_OPEN_ATTEMPTS = 3;
var
textBuf : array[0..512] of WideChar;
clipHandle : THandle;
dataPtr: Pointer;
dataSize : integer;
str : string;
attemptCount : integer;
isClipboardOpened : boolean;
begin
if (NOT Assigned(_addClipboardFormatListener)) then
begin
ApplicationEvents_ClipboardChange.OnMessage := nil;
Exit;
end;
if (Msg.message = WM_CLIPBOARDUPDATE) AND (Clipboard.HasFormat(CF_UNICODETEXT)) then
if NOT _isClipboardChangeRequired then
begin
_isClipboardChangeRequired := true;
Exit;
end
else
begin
attemptCount := 1;
isClipboardOpened := false;
repeat
try
Clipboard.Open();
isClipboardOpened := true;
except
if (attemptCount >= MAX_CLIPBOARD_OPEN_ATTEMPTS) then
begin
OutputDebugString(PChar(': - !'));
Exit;
end
else
inc(attemptCount);
end;
until isClipboardOpened;
clipHandle := Clipboard.GetAsHandle(CF_UNICODETEXT);
dataPtr := GlobalLock(clipHandle);
if (dataPtr <> nil) then
try
dataSize := GlobalSize(clipHandle);
ZeroMemory(@textBuf, sizeof(textBuf));
CopyMemory(@textBuf, dataPtr, dataSize);
SetString(str, textBuf, dataSize);
str := Trim(str);
Clipboard.AsText := str;
_isClipboardChangeRequired := false;
OutputDebugString(PChar('Clipboard encoding converted!'));
finally
GlobalUnlock(clipHandle);
end;
Clipboard.Close();
end;
end;