用AHK的GUI+activeX实现文字悬浮在桌面上,并ctrl+c复制

您所在的位置:网站首页 悬浮窗怎么复制粘贴图片呢 用AHK的GUI+activeX实现文字悬浮在桌面上,并ctrl+c复制

用AHK的GUI+activeX实现文字悬浮在桌面上,并ctrl+c复制

2024-07-05 01:10:56| 来源: 网络整理| 查看: 265

背景:

作为一个复制粘贴程序员,日常使用的就是复制粘贴,单是我发现,有时候需要频繁的切换窗口来复制我们需要的文字,而且是在同一个文件中进行复制操作,比如写java对象的时候我们要去复制这个对象的所有字段,来设置值,这时能不能把所有字段放悬浮在桌面,然后在另一个java代码中来操作,找了一下还没找到有这样的工具,但是有个工具snipast(贴图工具)和这个类似,但是他贴出来的都是图片,文字也被转换为图片了,我们只能看不能复制,很是不方便,后来就决定自己仿照snipast开发一个可以复制文本的悬浮窗呢,后来花了一周时间终于实现了。

准备: 

autohotkey ,gui, activeX 相关知识。 

windows粘贴板相关知识。

实现原理 &操作方式:

ahk的gui中调用activeX空间渲染从粘贴板中获取的带格式的文本(html格式),然后通过快捷键悬浮在桌面上。 

F3:显示gui

Shift+F3:隐藏/显示gui

拖动:选中任意文本内容,然后鼠标变为箭头即可拖动

ESC : 退出当前选中gui

最终效果 : 

实现难点:

1、实现从粘贴板中获取带格式的文本,这个需要调用dll来实现,我也是找了很多资料才实现。

2、粘贴范围的锁定,即gui的长宽的确定

它的实现机制就是gui+activeX控件,大家都知道这个activeX控件很多js的东西不兼容,有的时候这个属性不行就换另一个属性,说不定就行了。

        确定宽度width:

        这个属实没法确定,只有通过计算粘贴板纯文本的最长字数来确定,区分汉字和范围在0-127的字符,然后确定单个字符长度(px)然后相加及是显示区域的宽度,为了美观我限制最大宽度为850。

        确定高度height:

        开始我使用计算行的方式,然后计算行高,最后能得出总高度,但是这样不是很准确,而且如果样式带背景会很不美观,所以我想到一个好方法,就是给样式的html中加入div,用div来包裹body中的所有内容,然后获取div的高度,就能完美得到整个gui的高度。

3、隐藏滑动快,最开始我想保留滑块,然后美化一下,但是ie没法改变滑块的样式,最后只有把他隐藏起来了,activeX控件的宽度大于gui的宽度20px以上就能隐藏右侧滑块。 

4、实现activeX中文本复制功能

        乍一看,不就是ctrl+c就能复制了吗,你都是文本了,可实际上不然,由于坑爹的activeX控件会拦截ctrl+c,enter,ctlr+x等操作,就只能通过右键选择复制来复制,然而这并不太方便,后来查阅资料都没有找到合适的解决方式,后来通过按键映射和js按键消息解决这个问题。

先是当前GUI界面监听ctrl+c按键操作,有ctrl+c我就给控件activeX发送非ctrl+c按键,这个我用的是P

;当前窗口GUI界面 #If WinActive(A_ScriptName) $^c:: ;获取选中文本 ; tooltip ctl+c ControlSend,% "Internet Explorer_Server1" , P, %A_ScriptName% return ; msgBox % VB #If

然后在html页面 写js来监听按键P,监听到以后发送复制操作,最后两行代码是阻止用户输入的。

document.onkeypress = function() { var evt = (evt) ? evt : window.event; if (evt.keyCode == 80) { document.execCommand("Copy"); } evt.keyCode = 0; evt.returnValue = false }

啰嗦一下,为什么用document.onekeypress,因为其他属性activeX不支持,比如最开始我就是用的document.onkeydown ,死活复制不了,后来发现是这个代码就没起作用。

完整ahk代码 :

