对剪贴板的深入探讨

By 笑口常 at 2020-11-01 • 0人收藏 • 230人看过

剪贴板可以操作图片和文本, 那么如何才能同时操作图片+文本呢?

网上的一些方法试了下, 没啥作用, 也许是我用法不对... 但是确实是按照他们文档写的...


那么, 对它进行了深入一点的研究.

拦截它的操作信息;

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();


上面本来我想弄出所有的信息, 可惜文档都不全, 目前实现了把剪贴板内信息输出, 看看图片和文本外加图片+文本在剪贴板中到底怎么实现链表存储的. 也许这样就能打开关键所在

image.png

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

image.png

3 个回复 | 最后更新于 29 天前
2020-11-03   #1

利用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();

image.png





我找到一篇微软提供的文章, 里面有相应的示例, 我把它封装成了个dll来调用

https://docs.microsoft.com/zh-cn/troubleshoot/cpp/add-html-code-clipboard

clipHtml.zip

使用方法:

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" />
	`);
}


2020-11-04   #2

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可以写键值对。

29 天前   #3

回复#2 @codex :

大佬的代码总是写得这么出神入画

登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前在学aardio+halcon机器视觉.
Htmlayout界面在线学习文档
Sciter中文在线文档Sciter在线学习文档
本 站 主 站:Stm32cube中文网
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
aardio在线手册Aardio在线手册
C大Aardio论坛:Aar爱好者论坛
简码教程网:简码编程
AARDIO语言QQ群:70517368
赞助商:才仁机械
下载站:非凡软件站
Loading...