├── .gitignore ├── LICENSE ├── LICENSE - English ├── Readme.md ├── bin ├── OEScreenshot.dll ├── OEScreenshot.lib ├── OEScreenshot.md ├── Readme.md └── 一键发布.bat ├── demo ├── Readme.md ├── ScreenShotLib │ ├── Readme.md │ ├── ScreenShotLibDemo.pro │ ├── main.cpp │ ├── widget.cpp │ └── widget.h └── SimpleShortcutKey │ ├── Readme.md │ ├── SimpleShortcutKey.pro │ ├── main.cpp │ ├── qxt │ ├── qxt.pri │ ├── qxtglobal.h │ ├── qxtglobalshortcut.cpp │ ├── qxtglobalshortcut.h │ ├── qxtglobalshortcut_mac.cpp │ ├── qxtglobalshortcut_p.h │ ├── qxtglobalshortcut_win.cpp │ └── qxtglobalshortcut_x11.cpp │ ├── widget.cpp │ ├── widget.h │ └── widget.ui ├── doc ├── Doxyfile ├── build │ ├── build_osx.md │ ├── build_unix.md │ ├── build_window.md │ └── build_window_msvc.md ├── demo show │ ├── 20170401.gif │ ├── 20170427.gif │ ├── 20170428.gif │ └── 20170429.gif └── 更新历史.md ├── msvs ├── Readme.md └── vs2015.sln └── src ├── OE ├── OEasyScreenshot └── oescreenshot │ ├── Readme - English.md │ ├── Readme.md │ ├── oeamplifier.cpp │ ├── oeamplifier.h │ ├── oecommonhelper.cpp │ ├── oecommonhelper.h │ ├── oemodelview.cpp │ ├── oemodelview.h │ ├── oescreenshot.cpp │ └── oescreenshot.h ├── OEScreenshotLib.pro └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | *.smod 19 | 20 | # Compiled Static libraries 21 | *.lai 22 | *.la 23 | *.a 24 | *.lib 25 | 26 | # Executables 27 | *.exe 28 | *.out 29 | *.app 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 1. 定义. 2 | 3 | “许可”是指从本文档1 到 9节所定义的使用、复制及分发的条款。 4 | 5 | “授权人”是指版权拥有者或由版权拥有者授权许可的实体。 6 | 7 | “法律实体”是指代理团体及控制、受该实体共同控制的所有其 8 | 他团体。关于这个定义的用途,“控制”意思是 (i)直接或间接 9 | 地无论是通过合同或其他方式操纵这样实体的引导方向或管理, 10 | 或者(ii) 流通股百分之五十(50%)以上的拥有,或者(iii)这 11 | 样实体有权受益的拥有。 12 | 13 | “你”(或“你的”)只行使本许可授权的权限的个人或法律实体。 14 | 15 | “源”形式指做出修改的首选形式,包括但不限于软件源代码、 16 | 文档源代码及配置文件。 17 | 18 | “目标”形式指从一种源形式机械地转换或翻译而产生的任何形式, 19 | 包括但不限于编译的目标代码、生成的文档及其他媒体类型的转 20 | 换。 21 | 22 | “作品”是指根据本许可协议可用的原作者的作品,无论是源形式 23 | 还是目标形式的,如包含或附加在作品中的版权声明所示的(下 24 | 面的附录提供了一个例子)。 25 | 26 | “派生的作品”指无论是源形式还是目标形式的基于作品(或从其 27 | 派生的)任何作品,整体上,原作者的原作品的编辑修改、标注、 28 | 修饰或者其他的修改形式。对于本许可的这种用途,派生的作品 29 | 不能包含与原作品分离的,或者仅仅到接口的链接(或者按名称 30 | 绑定的)从而派生的作品。 31 | 32 | “奉献”指任何原作者的作品,包括作品的原始版本及对该作品或 33 | 派生作品的任何修改与增补,即有意提交给授权人,或者由个人 34 | 或者法律实体代表版权拥有者提交给授权人,由作品的版本拥有 35 | 者包含在作品中。对于这个定义的用途,“提交”意思是发送给授 36 | 权人或其代表的任何形式的,电子的、口头或书面交流,包括但 37 | 不限于电子邮件列表、由授权人出于讨论及改进作品目的的源代 38 | 码控制系统及问题跟踪系统,但是不包括由版权拥有者明确地标 39 | 记或者书面指定为“非奉献”的交流。 40 | 41 | “奉献者”指授权人及代表其奉献由授权人接受并后来包含到作品 42 | 中的任何个人或者法律实体。 43 | 44 | 2. 授予版权许可. 按照本许可的条款,每个奉献者授予您一个永 45 | 久的、全球性的、非排他性的、不收费,免版税的,不可撤销的 46 | 版权许可证,许可您以源形式或目标形式复制、准备派生作品、 47 | 公开展示、公开表演、再授权、分发作品及派生作品。 48 | 49 | 3. 授予专利许可. 按照本许可的条款,每个奉献者授权您一个永 50 | 久性、全球的、非排他性的、不收费、免版税的、不可撤销的(除 51 | 本节所述)专利实施许可,可以创建、使用、许诺销售、销售、引 52 | 进及转换作品,其中这样的许可只适用于因其奉献者单独或者与其 53 | 奉献者与提交的作品结合而受到侵犯的这些奉献者授权的那些专利 54 | 声明。如果您针对任何实体提起诉讼(包括反诉或诉讼中的反诉), 55 | 主张作品或者纳入到作品中的奉献构成直接或间接的侵犯,那么按 56 | 本许可授权您该作品的任何专利许可在提起诉讼之时终止。 57 | 58 | 4. 再分发. 您可以任何媒体形式,无论是否修改,以源或目标形 59 | 式复制和分发作品或派生作品的副本,只要你符合下列条件: 60 | 61 | 您必须给予作品或派生作品的任何其他的接收者以本许可,并 62 | 63 | 您必须对于任何修改过的文件带有明显的声明,说明你改变了这个 64 | 文件;而且 65 | 66 | 您必须用您分发的任何派生作品的源形式保留,作品源形式的所有 67 | 的版权、专利、商标及属性声明,不包括不输入派生作品的任何部 68 | 分的那些说明;而且 69 | 70 | 如果作品包含一个“声明”文本文件作为其分发的部分,那么你分发 71 | 的任何派生的作品必须在至少下面的地方之一,包含这样的声明文 72 | 件在内的一个包含该属性声明的可读的副本,不包含不属于派生作 73 | 品的任何部分的那些:在作为派生作品的部分分发的一个声明文件 74 | 之内;在源代形式或者文档中,如果随着派生的作品提供的话;或 75 | 者在由派生作品生成的显示中,如果在第三方声明出现的任何地方。 76 | 这个声明文件的内容是只是信息性用途的,不修改许可协议。您可 77 | 以在您分发的派生作品中添加你自己的属性声明,如果这样额外的 78 | 属性声明不能构造为对许可协议的修改的话,那么与作品的声明文 79 | 本一起或作为附录。你可以给你的修改添加你自己的版权声明,可 80 | 以提供使用、复制或分发你的修改的不同的许可协议条款,或者对 81 | 于任何这样的派生作品整体上,只要您的使用、复制及分发作品符 82 | 合本许可规定的条件。 83 | 84 | 85 | 5. 奉献的提交. 除非你明确地不同地声明,否则按照本许可协议 86 | 的条款任何由您向授权人提交的奉献都有意包含在作品中而没有任 87 | 何额外的条款。尽管如上所述,但是任何情况下均不得取代或修改 88 | 你也许已经与授权人执行的关于奉献的任何许可协议条款。 89 | 90 | 6. 商标. 本许可不授予许可权限使用授权人的商品名称、商标、 91 | 服务标记、或产品名称,除了用于说明原作品及声明作品的声明 92 | 文件的内容需要的合理及习惯使用之外。 93 | 94 | 7. 免责条款. 除非适用法律或者书面同意的需要,授权人都“原 95 | 样”提供作品(及每个奉献者提供其奉献),无任何形式的无论是 96 | 明确的还是隐含的担保或条款,包括但不限于标题、非侵权性, 97 | 适销性或针对特定用途的适用性的担保或条款。您唯一地确定对 98 | 作品的使用或再分发是否合适,并承担与你行使本许可权限相关 99 | 的任何风险。 100 | 101 | 8. 责任限制. 在任何情况下,没有有法律理论,在是否侵权(包 102 | 括过失)、合同或者否则因适用法律的需要(如故意和疏忽行为) 103 | 或者书面同意任何风险者对您的伤害负责,包括任何直接、间接的、 104 | 特殊的、偶然的或者任何特征的引起的伤害(包括但不限于商誉损 105 | 失,工作停止,计算机故障或失灵,或任何和所有其他商业损害或 106 | 损失),即使这样的奉献者已被告知此类损害的可能性。 107 | 108 | 9. 接受保证或附加责任. 在再分发作品及派生作品时,你可以选 109 | 择提供、并收取一定的费用、接受支持、担保、免除或者其他的责 110 | 任义务及/或符合本许可的权限。但是,接受这些义务时您可以仅 111 | 以进自己的名义,仅对您自己的行动负责,而不代表任何其他的奉 112 | 献者,如果你由这样的奉献者因接受任何这样的担保及附带责任引 113 | 起或针对其主张的任何义务同意赔偿、辩护,保证对每个奉献者无 114 | 害。 115 | 116 | 条款结束 117 | 118 | 附录: 如何应用Apache 许可到您的作品 119 | 120 | 要对您的作品应用 Apache 许可,添加下面的样本声明,用你自己 121 | 的区别性信息替换括号封闭的字段。(不要包含括号!)。这段文 122 | 本应该用文件格式的合适的注释语法封闭起来。我还推荐在与版权 123 | 声明相同的“打印页”上包含一个文件或者类名及用途说明,更容易 124 | 在第三方文件之内区分。 125 | 126 | 版权所有 [2017-04] [陈鲁勇] 127 | 项目地址:https://git.oschina.net/Mr_ChenLuYong/screenshot 128 | 项目地址:https://github.com/chenluyong/OEasyScreenshot 129 | 根据 Apache 许可证2.0 版(以下简称“许可证”)授权; 130 | 除非遵守本许可,否则您不能使用这个文件。 131 | 您可一获得该许可的副本,在http://www.apache.org/licenses/LICENSE-2.0 132 | 除非适用法律需要或者书面同意,按本许可分发的软件 133 | 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 134 | 参见按照本许可控制许可权限及限制的特定语言的许可证。 -------------------------------------------------------------------------------- /LICENSE - English: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright 2017 chenluyong 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 |  2 | # 首页致词 3 | 4 | 这个项目,有幸得到你的浏览。 5 | 6 | 这是一个基于 Qt 5 开发的项目,Qt Creator 4 作为主要的开发 IDE, 7 | 8 | 项目打开方式,请移步 demo 文件夹,根据自己的编译器选择对应的 pro 工程文件。 9 | 10 | 主要目的是完成一款接口极简的截图工具,即插即用。 11 | 12 | 在极简的基础上不断细化,添加一些细致的功能,为优质的软件添加一份助力。 13 | 14 | 一个优秀的项目,少不了各位的支持与参与,欢迎你加入我们。 15 | 16 | `注:如果您使用了我们的项目,请告诉我们,我们会把您的软件公布到 Wiki 中。` 17 | 18 | # 示例效果 19 | 20 | ![示例效果](doc/demo%20show/20170429.gif) 21 | 22 | 23 | # 关于项目 24 | ---- 25 | 26 | ### 已支持功能 27 | 28 | 1.基本的截图功能 29 | 30 | 2.截图窗口二次编辑 31 | 32 | 3.截图界面霸道置顶 33 | 34 | 4.支持多屏幕截图 35 | 36 | 5.支持窗口自动校准 37 | 38 | 6.支持鼠标取色 39 | 40 | 7.支持截图到剪切板 41 | 42 | 8.保存本地到jpg(具体格式可自行修改,若又更好的优化可以Pull哟) 43 | 44 | ### 待开发功能 45 | 46 | - 绘图功能 47 | 48 | 1.马赛克 49 | 50 | 2.图形 51 | 52 | 3.文字 53 | 54 | 4.撤销功能 55 | 56 | 5.擦除功能 57 | 58 | 绘图功能,作者已给出范例,可以模仿修改优化。 [【点击前往】](src/OE/oescreenshot/oemodelview.cpp) 59 | 60 | 61 | ---- 62 | 63 | 工程环境:Qt Creator 4.2.1 64 | 65 | Qt库版本:Qt 5.8.1 (测试5.0以上都可以正常编译) 66 | 67 | 更新内容: [【点击查看】](doc) 68 | 69 | 70 | 71 | 效果演示 - demo show [【点击查看】](doc) 72 | 73 | 74 | doc文档: [【点击下载】](https://gitee.com/Mr_ChenLuYong/screenshot/attach_files/download?i=80250&u=http%3A%2F%2Ffiles.git.oschina.net%2Fgroup1%2FM00%2F01%2F32%2FPaAvDFkEMRiAU8ApAAR5kUgxDQw424.zip%3Ftoken%3D904472a9bfa0afa7162465cbf5b6b3e2%26ts%3D1538794364%26attname%3Ddoc.zip) 75 | 76 | 77 | 附 言: 如果您通过其它环境编译通过(例:VS2010~VS2017 或 Linux), 都可以Pull有效文件来,请允许我代表需要这份代码的所有朋友们,感谢您。 78 | 79 | 80 | 81 | 82 | # 开源通知 83 | 84 | - 简介 85 | 86 | 项目名:oe_screenshot 87 | 88 | 开源协议:[Apache-2.0](LICENSE) 89 | 90 | 作者:Mr_ChenLuYong 91 | 92 | 贡献: 93 | 94 | - [开源小组.Chen](http://blog.csdn.net/csnd_ayo) 95 | 96 | 97 | 98 | - 详情 99 | 100 | 当前插件因他的通用性,作者考虑将其开源,让代码更好的服务广大码农,减少不必要的劳动开销。 101 | 102 | 103 | - 注意 104 | 105 | 这是一个可以随意修改源码的项目。 106 | 107 | 108 | - 开源 109 | 110 | 码云地址:http://git.oschina.net/Mr_ChenLuYong/screenshot 【实时更新,作者关注】 111 | 112 | github地址:https://github.com/chenluyong/OEasyScreenshot 113 | -------------------------------------------------------------------------------- /bin/OEScreenshot.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/bin/OEScreenshot.dll -------------------------------------------------------------------------------- /bin/OEScreenshot.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/bin/OEScreenshot.lib -------------------------------------------------------------------------------- /bin/OEScreenshot.md: -------------------------------------------------------------------------------- 1 | # OEScreenshot的说明文档 2 | 3 | 为了方便各位使用,我利用 src/OEScreenshotLib.pro 生成了具备C接口的动态库 OEScreenshot.dll 4 | 5 | 大家可以动态的加载这个库,以达到快速使用截图功能的目的。 6 | 7 | 8 | 接口原型如下: 9 | 10 | extern "C" void OEScreenshot(void); 11 | 12 | 我也提供了调用的示例程序 13 | 14 | 这个示例程序可以在 demo/ScreenShotLib 文件夹下轻松找到,希望它对你能产生帮助。 15 | 16 | 17 | 18 | # 注意 19 | 20 | 有些朋友可能会遇到加载动态库失败的问题,这里我需要简单的说一下课外知识 21 | 22 | 在window下,若加载一个动态,那么必须能够在当前目录下或系统目录下搜索到,这个被加载的动态库所依赖的相关库,否则会加载失败。 23 | -------------------------------------------------------------------------------- /bin/Readme.md: -------------------------------------------------------------------------------- 1 | 当前依赖文件树 2 | 3 | ---- 4 | 5 | - Qt 5.0.2 6 | 7 | platforms/qminimal.dll 8 | 9 | platforms/qwindows.dll 10 | 11 | demo.exe 12 | 13 | icudt49.dll 14 | 15 | icuin49.dll 16 | 17 | icuuc49.dll 18 | 19 | libEGL.dll 20 | 21 | libgcc_s_sjlj-1.dll 22 | 23 | libGLESv2.dll 24 | 25 | libstdc++-6.dll 26 | 27 | libwinpthread-1.dll 28 | 29 | Qt5Core.dll 30 | 31 | Qt5Gui.dll 32 | 33 | Qt5Widgets.dll 34 | 35 | 36 | ----- 37 | 38 | [Qt 使用 windeployqt 讲述史上最正确window发布版本的生成姿势](http://blog.csdn.net/csnd_ayo/article/details/72130015) -------------------------------------------------------------------------------- /bin/一键发布.bat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/bin/一键发布.bat -------------------------------------------------------------------------------- /demo/Readme.md: -------------------------------------------------------------------------------- 1 | # 注意事项 2 | 3 | - 根据自己的编译器去选择 pro 工程文件 4 | 5 | `MSVC : GBK2312编码格式` 6 | 7 | `MinGW: UTF-8编码格式` 8 | 9 | 10 | ## 编译发现编码,出现N+1条报错警告信息 11 | 12 | 13 | 很多朋友说为什么打开以后编码不同,爆了很多错误。 14 | 15 | 首先对此问题,先做声明,我们使用的是Qt Creator 4 以上的 IDE,并使用UTF-8作为编码格式。 16 | 若与以上信息有出入,需要对文件进行修改。如果修改完毕,为帮助其他朋友,烦请将您修改后的代码 Pull 到开源社区, 17 | 或者发送 e-mail 到 727057301@qq.com,感谢您的付出。 18 | 19 | 20 | 如果你使用的是 Qt Creator 且你出现编码不同而导致的编译失败,可以查看下当前构建环境是否使用了 MSVC 的编译器。 21 | 该编译器属于 VC++ 编译器,可能在字符集上与MinGW有出入,使用并建议使用 MinGW 编译器,可以改善这个问题。 22 | 23 | 24 | ### MinGW 介绍 25 | 26 | MinGW,是Minimalist GNUfor Windows的缩写。它是一个可自由使用和自由发布的Windows特定 27 | 头文件和使用GNU工具集导入库的集合,允许你在GNU/Linux和Windows平台生成本地的Windows程序 28 | 而不需要第三方C运行时(C Runtime)库。 29 | 30 | ### MSVC 介绍 31 | 32 | 他是微软的一款编译器,支持且仅支持 Windows 操作系统。 33 | 此软件包安装 C 运行时 (CRT)、标准 C++、ATL、MFC、OpenMP 和 MSDIA 库的运行时组件。 34 | 对于支持并行部署模型的库(CRT、SCL、ATL、MFC、OpenMP),这些运行时组件被安装到支持 35 | 并行程序集的 Windows 操作系统的本机程序集 -------------------------------------------------------------------------------- /demo/ScreenShotLib/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/demo/ScreenShotLib/Readme.md -------------------------------------------------------------------------------- /demo/ScreenShotLib/ScreenShotLibDemo.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/demo/ScreenShotLib/ScreenShotLibDemo.pro -------------------------------------------------------------------------------- /demo/ScreenShotLib/main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | Widget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /demo/ScreenShotLib/widget.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/demo/ScreenShotLib/widget.cpp -------------------------------------------------------------------------------- /demo/ScreenShotLib/widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | 6 | 7 | class Widget : public QWidget 8 | { 9 | Q_OBJECT 10 | 11 | public: 12 | explicit Widget(QWidget *parent = 0); 13 | ~Widget(); 14 | 15 | }; 16 | 17 | #endif // WIDGET_H 18 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/Readme.md: -------------------------------------------------------------------------------- 1 | # SimpleShortcutKey 说明文档 2 | 3 | 从名字上,我们可以立马看出这个工程的意图。 4 | 5 | 是的,这个demo,将提供了全局快捷键的功能,和某些应用程序一样。 6 | 7 | 他可以后台,使用全局快捷键呼出自己想要的功能。 8 | 9 | qxt 他的应用领域非常广,感谢开源作者的辛勤付出。 -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/SimpleShortcutKey.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by QtCreator 2017-05-05T10:52:23 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += core gui 8 | CONFIG += C++11 9 | DESTDIR = ../../bin 10 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 11 | 12 | TARGET = SimpleShortcutKey 13 | TEMPLATE = app 14 | INCLUDEPATH += "../../src/" 15 | include(qxt/qxt.pri) 16 | 17 | SOURCES += main.cpp\ 18 | widget.cpp \ 19 | ../../src/OE/oescreenshot/oeamplifier.cpp \ 20 | ../../src/OE/oescreenshot/oecommonhelper.cpp \ 21 | ../../src/OE/oescreenshot/oemodelview.cpp \ 22 | ../../src/OE/oescreenshot/oescreenshot.cpp 23 | 24 | HEADERS += widget.h \ 25 | ../../src/OE/oescreenshot/oeamplifier.h \ 26 | ../../src/OE/oescreenshot/oecommonhelper.h \ 27 | ../../src/OE/oescreenshot/oemodelview.h \ 28 | ../../src/OE/oescreenshot/oescreenshot.h 29 | 30 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/main.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | #include 3 | 4 | int main(int argc, char *argv[]) 5 | { 6 | QApplication a(argc, argv); 7 | Widget w; 8 | w.show(); 9 | 10 | return a.exec(); 11 | } 12 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxt.pri: -------------------------------------------------------------------------------- 1 | INCLUDEPATH += $$PWD 2 | DEPENDPATH += $$PWD 3 | 4 | HEADERS += $$PWD/qxtglobal.h \ 5 | $$PWD/qxtglobalshortcut.h \ 6 | $$PWD/qxtglobalshortcut_p.h 7 | SOURCES += $$PWD/qxtglobalshortcut.cpp 8 | win32{ 9 | SOURCES += $$PWD/qxtglobalshortcut_win.cpp 10 | LIBS += -luser32 11 | } 12 | unix:SOURCES += $$PWD/qxtglobalshortcut_x11.cpp 13 | mac:SOURCES += $$PWD/qxtglobalshortcut_mac.cpp 14 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobal.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtCore module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | 26 | #ifndef QXTGLOBAL_H 27 | #define QXTGLOBAL_H 28 | 29 | #include 30 | 31 | #define QXT_VERSION 0x000600 32 | #define QXT_VERSION_STR "0.6.0" 33 | 34 | //--------------------------global macros------------------------------ 35 | 36 | #ifndef QXT_NO_MACROS 37 | 38 | #endif // QXT_NO_MACROS 39 | 40 | //--------------------------export macros------------------------------ 41 | 42 | #define QXT_DLLEXPORT DO_NOT_USE_THIS_ANYMORE 43 | 44 | #if !defined(QXT_STATIC) 45 | # if defined(BUILD_QXT_CORE) 46 | # define QXT_CORE_EXPORT Q_DECL_EXPORT 47 | # else 48 | # define QXT_CORE_EXPORT Q_DECL_IMPORT 49 | # endif 50 | #else 51 | # define QXT_CORE_EXPORT 52 | #endif // BUILD_QXT_CORE 53 | 54 | #if !defined(QXT_STATIC) 55 | # if defined(BUILD_QXT_GUI) 56 | # define QXT_GUI_EXPORT Q_DECL_EXPORT 57 | # else 58 | # define QXT_GUI_EXPORT Q_DECL_IMPORT 59 | # endif 60 | #else 61 | # define QXT_GUI_EXPORT 62 | #endif // BUILD_QXT_GUI 63 | 64 | #if !defined(QXT_STATIC) 65 | # if defined(BUILD_QXT_NETWORK) 66 | # define QXT_NETWORK_EXPORT Q_DECL_EXPORT 67 | # else 68 | # define QXT_NETWORK_EXPORT Q_DECL_IMPORT 69 | # endif 70 | #else 71 | # define QXT_NETWORK_EXPORT 72 | #endif // BUILD_QXT_NETWORK 73 | 74 | #if !defined(QXT_STATIC) 75 | # if defined(BUILD_QXT_SQL) 76 | # define QXT_SQL_EXPORT Q_DECL_EXPORT 77 | # else 78 | # define QXT_SQL_EXPORT Q_DECL_IMPORT 79 | # endif 80 | #else 81 | # define QXT_SQL_EXPORT 82 | #endif // BUILD_QXT_SQL 83 | 84 | #if !defined(QXT_STATIC) 85 | # if defined(BUILD_QXT_WEB) 86 | # define QXT_WEB_EXPORT Q_DECL_EXPORT 87 | # else 88 | # define QXT_WEB_EXPORT Q_DECL_IMPORT 89 | # endif 90 | #else 91 | # define QXT_WEB_EXPORT 92 | #endif // BUILD_QXT_WEB 93 | 94 | #if !defined(QXT_STATIC) 95 | # if defined(BUILD_QXT_BERKELEY) 96 | # define QXT_BERKELEY_EXPORT Q_DECL_EXPORT 97 | # else 98 | # define QXT_BERKELEY_EXPORT Q_DECL_IMPORT 99 | # endif 100 | #else 101 | # define QXT_BERKELEY_EXPORT 102 | #endif // BUILD_QXT_BERKELEY 103 | 104 | #if !defined(QXT_STATIC) 105 | # if defined(BUILD_QXT_ZEROCONF) 106 | # define QXT_ZEROCONF_EXPORT Q_DECL_EXPORT 107 | # else 108 | # define QXT_ZEROCONF_EXPORT Q_DECL_IMPORT 109 | # endif 110 | #else 111 | # define QXT_ZEROCONF_EXPORT 112 | #endif // QXT_ZEROCONF_EXPORT 113 | 114 | #if defined BUILD_QXT_CORE || defined BUILD_QXT_GUI || defined BUILD_QXT_SQL || defined BUILD_QXT_NETWORK || defined BUILD_QXT_WEB || defined BUILD_QXT_BERKELEY || defined BUILD_QXT_ZEROCONF 115 | # define BUILD_QXT 116 | #endif 117 | 118 | QXT_CORE_EXPORT const char* qxtVersion(); 119 | 120 | #ifndef QT_BEGIN_NAMESPACE 121 | #define QT_BEGIN_NAMESPACE 122 | #endif 123 | 124 | #ifndef QT_END_NAMESPACE 125 | #define QT_END_NAMESPACE 126 | #endif 127 | 128 | #ifndef QT_FORWARD_DECLARE_CLASS 129 | #define QT_FORWARD_DECLARE_CLASS(Class) class Class; 130 | #endif 131 | 132 | /**************************************************************************** 133 | ** This file is derived from code bearing the following notice: 134 | ** The sole author of this file, Adam Higerd, has explicitly disclaimed all 135 | ** copyright interest and protection for the content within. This file has 136 | ** been placed in the public domain according to United States copyright 137 | ** statute and case law. In jurisdictions where this public domain dedication 138 | ** is not legally recognized, anyone who receives a copy of this file is 139 | ** permitted to use, modify, duplicate, and redistribute this file, in whole 140 | ** or in part, with no restrictions or conditions. In these jurisdictions, 141 | ** this file shall be copyright (C) 2006-2008 by Adam Higerd. 142 | ****************************************************************************/ 143 | 144 | #define QXT_DECLARE_PRIVATE(PUB) friend class PUB##Private; QxtPrivateInterface qxt_d; 145 | #define QXT_DECLARE_PUBLIC(PUB) friend class PUB; 146 | #define QXT_INIT_PRIVATE(PUB) qxt_d.setPublic(this); 147 | #define QXT_D(PUB) PUB##Private& d = qxt_d() 148 | #define QXT_P(PUB) PUB& p = qxt_p() 149 | 150 | template 151 | class QxtPrivate 152 | { 153 | public: 154 | virtual ~QxtPrivate() 155 | {} 156 | inline void QXT_setPublic(PUB* pub) 157 | { 158 | qxt_p_ptr = pub; 159 | } 160 | 161 | protected: 162 | inline PUB& qxt_p() 163 | { 164 | return *qxt_p_ptr; 165 | } 166 | inline const PUB& qxt_p() const 167 | { 168 | return *qxt_p_ptr; 169 | } 170 | 171 | private: 172 | PUB* qxt_p_ptr; 173 | }; 174 | 175 | template 176 | class QxtPrivateInterface 177 | { 178 | friend class QxtPrivate; 179 | public: 180 | QxtPrivateInterface() 181 | { 182 | pvt = new PVT; 183 | } 184 | ~QxtPrivateInterface() 185 | { 186 | delete pvt; 187 | } 188 | 189 | inline void setPublic(PUB* pub) 190 | { 191 | pvt->QXT_setPublic(pub); 192 | } 193 | inline PVT& operator()() 194 | { 195 | return *static_cast(pvt); 196 | } 197 | inline const PVT& operator()() const 198 | { 199 | return *static_cast(pvt); 200 | } 201 | private: 202 | QxtPrivateInterface(const QxtPrivateInterface&) { } 203 | QxtPrivateInterface& operator=(const QxtPrivateInterface&) { } 204 | QxtPrivate* pvt; 205 | }; 206 | 207 | #endif // QXT_GLOBAL 208 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | #include "qxtglobalshortcut.h" 26 | #include "qxtglobalshortcut_p.h" 27 | #include 28 | #include 29 | 30 | bool QxtGlobalShortcutPrivate::error = false; 31 | int QxtGlobalShortcutPrivate::ref = 0; 32 | 33 | #if(QT_VERSION<0x050000) 34 | QAbstractEventDispatcher::EventFilter QxtGlobalShortcutPrivate::prevEventFilter = 0; 35 | #endif 36 | 37 | QHash, QxtGlobalShortcut*> QxtGlobalShortcutPrivate::shortcuts; 38 | 39 | QxtGlobalShortcutPrivate::QxtGlobalShortcutPrivate() : enabled(true), key(Qt::Key(0)), mods(Qt::NoModifier) 40 | { 41 | if (!ref++){ 42 | #if(QT_VERSION<0x050000) 43 | prevEventFilter = QAbstractEventDispatcher::instance()->setEventFilter(eventFilter); 44 | #else 45 | QAbstractEventDispatcher::instance ()->installNativeEventFilter (this); 46 | #endif 47 | } 48 | } 49 | 50 | QxtGlobalShortcutPrivate::~QxtGlobalShortcutPrivate() 51 | { 52 | if (!--ref){ 53 | #if(QT_VERSION<0x050000) 54 | QAbstractEventDispatcher::instance()->setEventFilter(prevEventFilter); 55 | #else 56 | QAbstractEventDispatcher::instance ()->removeNativeEventFilter (this); 57 | #endif 58 | } 59 | } 60 | 61 | bool QxtGlobalShortcutPrivate::setShortcut(const QKeySequence& shortcut) 62 | { 63 | Qt::KeyboardModifiers allMods = Qt::ShiftModifier | Qt::ControlModifier | Qt::AltModifier | Qt::MetaModifier; 64 | key = shortcut.isEmpty() ? Qt::Key(0) : Qt::Key((shortcut[0] ^ allMods) & shortcut[0]); 65 | mods = shortcut.isEmpty() ? Qt::KeyboardModifiers(0) : Qt::KeyboardModifiers(shortcut[0] & allMods); 66 | const quint32 nativeKey = nativeKeycode(key); 67 | const quint32 nativeMods = nativeModifiers(mods); 68 | const bool res = registerShortcut(nativeKey, nativeMods); 69 | shortcuts.insert(qMakePair(nativeKey, nativeMods), &qxt_p()); 70 | if (!res) 71 | qWarning() << "QxtGlobalShortcut failed to register:" << QKeySequence(key + mods).toString(); 72 | return res; 73 | } 74 | 75 | bool QxtGlobalShortcutPrivate::unsetShortcut() 76 | { 77 | const quint32 nativeKey = nativeKeycode(key); 78 | const quint32 nativeMods = nativeModifiers(mods); 79 | const bool res = unregisterShortcut(nativeKey, nativeMods); 80 | shortcuts.remove(qMakePair(nativeKey, nativeMods)); 81 | if (!res) 82 | qWarning() << "QxtGlobalShortcut failed to unregister:" << QKeySequence(key + mods).toString(); 83 | key = Qt::Key(0); 84 | mods = Qt::KeyboardModifiers(0); 85 | return res; 86 | } 87 | 88 | void QxtGlobalShortcutPrivate::activateShortcut(quint32 nativeKey, quint32 nativeMods) 89 | { 90 | 91 | QxtGlobalShortcut* shortcut = shortcuts.value(qMakePair(nativeKey, nativeMods)); 92 | if (shortcut && shortcut->isEnabled()) 93 | emit shortcut->activated(); 94 | } 95 | 96 | /*! 97 | \class QxtGlobalShortcut 98 | \inmodule QxtGui 99 | \brief The QxtGlobalShortcut class provides a global shortcut aka "hotkey". 100 | 101 | A global shortcut triggers even if the application is not active. This 102 | makes it easy to implement applications that react to certain shortcuts 103 | still if some other application is active or if the application is for 104 | example minimized to the system tray. 105 | 106 | Example usage: 107 | \code 108 | QxtGlobalShortcut* shortcut = new QxtGlobalShortcut(window); 109 | connect(shortcut, SIGNAL(activated()), window, SLOT(toggleVisibility())); 110 | shortcut->setShortcut(QKeySequence("Ctrl+Shift+F12")); 111 | \endcode 112 | 113 | \bold {Note:} Since Qxt 0.6 QxtGlobalShortcut no more requires QxtApplication. 114 | */ 115 | 116 | /*! 117 | \fn QxtGlobalShortcut::activated() 118 | 119 | This signal is emitted when the user types the shortcut's key sequence. 120 | 121 | \sa shortcut 122 | */ 123 | 124 | /*! 125 | Constructs a new QxtGlobalShortcut with \a parent. 126 | */ 127 | QxtGlobalShortcut::QxtGlobalShortcut(QObject* parent) 128 | : QObject(parent) 129 | { 130 | QXT_INIT_PRIVATE(QxtGlobalShortcut); 131 | } 132 | 133 | /*! 134 | Constructs a new QxtGlobalShortcut with \a shortcut and \a parent. 135 | */ 136 | QxtGlobalShortcut::QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent) 137 | : QObject(parent) 138 | { 139 | QXT_INIT_PRIVATE(QxtGlobalShortcut); 140 | setShortcut(shortcut); 141 | } 142 | 143 | /*! 144 | Destructs the QxtGlobalShortcut. 145 | */ 146 | QxtGlobalShortcut::~QxtGlobalShortcut() 147 | { 148 | if (qxt_d().key != 0) 149 | qxt_d().unsetShortcut(); 150 | } 151 | 152 | /*! 153 | \property QxtGlobalShortcut::shortcut 154 | \brief the shortcut key sequence 155 | 156 | \bold {Note:} Notice that corresponding key press and release events are not 157 | delivered for registered global shortcuts even if they are disabled. 158 | Also, comma separated key sequences are not supported. 159 | Only the first part is used: 160 | 161 | \code 162 | qxtShortcut->setShortcut(QKeySequence("Ctrl+Alt+A,Ctrl+Alt+B")); 163 | Q_ASSERT(qxtShortcut->shortcut() == QKeySequence("Ctrl+Alt+A")); 164 | \endcode 165 | */ 166 | QKeySequence QxtGlobalShortcut::shortcut() const 167 | { 168 | return QKeySequence(qxt_d().key | qxt_d().mods); 169 | } 170 | 171 | bool QxtGlobalShortcut::setShortcut(const QKeySequence& shortcut) 172 | { 173 | if (qxt_d().key != 0) 174 | qxt_d().unsetShortcut(); 175 | return qxt_d().setShortcut(shortcut); 176 | } 177 | 178 | /*! 179 | \property QxtGlobalShortcut::enabled 180 | \brief whether the shortcut is enabled 181 | 182 | A disabled shortcut does not get activated. 183 | 184 | The default value is \c true. 185 | 186 | \sa setDisabled() 187 | */ 188 | bool QxtGlobalShortcut::isEnabled() const 189 | { 190 | return qxt_d().enabled; 191 | } 192 | 193 | void QxtGlobalShortcut::setEnabled(bool enabled) 194 | { 195 | qxt_d().enabled = enabled; 196 | } 197 | 198 | /*! 199 | Sets the shortcut \a disabled. 200 | 201 | \sa enabled 202 | */ 203 | void QxtGlobalShortcut::setDisabled(bool disabled) 204 | { 205 | qxt_d().enabled = !disabled; 206 | } 207 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | #ifndef QXTGLOBALSHORTCUT_H 26 | #define QXTGLOBALSHORTCUT_H 27 | 28 | #include "qxtglobal.h" 29 | #include 30 | #include 31 | class QxtGlobalShortcutPrivate; 32 | 33 | class QxtGlobalShortcut : public QObject 34 | { 35 | Q_OBJECT 36 | QXT_DECLARE_PRIVATE(QxtGlobalShortcut) 37 | Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled) 38 | Q_PROPERTY(QKeySequence shortcut READ shortcut WRITE setShortcut) 39 | 40 | public: 41 | explicit QxtGlobalShortcut(QObject* parent = 0); 42 | explicit QxtGlobalShortcut(const QKeySequence& shortcut, QObject* parent = 0); 43 | virtual ~QxtGlobalShortcut(); 44 | 45 | QKeySequence shortcut() const; 46 | bool setShortcut(const QKeySequence& shortcut); 47 | 48 | bool isEnabled() const; 49 | 50 | public Q_SLOTS: 51 | void setEnabled(bool enabled = true); 52 | void setDisabled(bool disabled = true); 53 | 54 | Q_SIGNALS: 55 | void activated(); 56 | }; 57 | 58 | #endif // QXTGLOBALSHORTCUT_H 59 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut_mac.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | //#include 26 | #include "qxtglobalshortcut_p.h" 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | typedef QPair Identifier; 33 | static QMap keyRefs; 34 | static QHash keyIDs; 35 | static quint32 hotKeySerial = 0; 36 | static bool qxt_mac_handler_installed = false; 37 | 38 | OSStatus qxt_mac_handle_hot_key(EventHandlerCallRef nextHandler, EventRef event, void* data) 39 | { 40 | // pass event to the app event filter 41 | Q_UNUSED(data); 42 | qApp->macEventFilter(nextHandler, event); 43 | return noErr; 44 | } 45 | #if(QT_VERSION<0x050000) 46 | bool QxtGlobalShortcutPrivate::eventFilter(void* message) 47 | //bool QxtGlobalShortcutPrivate::macEventFilter(EventHandlerCallRef caller, EventRef event) 48 | { 49 | EventRef event = (EventRef) message; 50 | if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) 51 | { 52 | EventHotKeyID keyID; 53 | GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); 54 | Identifier id = keyIDs.key(keyID.id); 55 | activateShortcut(id.second, id.first); 56 | } 57 | return false; 58 | } 59 | #else 60 | bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray &, void *message, long *) 61 | { 62 | EventRef event = (EventRef) message; 63 | if (GetEventClass(event) == kEventClassKeyboard && GetEventKind(event) == kEventHotKeyPressed) 64 | { 65 | EventHotKeyID keyID; 66 | GetEventParameter(event, kEventParamDirectObject, typeEventHotKeyID, NULL, sizeof(keyID), NULL, &keyID); 67 | Identifier id = keyIDs.key(keyID.id); 68 | activateShortcut(id.second, id.first); 69 | } 70 | return false; 71 | } 72 | #endif 73 | quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) 74 | { 75 | quint32 native = 0; 76 | if (modifiers & Qt::ShiftModifier) 77 | native |= shiftKeyBit; 78 | if (modifiers & Qt::ControlModifier) 79 | native |= cmdKey; 80 | if (modifiers & Qt::AltModifier) 81 | native |= optionKey; 82 | if (modifiers & Qt::MetaModifier) 83 | native |= controlKey; 84 | if (modifiers & Qt::KeypadModifier) 85 | native |= kEventKeyModifierNumLockMask; 86 | return native; 87 | } 88 | 89 | quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) 90 | { 91 | UTF16Char ch; 92 | // Constants found in NSEvent.h from AppKit.framework 93 | if (key == Qt::Key_Up) ch = 0xF700; 94 | else if (key == Qt::Key_Down) ch = 0xF701; 95 | else if (key == Qt::Key_Left) ch = 0xF702; 96 | else if (key == Qt::Key_Right) ch = 0xF703; 97 | else if (key >= Qt::Key_F1 && key <= Qt::Key_F35) 98 | ch = key - Qt::Key_F1 + 0xF704; 99 | else if (key == Qt::Key_Insert) ch = 0xF727; 100 | else if (key == Qt::Key_Delete) ch = 0xF728; 101 | else if (key == Qt::Key_Home) ch = 0xF729; 102 | else if (key == Qt::Key_End) ch = 0xF72B; 103 | else if (key == Qt::Key_PageUp) ch = 0xF72C; 104 | else if (key == Qt::Key_PageDown) ch = 0xF72D; 105 | else if (key == Qt::Key_Print) ch = 0xF72E; 106 | else if (key == Qt::Key_ScrollLock) ch = 0xF72F; 107 | else if (key == Qt::Key_Pause) ch = 0xF730; 108 | else if (key == Qt::Key_SysReq) ch = 0xF731; 109 | else if (key == Qt::Key_Stop) ch = 0xF734; 110 | else if (key == Qt::Key_Menu) ch = 0xF735; 111 | else if (key == Qt::Key_Select) ch = 0xF741; 112 | else if (key == Qt::Key_Execute) ch = 0xF742; 113 | else if (key == Qt::Key_Help) ch = 0xF746; 114 | else if (key == Qt::Key_Mode_switch) ch = 0xF747; 115 | else if (key == Qt::Key_Escape) ch = 27; 116 | else if (key == Qt::Key_Return) ch = 13; 117 | else if (key == Qt::Key_Enter) ch = 3; 118 | else if (key == Qt::Key_Tab) ch = 9; 119 | else ch = key; 120 | 121 | KeyboardLayoutRef layout; 122 | KeyboardLayoutKind layoutKind; 123 | KLGetCurrentKeyboardLayout(&layout); 124 | KLGetKeyboardLayoutProperty(layout, kKLKind, const_cast(reinterpret_cast(&layoutKind))); 125 | 126 | if (layoutKind == kKLKCHRKind) 127 | { // no Unicode available 128 | if (ch > 255) return 0; 129 | 130 | char* data; 131 | KLGetKeyboardLayoutProperty(layout, kKLKCHRData, const_cast(reinterpret_cast(&data))); 132 | int ct = *reinterpret_cast(data + 258); 133 | for (int i = 0; i < ct; i++) 134 | { 135 | char* keyTable = data + 260 + 128 * i; 136 | for (int j = 0; j < 128; j++) 137 | { 138 | if (keyTable[j] == ch) return j; 139 | } 140 | } 141 | 142 | return 0; 143 | } 144 | 145 | char* data; 146 | KLGetKeyboardLayoutProperty(layout, kKLuchrData, const_cast(reinterpret_cast(&data))); 147 | UCKeyboardLayout* header = reinterpret_cast(data); 148 | UCKeyboardTypeHeader* table = header->keyboardTypeList; 149 | 150 | for (quint32 i=0; i < header->keyboardTypeCount; i++) 151 | { 152 | UCKeyStateRecordsIndex* stateRec = 0; 153 | if (table[i].keyStateRecordsIndexOffset != 0) 154 | { 155 | stateRec = reinterpret_cast(data + table[i].keyStateRecordsIndexOffset); 156 | if (stateRec->keyStateRecordsIndexFormat != kUCKeyStateRecordsIndexFormat) stateRec = 0; 157 | } 158 | 159 | UCKeyToCharTableIndex* charTable = reinterpret_cast(data + table[i].keyToCharTableIndexOffset); 160 | if (charTable->keyToCharTableIndexFormat != kUCKeyToCharTableIndexFormat) continue; 161 | 162 | for (quint32 j=0; j < charTable->keyToCharTableCount; j++) 163 | { 164 | UCKeyOutput* keyToChar = reinterpret_cast(data + charTable->keyToCharTableOffsets[j]); 165 | for (quint32 k=0; k < charTable->keyToCharTableSize; k++) 166 | { 167 | if (keyToChar[k] & kUCKeyOutputTestForIndexMask) 168 | { 169 | long idx = keyToChar[k] & kUCKeyOutputGetIndexMask; 170 | if (stateRec && idx < stateRec->keyStateRecordCount) 171 | { 172 | UCKeyStateRecord* rec = reinterpret_cast(data + stateRec->keyStateRecordOffsets[idx]); 173 | if (rec->stateZeroCharData == ch) return k; 174 | } 175 | } 176 | else if (!(keyToChar[k] & kUCKeyOutputSequenceIndexMask) && keyToChar[k] < 0xFFFE) 177 | { 178 | if (keyToChar[k] == ch) return k; 179 | } 180 | } // for k 181 | } // for j 182 | } // for i 183 | 184 | return 0; 185 | } 186 | 187 | bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) 188 | { 189 | if (!qxt_mac_handler_installed) 190 | { 191 | EventTypeSpec t; 192 | t.eventClass = kEventClassKeyboard; 193 | t.eventKind = kEventHotKeyPressed; 194 | InstallApplicationEventHandler(&qxt_mac_handle_hot_key, 1, &t, NULL, NULL); 195 | } 196 | 197 | EventHotKeyID keyID; 198 | keyID.signature = 'cute'; 199 | keyID.id = ++hotKeySerial; 200 | 201 | EventHotKeyRef ref = 0; 202 | bool rv = !RegisterEventHotKey(nativeKey, nativeMods, keyID, GetApplicationEventTarget(), 0, &ref); 203 | if (rv) 204 | { 205 | keyIDs.insert(Identifier(nativeMods, nativeKey), keyID.id); 206 | keyRefs.insert(keyID.id, ref); 207 | } 208 | qDebug() << ref; 209 | return rv; 210 | } 211 | 212 | bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) 213 | { 214 | Identifier id(nativeMods, nativeKey); 215 | if (!keyIDs.contains(id)) return false; 216 | 217 | EventHotKeyRef ref = keyRefs.take(keyIDs[id]); 218 | keyIDs.remove(id); 219 | return !UnregisterEventHotKey(ref); 220 | } 221 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut_p.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | #ifndef QXTGLOBALSHORTCUT_P_H 26 | #define QXTGLOBALSHORTCUT_P_H 27 | 28 | #include "qxtglobalshortcut.h" 29 | #include 30 | #include 31 | #include 32 | #if(QT_VERSION>=0x050000) 33 | #include 34 | #endif 35 | 36 | class QxtGlobalShortcutPrivate : public QxtPrivate 37 | #if(QT_VERSION>=0x050000) 38 | , public QAbstractNativeEventFilter 39 | #endif 40 | { 41 | public: 42 | QXT_DECLARE_PUBLIC(QxtGlobalShortcut) 43 | QxtGlobalShortcutPrivate(); 44 | ~QxtGlobalShortcutPrivate(); 45 | 46 | bool enabled; 47 | Qt::Key key; 48 | Qt::KeyboardModifiers mods; 49 | 50 | bool setShortcut(const QKeySequence& shortcut); 51 | bool unsetShortcut(); 52 | 53 | static bool error; 54 | static int ref; 55 | #if(QT_VERSION<0x050000) 56 | static QAbstractEventDispatcher::EventFilter prevEventFilter; 57 | static bool eventFilter(void* message); 58 | #else 59 | bool nativeEventFilter(const QByteArray &eventType, void *message, long *result); 60 | #endif 61 | private: 62 | static quint32 nativeKeycode(Qt::Key keycode); 63 | static quint32 nativeModifiers(Qt::KeyboardModifiers modifiers); 64 | 65 | static bool registerShortcut(quint32 nativeKey, quint32 nativeMods); 66 | static bool unregisterShortcut(quint32 nativeKey, quint32 nativeMods); 67 | static void activateShortcut(quint32 nativeKey, quint32 nativeMods); 68 | 69 | static QHash, QxtGlobalShortcut*> shortcuts; 70 | }; 71 | 72 | #endif // QXTGLOBALSHORTCUT_P_H 73 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut_win.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | #include "qxtglobalshortcut_p.h" 26 | #include 27 | #include 28 | #include 29 | #if(QT_VERSION<0x050000) 30 | bool QxtGlobalShortcutPrivate::eventFilter(void* message) 31 | { 32 | MSG* msg = static_cast(message); 33 | if (msg->message == WM_HOTKEY) 34 | { 35 | const quint32 keycode = HIWORD(msg->lParam); 36 | const quint32 modifiers = LOWORD(msg->lParam); 37 | activateShortcut(keycode, modifiers); 38 | } 39 | return false; 40 | } 41 | #else 42 | bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray &, void *message, long *) 43 | { 44 | MSG* msg = static_cast(message); 45 | if (msg->message == WM_HOTKEY) 46 | { 47 | // qDebug() << "nativeEventFilter"; 48 | const quint32 keycode = HIWORD(msg->lParam); 49 | const quint32 modifiers = LOWORD(msg->lParam); 50 | activateShortcut(keycode, modifiers); 51 | } 52 | return false; 53 | } 54 | #endif 55 | quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) 56 | { 57 | // MOD_ALT, MOD_CONTROL, (MOD_KEYUP), MOD_SHIFT, MOD_WIN 58 | quint32 native = 0; 59 | if (modifiers & Qt::ShiftModifier) 60 | native |= MOD_SHIFT; 61 | if (modifiers & Qt::ControlModifier) 62 | native |= MOD_CONTROL; 63 | if (modifiers & Qt::AltModifier) 64 | native |= MOD_ALT; 65 | if (modifiers & Qt::MetaModifier) 66 | native |= MOD_WIN; 67 | // TODO: resolve these? 68 | //if (modifiers & Qt::KeypadModifier) 69 | //if (modifiers & Qt::GroupSwitchModifier) 70 | return native; 71 | } 72 | 73 | quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) 74 | { 75 | switch (key) 76 | { 77 | case Qt::Key_Escape: 78 | return VK_ESCAPE; 79 | case Qt::Key_Tab: 80 | case Qt::Key_Backtab: 81 | return VK_TAB; 82 | case Qt::Key_Backspace: 83 | return VK_BACK; 84 | case Qt::Key_Return: 85 | case Qt::Key_Enter: 86 | return VK_RETURN; 87 | case Qt::Key_Insert: 88 | return VK_INSERT; 89 | case Qt::Key_Delete: 90 | return VK_DELETE; 91 | case Qt::Key_Pause: 92 | return VK_PAUSE; 93 | case Qt::Key_Print: 94 | return VK_PRINT; 95 | case Qt::Key_Clear: 96 | return VK_CLEAR; 97 | case Qt::Key_Home: 98 | return VK_HOME; 99 | case Qt::Key_End: 100 | return VK_END; 101 | case Qt::Key_Left: 102 | return VK_LEFT; 103 | case Qt::Key_Up: 104 | return VK_UP; 105 | case Qt::Key_Right: 106 | return VK_RIGHT; 107 | case Qt::Key_Down: 108 | return VK_DOWN; 109 | case Qt::Key_PageUp: 110 | return VK_PRIOR; 111 | case Qt::Key_PageDown: 112 | return VK_NEXT; 113 | case Qt::Key_F1: 114 | return VK_F1; 115 | case Qt::Key_F2: 116 | return VK_F2; 117 | case Qt::Key_F3: 118 | return VK_F3; 119 | case Qt::Key_F4: 120 | return VK_F4; 121 | case Qt::Key_F5: 122 | return VK_F5; 123 | case Qt::Key_F6: 124 | return VK_F6; 125 | case Qt::Key_F7: 126 | return VK_F7; 127 | case Qt::Key_F8: 128 | return VK_F8; 129 | case Qt::Key_F9: 130 | return VK_F9; 131 | case Qt::Key_F10: 132 | return VK_F10; 133 | case Qt::Key_F11: 134 | return VK_F11; 135 | case Qt::Key_F12: 136 | return VK_F12; 137 | case Qt::Key_F13: 138 | return VK_F13; 139 | case Qt::Key_F14: 140 | return VK_F14; 141 | case Qt::Key_F15: 142 | return VK_F15; 143 | case Qt::Key_F16: 144 | return VK_F16; 145 | case Qt::Key_F17: 146 | return VK_F17; 147 | case Qt::Key_F18: 148 | return VK_F18; 149 | case Qt::Key_F19: 150 | return VK_F19; 151 | case Qt::Key_F20: 152 | return VK_F20; 153 | case Qt::Key_F21: 154 | return VK_F21; 155 | case Qt::Key_F22: 156 | return VK_F22; 157 | case Qt::Key_F23: 158 | return VK_F23; 159 | case Qt::Key_F24: 160 | return VK_F24; 161 | case Qt::Key_Space: 162 | return VK_SPACE; 163 | case Qt::Key_Asterisk: 164 | return VK_MULTIPLY; 165 | case Qt::Key_Plus: 166 | return VK_ADD; 167 | case Qt::Key_Comma: 168 | return VK_SEPARATOR; 169 | case Qt::Key_Minus: 170 | return VK_SUBTRACT; 171 | case Qt::Key_Slash: 172 | return VK_DIVIDE; 173 | 174 | // numbers 175 | case Qt::Key_0: 176 | case Qt::Key_1: 177 | case Qt::Key_2: 178 | case Qt::Key_3: 179 | case Qt::Key_4: 180 | case Qt::Key_5: 181 | case Qt::Key_6: 182 | case Qt::Key_7: 183 | case Qt::Key_8: 184 | case Qt::Key_9: 185 | return key; 186 | 187 | // letters 188 | case Qt::Key_A: 189 | case Qt::Key_B: 190 | case Qt::Key_C: 191 | case Qt::Key_D: 192 | case Qt::Key_E: 193 | case Qt::Key_F: 194 | case Qt::Key_G: 195 | case Qt::Key_H: 196 | case Qt::Key_I: 197 | case Qt::Key_J: 198 | case Qt::Key_K: 199 | case Qt::Key_L: 200 | case Qt::Key_M: 201 | case Qt::Key_N: 202 | case Qt::Key_O: 203 | case Qt::Key_P: 204 | case Qt::Key_Q: 205 | case Qt::Key_R: 206 | case Qt::Key_S: 207 | case Qt::Key_T: 208 | case Qt::Key_U: 209 | case Qt::Key_V: 210 | case Qt::Key_W: 211 | case Qt::Key_X: 212 | case Qt::Key_Y: 213 | case Qt::Key_Z: 214 | return key; 215 | 216 | default: 217 | return 0; 218 | } 219 | } 220 | 221 | bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) 222 | { 223 | return RegisterHotKey(0, nativeMods ^ nativeKey, nativeMods, nativeKey); 224 | } 225 | 226 | bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) 227 | { 228 | return UnregisterHotKey(0, nativeMods ^ nativeKey); 229 | } 230 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/qxt/qxtglobalshortcut_x11.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) Qxt Foundation. Some rights reserved. 4 | ** 5 | ** This file is part of the QxtGui module of the Qxt library. 6 | ** 7 | ** This library is free software; you can redistribute it and/or modify it 8 | ** under the terms of the Common Public License, version 1.0, as published 9 | ** by IBM, and/or under the terms of the GNU Lesser General Public License, 10 | ** version 2.1, as published by the Free Software Foundation. 11 | ** 12 | ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY 13 | ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY 14 | ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR 15 | ** FITNESS FOR A PARTICULAR PURPOSE. 16 | ** 17 | ** You should have received a copy of the CPL and the LGPL along with this 18 | ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files 19 | ** included with the source distribution for more information. 20 | ** If you did not receive a copy of the licenses, contact the Qxt Foundation. 21 | ** 22 | ** 23 | ** 24 | ****************************************************************************/ 25 | #include "qxtglobalshortcut_p.h" 26 | //#include 27 | //#include 28 | 29 | static int (*original_x_errhandler)(Display* display, XErrorEvent* event); 30 | 31 | static int qxt_x_errhandler(Display* display, XErrorEvent *event) 32 | { 33 | Q_UNUSED(display); 34 | switch (event->error_code) 35 | { 36 | case BadAccess: 37 | case BadValue: 38 | case BadWindow: 39 | if (event->request_code == 33 /* X_GrabKey */ || 40 | event->request_code == 34 /* X_UngrabKey */) 41 | { 42 | QxtGlobalShortcutPrivate::error = true; 43 | //TODO: 44 | //char errstr[256]; 45 | //XGetErrorText(dpy, err->error_code, errstr, 256); 46 | } 47 | default: 48 | return 0; 49 | } 50 | } 51 | #if(QT_VERSION<0x050000) 52 | bool QxtGlobalShortcutPrivate::eventFilter(void* message) 53 | { 54 | XEvent* event = static_cast(message); 55 | if (event->type == KeyPress) 56 | { 57 | XKeyEvent* key = (XKeyEvent*) event; 58 | activateShortcut(key->keycode, 59 | // Mod1Mask == Alt, Mod4Mask == Meta 60 | key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); 61 | } 62 | return false; 63 | } 64 | #else 65 | bool QxtGlobalShortcutPrivate::nativeEventFilter(const QByteArray &, void *message, long *) 66 | { 67 | XEvent* event = static_cast(message); 68 | if (event->type == KeyPress) 69 | { 70 | XKeyEvent* key = (XKeyEvent*) event; 71 | activateShortcut(key->keycode, 72 | // Mod1Mask == Alt, Mod4Mask == Meta 73 | key->state & (ShiftMask | ControlMask | Mod1Mask | Mod4Mask)); 74 | } 75 | return false; 76 | } 77 | #endif 78 | quint32 QxtGlobalShortcutPrivate::nativeModifiers(Qt::KeyboardModifiers modifiers) 79 | { 80 | // ShiftMask, LockMask, ControlMask, Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, and Mod5Mask 81 | quint32 native = 0; 82 | if (modifiers & Qt::ShiftModifier) 83 | native |= ShiftMask; 84 | if (modifiers & Qt::ControlModifier) 85 | native |= ControlMask; 86 | if (modifiers & Qt::AltModifier) 87 | native |= Mod1Mask; 88 | // TODO: resolve these? 89 | //if (modifiers & Qt::MetaModifier) 90 | //if (modifiers & Qt::KeypadModifier) 91 | //if (modifiers & Qt::GroupSwitchModifier) 92 | return native; 93 | } 94 | 95 | quint32 QxtGlobalShortcutPrivate::nativeKeycode(Qt::Key key) 96 | { 97 | Display* display = QX11Info::display(); 98 | return XKeysymToKeycode(display, XStringToKeysym(QKeySequence(key).toString().toLatin1().data())); 99 | } 100 | 101 | bool QxtGlobalShortcutPrivate::registerShortcut(quint32 nativeKey, quint32 nativeMods) 102 | { 103 | Display* display = QX11Info::display(); 104 | Window window = QX11Info::appRootWindow(); 105 | Bool owner = True; 106 | int pointer = GrabModeAsync; 107 | int keyboard = GrabModeAsync; 108 | error = false; 109 | original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); 110 | XGrabKey(display, nativeKey, nativeMods, window, owner, pointer, keyboard); 111 | XGrabKey(display, nativeKey, nativeMods | Mod2Mask, window, owner, pointer, keyboard); // allow numlock 112 | XSync(display, False); 113 | XSetErrorHandler(original_x_errhandler); 114 | return !error; 115 | } 116 | 117 | bool QxtGlobalShortcutPrivate::unregisterShortcut(quint32 nativeKey, quint32 nativeMods) 118 | { 119 | Display* display = QX11Info::display(); 120 | Window window = QX11Info::appRootWindow(); 121 | error = false; 122 | original_x_errhandler = XSetErrorHandler(qxt_x_errhandler); 123 | XUngrabKey(display, nativeKey, nativeMods, window); 124 | XUngrabKey(display, nativeKey, nativeMods | Mod2Mask, window); // allow numlock 125 | XSync(display, False); 126 | XSetErrorHandler(original_x_errhandler); 127 | return !error; 128 | } 129 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/widget.cpp: -------------------------------------------------------------------------------- 1 | #include "widget.h" 2 | 3 | #include 4 | 5 | #ifndef QT_NO_DEBUG 6 | #include 7 | #endif 8 | 9 | #include "OE/OEasyScreenshot" 10 | #include "qxt/qxtglobalshortcut.h" 11 | 12 | Widget::Widget(QWidget *parent) : 13 | QWidget(parent),openScreenshotButton_(new QPushButton(this)) { 14 | 15 | openScreenshotButton_->setGeometry(0,0,300,300); 16 | openScreenshotButton_->setObjectName("OpenScreenshotButton"); 17 | openScreenshotButton_->show(); 18 | openScreenshotButton_->setText(QStringLiteral( 19 | "单击我\n\n快捷键( Shift+A )")); 20 | QxtGlobalShortcut* shortcut = new QxtGlobalShortcut( 21 | QKeySequence("Shift+A"), this); 22 | 23 | connect(shortcut, SIGNAL(activated()), 24 | this, SLOT(onScreenshot())); 25 | connect(openScreenshotButton_.get(), SIGNAL(clicked()), 26 | this, SLOT(onScreenshot())); 27 | } 28 | 29 | 30 | void Widget::onScreenshot() 31 | { 32 | OEScreenshot::Instance(); 33 | } 34 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/widget.h: -------------------------------------------------------------------------------- 1 | #ifndef WIDGET_H 2 | #define WIDGET_H 3 | 4 | #include 5 | #include 6 | 7 | class QPushButton; 8 | class QxtGlobalShortcut; 9 | class Widget : public QWidget 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit Widget(QWidget *parent = 0); 15 | 16 | protected slots: 17 | 18 | void onScreenshot(); 19 | 20 | private: 21 | 22 | std::shared_ptr openScreenshotButton_; 23 | std::shared_ptr closeScreenshotButton_; 24 | 25 | }; 26 | 27 | #endif // WIDGET_H 28 | -------------------------------------------------------------------------------- /demo/SimpleShortcutKey/widget.ui: -------------------------------------------------------------------------------- 1 | 2 | Widget 3 | 4 | 5 | 6 | 0 7 | 0 8 | 400 9 | 300 10 | 11 | 12 | 13 | Widget 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /doc/build/build_osx.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/build/build_osx.md -------------------------------------------------------------------------------- /doc/build/build_unix.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/build/build_unix.md -------------------------------------------------------------------------------- /doc/build/build_window.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/build/build_window.md -------------------------------------------------------------------------------- /doc/build/build_window_msvc.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/build/build_window_msvc.md -------------------------------------------------------------------------------- /doc/demo show/20170401.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/demo show/20170401.gif -------------------------------------------------------------------------------- /doc/demo show/20170427.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/demo show/20170427.gif -------------------------------------------------------------------------------- /doc/demo show/20170428.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/demo show/20170428.gif -------------------------------------------------------------------------------- /doc/demo show/20170429.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/doc/demo show/20170429.gif -------------------------------------------------------------------------------- /doc/更新历史.md: -------------------------------------------------------------------------------- 1 | - 2017年4月29日 2 | 3 | 新增窗口霸道置顶 4 | 5 | 新增取色放大器 6 | 7 | - 2017年4月28日 8 | 9 | 新增窗口自动锁定 10 | 11 | 12 | - 2017年4月27日 13 | 14 | 增加截图器大小感知控件 15 | 16 | 17 | - 2017年4月27日之前 18 | 19 | 截图功能 20 | 21 | 支持窗口大小的二次修改 22 | 23 | 支持截图窗口的移动 24 | 25 | 兼容了双显示器的截图 26 | 27 | 支持截图到剪切板 -------------------------------------------------------------------------------- /msvs/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/msvs/Readme.md -------------------------------------------------------------------------------- /msvs/vs2015.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{900A8FBA-6E79-49B0-AED7-5E125FEE3CE5}" 7 | ProjectSection(SolutionItems) = preProject 8 | Readme.md = Readme.md 9 | EndProjectSection 10 | EndProject 11 | Global 12 | GlobalSection(SolutionProperties) = preSolution 13 | HideSolutionNode = FALSE 14 | EndGlobalSection 15 | EndGlobal 16 | -------------------------------------------------------------------------------- /src/OE/OEasyScreenshot: -------------------------------------------------------------------------------- 1 | #include "oescreenshot/oescreenshot.h" 2 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/Readme - English.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/src/OE/oescreenshot/Readme - English.md -------------------------------------------------------------------------------- /src/OE/oescreenshot/Readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/src/OE/oescreenshot/Readme.md -------------------------------------------------------------------------------- /src/OE/oescreenshot/oeamplifier.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | 31 | 32 | #include "oeamplifier.h" 33 | 34 | #include 35 | #include 36 | 37 | #ifndef QT_NO_DEBUG 38 | #include 39 | #endif 40 | 41 | #include "oecommonhelper.h" 42 | 43 | OEAmplifier::OEAmplifier(std::shared_ptr originPainting, 44 | QWidget *parent) :QWidget(parent), 45 | originPainting_(originPainting) { 46 | /// 设置成无边框对话框 47 | setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint); 48 | /// 开启鼠标实时追踪 49 | setMouseTracking(true); 50 | 51 | /// 设置默认大小 52 | sideLength_ = 122 * OECommonHelper::getWindowHeightMultiplyingPower(); 53 | imageHeight_ = 90 * OECommonHelper::getWindowHeightMultiplyingPower(); 54 | setFixedSize(sideLength_,sideLength_); 55 | 56 | /// 默认隐藏 57 | hide(); 58 | } 59 | 60 | void OEAmplifier::onSizeChange(int w, int h) { 61 | screenSize_ = QSize(w, h); 62 | } 63 | 64 | void OEAmplifier::onPostionChange(int x, int y) { 65 | cursorPoint_ = QPoint(x, y); 66 | raise(); 67 | int dest_x = x + 4; 68 | int dest_y = y + 26; 69 | 70 | /// 超出屏幕检测 71 | const QSize& parent_size = parentWidget()->size(); 72 | if (dest_y + height() > parent_size.height()) { 73 | dest_y = y - 26 - height(); 74 | } 75 | if (dest_x + width() > parent_size.width()) { 76 | dest_x = x - 4 - width(); 77 | } 78 | 79 | move(dest_x, dest_y); 80 | } 81 | 82 | 83 | /// 绘制鼠标拖拽时选区矩形的右下顶点的放大图; 84 | void OEAmplifier::paintEvent(QPaintEvent *) { 85 | QPainter painter(this); 86 | 87 | /// 绘制背景 88 | painter.fillRect(rect(), QColor(0, 0, 0, 160)); 89 | 90 | QPixmap endPointImage; 91 | /// 绘制放大图; 92 | const QSize& parent_size = parentWidget()->size(); 93 | /** 94 | * @bug : 在屏幕边缘绘制放大图时会出现图片拉伸 95 | * 这里暂时做了边缘检测,若是屏幕边缘则不进行放大图的绘制,和QQ截图的采取方式是一致的。 96 | * 97 | * @marker: 颜色还是照样识别,但是局部放大的效果暂时禁用 98 | * 99 | * @note : 解决方法,可以发现边缘时,将不能放大的地方,不描绘,或填充黑色,以避免图片被非预期的拉伸问题。 100 | */ 101 | if ((cursorPoint_.x() + 15 < parent_size.width() && cursorPoint_.x() - 15 > 0) 102 | && (cursorPoint_.y() + 11 < parent_size.height() && cursorPoint_.y() - 11 > 0)) { 103 | endPointImage = originPainting_-> 104 | copy(QRect(cursorPoint_.x() - 15, 105 | cursorPoint_.y() - 11, 30, 22)) 106 | .scaled(sideLength_, imageHeight_); 107 | painter.drawPixmap(0,0, endPointImage); 108 | } 109 | else { 110 | endPointImage = originPainting_-> 111 | copy(QRect(cursorPoint_.x() - 15, 112 | cursorPoint_.y() - 11, 30, 22)); 113 | } 114 | 115 | 116 | /// 绘制十字 117 | painter.setPen(QPen(QColor(0, 180, 255 , 180), 4)); 118 | // 竖线; 119 | painter.drawLine(QPoint(sideLength_ >> 1, 0), 120 | QPoint(sideLength_ >> 1, 121 | imageHeight_ - 4)); 122 | // 横线; 123 | painter.drawLine(QPoint(0, imageHeight_ >> 1), 124 | QPoint(sideLength_, 125 | imageHeight_ >> 1)); 126 | 127 | /// 绘制大图内边框 128 | painter.setPen(QPen(Qt::white, 2)); 129 | painter.drawRect(2,2,width()-4, imageHeight_-4); 130 | 131 | /// 绘制外边框 132 | painter.setPen(QPen(Qt::black, 1)); 133 | painter.drawRect(0,0,width()-1,height()-1); 134 | 135 | /// 当前选中矩形的宽高信息; 136 | QString select_screen_info = QString("%1×%2") 137 | .arg(screenSize_.width()).arg(screenSize_.height()); 138 | 139 | /// 当前鼠标像素值的RGB信息 140 | QImage image = originPainting_->toImage(); 141 | QColor cursor_pixel = image.pixel(cursorPoint_); 142 | QString select_pt_rgb = QString("RGB:(%1,%2,%3)") 143 | .arg(cursor_pixel.red()) 144 | .arg(cursor_pixel.green()) 145 | .arg(cursor_pixel.blue()); 146 | 147 | /// 绘制坐标轴相关数据 148 | painter.setPen(Qt::white); 149 | painter.drawText(QPoint(6, imageHeight_+14),select_screen_info); 150 | painter.drawText(QPoint(6, imageHeight_+27),select_pt_rgb); 151 | } 152 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oeamplifier.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | 31 | #ifndef OEAMPLIFIER_H 32 | #define OEAMPLIFIER_H 33 | #include 34 | #include 35 | 36 | 37 | /** 38 | * @class : OEAmplifier 39 | * @brief : 放大取色器 40 | * @note : 关于鼠标位置局部放大的操作以及色卡取值的操作 41 | */ 42 | class OEAmplifier : public QWidget 43 | { 44 | Q_OBJECT 45 | public: 46 | explicit OEAmplifier(std::shared_ptr originPainting, QWidget *parent = 0); 47 | 48 | signals: 49 | 50 | public slots: 51 | 52 | 53 | /** 54 | * @brief : 大小修改 55 | * @param : w 宽度 56 | * @param : h 高度 57 | * @date : 2017年4月29日 58 | */ 59 | void onSizeChange(int w, int h); 60 | 61 | /** 62 | * @brief : 大小修改 63 | * @param : w 宽度 64 | * @param : h 高度 65 | * @date : 2017年4月29日 66 | */ 67 | void onPostionChange(int x, int y); 68 | 69 | protected: 70 | 71 | /** 72 | * @brief : 窗口自绘事件 73 | * @date : 2017年4月29日 74 | */ 75 | virtual void paintEvent(QPaintEvent *); 76 | 77 | private: 78 | 79 | /// 外部组件的大小信息 80 | QSize screenSize_; 81 | /// 鼠标的位置 82 | QPoint cursorPoint_; 83 | /// 取色放大器的边长 84 | int sideLength_; 85 | /// 放大区的高度 86 | int imageHeight_; 87 | /// 屏幕原画 88 | std::shared_ptr originPainting_; 89 | 90 | }; 91 | 92 | #endif /// OEAMPLIFIER_H 93 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oecommonhelper.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | 31 | #include "oecommonhelper.h" 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | #include 40 | 41 | #ifndef QT_NO_DEBUG 42 | #include 43 | #endif 44 | 45 | 46 | #define WINDOW_BASESIZE_WIDTH (1920) 47 | #define WINDOW_BASESIZE_HEIGHT (1080) 48 | 49 | float OECommonHelper::widthMultiplyingPower_ = 0; 50 | float OECommonHelper::heightMultiplyingPower_ = 0; 51 | 52 | void OECommonHelper::setStyle(const QString &style) { 53 | QFile qss(style); 54 | qss.open(QFile::ReadOnly); 55 | qApp->setStyleSheet(qss.readAll()); 56 | qss.close(); 57 | } 58 | 59 | void OECommonHelper::setLanguagePack(const QString &language) { 60 | // 加载中文包 61 | QTranslator translator; 62 | translator.load(language); 63 | qApp->installTranslator(&translator); 64 | } 65 | 66 | void OECommonHelper::moveCenter(QWidget *widget, QRect parentRect) { 67 | if (parentRect.isEmpty()) { 68 | parentRect = QApplication::desktop()->rect(); 69 | } 70 | widget->move (((parentRect.width() - widget->width()) >> 1), 71 | ((parentRect.height() - widget->height()) >> 1)); 72 | } 73 | 74 | const float &OECommonHelper::getWindowWidthMultiplyingPower() { 75 | if (widthMultiplyingPower_ == 0) { 76 | upWindowSizeMultiplyingPower(); 77 | } 78 | return widthMultiplyingPower_; 79 | } 80 | 81 | const float & OECommonHelper::getWindowHeightMultiplyingPower() { 82 | if (heightMultiplyingPower_ == 0) { 83 | upWindowSizeMultiplyingPower(); 84 | } 85 | return heightMultiplyingPower_; 86 | } 87 | 88 | void OECommonHelper::upWindowSizeMultiplyingPower() { 89 | QSize temp_size = QApplication::desktop()->size(); 90 | widthMultiplyingPower_ = (float)temp_size.width() 91 | / (float)WINDOW_BASESIZE_WIDTH; 92 | heightMultiplyingPower_ = (float)temp_size.height() 93 | / (float)WINDOW_BASESIZE_HEIGHT; 94 | } 95 | 96 | bool OECommonHelper::getSmallestWindowFromCursor(QRect& out_rect) { 97 | HWND hwnd; 98 | POINT pt; 99 | // 获得当前鼠标位置 100 | ::GetCursorPos(&pt); 101 | // 获得当前位置桌面上的子窗口 102 | hwnd = ::ChildWindowFromPointEx(::GetDesktopWindow(), 103 | pt, CWP_SKIPDISABLED | CWP_SKIPINVISIBLE); 104 | if (hwnd != NULL) { 105 | HWND temp_hwnd; 106 | temp_hwnd = hwnd; 107 | while (true) { 108 | ::GetCursorPos(&pt); 109 | ::ScreenToClient(temp_hwnd, &pt); 110 | temp_hwnd = ::ChildWindowFromPointEx(temp_hwnd, 111 | pt, CWP_SKIPINVISIBLE); 112 | if (temp_hwnd == NULL || temp_hwnd == hwnd) 113 | break; 114 | hwnd = temp_hwnd; 115 | } 116 | RECT temp_window; 117 | ::GetWindowRect(hwnd, &temp_window); 118 | out_rect.setRect(temp_window.left,temp_window.top, 119 | temp_window.right - temp_window.left, 120 | temp_window.bottom - temp_window.top); 121 | return true; 122 | } 123 | return false; 124 | } 125 | 126 | bool OECommonHelper::getCurrentWindowFromCursor(QRect &out_rect) 127 | { 128 | HWND hwnd; 129 | POINT pt; 130 | // 获得当前鼠标位置 131 | ::GetCursorPos(&pt); 132 | // 获得当前位置桌面上的子窗口 133 | hwnd = ::ChildWindowFromPointEx(::GetDesktopWindow(), pt, 134 | CWP_SKIPDISABLED | CWP_SKIPINVISIBLE); 135 | if (hwnd != NULL) { 136 | RECT temp_window; 137 | ::GetWindowRect(hwnd, &temp_window); 138 | out_rect.setRect(temp_window.left, temp_window.top, 139 | temp_window.right - temp_window.left, 140 | temp_window.bottom - temp_window.top); 141 | return true; 142 | } 143 | return false; 144 | } 145 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oecommonhelper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | 31 | #ifndef COMMONHELPER_H 32 | #define COMMONHELPER_H 33 | #include 34 | #include 35 | 36 | class QWidget; 37 | 38 | /** 39 | * @class : OECommonHelper 40 | * @brief : 通用助手 41 | * @note : 完成一些比较常用又通用的功能 42 | */ 43 | class OECommonHelper 44 | { 45 | public: 46 | 47 | /** 48 | * @brief : 设置QSS文件 49 | * @param : style 文件名 50 | * @author: 陈鲁勇 51 | * @date : 2017年04月10日 52 | * @remark: 如果是qrc路径,请带上 qrc:/ 53 | **/ 54 | static void setStyle(const QString &style); 55 | 56 | /** 57 | * @brief : 设置语言包 58 | * @param : language 语言包的文件名 59 | * @author: 陈鲁勇 60 | * @date : 2017年04月10日 61 | **/ 62 | static void setLanguagePack(const QString& language); 63 | 64 | /** 65 | * @brief : 将窗口移动到中心 66 | * @param : widget 要移动的窗口 67 | * @param : parentRect 矩形几何数据 68 | * @author: 陈鲁勇 69 | * @date : 2017年04月10日 70 | **/ 71 | static void moveCenter(QWidget* widget, QRect parentRect = {}); 72 | 73 | 74 | /** 75 | * @brief : 获得当前界面与开发时的界面之间的横向倍率 76 | * @return: float 倍率 77 | * @author: 陈鲁勇 78 | * @date : 2017年04月10日 79 | **/ 80 | static const float& getWindowWidthMultiplyingPower(void); 81 | 82 | 83 | /** 84 | * @brief : 获得当前界面与开发时的界面之间的纵向倍率 85 | * @return: float 倍率 86 | * @author: 陈鲁勇 87 | * @date : 2017年04月10日 88 | **/ 89 | static const float& getWindowHeightMultiplyingPower(void); 90 | 91 | 92 | /** 93 | * @brief : 获得当前鼠标位置最小的子窗口 94 | * @param : out_rect 矩形 (返回) 95 | * @return: 成功:true 96 | * @author: 陈鲁勇 97 | * @date : 2017年04月10日 98 | **/ 99 | static bool getSmallestWindowFromCursor(QRect &out_rect); 100 | 101 | /** 102 | * @brief : 获得当前鼠标位置的窗口 103 | * @param : out_rect 矩形 (返回) 104 | * @return: 成功:true 105 | * @author: 陈鲁勇 106 | * @date : 2017年04月10日 107 | **/ 108 | static bool getCurrentWindowFromCursor(QRect &out_rect); 109 | 110 | protected: 111 | 112 | /** 113 | * @brief : 更新窗口倍率 114 | * @author: 陈鲁勇 115 | * @date : 2017年04月10日 116 | **/ 117 | static void upWindowSizeMultiplyingPower(void); 118 | 119 | 120 | private: 121 | /// 窗口横向倍率 122 | static float widthMultiplyingPower_; 123 | /// 窗口纵向倍率 124 | static float heightMultiplyingPower_; 125 | }; 126 | 127 | #endif /// COMMONHELPER_H 128 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oemodelview.cpp: -------------------------------------------------------------------------------- 1 | #include "oemodelview.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /// @test : 测试变量 9 | QPoint startPoint_; 10 | QPoint endPoint_; 11 | 12 | 13 | OEModelView::OEModelView(MODEL model, 14 | QWidget *parent) : QWidget(parent), 15 | color_(Qt::red) { 16 | /// 确定画图样式 17 | switch (model) { 18 | case MODEL::Arrows: 19 | drawFunc_ = &OEModelView::drawArrows; 20 | break; 21 | case MODEL::Rectangle: 22 | drawFunc_ = &OEModelView::drawRect; 23 | break; 24 | case MODEL::Roundness: 25 | drawFunc_ = &OEModelView::drawEllipse; 26 | break; 27 | default: 28 | { 29 | drawFunc_ = &OEModelView::drawArrows; 30 | } 31 | } 32 | } 33 | 34 | 35 | void OEModelView::paintEvent(QPaintEvent *) { 36 | QPainter paiter(this); 37 | 38 | /// @test : 测试变量 39 | startPoint_ = QPoint(width(),height()); 40 | endPoint_ = {}; 41 | 42 | /// 绘制图形 43 | (this->*drawFunc_)(startPoint_, endPoint_, paiter); 44 | } 45 | 46 | 47 | void OEModelView::drawArrows(const QPoint& startPoint, 48 | const QPoint& endPoint, 49 | QPainter &paiter) { 50 | /// 消锯齿 51 | paiter.setRenderHint(QPainter::Antialiasing, true); 52 | /// 创建画笔,设置画刷 53 | QPen pen; 54 | pen.setColor(color_); 55 | pen.setWidth(1); 56 | paiter.setPen(pen); 57 | paiter.setBrush(color_); 58 | 59 | 60 | /// 箭头部分三角形的腰长 61 | double par = 15.0; 62 | double slopy = atan2((endPoint.y() - startPoint.y()), 63 | (endPoint.x() - startPoint.x())); 64 | double cos_y = cos(slopy); 65 | double sin_y = sin(slopy); 66 | QPoint head_point1 = QPoint(endPoint.x() + int(-par*cos_y - (par / 2.0 * sin_y)), 67 | endPoint.y() + int(-par*sin_y + (par / 2.0 * cos_y))); 68 | QPoint head_point2 = QPoint(endPoint.x() + int(-par*cos_y + (par / 2.0 * sin_y)), 69 | endPoint.y() - int(par / 2.0*cos_y + par * sin_y)); 70 | QPoint head_points[3] = { endPoint, head_point1, head_point2 }; 71 | /// 绘制箭头部分 72 | paiter.drawPolygon(head_points, 3); 73 | 74 | 75 | /// 计算箭身部分 76 | int offset_x = int(par*sin_y / 3); 77 | int offset_y = int(par*cos_y / 3); 78 | QPoint body_point1, body_point2; 79 | body_point1 = QPoint(endPoint.x() + int(-par*cos_y - (par / 2.0*sin_y)) + 80 | offset_x, endPoint.y() + int(-par*sin_y + (par / 2.0*cos_y)) - offset_y); 81 | body_point2 = QPoint(endPoint.x() + int(-par*cos_y + (par / 2.0*sin_y) - offset_x), 82 | endPoint.y() - int(par / 2.0*cos_y + par*sin_y) + offset_y); 83 | QPoint body_points[3] = { startPoint, body_point1, body_point2 }; 84 | /// 绘制箭身部分 85 | paiter.drawPolygon(body_points, 3); 86 | 87 | } 88 | 89 | void OEModelView::drawRect(const QPoint &startPoint, const QPoint &endPoint, 90 | QPainter &paiter) { 91 | paiter.setPen(color_); 92 | paiter.drawRect(QRect(startPoint, endPoint)); 93 | } 94 | 95 | void OEModelView::drawEllipse(const QPoint &startPoint, const QPoint &endPoint, 96 | QPainter &paiter) { 97 | paiter.setPen(color_); 98 | paiter.drawEllipse(QRect(startPoint, endPoint)); 99 | } 100 | void OEModelView::onColor(const QColor &color) { 101 | color_ = color; 102 | } 103 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oemodelview.h: -------------------------------------------------------------------------------- 1 | #ifndef OEMODELVIEW_H 2 | #define OEMODELVIEW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class OEModelView : public QWidget 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | 15 | /** 16 | * @brief : 模型种类 17 | */ 18 | enum MODEL{ 19 | Arrows = 0, /// 箭头 20 | Rectangle = 1, /// 矩形 21 | Roundness /// 圆形 22 | }; 23 | 24 | private: 25 | typedef void (OEModelView::*PDRAWFUNC) 26 | (const QPoint &,const QPoint &, QPainter&); 27 | 28 | 29 | signals: 30 | 31 | public: 32 | explicit OEModelView(MODEL model = MODEL::Arrows, 33 | QWidget *parent = 0); 34 | 35 | protected: 36 | 37 | /** 38 | * @brief : 自绘事件 39 | */ 40 | virtual void paintEvent(QPaintEvent *); 41 | 42 | private: 43 | 44 | /** 45 | * @brief : 画箭头 46 | * @param : 箭头起点 47 | * @param : 箭头终点 48 | * @param : 画板 49 | */ 50 | void drawArrows(const QPoint &startPoint, 51 | const QPoint &endPoint, 52 | QPainter& paiter); 53 | /** 54 | * @brief : 画方块 55 | * @param : 方块起点 56 | * @param : 方块终点 57 | * @param : 画板 58 | */ 59 | void drawRect(const QPoint &startPoint, 60 | const QPoint &endPoint, 61 | QPainter& paiter); 62 | 63 | /** 64 | * @brief : 画圆形 65 | * @param : 圆形起点 66 | * @param : 圆形终点 67 | * @param : 画板 68 | */ 69 | void drawEllipse(const QPoint &startPoint, 70 | const QPoint &endPoint, 71 | QPainter& paiter); 72 | 73 | public slots: 74 | 75 | void onColor(const QColor &color); 76 | 77 | private: 78 | QColor color_; 79 | PDRAWFUNC drawFunc_; 80 | }; 81 | 82 | 83 | #endif // OEMODELVIEW_H 84 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oescreenshot.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | #include "oescreenshot.h" 31 | 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #ifndef QT_NO_DEBUG 46 | #include 47 | #endif 48 | 49 | #include 50 | 51 | #include "oeamplifier.h" 52 | #include "oecommonhelper.h" 53 | 54 | 55 | /// 鼠标按钮图片的十六进制数据 56 | static const unsigned char uc_mouse_image[] = { 57 | 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52 58 | ,0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2D, 0x08, 0x06, 0x00, 0x00, 0x00, 0x52, 0xE9, 0x60 59 | ,0xA2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B 60 | ,0x13, 0x01, 0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x01, 0x40, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85 61 | ,0xED, 0xD5, 0x21, 0x6E, 0xC3, 0x30, 0x14, 0xC6, 0xF1, 0xFF, 0x9B, 0xC6, 0x36, 0x30, 0x38, 0xA9 62 | ,0x05, 0x01, 0x05, 0x81, 0x05, 0x03, 0x39, 0xCA, 0x60, 0x8F, 0xD2, 0x03, 0xEC, 0x10, 0x3B, 0x46 63 | ,0xC1, 0xC0, 0xC6, 0x0A, 0x3B, 0x96, 0xB1, 0x80, 0x82, 0xC1, 0x56, 0x2A, 0xFF, 0x06, 0xE2, 0x36 64 | ,0x75, 0x9A, 0xB4, 0xCA, 0xEC, 0x4E, 0x9A, 0xE4, 0x2F, 0xB2, 0x42, 0x22, 0xFF, 0xF2, 0xFC, 0x9C 65 | ,0x18, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0xFE, 0x55, 0xE4, 0xC6, 0xA0 66 | ,0xDC, 0xC4, 0x71, 0x87, 0xC1, 0xC1, 0x68, 0x01, 0xCC, 0x06, 0xC2, 0x51, 0xD0, 0x29, 0xB0, 0x18 67 | ,0x00, 0xDF, 0xC6, 0x40, 0x33, 0x37, 0x84, 0x30, 0x4C, 0x80, 0x85, 0xCE, 0x7B, 0x2E, 0x2A, 0x91 68 | ,0x84, 0x24, 0xBE, 0x25, 0xDE, 0x25, 0x5E, 0x2F, 0x6E, 0xAE, 0xD0, 0x37, 0x92, 0x10, 0xF0, 0x09 69 | ,0x54, 0x40, 0xE9, 0xEE, 0x15, 0xC6, 0xA2, 0x77, 0xFE, 0xE0, 0xE5, 0x85, 0x8F, 0x16, 0x58, 0xDF 70 | ,0x35, 0x06, 0x5B, 0xD3, 0xB9, 0xD4, 0x11, 0xD0, 0xA5, 0x8F, 0xDE, 0x57, 0x75, 0x83, 0x73, 0x50 71 | ,0x06, 0xF6, 0x72, 0x0A, 0x47, 0x40, 0x57, 0x0D, 0x38, 0xDE, 0xC0, 0x04, 0x6F, 0x68, 0x05, 0x36 72 | ,0xF5, 0xE1, 0x08, 0x3D, 0xCD, 0xEA, 0xEA, 0x5A, 0xD8, 0xBE, 0x5A, 0x46, 0xB0, 0x05, 0x1E, 0xAC 73 | ,0xF1, 0xC2, 0xD1, 0xCC, 0x01, 0x6D, 0x74, 0x02, 0xDB, 0x3B, 0xBF, 0xD3, 0x73, 0x07, 0x87, 0x2F 74 | ,0xEF, 0x53, 0x07, 0x38, 0x82, 0x2F, 0xF6, 0xFB, 0xB8, 0x81, 0x73, 0x41, 0x69, 0x28, 0x3A, 0x7A 75 | ,0x5C, 0xDD, 0x73, 0xCF, 0x3A, 0x86, 0xA3, 0x05, 0x87, 0xEA, 0xCC, 0x60, 0xA1, 0x06, 0x75, 0x89 76 | ,0xFE, 0x77, 0x92, 0x76, 0x68, 0x23, 0xEF, 0x88, 0xD3, 0x4C, 0xA8, 0x10, 0x7A, 0xD4, 0xEF, 0x8E 77 | ,0xBE, 0x8B, 0x68, 0x79, 0x3A, 0xB1, 0x72, 0xE1, 0xAE, 0xBC, 0x13, 0x0D, 0xDE, 0xBD, 0x3D, 0xF3 78 | ,0x08, 0x15, 0xD4, 0xDF, 0x4C, 0x06, 0x36, 0xF7, 0x9E, 0x09, 0xED, 0xE9, 0x99, 0x97, 0x3E, 0x42 79 | ,0xFF, 0x30, 0x42, 0x4B, 0xA1, 0x8D, 0xD8, 0xE9, 0x2A, 0xBD, 0xED, 0x41, 0x25, 0x2A, 0x89, 0x37 80 | ,0x1F, 0xBD, 0xEA, 0x61, 0x8B, 0x5F, 0xDD, 0xC1, 0xFA, 0x01, 0xD8, 0xA3, 0x8F, 0xFB, 0xCA, 0x70 81 | ,0x16, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 82 | }; 83 | 84 | 85 | 86 | OEScreenshot * OEScreenshot::self_ = nullptr; 87 | bool OEScreenshot::isActivity_ = false; 88 | bool OEScreen::isInit_ = false; 89 | 90 | OEScreenshot::OEScreenshot(QWidget *parent) : QWidget(parent), 91 | isLeftPressed_ (false), backgroundScreen_(nullptr), 92 | originPainting_(nullptr), screenTool_(nullptr) { 93 | /// 初始化鼠标 94 | initCursor(); 95 | /// 截取屏幕信息 96 | initGlobalScreen(); 97 | /// 初始化鼠标放大器 98 | initAmplifier(); 99 | /// 初始化大小感知器 100 | initMeasureWidget(); 101 | /// 全屏窗口 102 | showFullScreen(); 103 | /// 窗口与显示屏对齐 104 | setGeometry(getScreenRect()); 105 | /// 霸道置顶 106 | onEgoistic(); 107 | /// 开启鼠标实时追踪 108 | setMouseTracking(true); 109 | /// 更新鼠标的位置 110 | emit cursorPosChange(cursor().pos().x(), cursor().pos().y()); 111 | /// 更新鼠标区域窗口 112 | updateMouse(); 113 | /// 展示窗口 114 | show(); 115 | } 116 | 117 | OEScreenshot::~OEScreenshot(void) { 118 | } 119 | 120 | /** 121 | * @brief:窗口实例 122 | * @return:OEScreenshot 123 | */ 124 | OEScreenshot *OEScreenshot::Instance(void) { 125 | if (!isActivity_ && self_) { 126 | destroy(); 127 | } 128 | static QMutex mutex; 129 | if (!self_) { 130 | QMutexLocker locker(&mutex); 131 | if (!self_) { 132 | isActivity_ = true; 133 | self_ = new OEScreenshot; 134 | } 135 | } 136 | return self_; 137 | } 138 | 139 | void OEScreenshot::destroy(void) { 140 | if (!isActivity_ && self_) { 141 | delete self_; 142 | self_ = nullptr; 143 | } 144 | } 145 | 146 | void OEScreenshot::hideEvent(QHideEvent *) { 147 | isActivity_ = false; 148 | } 149 | 150 | 151 | void OEScreenshot::closeEvent(QCloseEvent *) { 152 | isActivity_ = false; 153 | } 154 | 155 | void OEScreenshot::mouseDoubleClickEvent(QMouseEvent *) { 156 | emit doubleClick(); 157 | } 158 | 159 | 160 | /** 161 | * 初始化放大镜 (色彩采集器) 162 | */ 163 | void OEScreenshot::initAmplifier(std::shared_ptr originPainting) { 164 | std::shared_ptr temp_pm = originPainting; 165 | if (temp_pm == nullptr) { 166 | temp_pm = originPainting_; 167 | } 168 | amplifierTool_.reset(new OEAmplifier(temp_pm, this)); 169 | connect(this,SIGNAL(cursorPosChange(int,int)), 170 | amplifierTool_.get(), SLOT(onPostionChange(int,int))); 171 | amplifierTool_->show(); 172 | amplifierTool_->raise(); 173 | } 174 | 175 | void OEScreenshot::initMeasureWidget(void) 176 | { 177 | rectTool_.reset(new OERect(this)); 178 | rectTool_->raise(); 179 | } 180 | 181 | /** 182 | * 功能:获得当前屏幕的大小 183 | */ 184 | const QRect &OEScreenshot::getScreenRect(void) { 185 | if (!desktopRect_.isEmpty()) { 186 | return desktopRect_; 187 | } 188 | /// 兼容多个屏幕的问题 189 | desktopRect_ = QRect(QApplication::desktop()->pos(), 190 | QApplication::desktop()->size()); 191 | return desktopRect_; 192 | } 193 | 194 | std::shared_ptr OEScreenshot::initGlobalScreen(void) { 195 | if (backgroundScreen_.get() != nullptr) { 196 | return backgroundScreen_; 197 | } 198 | /// 获得屏幕原画 199 | std::shared_ptr temp_screen = getGlobalScreen(); 200 | 201 | /// 制作暗色屏幕背景 202 | QPixmap temp_dim_pix(temp_screen->width(), temp_screen->height()); 203 | temp_dim_pix.fill((QColor(0, 0, 0, 160))); 204 | backgroundScreen_.reset(new QPixmap(*temp_screen)); 205 | QPainter p(backgroundScreen_.get()); 206 | p.drawPixmap(0, 0, temp_dim_pix); 207 | 208 | return backgroundScreen_; 209 | } 210 | 211 | /* 212 | * 获得屏幕的原画 213 | * 返回:QPixmap* 指针 214 | */ 215 | std::shared_ptr OEScreenshot::getGlobalScreen(void) { 216 | if (originPainting_.get() == nullptr) { 217 | /// 截取当前桌面,作为截屏的背景图 218 | QScreen *screen = QGuiApplication::primaryScreen(); 219 | const QRect& temp_rect = getScreenRect(); 220 | originPainting_.reset(new QPixmap(screen->grabWindow(0, temp_rect.x(), 221 | temp_rect.y(), temp_rect.width(), 222 | temp_rect.height()))); 223 | } 224 | return originPainting_; 225 | } 226 | void OEScreenshot::onEgoistic(void) 227 | { 228 | /// 窗口置顶 229 | #ifdef Q_OS_WIN32 230 | SetWindowPos((HWND)this->winId(),HWND_TOPMOST,this->pos().x(),this->pos().y(),this->width(),this->height(),SWP_SHOWWINDOW); 231 | #else 232 | Qt::WindowFlags flags = windowFlags(); 233 | flags |= Qt::WindowStaysOnTopHint; 234 | setWindowFlags(flags); 235 | #endif 236 | } 237 | 238 | /* 239 | * 初始化鼠标 240 | * 参数:_ico 鼠标图片的资源文件 241 | */ 242 | void OEScreenshot::initCursor(const QString& ico) { 243 | QPixmap pixmap; 244 | if (ico.isEmpty()) { 245 | pixmap.loadFromData(uc_mouse_image, sizeof(uc_mouse_image)); 246 | } 247 | else { 248 | pixmap.load(ico); 249 | } 250 | QCursor cursor; 251 | cursor = QCursor(pixmap, 15, 23); 252 | setCursor(cursor); 253 | } 254 | 255 | std::shared_ptr OEScreenshot::createScreen(const QPoint &pos) { 256 | if (screenTool_.get() == nullptr) { 257 | /// 创建截图器 258 | screenTool_.reset(new OEScreen(originPainting_, pos, this)); 259 | /// 建立信号连接 260 | connect (this, SIGNAL(cursorPosChange(int,int)), 261 | screenTool_.get(),SLOT(onMouseChange(int,int))); 262 | /// 建立主界面双击保存信号关联 263 | connect (this, SIGNAL(doubleClick()), 264 | screenTool_.get(),SLOT(onSaveScreen())); 265 | /// 建立截图器大小关联 266 | connect(screenTool_.get(), SIGNAL(sizeChange(int,int)), 267 | rectTool_.get(), SLOT(onSizeChange(int,int))); 268 | connect(screenTool_.get(), SIGNAL(sizeChange(int,int)), 269 | amplifierTool_.get(), SLOT(onSizeChange(int,int))); 270 | /// 建立截图器与感知器的位置关联 271 | connect(screenTool_.get(), SIGNAL(postionChange(int,int)), 272 | rectTool_.get(), SLOT(onPostionChange(int,int))); 273 | 274 | /// 获得截图器当前起始位置 275 | startPoint_ = pos; 276 | isLeftPressed_ = true; 277 | } 278 | return screenTool_; 279 | } 280 | 281 | void OEScreenshot::destroyScreen() { 282 | if (screenTool_.get() != nullptr) { 283 | /// 断开信号资源 284 | disconnect (this, SIGNAL(doubleClick()), 285 | screenTool_.get(),SLOT(onSaveScreen())); 286 | disconnect(screenTool_.get(), SIGNAL(sizeChange(int,int)), 287 | rectTool_.get(), SLOT(onSizeChange(int,int))); 288 | disconnect(screenTool_.get(), SIGNAL(postionChange(int,int)), 289 | rectTool_.get(), SLOT(onPostionChange(int,int))); 290 | /// 清理工具 291 | screenTool_.reset(); 292 | screenTool_ = nullptr; 293 | isLeftPressed_ = false; 294 | update(); 295 | return; 296 | } 297 | } 298 | 299 | void OEScreenshot::mousePressEvent(QMouseEvent *e) { 300 | if (e->button() == Qt::LeftButton) { 301 | createScreen(e->pos()); 302 | return ; 303 | } 304 | } 305 | 306 | void OEScreenshot::mouseReleaseEvent(QMouseEvent *e) { 307 | if (e->button() == Qt::RightButton) { 308 | if (screenTool_.get() != nullptr) { 309 | rectTool_->hide(); 310 | amplifierTool_->onPostionChange(e->x(), e->y()); 311 | amplifierTool_->show(); 312 | /// 更新当前鼠标选中的窗口 313 | updateMouse(); 314 | return destroyScreen(); 315 | } 316 | close(); 317 | return ; 318 | } 319 | else if (isLeftPressed_ == true 320 | && e->button() == Qt::LeftButton) { 321 | /// 选择窗口选区 322 | if (startPoint_ == e->pos() 323 | && !windowRect_.isEmpty()) { 324 | screenTool_->setGeometry(windowRect_); 325 | screenTool_->show(); 326 | windowRect_ = {}; 327 | } 328 | /// 断开鼠标移动的信号 329 | disconnect (this, SIGNAL(cursorPosChange(int,int)), 330 | screenTool_.get(),SLOT(onMouseChange(int,int))); 331 | /// 隐藏放大器 332 | amplifierTool_->hide(); 333 | /// 断开截图器的大小修改信号 334 | disconnect (screenTool_.get(), SIGNAL(sizeChange(int,int)), 335 | amplifierTool_.get(),SLOT(onSizeChange(int,int))); 336 | isLeftPressed_ = false; 337 | } 338 | QWidget::mouseReleaseEvent(e); 339 | } 340 | 341 | void OEScreenshot::mouseMoveEvent(QMouseEvent *e) { 342 | emit cursorPosChange(e->x(), e->y()); 343 | if (isLeftPressed_) { 344 | amplifierTool_->raise(); 345 | windowRect_ = {}; 346 | update(); 347 | } 348 | else if (isLeftPressed_ == false 349 | && false == OEScreen::state()){ 350 | /// 霸道置顶 351 | onEgoistic(); 352 | 353 | /// 更新当前鼠标选中的窗口 354 | updateMouse(); 355 | } 356 | QWidget::mouseMoveEvent(e); 357 | } 358 | 359 | void OEScreenshot::paintEvent(QPaintEvent *) { 360 | QPainter painter(this); 361 | /// 画全屏图 362 | painter.drawPixmap(0,0,desktopRect_.width(), 363 | desktopRect_.height(), *backgroundScreen_); 364 | 365 | if (!windowRect_.isEmpty()) { 366 | /// 绘制选区 367 | QPen pen = painter.pen(); 368 | pen.setColor(QColor(0,175,255)); 369 | pen.setWidth(2); 370 | painter.setPen(pen); 371 | painter.drawRect(windowRect_.x(),windowRect_.y(), 372 | windowRect_.width(),windowRect_.height()); 373 | painter.drawPixmap(QPoint(windowRect_.x(),windowRect_.y()), 374 | *originPainting_, windowRect_); 375 | } 376 | } 377 | 378 | void OEScreenshot::updateMouse(void) { 379 | /// 获取当前鼠标选中的窗口 380 | ::EnableWindow((HWND)winId(), FALSE); 381 | /// @marker: 只更新一次,可以修复用户误操作导致的查找窗口与识别界面窗口不一致. 382 | OECommonHelper::getSmallestWindowFromCursor(windowRect_); 383 | QPoint temp_pt = mapFromGlobal(QPoint(windowRect_.x(), windowRect_.y())); 384 | windowRect_ = QRect(temp_pt.x(), temp_pt.y(), 385 | windowRect_.width(), windowRect_.height()); 386 | ::EnableWindow((HWND)winId(), TRUE); 387 | amplifierTool_->onSizeChange(windowRect_.width(),windowRect_.height()); 388 | emit findChildWind(windowRect_); 389 | update(); 390 | } 391 | 392 | void OEScreenshot::keyPressEvent(QKeyEvent *e) { 393 | /// Esc 键退出截图; 394 | if (e->key() == Qt::Key_Escape) { 395 | close(); 396 | } 397 | else { 398 | e->ignore(); 399 | } 400 | 401 | } 402 | 403 | 404 | 405 | /////////////////////////////////////////////////////////// 406 | 407 | 408 | 409 | 410 | OERect::OERect(QWidget *parent) : QWidget(parent) { 411 | 412 | /// 设置感知器默认大小 413 | setFixedSize(95 * OECommonHelper::getWindowHeightMultiplyingPower(), 414 | 20 * OECommonHelper::getWindowHeightMultiplyingPower()); 415 | 416 | /// 填充默认背景 417 | backgroundPixmap_.reset(new QPixmap(width(),height())); 418 | backgroundPixmap_->fill((QColor(8, 8, 8, 160))); 419 | 420 | /// 默认隐藏 421 | hide(); 422 | } 423 | 424 | 425 | void OERect::paintEvent(QPaintEvent *) { 426 | QPainter painter(this); 427 | painter.drawPixmap(rect(),*backgroundPixmap_); 428 | painter.setPen(QPen(QColor(Qt::white))); 429 | painter.drawText(rect(), Qt::AlignCenter, info_); 430 | } 431 | 432 | void OERect::onPostionChange(int x, int y) { 433 | if (x < 0) x = 0; 434 | if (y < 0) y = 0; 435 | const int& ry = y - height() - 1; 436 | if (ry < 0) { 437 | this->raise(); 438 | } 439 | move(x, ((ry < 0) ? y : ry)); 440 | show(); 441 | } 442 | 443 | void OERect::onSizeChange(int w, int h) { 444 | info_ = QString("%1 × %2").arg(w).arg(h); 445 | } 446 | 447 | 448 | 449 | 450 | /////////////////////////////////////////////////////////// 451 | 452 | 453 | 454 | 455 | 456 | OEScreen::OEScreen(std::shared_ptr originPainting, QPoint pos, QWidget *parent) 457 | : QWidget(parent), direction_(NONE), originPoint_(pos), 458 | isPressed_(false), originPainting_(originPainting) { 459 | menu_ = new QMenu(this); 460 | menu_->addAction(QStringLiteral("完成截图"), this, SLOT(onSaveScreen())); 461 | menu_->addAction(QStringLiteral("保存"), this, SLOT(onSaveScreenOther())); 462 | menu_->addSeparator(); 463 | menu_->addAction(QStringLiteral("退出截图"), this, SLOT(quitScreenshot())); 464 | 465 | /// 双击即完成 466 | connect(this, SIGNAL(doubleClick()), 467 | this, SLOT(onSaveScreen())); 468 | 469 | /// 开启鼠标实时追踪 470 | setMouseTracking(true); 471 | /// 默认隐藏 472 | hide(); 473 | } 474 | 475 | OEScreen::DIRECTION OEScreen::getRegion(const QPoint &cursor) { 476 | if (!isInit_) { 477 | return NONE; 478 | } 479 | OEScreen::DIRECTION ret_dir = NONE; 480 | // left upper 481 | QPoint pt_lu = mapToParent(rect().topLeft()); 482 | // right lower 483 | QPoint pt_rl = mapToParent(rect().bottomRight()); 484 | 485 | int x = cursor.x(); 486 | int y = cursor.y(); 487 | 488 | /// 获得鼠标当前所处窗口的边界方向 489 | if(pt_lu.x() + PADDING_ >= x 490 | && pt_lu.x() <= x 491 | && pt_lu.y() + PADDING_ >= y 492 | && pt_lu.y() <= y) { 493 | // 左上角 494 | ret_dir = LEFTUPPER; 495 | this->setCursor(QCursor(Qt::SizeFDiagCursor)); 496 | } else if(x >= pt_rl.x() - PADDING_ 497 | && x <= pt_rl.x() 498 | && y >= pt_rl.y() - PADDING_ 499 | && y <= pt_rl.y()) { 500 | // 右下角 501 | ret_dir = RIGHTLOWER; 502 | this->setCursor(QCursor(Qt::SizeFDiagCursor)); 503 | } else if(x <= pt_lu.x() + PADDING_ 504 | && x >= pt_lu.x() 505 | && y >= pt_rl.y() - PADDING_ 506 | && y <= pt_rl.y()) { 507 | // 左下角 508 | ret_dir = LEFTLOWER; 509 | this->setCursor(QCursor(Qt::SizeBDiagCursor)); 510 | } else if(x <= pt_rl.x() 511 | && x >= pt_rl.x() - PADDING_ 512 | && y >= pt_lu.y() 513 | && y <= pt_lu.y() + PADDING_) { 514 | // 右上角 515 | ret_dir = RIGHTUPPER; 516 | this->setCursor(QCursor(Qt::SizeBDiagCursor)); 517 | } else if(x <= pt_lu.x() + PADDING_ 518 | && x >= pt_lu.x()) { 519 | // 左边 520 | ret_dir = LEFT; 521 | this->setCursor(QCursor(Qt::SizeHorCursor)); 522 | } else if( x <= pt_rl.x() 523 | && x >= pt_rl.x() - PADDING_) { 524 | // 右边 525 | ret_dir = RIGHT; 526 | this->setCursor(QCursor(Qt::SizeHorCursor)); 527 | }else if(y >= pt_lu.y() 528 | && y <= pt_lu.y() + PADDING_){ 529 | // 上边 530 | ret_dir = UPPER; 531 | this->setCursor(QCursor(Qt::SizeVerCursor)); 532 | } else if(y <= pt_rl.y() 533 | && y >= pt_rl.y() - PADDING_) { 534 | // 下边 535 | ret_dir = LOWER; 536 | this->setCursor(QCursor(Qt::SizeVerCursor)); 537 | }else { 538 | // 默认 539 | ret_dir = NONE; 540 | this->setCursor(QCursor(Qt::SizeAllCursor)); 541 | } 542 | return ret_dir; 543 | } 544 | 545 | 546 | void OEScreen::contextMenuEvent(QContextMenuEvent *) { 547 | /// 在鼠标位置弹射出菜单栏 548 | menu_->exec(cursor().pos()); 549 | } 550 | 551 | void OEScreen::mouseDoubleClickEvent(QMouseEvent *e) { 552 | if (e->button() == Qt::LeftButton) { 553 | emit doubleClick(); 554 | e->accept(); 555 | } 556 | } 557 | 558 | void OEScreen::mousePressEvent(QMouseEvent *e) { 559 | if (e->button() == Qt::LeftButton) { 560 | isPressed_ = true; 561 | if(direction_ != NONE) { 562 | this->mouseGrabber(); 563 | } 564 | /// @bug :这里可能存在问题, 不应当使用globalPos 565 | movePos_ = e->globalPos() - pos(); 566 | } 567 | } 568 | 569 | void OEScreen::mouseReleaseEvent(QMouseEvent * e) { 570 | if (e->button() == Qt::LeftButton) { 571 | isPressed_ = false; 572 | if(direction_ != NONE) { 573 | setCursor(QCursor(Qt::SizeAllCursor)); 574 | } 575 | } 576 | } 577 | 578 | void OEScreen::mouseMoveEvent(QMouseEvent * e) { 579 | QPoint gloPoint = mapToParent(e->pos()); 580 | // left upper 581 | QPoint pt_lu = mapToParent(rect().topLeft()); 582 | // left lower 583 | QPoint pt_ll = mapToParent(rect().bottomLeft()); 584 | // right lower 585 | QPoint pt_rl = mapToParent(rect().bottomRight()); 586 | // right upper 587 | QPoint pt_ru = mapToParent(rect().topRight()); 588 | if(!isPressed_) { 589 | /// 检查鼠标鼠标方向 590 | direction_ = getRegion(gloPoint); 591 | 592 | /// 根据方位判断拖拉对应支点 593 | switch(direction_) { 594 | case NONE: 595 | case RIGHT: 596 | case RIGHTLOWER: 597 | originPoint_ = pt_lu; 598 | break; 599 | case RIGHTUPPER: 600 | originPoint_ = pt_ll; 601 | break; 602 | case LEFT: 603 | case LEFTLOWER: 604 | originPoint_ = pt_ru; 605 | break; 606 | case LEFTUPPER: 607 | case UPPER: 608 | originPoint_ = pt_rl; 609 | break; 610 | case LOWER: 611 | originPoint_ = pt_lu; 612 | break; 613 | } 614 | } 615 | else { 616 | if(direction_ != NONE) { 617 | const int& global_x = gloPoint.x(); 618 | #ifndef QT_NO_DEBUG 619 | qDebug() << "OEScreen::" << __FUNCTION__ << "call onMouseChange()"; 620 | #endif 621 | /// 鼠标进行拖拉拽 622 | switch(direction_) { 623 | case LEFT: 624 | return onMouseChange(global_x, pt_ll.y() + 1); 625 | case RIGHT: 626 | return onMouseChange(global_x, pt_rl.y() + 1); 627 | case UPPER: 628 | return onMouseChange(pt_lu.x(), gloPoint.y()); 629 | case LOWER: 630 | return onMouseChange(pt_rl.x() + 1, gloPoint.y()); 631 | case LEFTUPPER: 632 | case RIGHTUPPER: 633 | case LEFTLOWER: 634 | case RIGHTLOWER: 635 | return onMouseChange(global_x, gloPoint.y()); 636 | default: 637 | break; 638 | } 639 | } 640 | else { 641 | /// 窗口的移动 642 | /// @bug :这里可能存在问题, 不应当使用globalPos 643 | move(e->globalPos() - movePos_); 644 | movePos_ = e->globalPos() - pos(); 645 | #ifndef QT_NO_DEBUG 646 | qDebug() << "OEScreen::" << __FUNCTION__ << pos(); 647 | #endif 648 | } 649 | } 650 | currentRect_ = geometry(); 651 | } 652 | 653 | void OEScreen::moveEvent(QMoveEvent *) { 654 | emit postionChange(x(), y()); 655 | } 656 | 657 | void OEScreen::resizeEvent(QResizeEvent *) { 658 | listMarker_.clear(); 659 | 660 | /// 重新计算八个锚点 661 | // 角点 662 | listMarker_.push_back(QPoint(0, 0)); 663 | listMarker_.push_back(QPoint(width(), 0)); 664 | listMarker_.push_back(QPoint(0, height())); 665 | listMarker_.push_back(QPoint(width(), height())); 666 | 667 | // 中点 668 | listMarker_.push_back(QPoint((width() >> 1), 0)); 669 | listMarker_.push_back(QPoint((width() >> 1), height())); 670 | listMarker_.push_back(QPoint(0, (height() >> 1))); 671 | listMarker_.push_back(QPoint(width(), (height() >> 1))); 672 | 673 | emit sizeChange(width(), height()); 674 | } 675 | 676 | void OEScreen::showEvent(QShowEvent *) { 677 | isInit_ = true; 678 | } 679 | 680 | void OEScreen::hideEvent(QHideEvent *) { 681 | currentRect_ = {}; 682 | movePos_ = {}; 683 | originPoint_ = {}; 684 | isInit_ = false; 685 | } 686 | 687 | void OEScreen::enterEvent(QEvent *e) { 688 | setCursor(Qt::SizeAllCursor); 689 | QWidget::enterEvent(e); 690 | } 691 | 692 | void OEScreen::leaveEvent(QEvent *e) { 693 | setCursor(Qt::ArrowCursor); 694 | QWidget::leaveEvent(e); 695 | } 696 | 697 | void OEScreen::closeEvent(QCloseEvent *) 698 | { 699 | isInit_ = false; 700 | } 701 | 702 | void OEScreen::paintEvent(QPaintEvent *) { 703 | QPainter painter(this); 704 | /// 绘制截屏编辑窗口 705 | painter.drawPixmap(QPoint(0,0), 706 | *originPainting_, currentRect_); 707 | 708 | /// 绘制边框线 709 | QPen pen(QColor(0,174,255),2); 710 | painter.setPen(pen); 711 | painter.drawRect(rect()); 712 | 713 | /// 绘制八个点 714 | //改变点的宽度 715 | pen.setWidth(4); 716 | pen.setColor(Qt::red); 717 | painter.setPen(pen); 718 | painter.drawPoints(listMarker_); 719 | } 720 | 721 | 722 | const QString OEScreen::getFileName(void) { 723 | QString file_name = QDateTime::currentDateTime(). 724 | toString(QStringLiteral("CSDN博客_瓯裔_yyyy-MM-dd-HH-mm-ss")); 725 | return file_name; 726 | } 727 | 728 | 729 | void OEScreen::onSaveScreenOther(void) { 730 | 731 | QString fileName = QFileDialog::getSaveFileName(this, 732 | QStringLiteral("保存图片"), 733 | getFileName(), "JPEG Files (*.jpg)"); 734 | 735 | if (fileName.length() > 0) { 736 | originPainting_->copy(currentRect_).save(fileName, "jpg"); 737 | quitScreenshot(); 738 | } 739 | } 740 | 741 | void OEScreen::onSaveScreen(void) { 742 | /// 把图片放入剪切板 743 | QClipboard *board = QApplication::clipboard(); 744 | board->setPixmap(originPainting_->copy(currentRect_)); 745 | /// 退出当前截图工具 746 | quitScreenshot(); 747 | } 748 | 749 | 750 | void OEScreen::quitScreenshot(void) { 751 | close(); 752 | parentWidget()->close(); 753 | } 754 | 755 | void OEScreen::onMouseChange(int x, int y) { 756 | show(); 757 | if (x < 0 || y < 0) { 758 | return; 759 | } 760 | const int& rx = (x >= originPoint_.x()) ? originPoint_.x() : x; 761 | const int& ry = (y >= originPoint_.y()) ? originPoint_.y() : y; 762 | const int& rw = abs(x - originPoint_.x()); 763 | const int& rh = abs(y - originPoint_.y()); 764 | 765 | /// 改变大小 766 | currentRect_ = QRect(rx, ry, rw, rh); 767 | 768 | this->setGeometry(currentRect_); 769 | /// 改变大小后更新父窗口,防止父窗口未及时刷新而导致的问题 770 | parentWidget()->update(); 771 | } 772 | 773 | 774 | extern "C" void OEScreenshot(void) { 775 | OEScreenshot::Instance(); 776 | } 777 | -------------------------------------------------------------------------------- /src/OE/oescreenshot/oescreenshot.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @author : 陈鲁勇 3 | * @date : 2017年04月 4 | * @version: 1.0 5 | * @note : 根据 Apache 许可证 2.0 版(以下简称“许可证”)授权; 6 | * 除非遵守本许可,否则您不能使用这个文件。 7 | * @remarks: 您可以获得该许可的副本: 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 除非适用法律需要或者书面同意,按本许可分发的软件 10 | * 要按“原样”分发,没有任何形式的,明确或隐含的担保条款。 11 | * 参见按照本许可控制许可权限及限制的特定语言的许可证。 12 | * 13 | * 你可以获得该代码的最新版本: 14 | * 15 | * https://git.oschina.net/Mr_ChenLuYong/screenshot 16 | * 17 | * 开源社区的所有人都期待与你的共同维护。 18 | * 19 | * 20 | * 如果你对这些代码还有不理解的地方可以通过最新的文章进行学习: 21 | * 22 | * 博客地址:http://blog.csdn.net/csnd_ayo 23 | * 24 | * 文章地址:http://blog.csdn.net/csnd_ayo/article/details/70197915 25 | * 26 | * 期待你提交Bug,欢迎Issues。 27 | * 28 | */ 29 | 30 | 31 | #ifndef OESCREENSHOT_H 32 | #define OESCREENSHOT_H 33 | 34 | #include 35 | #include 36 | #include 37 | 38 | class OEScreen; 39 | class OERect; 40 | class OEAmplifier; 41 | class QTimer; 42 | class QMenu; 43 | 44 | 45 | /** 46 | * @class : OEScreenshot 47 | * @brief : 截屏功能的主要入口, 48 | * 管理全局热键,资源的回收与释放. 49 | * @remark: 调用示例( OEScreenshot::Instance(); ) 50 | */ 51 | class OEScreenshot : public QWidget { 52 | Q_OBJECT 53 | 54 | signals: 55 | 56 | /** 57 | * @brief : 鼠标移动(信号) 58 | * @param : int x轴的坐标 59 | * @param : int y轴的坐标 60 | * @date : 2017年04月18日 61 | */ 62 | void cursorPosChange(int, int); 63 | 64 | /** 65 | * @brief : 双击(信号) 66 | * @date : 2017年04月18日 67 | */ 68 | void doubleClick(void); 69 | 70 | /** 71 | * @brief : 鼠标当前位置最小的子窗口(信号) 72 | * @param : QRect 当前窗口的矩形数据 73 | * @date : 2017年04月18日 74 | */ 75 | void findChildWind(QRect); 76 | 77 | public: 78 | /** 79 | * @brief : 构造函数 80 | * @note : 当前依附的父窗口(一般不给父窗口) 81 | * @date : 2017年04月16日 82 | */ 83 | explicit OEScreenshot(QWidget *parent = 0); 84 | ~OEScreenshot(void); 85 | 86 | /** 87 | * @brief : 窗口实例 88 | * @note : 通过这个函数获得截图器的整个实例 89 | * @return: 返回 OEScreenshot 实例指针 90 | * @date : 2017年04月15日 91 | */ 92 | static OEScreenshot *Instance(void); 93 | 94 | /** 95 | * @brief : 摧毁截图窗口 96 | * @note : 通过这个函数可以摧毁整个截图窗口 97 | * @date : 2017年04月30日 98 | */ 99 | static void destroy(void); 100 | 101 | protected: 102 | 103 | /** 104 | * @brief : 隐藏窗口事件 105 | */ 106 | virtual void hideEvent(QHideEvent *); 107 | /** 108 | * @brief : 关闭窗口事件 109 | */ 110 | virtual void closeEvent(QCloseEvent *); 111 | /** 112 | * @brief : 双击事件 113 | */ 114 | virtual void mouseDoubleClickEvent(QMouseEvent*); 115 | /** 116 | * @brief : 鼠标按下事件 117 | */ 118 | virtual void mousePressEvent(QMouseEvent *); 119 | /** 120 | * @brief : 鼠标释放事件 121 | */ 122 | virtual void mouseReleaseEvent(QMouseEvent *e); 123 | /** 124 | * @brief : 鼠标移动事件 125 | */ 126 | virtual void mouseMoveEvent(QMouseEvent *e); 127 | 128 | /** 129 | * @brief : 按键按下事件 130 | */ 131 | virtual void keyPressEvent(QKeyEvent *e); 132 | /** 133 | * @brief : 自绘事件 134 | */ 135 | virtual void paintEvent(QPaintEvent *); 136 | 137 | /** 138 | * @brief : 更新当前鼠标选区的窗口 139 | */ 140 | void updateMouse(void); 141 | 142 | private: 143 | 144 | 145 | /** 146 | * @brief : 初始化放大镜 (色彩采集器) 147 | * @note : 他需要屏幕的原画作为放大器的放大元素 148 | * @param : originPainting 放大器必要的元素,若为空,则默认用originPainting_原画 149 | * @date : 2017年04月15日 150 | * @remark: 需先行调用getGlobalScreen。 151 | */ 152 | void initAmplifier(std::shared_ptr originPainting = nullptr); 153 | 154 | /** 155 | * @brief : 测量控件 (大小感知器) 156 | * @date : 2017年04月27日 157 | */ 158 | void initMeasureWidget(void); 159 | 160 | /** 161 | * @brief : 初始化截屏背景 162 | * @return: QPixmap 经过暗色处理的屏幕图 163 | * @date : 2017年04月15日 164 | */ 165 | std::shared_ptr initGlobalScreen(void); 166 | 167 | 168 | /** 169 | * @brief : 初始化鼠标 170 | * @note : 为鼠标设置默认状态下的图标样式 171 | * @param : ico 鼠标图片的资源文件路径 172 | * @date : 2017年04月15日 173 | * @remark: 若参数未填写,在使用本程序默认的鼠标Logo 174 | */ 175 | void initCursor(const QString& ico = ""); 176 | 177 | /** 178 | * @brief : 创建截图器 179 | * @note : 若截图器已存在,则返回截图器示例,不会重复创建。 180 | * @param : pos 截图器的起始位置 (给当前鼠标位置即可) 181 | * @date : 2017年04月16日 182 | * @remark: 创建截图器前,需要创建相关的组件,(例:大小感知器,放大取色器) 183 | */ 184 | std::shared_ptr createScreen(const QPoint &pos); 185 | 186 | /** 187 | * @brief : 摧毁截图器 188 | * @note : 若截图器已存在,则摧毁示例,并清理示例创建的连带资源 189 | * @date : 2017年04月16日 190 | */ 191 | void destroyScreen(void); 192 | 193 | 194 | /** 195 | * @brief : 获得当前屏幕的大小 196 | * @note : 这个函数是支持多屏幕的,示例:双屏幕 QRect(-1920, 0, 3840, 1080) 197 | * @return: 返回 QRect 引用 198 | * @date : 2017年04月15日 199 | */ 200 | const QRect& getScreenRect(void); 201 | 202 | /** 203 | * @brief : 获得屏幕的原画 204 | * @note : 他不会重复获得屏幕原画,如果有,则返回原有的原画 205 | * @return: QPixmap* 指针 206 | * @date : 2017年04月15日 207 | * @remark: 若想重新获得屏幕原画,需要清理原有资源 208 | */ 209 | std::shared_ptr getGlobalScreen(void); 210 | 211 | 212 | private: 213 | 214 | /// 截屏窗口是否已经展示 215 | bool isLeftPressed_; 216 | /// 用于检测误操作 217 | QPoint startPoint_; 218 | /// 当前桌面屏幕的矩形数据 219 | QRect desktopRect_; 220 | /// 屏幕暗色背景图 221 | std::shared_ptr backgroundScreen_; 222 | /// 屏幕原画 223 | std::shared_ptr originPainting_; 224 | /// 截图屏幕 225 | std::shared_ptr screenTool_; 226 | /// 截图器大小感知器 227 | std::shared_ptr rectTool_; 228 | /// 放大取色器 229 | std::shared_ptr amplifierTool_; 230 | /// 当前鼠标选区最小的矩形窗口 231 | QRect windowRect_; 232 | /// 截屏实例对象 233 | static OEScreenshot *self_; 234 | /// 置顶定时器 235 | QTimer *egoisticTimer_; 236 | /// 活动窗口 237 | static bool isActivity_; 238 | private slots: 239 | 240 | /** 241 | * @brief : Window下霸道置顶(唯我独尊) 242 | * @date : 2017年04月28日 243 | * @remark: 使用该函数时,会终止右键菜单的行为,慎重使用,避免BUG 244 | */ 245 | void onEgoistic(void); 246 | }; 247 | 248 | 249 | 250 | 251 | /** 252 | * @class : OERect 253 | * @brief : 大小感知器 254 | * @note : 主要关乎截图器左上方的大小感知控件 255 | */ 256 | class OERect : public QWidget { 257 | Q_OBJECT 258 | 259 | signals: 260 | 261 | 262 | public: 263 | 264 | explicit OERect(QWidget *parent = 0); 265 | 266 | protected: 267 | 268 | /** 269 | * @brief : 自绘函数 270 | */ 271 | void paintEvent(QPaintEvent *); 272 | 273 | public slots: 274 | 275 | /** 276 | * @brief : 外部组件位置修改(槽) 277 | * @note : 感知器修改自身位置 278 | * @param : x 横向位置 279 | * @param : y 纵向位置 280 | * @date : 2017年04月15日 281 | */ 282 | void onPostionChange(int x, int y); 283 | 284 | /** 285 | * @brief : 外部组件大小修改 (槽) 286 | * @note : 感知器修改显示的大小数据 287 | * @param : w 宽度 288 | * @param : h 高度 289 | * @date : 2017年04月15日 290 | */ 291 | void onSizeChange(int w, int h); 292 | 293 | private: 294 | /// 背景色 295 | std::shared_ptr backgroundPixmap_; 296 | /// 显示的文字信息 297 | QString info_; 298 | }; 299 | 300 | 301 | /** 302 | * @class : OEScreen 303 | * @brief : 截图器 304 | * @note : 主要关乎图片的编辑与保存 305 | */ 306 | class OEScreen : public QWidget { 307 | 308 | Q_OBJECT 309 | 310 | signals: 311 | 312 | 313 | /** 314 | * @brief : 截图器大小修改(信号) 315 | * @param : int 宽度 316 | * @param : int 高度 317 | * @date : 2017年04月17日 318 | */ 319 | void sizeChange(int,int); 320 | 321 | /** 322 | * @brief : 截图器窗口的位置(信号) 323 | * @param : int 窗口的横向位置 324 | * @param : int 窗口的纵向位置 325 | * @date : 2017年04月17日 326 | */ 327 | void postionChange(int,int); 328 | 329 | /** 330 | * @brief : 双击 (信号) 331 | * @date : 2017年04月17日 332 | */ 333 | void doubleClick(void); 334 | 335 | protected: 336 | 337 | /// 内边距,决定拖拽的触发。 338 | const int PADDING_ = 6; 339 | 340 | /// 方位枚举 341 | enum DIRECTION { 342 | UPPER=0, 343 | LOWER=1, 344 | LEFT, 345 | RIGHT, 346 | LEFTUPPER, 347 | LEFTLOWER, 348 | RIGHTLOWER, 349 | RIGHTUPPER, 350 | NONE 351 | }; 352 | 353 | public: 354 | 355 | explicit OEScreen(std::shared_ptr originPainting, QPoint pos, QWidget *parent = 0); 356 | 357 | ~OEScreen() { isInit_ = false; } 358 | 359 | /** 360 | * @brief : 获得当前截图器是否存在 361 | * @return: true : 存在 362 | * @date : 2017年04月17日 363 | */ 364 | static bool state(void) { return isInit_; } 365 | 366 | protected: 367 | 368 | /** 369 | * @brief : 获得当前坐标点的边界方位 370 | * @param : cursor 当前鼠标的位置 371 | * @return: DIRECTION 鼠标的方位枚举 372 | * @date : 2017年04月17日 373 | */ 374 | DIRECTION getRegion(const QPoint &cursor); 375 | 376 | 377 | /** 378 | * @brief : 呼出菜单事件 379 | */ 380 | virtual void contextMenuEvent(QContextMenuEvent *); 381 | 382 | /** 383 | * @brief : 双击事件 384 | */ 385 | virtual void mouseDoubleClickEvent(QMouseEvent *e); 386 | 387 | /** 388 | * @brief : 鼠标按下事件 389 | */ 390 | virtual void mousePressEvent(QMouseEvent *e); 391 | 392 | /** 393 | * @brief : 鼠标释放事件 394 | */ 395 | virtual void mouseReleaseEvent(QMouseEvent *e); 396 | /** 397 | * @brief : 鼠标移动事件 398 | */ 399 | virtual void mouseMoveEvent(QMouseEvent *e); 400 | 401 | /** 402 | * @brief : 窗口移动事件 403 | */ 404 | virtual void moveEvent(QMoveEvent *); 405 | 406 | /** 407 | * @brief : 窗口大小修改事件 408 | */ 409 | virtual void resizeEvent(QResizeEvent *); 410 | 411 | 412 | /** 413 | * @brief : 窗口显示事件 414 | */ 415 | virtual void showEvent(QShowEvent *); 416 | 417 | /** 418 | * @brief : 窗口隐藏事件 419 | */ 420 | virtual void hideEvent(QHideEvent *); 421 | 422 | /** 423 | * @brief : 鼠标进入窗口事件 424 | */ 425 | virtual void enterEvent(QEvent *e); 426 | 427 | /** 428 | * @brief : 鼠标离开窗口事件 429 | */ 430 | virtual void leaveEvent(QEvent *e); 431 | 432 | /** 433 | * @brief : 窗口关闭事件 434 | */ 435 | virtual void closeEvent(QCloseEvent *); 436 | 437 | /** 438 | * @brief : 界面自绘事件 439 | */ 440 | virtual void paintEvent(QPaintEvent *); 441 | 442 | private: 443 | 444 | /** 445 | * @brief : 获得一个以时间格式命名的文件名 446 | * @return: QString 文件名 447 | * @date : 2017年04月16日 448 | */ 449 | virtual const QString getFileName(void); 450 | 451 | public slots: 452 | 453 | 454 | /** 455 | * @brief : 根据鼠标位置修改窗口大小 456 | * @param : x 鼠标的横向位置 457 | * @param : y 鼠标的纵向位置 458 | * @date : 2017年04月16日 459 | */ 460 | void onMouseChange(int x,int y); 461 | 462 | /** 463 | * @brief : 保存屏幕到剪切板中 464 | * @date : 2017年04月16日 465 | */ 466 | void onSaveScreen(void); 467 | 468 | protected slots: 469 | 470 | /** 471 | * @brief : 保存编辑屏幕到其他路径下 472 | * @note : 会呼出路径选择的窗口 473 | * @date : 2017年04月16日 474 | */ 475 | void onSaveScreenOther(void); 476 | 477 | /** 478 | * @brief : 退出当前截图窗口 479 | * @date : 2017年04月16日 480 | */ 481 | void quitScreenshot(void); 482 | 483 | private: 484 | 485 | /// 是否已经设置初始大小 486 | static bool isInit_; 487 | /// 窗口大小改变时,记录改变方向 488 | DIRECTION direction_; 489 | /// 起点 490 | QPoint originPoint_; 491 | /// 鼠标是否按下 492 | bool isPressed_; 493 | /// 拖动的距离 494 | QPoint movePos_; 495 | /// 标记锚点 496 | QPolygon listMarker_; 497 | /// 屏幕原画 498 | std::shared_ptr originPainting_; 499 | /// 当前窗口几何数据 用于绘制截图区域 500 | QRect currentRect_; 501 | /// 右键菜单对象 502 | QMenu *menu_; 503 | 504 | }; 505 | 506 | 507 | 508 | #endif /// OESCREENSHOT_H 509 | -------------------------------------------------------------------------------- /src/OEScreenshotLib.pro: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chenluyong/OEasyScreenshot/4490539e3eb57bab4f93ebc3559d0641329e2e7f/src/OEScreenshotLib.pro -------------------------------------------------------------------------------- /src/Readme.md: -------------------------------------------------------------------------------- 1 | - 注:当前源码MinGW为实时更新的版本,MSVC同步性不高,建议使用MinGW,或妥善修改MSVC。 2 | - 详情查看 doc/build 目录下的文档 3 | 4 | 5 | 该文件夹包含了OEScreenshot核心文件。 6 | 7 | 通过加载 OEScreenshot 即可直接使用。 8 | 9 | /** 10 | 11 | * @brief : 窗口实例 12 | 13 | * @note : 通过这个函数获得截图器的整个实例 14 | 15 | * @return: 返回 OEScreenshot 实例指针 16 | 17 | * @date : 2017年04月15日 18 | 19 | */ 20 | static OEScreenshot *Instance(void); 21 | 22 | /** 23 | 24 | * @brief : 摧毁截图窗口 25 | 26 | * @note : 通过这个函数可以摧毁整个截图窗口 27 | 28 | * @date : 2017年04月30日 29 | 30 | */ 31 | static void destroy(void); 32 | 33 | 34 | 当前库秉承简单、独立的设计原则。 35 | 36 | 37 | 调用 Instance() 直接启动截图工具。 38 | 39 | (单例模式:若截图工具已经启动,不会重复启动) 40 | 41 | --------------------------------------------------------------------------------