# quick_search **Repository Path**: chaofan2685_admin/quick_search ## Basic Information - **Project Name**: quick_search - **Description**: 全局划词搜索,可实现PC端在任意界面(almost)选中文字后,使用快捷键快速搜索该文字,需配合Windows批处理文件使用。 - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2018-08-23 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: search-engine **Tags**: None ## README # quick_search #### 项目介绍   全局划词搜索,可实现PC端在任意界面(almost)选中文字后,使用快捷键快速搜索该文字,需配合Windows批处理文件使用。 #### 软件架构   Spring Boot #### 软件思路   首先明确一下我的需求,当我在任意界面浏览的时候,选中一些文字,此时使用快捷键(假设这个快捷键是`Ctrl+Shift+Q`)便可立即百度搜索这些字。   首先介绍Java端,Java程序中只有一个Controller,用于接收请求,收到请求后它会从系统剪切板中取出内容,并拼接成一条cmd命令,该命令大致意思时启动浏览器去访问拼接好的搜索链接(暂时只支持百度,有空了再添几种),这样就实现了查询的功能。 ``` Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); //从系统剪切板中获取数据 Transferable content = clipboard.getContents(null); //判断是否为文本类型 if (content.isDataFlavorSupported(DataFlavor.stringFlavor)) { //从数据中获取文本值 String text = (String) content.getTransferData(DataFlavor.stringFlavor); if (text == null) { return; } //拼接一条cmd命令 String url = "rundll32 url.dll,FileProtocolHandler https://www.baidu.com/s?wd="; //执行cmd命令 Runtime.getRuntime().exec(url+text); } ```   那么如何保证剪切板中取出的内容就是你浏览时选中的文字呢?并且要怎么出发这个请求?我用的是批处理文件(`search.bat`),该文件中的命令就是发送一个请求(`curl localhost:18088`),然后,给这个批处理文件新建一个快捷方式放在桌面,鼠标右键>属性,给它设置一个快捷键,就是刚才的`Ctrl+Shift+Q`,并将运行方式修改为最小化(这样在运行的时候不会弹出窗口,交互更友好),应用。   此时,当选中文字并按下该快捷键的时候,系统就会通过cmd命令发送请求到我们的Controller,然而,我们选中的文字还是没有复制啊!!!如果你不怕麻烦,可以先`Ctrl+C`复制了选中的文字后再`Ctrl+Shift+Q`,但是这样显然不够优雅。   因此我又想到了一个办法,让Java程序模拟`Ctrl+C`的操作,即请求到达Controller后,Java程序先模拟`Ctrl+C`,这样你选中的文字就会被复制,之后走“取”、“查”的操作,嗯,看似很美好,美滋滋。 ``` Robot robot = new Robot(); //模拟Ctrl+C,复制文字 robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_CONTROL); robot.delay(100);//必不可少 ```   然而实地应用之后发现有问题。当你选中文字并按下快捷键后,系统启动了一个cmd窗口,虽然他是最小化运行的,小到你甚至不会发现有这么一个窗口,但是你选中文字的窗口还是被挤到了后台,此时就算`Ctrl+C`了,也复制不到这些文字,冥思苦想,又想出一个骚操作,我们在Ctrl+C之前先执行`Alt+Tab`(切换到上个窗口),这样不就行了!果然,复制到了选中的文字,美滋滋。 ``` Robot robot = new Robot(); //模拟Alt+Tab,切换回上一个的窗口,也就是有选中文字的窗口 robot.keyPress(KeyEvent.VK_ALT); robot.keyPress(KeyEvent.VK_TAB); robot.keyRelease(KeyEvent.VK_TAB); robot.keyRelease(KeyEvent.VK_ALT); robot.delay(100);//必不可少 //模拟Ctrl+C,复制文字 robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_CONTROL); robot.delay(100);//必不可少 ```   本以为大功告成,结果使用了不到两分钟,又出现了致命的BUG。就是当你选中文字并按下快捷键后,如果抬手比较慢或是根本没抬手,这是请求到达Controller,立即就执行`Alt+Tab`,此时加上按下去的按键,直接导致按键冲突了,所以接下去的`Ctrl+C`就又复制不到你想要的东西了。这个BUG让我困惑了好久,直到下班也没解决。我想的就是在代码里加个“`while`”循环,判断用户是否按下了按键,直到监听不到有按键被按下,才执行后续操作,理想很丰满,然而实施起来并不简单,因为我对Java C/S架构知之甚少,键盘监听事件也不会用,而且好像这个事件还必须绑定到一个`JFrame`上(如果这里说错了,请大神指出,蟹蟹),我不可能为了实现我这简单的功能,再建一个`JFrame`,然后再。。。。不不不,这TM扯到哪儿去了。这条路行不通。   当然,还有一个简单但是却不完美的解决方案,就是在进入Controller后先`Thread.sleep(1000)`,让程序先等一会儿,给用户一个抬手的机会,但是用户:`我TM就是不抬手了你能咋地?`,那就GG了,而且等待的操作也会导致用户体验下降,造成反应迟钝的感觉,不行不行,这完全不符合我追求完美的精神,太不优雅了。   然而,最终还是被我想到了解决办法。我们在`Alt+Tab`之前,再模拟一个事件,就是`Ctrl`、`Shift`、`Alt`的抬起事件(因为一般的快捷键都是包含这三个的),这样就算用户手指还按在键盘上,但是实际这几个键已经不起作用了,之后就该干啥干啥,美滋滋。 ``` Robot robot = new Robot(); //模拟三大快捷键的抬起事件,以防止按键冲突 robot.keyRelease(KeyEvent.VK_CONTROL); robot.keyRelease(KeyEvent.VK_SHIFT); robot.keyRelease(KeyEvent.VK_ALT); robot.delay(100);//必不可少 //模拟Alt+Tab,切换回上一个的窗口,也就是有选中文字的窗口 robot.keyPress(KeyEvent.VK_ALT); robot.keyPress(KeyEvent.VK_TAB); robot.keyRelease(KeyEvent.VK_TAB); robot.keyRelease(KeyEvent.VK_ALT); robot.delay(100);//必不可少 //模拟Ctrl+C,复制文字 robot.keyPress(KeyEvent.VK_CONTROL); robot.keyPress(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_C); robot.keyRelease(KeyEvent.VK_CONTROL); robot.delay(100);//必不可少 ```   至此算是基本实现了我的需求,也许有更简单的办法可以实现这个看似非常简单的功能,但我作为一个菜鸟java程序员,暂时只能曲线救国的来实现该需求了。 #### 使用说明 1. 建议打jar包,并将jar包和“file”文件夹中的两个批处理文件一起复制到本地 2. 给`search.bat`创建一个快捷方式并按照上面的描述进行修改。 3. `switch.bat`是负责开启和关闭程序的脚本,如果jar包没运行,双击后会在后台启动jar包,如果已经运行了,可根据提示输入相关字符将其关闭。 > `search.bat`的快捷方式只能放在桌面,否则设置了快捷键后是不会生效的,这个是什么原因要@微软了。如果你有强迫症,也可以把它放到开始菜单里,具体操作如下:打开开始菜单,随便找个程序,右键>更多>打开文件位置,此时会打开一个文件夹(不是每个软件都有“打开文件位置”的选项,可以多试几个),之后将刚才的快捷方式放到这里并设置好快捷键,理论上放在这里快捷键也是可以生效的,如果有其他高招,欢迎交流,谢谢。 #### 参与贡献   [炒饭](https://gitee.com/chaofan2685_admin/events)    #### 资源分享 ​  该项目只是写着玩儿,要达到日用级别还不太靠谱,如果真有这种需求,推荐一款软件,[搜索易](http://www.i-ssy.com) #### 最后声明 ​  文章就不配图了,图片不好居中,看起来十分不优雅。哈哈哈哈嗝。。。😄