JCEF3——谷歌浏览器内核Java版实现(一):使用jawt获取窗体句柄
前言
最近一段时间研究谷歌浏览器内核。谷歌浏览器内核一直开源,并维护更新,它的开源项目中内核更新速度和Chrome浏览器版本更新进度一样!而且它不同于WebKit(值得一题的是谷歌浏览器已不使用WebKit内核了),它提供的不仅仅是页面渲染,而是提供一整浏览器解决方案和插件规则。
使用方便:我们给它一个“窗体”(操作系统或系统资源管理器中的本地窗体,本系列都使用Win32平台作为示例)和一些配置参数,它就能将你需要渲染的页面在给定窗口中完美地展示。
插件支持:Adobe和Google联合开发的pepperflashplayer功能完善,而且我们作为进程外插件安装的话可以不用考虑它的自动升级给用户造成困扰或我们开发中的版本变化。而你只需要一句代码即可完成插件的启用,获取和升级插件方式也很简单(先在电脑上装一个chrome浏览器,去安装目录下copy:-_-)。谷歌对pdf的插件也可以这样。
这个随笔系列主要使用Java给谷歌浏览套一个壳。因为cef(即“谷歌浏览器内核chromium embedded framework”,后文都使用cef作为简称,并且本系列都使用cef3)使用c/c++编写,并未直接提供Java语言API,虽然有Java版的一个维护版本,但本人认为并不好用。
获取AWT窗体句柄
我们今天要做的跟cef内核还没太大关系,我们先解决一个问题:获取Java窗体的句柄。
我们都知道:Java语言提供的GUI支持是建立在操作系统资源管理系统(或者桌面环境)的支持上的(在Java的2D/GUI中,最外层的窗体肯定是操作系统相关的),那么很简单的道理,我们可以使用JNI的一些API来获取窗体句柄。
- jni?
JNI是Java语言提供的本地化代码调用接口(在Java虚拟机里实际上不在乎下一个方法入口是内部指针还是外部-操作系统指针),我们可以写一个c/c++的函数去找到窗体句柄,然后返回给Java虚拟机,让我们在虚拟机内部也知晓某个Java窗体被操作系统分配的句柄。
- jawt
Java官方已经考虑到我们这种需求了,它提供了一个接口:jawt。包括一系列c/c++包含(头文件.h,平台相关)和一系列c/c++静态库文件。
具体包括jawt.h、jawt_md.h、jawt.lib(另外jni.h以及jni_md.h是使用jni必须的)
- javah
编写动态链接库(dll)需要使用c/c++头文件与c/++源文件联合编译。我们先使用JDK自带的javah工具(javah.exe)生成一个头文件并实现它。
当然,我们先写一个Java类,标注其native方法。
1 /* 2 * Copyright 2014 JootMir Project3 * Licensed under the Apache License, Version 2.0 (the "License");4 * you may not use this file except in compliance with the License.5 * You may obtain a copy of the License at6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 * Unless required by applicable law or agreed to in writing, software10 * distributed under the License is distributed on an "AS IS" BASIS,11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12 * See the License for the specific language governing permissions and13 * limitations under the License.14 *15 * Support:http://www.cnblogs.com/johness 16 */ 17 packagejohness.jcef3.util;18 19 importjavax.swing.JFrame;20 21 /** 22 * AWT工具集23 *24 *@authorShawRyan25 */ 26 public final classAWTUtil {27 /** 28 * 获取某个窗体句柄(在Windows平台下)29 *30 *@paramwindow31 * 需要获取句柄的窗体对象32 *@return窗体应用句柄33 */ 34 public static native intgetWindowHandleInWindows(JFrame window);35 }
AWTUtil
然后使用javah生成其对应头文件。
头文件内容如下:
/*DO NOT EDIT THIS FILE - it is machine generated*/#include<jni.h> /*Header for class johness_jcef3_util_AWTUtil*/#ifndef _Included_johness_jcef3_util_AWTUtil#define _Included_johness_jcef3_util_AWTUtil#ifdef __cplusplusextern "C"{#endif /** Class: johness_jcef3_util_AWTUtil* Method: getWindowHandleInWindows* Signature: (Ljavax/swing/JFrame;)I*/JNIEXPORT jint JNICALL Java_johness_jcef3_util_AWTUtil_getWindowHandleInWindows(JNIEnv*, jclass, jobject);#ifdef __cplusplus }#endif #endif
jni细则我就不赘述了。
- visual studio
接下来我们使用c++代码来实现接口函数并编译为动态链接库。
经典的VC++6.0或者优秀的Dev C++我都不喜欢使用,我就用Visual Studio 2012来编写并编译吧。
建立项目
删除一切我们不需要(我们就没有需要的-_-)文件
复制jni和jawt相关头文件及库文件到项目中(值得一题的是不是说让你复制粘贴到vs窗体内,而是真正复制到你c++项目文件夹内)
%JAVA_HOME%\include\jni.h
%JAVA_HOME%\include\jawt.h
%JAVA_HOME%\include\jni_md.h
%JAVA_HOME%\include\jawt_md.h
%JAVA_HOME%\lib\jawt.lib
你项目中的那个头文件
配置项目
配置项目为Release
配置项目使用jawt.lib静态库
更改头文件,把#include <jni.h>改为#include "jni.h"
(后面的竖线是光标)
写源文件
(创建好源文件并准备开始编写代码之前取消源文件预编译头)
开始编码(jawt.h里有使用示例,我们照着改)
1 #include "jni.h" 2 #include "jawt_md.h" 3 #include "johness_jcef3_util_AWTUtil.h" 4 5 JNIEXPORT jint JNICALL Java_johness_jcef3_util_AWTUtil_getWindowHandleInWindows (JNIEnv *env, jclass sender, jobject window) {6 HWND hwnd =NULL;7 8 JAWT_DrawingSurface *ds;9 JAWT_DrawingSurfaceInfo *dsi;10 JAWT_Win32DrawingSurfaceInfo *win;11 12 JAWT awt;13 awt.version =JAWT_VERSION_1_3;14 15 jboolean result = JAWT_GetAWT(env, &awt);16 if (result ==JNI_TRUE) {17 ds =awt.GetDrawingSurface(env, window);18 jint lock = ds ->Lock(ds);19 if (lock !=JAWT_LOCK_ERROR) {20 dsi = ds ->GetDrawingSurfaceInfo(ds);21 win = (JAWT_Win32DrawingSurfaceInfo *) dsi ->platformInfo;22 23 hwnd = win ->hwnd;24 25 ds ->FreeDrawingSurfaceInfo(dsi);26 ds ->Unlock(ds);27 awt.FreeDrawingSurface(ds);28 returnjint(hwnd);29 }30 return 0;31 }32 return 0;33 }
johness_jcef3_util_AWTUtil
编译生成
- 使用或测试
把生成的dll复制到Java项目中,在项目配置中配置librarypath,然后编写测试代码。
测试代码也很简单:
packagejohness.jcef3.util;importjavax.swing.JFrame;public classMain {public static voidmain(String[] args) {System.loadLibrary("jawt");System.loadLibrary("JCEF3");JFrame frame= newJFrame();frame.setSize(400, 300);frame.setVisible(true);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);System.out.println(AWTUtil.getWindowHandleInWindows(frame));}}
最后总结
使用visual studio编译时注意不使用预编译文件头。当然如果你稍微了解vc++的话可能也不用这么麻烦。
使用visual studio编译生成的dll需要运行时环境,比如msvcr110.dll之类的。如果你机器上没有安装过的话可能会爆出“Can't find dependent libraries”这种错,可以把这些个运行时环境的库打包过去。
写于2016-03-29
本来我想自己做java-cef,不过官方已经做了,我准备做几集视频(请看java-cef系列视频)来讲解它的使用方式
联系我,一起交流
欢迎您移步我们的交流群,无聊的时候大家一起打发时间:
或者通过QQ与我联系:
(最后编辑时间2016-03-29 10:26:41)
转载于:https://www.cnblogs.com/Johness/p/jcef3part1-usejawttogetjframehandleinwindowsos.html
JCEF3——谷歌浏览器内核Java版实现(一):使用jawt获取窗体句柄相关推荐
- 第八篇 :微信公众平台开发实战Java版之如何网页授权获取用户基本信息
第一部分:微信授权获取基本信息的介绍 我们首先来看看官方的文档怎么说: 如果用户在微信客户端中访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,进而实现业务逻辑. 关于网页授权回调域 ...
- java 窗口鼠标句柄_c#获取窗体句柄模拟鼠标点击
[实例简介] c#获取窗体句柄模拟鼠标点击实例2012年8月20日23:48:21,代码清楚,有详细注释,希望对大家有用 [实例截图] [核心代码] 获取窗体句柄模拟鼠标点击 └── 获取窗体句柄模拟 ...
- 第六篇 :微信公众平台开发实战Java版之如何自定义微信公众号菜单
我们来了解一下 自定义菜单创建接口: http请求方式:POST(请使用https协议) https://api.weixin.qq.com/cgi-bin/menu/create?access_to ...
- 第三篇 :微信公众平台开发实战Java版之请求消息,响应消息以及事件消息类的封装...
微信服务器和第三方服务器之间究竟是通过什么方式进行对话的? 下面,我们先看下图: 其实我们可以简单的理解: (1)首先,用户向微信服务器发送消息: (2)微信服务器接收到用户的消息处理之后,通过开发者 ...
- 第一篇:微信公众平台开发实战Java版之了解微信公众平台基础知识以及资料准备...
相信很多人或多或少听说了微信公众平台的火热.但是开发还是有一点门槛,鉴于挺多朋友问我怎么开发,问多了,自己平时也进行以下总结. 所以下面给大家分享一下我的经验: 第一部分 介绍微信公众号的一些简单 ...
- AKKA文档(java版)——准备开始
http://ifeve.com/akka-doc-java-getting-started/ AKKA文档(java版)--准备开始 原文:http://doc.akka.io/docs/ak ...
- 常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构)
常见数据结构和算法实现(排序/查找/数组/链表/栈/队列/树/递归/海量数据处理/图/位图/Java版数据结构) 数据结构和算法作为程序员的基本功,一定得稳扎稳打的学习,我们常见的框架底层就是各类数据 ...
- 超大数相乘的java代码,java版大数相乘
在搞ACM的时候遇到大数相乘的问题,在网上找了一下,看到了一个c++版本的 用java搞了一个版本 这里说一下思路 将数字已字符串形式接收,转换成int[]整型数组,然后num1[],num2[]依次 ...
- delphi 使用cef3谷歌浏览器内核加载带header请求头的网页
上一篇博文介绍到用IE加载带Header请求头的网页,本篇介绍使用cef3实现同样的功能. 我使用的谷歌浏览器内核是49版,支持XP系统的最新版,所以,版本有够低的了. procedure TForm ...
最新文章
- [C++]键盘钩子程序
- v-show与v-if的区别
- ADO.NET Entity Framework
- C++ string 用法详解(转)
- 使用github page + Hexo搭建个人博客折腾记
- linux 桥接stp原理,Linux操作系统网桥源码框架初步分析
- java spark 环境_在 IntelliJ IDEA 中配置 Spark(Java API) 运行环境
- 用户行为分析面面观之二
- 数组分割问题(转载学习)
- C语言实现一个简单的矩阵运算器
- linux 下 g++编译程序时,-I(大写i) 与-L(大写l)-l(小写l) 的作用
- 跨国公司怎样面试应聘者
- 俺博士三年的一点体会
- 分享老齐【学方法】宽信用周期对股市的影响!
- 惜我者,我惜之; 冷我者,我弃之
- ASP.NET2.0关于BIN目录下DLL文件访问的问题
- MySQL的性能优化理论
- 苹果的黑科技:如何让按不动的触控板产生点按的感觉
- python 拦截windows弹窗广告_win10系统怎样拦截各种软件的广告弹窗
- 陶伟死因 从微博看明星