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

  • 主题发起人 主题发起人 cAkk
  • 开始时间 开始时间
另外,能不能使用delphi的

clipboard.SetAsHandle
clipboard.GetAsHandle
 
可以多种数据格式同时存在,但是是同一个数据的几个形式,比如:
word里面copy,有text格式(可以给notepad访问的纯文本,无字体、颜色等数据),
有word自己的格式(给其他word程序看,数据复杂的多),但是内容是一样的
 
windows的一贯做法,可变大小结构
struct
{
......//其他不变的部分
int size;
//buf的长度
char buf[1];//最后一个是可变的长度,这里定义一个字节,分配大小时后面可以跟多一点空间
}
 
>>另外 DataHandle 不用自己来释放了,windows自己会干这事了
你的意思是不是说我可以不用处理"WM_..."消息?

>>我以为你用pchar换结构里面的array[0..255] of char
不行吗? 如果我要保存的数据包括一个integer和一个不定长的string怎么办?
 
分配大小时实际分配是 sizeof(struct)+(buf实际需要长度 - 1)
 
可使用,看原代码吧,使用他还可以省略很多步骤。

procedure TClipboard.SetAsHandle(Format: Word;
Value: THandle);
begin

Open;
try
Adding;
SetClipboardData(Format, Value);
finally
Close;
end;

end;



function TClipboard.GetAsHandle(Format: Word): THandle;
begin

Open;
try
Result := GetClipboardData(Format);
finally
Close;
end;

end;



还有Win32Help. //CoreAPI好象是错的,不用释放内存。

Once SetClipboardData is called, <font color=red>the system owns the object
identified by the hMem parameter</font>. The application can read the data,
but <font color=red>must not free the handle or leave it locked</font>. If the hMem
parameter identifies a memory object, the object must have been
allocated using the GlobalAlloc function with the GMEM_MOVEABLE and
GMEM_DDESHARE flags.
 
不用释放内存是不是就是"不用处理WM_..."?
如果是,我有一点疑问,那些被我拷贝的数据占据的内存什么时候被释放呢?

>>分配大小时实际分配是 sizeof(struct)+(buf实际需要长度 - 1)
这句话没看懂
 
>owns the object identified by the hMem parameter
当然由系统释放了,可以看Delphi的原码Clipbrd.pas,更本没有释放的地方。
在这里,好象是CoreAPI错了。

struct
{
......//其他不变的部分
int size;
//buf的长度
char buf[1000];//多一点空间
}

SizeOf(Struct)+1000-1 //Pipi.兄,是不是???
 
>>SizeOf(Struct)+1000-1
但是这样还是不能做到"不固定长度"呀!
 
如果这样,Windows可能不知道如何释放Buf
struct
{
......//其他不变的部分
int size;
//buf的长度
char* buf;//多一点空间
}

我认为这样:
struct
{
......//其他不变的部分
int size;
//buf的长度
}

P:=GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,
Sizeof(Struct)+length(memo1.text)+1);
Move(Memo1.Text,Pointer(Interger(P)+SizeOf(Struct))^,Length(Memo1.Text);
Strcut.Size:=Length(Memo1.Text);
 
我晚上试一试把
 
前卫兄,你老是把我的东西改得不成样子了。

windows管理那块clipboard数据用到的内存(包括把它影射到其他进程空间,
释放等等),只认 hMem , hMem 申请有多少就是多少,反正windows操作系统
也不懂struct是什么东西,反正系统就认 hMem 这块内存在哪里,有多大。

windows里面,ms自己的东西,可变长度的全部都是定义为长度 1 的,你改成1000,
我的数据如果没有那么多岂不是浪费了空间。c语言是不管界限的,虽然定义
长度为1,但是你用 buf[1000] 也是一样可以访问连下来的东西。(delphi会判断
出界,用起来麻烦一点,不过也是这样用的)

你说把buf定义从struct中去掉,也是可以的,因为实际上存储方式是一样的,
但是ms从来不这样做,因为写起程序麻烦,你把 buf[1] 写进struct去,
访问时 可以 struct->buf(作为char*类型) ,struct->buf[1024] (作为其中一个char)
多方便. 要是象你这样把buf从struct中去掉,
访问起来就要这样: (char*)(((char*)struct)+sizeof(struct)) 多麻烦
 
Pipi.兄,
不好意思,没理解你的意思,现在好象明白了。不过我的方法也行吧?
 
我没理解pipi的意思.

到底怎么实现这样的剪贴版数据结构:

myformat=record
Number:integer
Text:string;
end
 
myformat=record
Number:integer
Text:PChar;
end

GlobalAlloc(GMEM_DDESHARE or GMEM_MOVEABLE,
Sizeof(myformat)+length(memo1.text)+1);

访问Text:

move(Memo1.Text,myformat.Text,Length(Memo1.Text))

//Pipi.这次没错了吧。


 
按你的定义,很糟糕。

myformat.Text是个指针变量,你还要给它赋值指向本结构后面得地址才行啊。
但是,你在别的进程里面使用前还要自己给它赋值才行。

在第一个进程,你可以 myformat.Text=(char*)(((char*)myformat)+sizeof(myformat))
windows把myformat.Text的数字值忠实的转给了其他进程,但是其他进程得到
的myformat.Text值是没用的,因为GlobalLock得到的myformat地址不一定和
原来的一样(如果该地址已经使用,操作系统会 ReAlloc另外一个地址值给myformat)
 
所以,在里面定义一个指针是没用的。
(顺便说一下,char* p ,p是指针,它的值指向另一块内存 ,
char b[xx] ,b虽然可以当 char* 用,但是它就是一块内存,
所以是完全不一样的2 回事)
 
假如在里面定义了一个指针,传到了别的进程,可是GlobalLock以后
myformat 的基地址都变了,指针也没用了
 
那到底怎么用啊!!!!
 
后退
顶部