对剪贴板的深入探讨
By
笑口常
at 2020-11-01 • 0人收藏 • 2010人看过
剪贴板可以操作图片和文本, 那么如何才能同时操作图片+文本呢?
网上的一些方法试了下, 没啥作用, 也许是我用法不对... 但是确实是按照他们文档写的...
那么, 对它进行了深入一点的研究.
拦截它的操作信息;
import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=759;bottom=469)
winform.add(
button={cls="button";text="txt";left=0;top=402;right=93;bottom=470;z=1};
button2={cls="button";text="pic";left=105;top=402;right=205;bottom=470;z=2};
button3={cls="button";text="pic/txt";left=415;top=402;right=576;bottom=470;z=4};
button4={cls="button";text="count";left=602;top=402;right=673;bottom=470;z=5};
button5={cls="button";text="enum";left=697;top=402;right=760;bottom=470;z=6};
button6={cls="button";text="clear";left=232;top=402;right=338;bottom=470;z=7};
richedit={cls="richedit";text="RichEdit";left=0;top=0;right=758;bottom=389;align="center";edge=1;multiline=1;z=3}
)
/*}}*/
import console
console.open()
write = function(str){
str = ..string.toUnicode(str);
if(!str) return;
if(!::User32.OpenClipboard(0))
return;
User32.EmptyClipboard();
var clipbuffer = ::GlobalAlloc(0x2000/*_GMEM_DDESHARE*/, #str+2);
var buffer = ::GlobalLock(clipbuffer);
::CopyMemory(buffer,str,#str+2);
::GlobalUnlock(clipbuffer);
var hdl = ::User32.SetClipboardDataP(0xD/*_CF_UNICODETEXT*/,clipbuffer);
::User32.CloseClipboard();
return hdl;
}
writeBitmap = function(hBmp){
if(!::User32.OpenClipboard(0))
return;
::User32.EmptyClipboard();
var hdl = ::User32.SetClipboardDataP (0x2/*_CF_BITMAP*/
,::User32.CopyImageP(hBmp,0x0/*_IMAGE_BITMAP*/,0,0,0x4/*_LR_COPYRETURNORG*/) );
::User32.CloseClipboard();
return hdl;
}
hunWR = function(str,hBmp){
if(!::User32.OpenClipboard(0))
return;
::User32.EmptyClipboard();
str = ..string.toUnicode(str);
if(!str) return;
var clipbuffer = ::GlobalAlloc(0x2000/*_GMEM_DDESHARE*/, #str+2);
var buffer = ::GlobalLock(clipbuffer);
::CopyMemory(buffer,str,#str+2);
::GlobalUnlock(clipbuffer);
hd2 = ::User32.SetClipboardDataP(0xD/*_CF_UNICODETEXT*/,clipbuffer);
var picHW = ::User32.CopyImageP(hBmp,0x0/*_IMAGE_BITMAP*/,0,0,0x4/*_LR_COPYRETURNORG*/)
hdl = ::User32.SetClipboardDataP (0x2/*_CF_BITMAP*/,picHW );
::User32.CloseClipboard();
}
winform.button.oncommand = function(id,event){
write("adgfdfgfhgf23424546");
}
import gdip.bitmap;
var gdpic = gdip.bitmap("C:\Users\2222222\Desktop\28.png");
winform.button2.oncommand = function(id,event){
writeBitmap( gdpic.copyHandle() );
}
winform.button3.oncommand = function(id,event){
hunWR("adfgfhghj546768",gdpic.copyHandle());
}
winform.button4.oncommand = function(id,event){
console.log( ::User32.CountClipboardFormats() );
}
var func = function(i){
select(i) {
case 1 {
return "CF_TEXT 值:1";
}
case 2 {
return "2/*_CF_BITMAP*/";
}
case 3 {
return "3/*_CF_BOTH*/ 3/*_CF_METAFILEPICT*/";
}
case 4 {
return "CF_SYLK 值:4";
}
case 5 {
return "5/*_CF_DIF*/";
}
case 6 {
return "6/*_CF_TIFF*/";
}
case 7 {
return "7 CF_OEMTEXT";
}
case 8 {
return "8/*_CF_ENABLEHOOK*/ 8/*_CF_DIB*/";
}
case 9 {
return "9/*_CF_PALETTE*/";
}
case 10 {
return "10 CF_PENDATA";
}
case 11 {
return "0xB/*_CF_RIFF*/";
}
case 12 {
return "0xC/*_CF_WAVE*/";
}
case 13 {
return "0xD/*_CF_UNICODETEXT*/";
}
case 14 {
return "0xE/*_CF_ENHMETAFILE*/";
}
case 15 {
return "0xF/*_CF_HDROP*/";
}
case 16 {
return "0x10/*_CF_ENABLETEMPLATE*/";
}
case 17 {
return "0x11 CF_DIBV5";
}
else {
return null;
}
}
}
enumF = ::User32.api("EnumClipboardFormats","int(int)")
GetClipboardFormatName= User32.api("GetClipboardFormatName","int( INT format,string& Name,int cchMaxCount)");
winform.button5.oncommand = function(id,event){
if(!::User32.OpenClipboard(0))
return;
var count = ::User32.CountClipboardFormats();
console.log("------------",count)
var Name=..raw.buffer(100)
for(i=0;0x800000;1){
//var ret = func(enumF(i))
var ret = (enumF(i)!=0)?enumF(i):null;
if(ret){
x,data=GetClipboardFormatName(ret,Name,100)
console.log("ret,x,Name",ret,x,..raw.tostring(data))
count--;
if(count<=0){
break;
}
}
}
::User32.CloseClipboard();
}
winform.button6.oncommand = function(id,event){
if(!::User32.OpenClipboard(0))
return;
::User32.EmptyClipboard();
::User32.CloseClipboard();
}
winform.show();
win.loopMessage();上面本来我想弄出所有的信息, 可惜文档都不全, 目前实现了把剪贴板内信息输出, 看看图片和文本外加图片+文本在剪贴板中到底怎么实现链表存储的. 也许这样就能打开关键所在

先就是把这些信息逐个分析下.

3 个回复 | 最后更新于 2020-11-06
select语句完全可以用table替代,这样可以少写很多行代码
import console;
var func = function(i){
return ({
"CF_TEXT 值:1";
"2/*_CF_BITMAP*/";
"3/*_CF_BOTH*/ 3/*_CF_METAFILEPICT*/";
"CF_SYLK 值:4";
"5/*_CF_DIF*/";
"6/*_CF_TIFF*/";
"7 CF_OEMTEXT";
"8/*_CF_ENABLEHOOK*/ 8/*_CF_DIB*/";
"9/*_CF_PALETTE*/";
"10 CF_PENDATA";
"0xB/*_CF_RIFF*/";
"0xC/*_CF_WAVE*/";
"0xD/*_CF_UNICODETEXT*/";
"0xE/*_CF_ENHMETAFILE*/";
"0xF/*_CF_HDROP*/";
"0x10/*_CF_ENABLETEMPLATE*/";
"0x11 CF_DIBV5";
@{ _get = λ() "值不存在"} //else return null;
})[i];
}
console.log( func(18) )
console.pause(true);元表可以不写,因为键不存在时table默认返回的就是null,
当参数为string时 table可以写键值对。
登录后方可回帖


利用aardio封装好的win.clip.html库可以很方便实现同时复制图片和文字, 并且可以对图文进行编码排版, 就像html那样写
示例如下:
import win.ui; /*DSG{{*/ var winform = win.form(text="aardio form";right=338;bottom=185) winform.add( button={cls="button";text="copy";left=90;top=59;right=255;bottom=123;z=1} ) /*}}*/ import win.clip.html; var webClip = win.clip.html(); winform.button.oncommand = function(id,event){ webClip.write(` <b>This is a aardio program .这是一个测试。</b> <hr> <li>entry 1 <li>entry 2 <img src="C:\Users\2222\Desktop\28.png" /> `); } winform.show(); win.loopMessage();我找到一篇微软提供的文章, 里面有相应的示例, 我把它封装成了个dll来调用
https://docs.microsoft.com/zh-cn/troubleshoot/cpp/add-html-code-clipboard
使用方法:
var dll = raw.loadDll("/clipHtml.dll") CopyHTML = dll.api("CopyHTML","void(string)" ) winform.button.oncommand = function(id,event){ CopyHTML(` <b>This is a 12435 program .这是一个测试。</b> <hr> <li>entry 1 <li>entry 2 <img src="C:\Users\22222\Desktop\28.png" /> `); }