对剪贴板的深入探讨

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

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

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


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

拦截它的操作信息;

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 个回复 | 最后更新于 2020-11-06
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可以写键值对。

2020-11-06   #3

回复#2 @codex :

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

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...