怎样使用RegisterClipboardFormat? 300分(300分)

C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
如题.
我有一些固定格式的数据(其实就是文本),想通过剪贴版交换信息,
但是如果以CF_TEXT保存,可能会破坏别的程序的剪贴版文本,而且
也可能被别的程序读出来,我不希望这样,所以准备自己注册一种格式.

这个API怎么用? 好像clipboard.setashandle/getashandle和这个有关,
请大家指教.
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
y9y给的CoreAPI不是有吗

{our proprietary data format}
ProprietaryData = record
Number: Integer;
Text: array[0..255] of char;
end;


var
Form1: TForm1;
NewFormatID: UINT;
// holds the application defined clipboard format ID
DataHandle: THandle;
// a handle to our data

implementation

procedure TForm1.FormCreate(Sender: TObject);
begin

{register an application defined clipboard format}

NewFormatID := RegisterClipboardFormat('New Format Example');
end;


procedure TForm1.Button1Click(Sender: TObject);
var
DataPointer: ^ProprietaryData;
// a pointer to our data structure
begin

{allocate enough memory to hold our data structure}
DataHandle := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,
SizeOf(ProprietaryData));

{retrieve a pointer to the allocated memory}

DataPointer := GlobalLock(DataHandle);

{set the members of the structure with the supplied values}
DataPointer^.Number := StrToInt(Edit1.Text);
StrCopy(DataPointer^.Text, PChar(Edit2.Text));

{unlock the handle to the data}
GlobalUnlock(DataHandle);

{Open the clipboard}
OpenClipboard(Form1.Handle);

{empty the clipboard contents and assign Form1 as the clipboard owner}
EmptyClipboard;

{copy our proprietary data to the clipboard}

SetClipboardData(NewFormatID, DataHandle);

{close the clipboard}
CloseClipboard;
end;


procedure TForm1.WMDestroyClipboard(var Msg: TWMDestroyClipboard);
begin

{the clipboard is being emptied, so free our data}
GlobalFree(DataHandle);
inherited;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
RetrievedData: THandle;
// a handle to data

DataPointer: ^ProprietaryData;
// a pointer to our data type
begin

{open the clipboard}
OpenClipboard(Form1.Handle);

{retrieve the data in our application defined format}
RetrievedData := GetClipboardData(NewFormatID);

{get a pointer to the data}
DataPointer := GlobalLock(RetrievedData);

{display the data values}
Label1.Caption := IntToStr(DataPointer^.Number);
Label2.Caption := string(DataPointer^.Text);

{unlock the data handle}
GlobalUnlock(RetrievedData);

{close the clipboard}
CloseClipboard;
end;


The Tomes of Delphi 3: Win32 Core API Help File by Larry Diehl
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
****!我都忘了我还有这个宝贝了,我先看看把.
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
ProprietaryData 这个结构能否动态长度的? 因为文本长度不固定的.
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
能否用PCHAR代替ProprietaryData ?
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
ProprietaryData = record
Number: Integer;
Text: THandle;
end;


PropritearyData^Text := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,
100000000);


..........

如果是程序键,用OpenFileMapping......
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
说详细一点,能不不能用pchar代替record?
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
搞出来了,用pchar代替可以的,2个过程修改如下:

procedure TForm1.Button1Click(Sender: TObject);
var
DataPointer: pchar;
begin

DataHandle := GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,
length(memo1.text)+1);
DataPointer := GlobalLock(DataHandle);
StrpCopy(DataPointer, memo1.Text);
GlobalUnlock(DataHandle);
OpenClipboard(Form1.Handle);
EmptyClipboard;
SetClipboardData(NewFormatID, DataHandle);
CloseClipboard;
end;


procedure TForm1.Button2Click(Sender: TObject);
var
RetrievedData: THandle;
DataPointer: pchar;
begin

OpenClipboard(Form1.Handle);
RetrievedData := GetClipboardData(NewFormatID);
DataPointer := GlobalLock(RetrievedData);
memo2.text := strpas(DataPointer);

GlobalUnlock(RetrievedData);
CloseClipboard;
end;


就是有点担心会不会有内存泄漏?
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
一样的嘛。应该不会有内存泄漏,不过你要真确释放。
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
怎么叫"正确释放"? 怎么叫"不正确释放"?
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
成对使用就行嘛。还要在处理WM_DESTROYCLIPBOARD消息啊,不处理就可能
内存泄漏
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
>上面说错。

处理WM_DESTROYCLIPBOARD消息啊,不处理就可能内存泄漏

 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
你还少了这个:


procedure TForm1.WMDestroyClipboard(var Msg: TWMDestroyClipboard);
begin

{the clipboard is being emptied, so free our data}
GlobalFree(DataHandle);
inherited;
end;


 
P

Pipi.

Unregistered / Unconfirmed
GUEST, unregistred user!
>搞出来了,用pchar代替可以的

算了吧,你在不同的进程里面就不行了。(一个进程set、另一个进程get)

我又要来抢点分冲10000点了
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
Pipi.兄:
等等我啊!!!!!不要跑这么快!!!! {B-)))

如果是程序键,用OpenFileMapping......
 
P

Pipi.

Unregistered / Unconfirmed
GUEST, unregistred user!
哈。
看错了,可以的,我以为你用pchar换结构里面的array[0..255] of char

我去别处找分了,bye
 
P

Pipi.

Unregistered / Unconfirmed
GUEST, unregistred user!
前卫兄,不用 OpenFileMapping 了,windows会帮你把 hMem 转换一下
给其他进程看的了。

前卫用惯了filemapping就老是filemapping

另外 DataHandle 不用自己来释放了,windows自己会干这事了
 
P

Pipi.

Unregistered / Unconfirmed
GUEST, unregistred user!
cakk在开头说的:

》如果以CF_TEXT保存,可能会破坏别的程序的剪贴版文本

你用你自己的格式,也破坏了原先别人的剪贴版内容啊(任何格式)
 

沈前卫

Unregistered / Unconfirmed
GUEST, unregistred user!
但他又说:

“而且也可能被别的程序读出来,我不希望这样,所以准备自己注册一种格式.”
 
C

cAkk

Unregistered / Unconfirmed
GUEST, unregistred user!
哇! 没想到我睡了以后你们又聊了这么久!

前卫: 我处理了WM_...消息的.

>>另外 DataHandle 不用自己来释放了,windows自己会干这事了
你的意思是不是说我可以不用处理"WM_..."消息?

>>我以为你用pchar换结构里面的array[0..255] of char
不行吗? 如果我要保存的数据包括一个integer和一个不定长的string怎么办?

>>你用你自己的格式,也破坏了原先别人的剪贴版内容啊(任何格式)
哦,我还以为可以多种数据同时存在呢,我看API帮助里面好像说可以multi-format
的.

另外,等一等再分分,我昨晚睡觉前最后一次实验时发生死机,准备今晚看看是什么原因.
 
顶部