#SingleInstance, off OnExit,OnExit $F4:: ; xx1=C:\Users\Administrator\Desktop\xx1.html ; xx2=C:\Users\Administrator\Desktop\xx2.html ; xx3=C:\Users\Administrator\Desktop\xx3.html IfExist, %xx1% FileDelete ,%xx1% IfExist, %xx2% FileDelete ,%xx2% IfExist, %xx3% FileDelete ,%xx3% ;获取容器高度 html:=ClipboardGet_HTML("html") FileAppend, %html%,%xx1% ,UTF-8 if(html=0) ;普通文本格式 { ;组装html html:=getHtml() FileAppend, %html%, %xx3%,UTF-8 } html:=changeHtml(html) if(html=0) { html:=getHtml() html:=changeHtml(html) } FileAppend, %html%, %xx2%,UTF-8 HTML_page:=html width_outter:=getClipboardMaxLineWidthPX() width_outter:=width_outter850?850:width_outter width_inner:=width_outter+20 wpx:= "w" width_outter wpx2:="w" width_inner ; wpx2:="w600" Gui New Gui Add, ActiveX, x0 y0 %wpx2% h870 vWB, Shell.Explorer ; The final parameter is the name of the ActiveX component. WB.silent := true ;Surpress JS Error boxes Display(WB,HTML_page) ;Wait for IE to load the page, before we connect the event handlers while WB.readystate != 4 or WB.busy sleep 10 ;;获取内部div高度 hdiv:=WB.document.getElementById("mainDiv").offsetHeight hdiv:=hdiv>850?850:hdiv hpx:="h" hdiv ;Use DOM access just like javascript! Gui +AlwaysOntop Gui -Caption +Border +ToolWindow Gui Show, %wpx% %hpx% return ;隐藏或显示桌面上的展示,贴图操作 DetectHiddenText, On shift_f3_flag:=0 $+F4:: if(!shift_f3_flag) WinHide ,%A_ScriptName% else WinShow ,%A_ScriptName% shift_f3_flag:=!shift_f3_flag send {Shift down}{F3}{Shift up} return GuiClose: Gui Destroy OnExit: FileDelete,%A_Temp%\*.DELETEME.html ;clean tmp file Gui Destroy return GuiEscape: Gui Destroy return ;------------------ Display(WB,html_str) { Count:=0 while % FileExist(f:=A_Temp "\" A_TickCount A_NowUTC "-tmp" Count ".DELETEME.html") Count+=1 FileAppend,%html_str%,%f%,UTF-8 WB.Navigate("file://" . f) } ;获取粘贴板的html格式数据 ClipboardGet_HTML( byref Data ) { ; http://www.autohotkey.com/forum/viewtopic.php?p=392624#392624 If CBID := DllCall( "RegisterClipboardFormat", Str,"HTML Format", UInt ) If DllCall( "IsClipboardFormatAvailable", UInt,CBID ) 0 If DllCall( "OpenClipboard", UInt,0 ) 0 If hData := DllCall( "GetClipboardData", UInt,CBID, UInt ) DataL := DllCall( "GlobalSize", UInt,hData, UInt ) , pData := DllCall( "GlobalLock", UInt,hData, UInt ) , Data := StrGet( pData, dataL, "UTF-8" ) , DllCall( "GlobalUnlock", UInt,hData ) DllCall( "CloseClipboard" ) Return dataL ? Data : 0 } ;获取粘贴板的html,并添加一些内容... 和 .... changeHtml(clipHtml) { ;屏蔽浏览器间隙 head=*{margin: 0px;padding: 0px;}#mainDiv{overflow-x: visible;padding: 10px;} ;主div用于测量高度 beginDiv= endDiv= js=if(document.getElementsByTagName("pre")[0]!=null){var rgb = document.getElementsByTagName("pre")[0].style.backgroundColor;document.getElementById("body1").style.backgroundColor = rgb;document.getElementById("body1").style.backgroundColor = rgb;}document.onkeypress = function() {var evt = (evt) ? evt : window.event;if(evt.keyCode==80){document.execCommand("Copy");}evt.keyCode = 0;evt.returnValue = false } endDiv:=endDiv js beginCount:=0 htmlTxt:="" Loop, parse, clipHtml, `n, `r { index:=A_Index if(index=6 &&!A_LoopField ) ;不处理office系列的各种格式 return 0 if index> 6 { tempField:=A_LoopField if(index=7 && strBeginWith(tempField,"")) StringReplace, tempField, tempField, , % head if(inStr(tempField,"") && !beginCount) { StringReplace, tempField, tempField, , % beginDiv beginCount+=1 } htmlTxt:=htmlTxt tempField "`r`n" } } StringGetPos, position, htmlTxt, ,R str1:=SubStr(htmlTxt,1,positIon) str2:=SubStr(htmlTxt,position+1) StringReplace, str2, str2, , % endDiv htmlTxt:=str1 str2 return htmlTxt } ;获取粘贴板最长行的像素 getClipboardMaxLineWidthPX() { a_length:=9 ;字符占用宽度 b_length:=18 ;汉字占用宽度 clip:=clipboard max_width_px:=0 Loop, parse, clip, `n, `r { index:=A_Index line:=A_loopfield temp_width_px:=0 Loop, parse, line { char:=A_loopfield if chr(char)max_width_px) max_width_px:=temp_width_px } return max_width_px } ;粘贴板文本转为html格式文件 getHtml() { clip:=clipboard head=body { background-color:#3c3f41; font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;font-size:15px; color:#ffffff;line-height:18px;letter-spacing:1.06px} head:= "1`r`n2`r`n3`r`n4`r`n5`r`n6`r`n" head Loop, parse, clip, `n, `r { line:=A_loopField StringReplace, line, line,% " " ,% ";",All head:=head "

" line "

" } head:=head "" return head } strBeginWith(str,suffix) { return str!=LTrim(str,suffix) } ;移动选框 WM_LBUTTONDOWN(){ Static init:=OnMessage(0x0201, "WM_LBUTTONDOWN") if(A_Cursor="Arrow") PostMessage, 0xA1, 2 } ;当前窗口GUI界面 #If WinActive(A_ScriptName) $^c:: ;获取选中文本 ; tooltip ctl+c ControlSend,% "Internet Explorer_Server1" , P, %A_ScriptName% return ; msgBox % VB #If

最后:

这个代码不是很复杂,但是细节东西很多,ahk在这方面资料又比较少,遇到问题只有自己想办法解决,所以还是花了我一周时间来写这个工具,我把代码分享出来就是为了大家少躺坑,当然看不懂的直接用就行了 ,我把打包好的exe放到csdn了 链接:xxxxxxx。     



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