brjcomponent.cpp

来自「java调用ie浏览器demo源码,可以用在windows或者linux」· C++ 代码 · 共 1,409 行 · 第 1/3 页

CPP
1,409
字号
//////////////////////////////////
// Copyright (C) 2008 Sun Microsystems, Inc. All rights reserved. Use is
// subject to license terms.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the Lesser GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.

#include "stdafx.h" 
#include "BrJComponent.h"
#include "BrMain.h"
#include "BrHolderThread.h"
#include "windowsx.h"


//struct __declspec(uuid("BB1A2AE1-A4F9-11CF-8F20-00805F2CD064")) IActiveScript;
_COM_SMARTPTR_TYPEDEF(IActiveScript, __uuidof(IActiveScript));

//struct __declspec(uuid("BB1A2AE2-A4F9-11CF-8F20-00805F2CD064")) IActiveScriptParse;
_COM_SMARTPTR_TYPEDEF(IActiveScriptParse, __uuidof(IActiveScriptParse));


#if defined(__IHTMLDocument2_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IHTMLDocument2, __uuidof(IHTMLDocument2));
#endif// #if defined(__IHTMLDocument2_INTERFACE_DEFINED__)
#if defined(__IHTMLDocument3_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IHTMLDocument3, __uuidof(IHTMLDocument3));
#endif// #if defined(__IHTMLDocument3_INTERFACE_DEFINED__)
#if defined(__IDisplayServices_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IDisplayServices, __uuidof(IDisplayServices));
#endif// #if defined(__IDisplayServices_INTERFACE_DEFINED__)
#if defined(__IHTMLCaret_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IHTMLCaret, __uuidof(IHTMLCaret));
#endif// #if defined(__IHTMLCaret_INTERFACE_DEFINED__)
#if defined(__IHTMLWindow2_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IHTMLWindow2, __uuidof(IHTMLWindow2));
#endif// #if defined(__IHTMLWindow2_INTERFACE_DEFINED__)
#if defined(__IHTMLElement_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IHTMLElement, __uuidof(IHTMLElement));
#endif// #if defined(__IHTMLElement_INTERFACE_DEFINED__)
/*
#if defined(__IActiveScript_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IActiveScript, __uuidof(IActiveScript));
#endif// #if defined(__IActiveScript_INTERFACE_DEFINED__)
#if defined(__IActiveScriptError_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IActiveScriptError, __uuidof(IActiveScriptError));
#endif// #if defined(__IActiveScriptError_INTERFACE_DEFINED__)
*/


#if defined(__IActiveScriptParseProcedure_INTERFACE_DEFINED__)
_COM_SMARTPTR_TYPEDEF(IActiveScriptParseProcedure, __uuidof(IActiveScriptParseProcedure));
#endif// #if defined(__IActiveScriptParseProcedure_INTERFACE_DEFINED__)


jclass    BrJComponent::ms_jcidBrComponent = NULL;
jfieldID  BrJComponent::ms_jcidWBrComponent_x = NULL;
jfieldID  BrJComponent::ms_jcidWBrComponent_y = NULL;
jfieldID  BrJComponent::ms_jcidWBrComponent_width = NULL;
jfieldID  BrJComponent::ms_jcidWBrComponent_height = NULL;
jmethodID BrJComponent::ms_jcidWBrComponent_getCursor = NULL;

jfieldID  BrJComponent::ms_jcidWBrComponentPeer_data = NULL;
jfieldID  BrJComponent::ms_jcidWBrComponentPeer_target = NULL;
jmethodID BrJComponent::ms_jcidWBrComponentPeer_postEvent = NULL;
jmethodID BrJComponent::ms_jcidWBrComponentPeer_handlePaint = NULL;

jclass    BrJComponent::ms_jcidCursor = NULL;
jfieldID  BrJComponent::ms_jcidCursor_pData = NULL;

void BrJComponent::initIDs(JNIEnv *env, jclass clazz)
{
    ms_jcidBrComponent = getGlobalJavaClazz(
        env,
        "org/jdic/web/BrComponent"
    );
    ms_jcidWBrComponent_x = env->GetFieldID(ms_jcidBrComponent, "x", "I");
    ms_jcidWBrComponent_y = env->GetFieldID(ms_jcidBrComponent, "y", "I");
    ms_jcidWBrComponent_width = env->GetFieldID(ms_jcidBrComponent, "width", "I");
    ms_jcidWBrComponent_height = env->GetFieldID(ms_jcidBrComponent, "height", "I");
    ms_jcidWBrComponent_getCursor = env->GetMethodID(
        ms_jcidBrComponent, 
        "getCursor", 
        "()Ljava/awt/Cursor;");


    ms_jcidCursor = getGlobalJavaClazz(
        env,
        "java/awt/Cursor"
    );
    ms_jcidCursor_pData = env->GetFieldID(ms_jcidCursor, "pData", "J");

    ms_jcidWBrComponentPeer_postEvent = env->GetMethodID(
        clazz, 
        "postEvent", 
        "(ILjava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
    ms_jcidWBrComponentPeer_handlePaint = env->GetMethodID(
        clazz, 
        "handlePaint", 
        "(IIII)V");
    ms_jcidWBrComponentPeer_data = env->GetFieldID(clazz, "data", "J");
    ms_jcidWBrComponentPeer_target = env->GetFieldID(clazz, "target", "Lorg/jdic/web/BrComponent;");
}


/************************************************************************
 * BrJComponent methods
 */

BrJComponent::BrJComponent(
    JNIEnv *env, 
    jobject othis
)
:m_synthetic(false),
 m_bBlockNativeInputHandler(false),
 m_this(makeGlobal(env, othis)),
 m_hChildArea(CreateRectRgn(0,0,0,0)),
 m_pThread(BrowserThread::GetInstance())
{}

HRESULT BrJComponent::getTargetRect(
    JNIEnv *env, 
    LPRECT prc)
{
    jobject target = env->GetObjectField(m_this, ms_jcidWBrComponentPeer_target);
    if(NULL!=target){
        prc->left = env->GetIntField(target, ms_jcidWBrComponent_x);
        prc->top = env->GetIntField(target, ms_jcidWBrComponent_y);
        prc->right = prc->left + env->GetIntField(target, ms_jcidWBrComponent_width);
        prc->bottom = prc->top + env->GetIntField(target, ms_jcidWBrComponent_height);
        env->DeleteLocalRef(target);
        return S_OK;
    }
    return E_INVALIDARG;
}

HRESULT BrJComponent::create(    
    JNIEnv *env, 
    HWND    hParent,
    int     ePaintAlgorithm)
{
    SEP(_T("create"))
    m_ePaintAlgorithm = ePaintAlgorithm;
    STRACE(_T("paint: %04x"), ePaintAlgorithm);
    OLE_TRY
    RECT rcIE = {0};
    SetWindowLong(
        hParent, 
        GWL_STYLE, 
        GetWindowLong(hParent, GWL_STYLE) & ~(WS_CLIPCHILDREN | WS_CLIPSIBLINGS) );

    OLE_HRT( getTargetRect(
        env, 
        &rcIE))
    OLE_HRT( CreateControl(
        hParent,
        &rcIE,
        NULL))

    HWND hFO = GetFocus();
    if( GetTopWnd()==hFO || GetIEWnd()==hFO ){
        SetFocus(GetParent());
    }
    m_bTransparent = false;
    setTransparent(true);
    OLE_CATCH
    OLE_RETURN_HR
}

BrJComponent::~BrJComponent()
{
    SEP0(_T("~BrJComponent"));
    if(!bool(m_spIWebBrowser2) || NULL!=m_this){
        STRACE1(_T("alarm!"));
    }
    if(m_pThread){
        m_pThread->Release();
    }
}

void BrJComponent::destroy(JNIEnv *env)
{
    if(m_spIWebBrowser2){
        OLE_TRY
        OLE_HRT( DestroyControl() )
        OLE_CATCH
    }
    releaseGlobal(env, m_this);
    if(m_hChildArea){
        DeleteObject((HGDIOBJ)m_hChildArea);
        m_hChildArea = NULL;
    }
    m_this = NULL;
}

void BrJComponent::updateTransparentMask(LPRECT prc)
{
    if( !m_bTransparent || PAINT_NATIVE==m_ePaintAlgorithm){
        HRGN hPaintRgn = NULL;
        RECT rc;
        BOOL bRepaint = TRUE;
        /*if(NULL==prc)*/
        {
            ::GetClientRect(GetTopWnd(), &rc);
            prc = &rc;
            //STRACE1(_T("updateTransparentMask:GetClientRect(%d, %d, %d, %d)"), prc->left, prc->top, prc->right, prc->bottom);
        }
        if(NULL!=m_hChildArea){
            //STRACE1(_T("CreateRectRgn(%d, %d, %d, %d)"), prc->left, prc->top, prc->right, prc->bottom);
            hPaintRgn = CreateRectRgn(prc->left, prc->top, prc->right, prc->bottom); 
            if( NULL!=hPaintRgn && NULL!=m_hChildArea){
                CombineRgn(
                    hPaintRgn,
                    hPaintRgn,
                    m_hChildArea,
                    RGN_XOR);
            }
        }        
        SetWindowRgn(
            GetTopWnd(), 
            hPaintRgn, 
            FALSE);
    }
}

void BrJComponent::setTransparent(boolean bTransparent)
{
    if( m_bTransparent == (int)bTransparent)
        return;

    m_bTransparent = bTransparent;
    if( PAINT_NATIVE==m_ePaintAlgorithm )
        return;

    if(m_bTransparent){
        SetWindowRgn(
            GetTopWnd(), 
            CreateRectRgn(0, 0, 0, 0), 
            FALSE);
        STRACE0(_T("[]->."));
    } else {
        updateTransparentMask(NULL);
        STRACE0(_T(".->[]"));
    }
}


void BrJComponent::RedrawParentRect(LPRECT pRect)
{  
    if( PAINT_NATIVE == m_ePaintAlgorithm || (!m_bTransparent && PAINT_JAVA_NATIVE==m_ePaintAlgorithm)){
        //nothing to do
        //PaintScreenShort();
        return;
    }

    SEP(_T("BrJComponent::RedrawParentRect"));
//   STRACE1(_T("BrJComponent::RedrawParentRect x:%d y:%d w:%d h:%d"),
//        pRect->left, pRect->top, 
//        pRect->right - pRect->left, pRect->bottom - pRect->top);
    //if(m_visible){
    {
        OLE_TRY
        //IViewObjectPtr spViewObject(m_spIWebBrowser2);
        //OLE_HRT( spViewObject->Freeze(
        //  DVASPECT_CONTENT,
        //  -1, 
        //  NULL,
        //  &m_dwKey
        //));

        //that is mandatory due to WS_CLIPCHILDREN or WS_CLIPCHILDREN style in parent
        ::SetWindowRgn(m_hwndParent, NULL, FALSE);

        //CBrIELWControl::RedrawParentRect(pRect);
        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
        if( NULL != env ){
            env->CallVoidMethod(
                m_this, 
                ms_jcidWBrComponentPeer_handlePaint,
                pRect->left - m_rcIE2.left, 
                pRect->top - m_rcIE2.top, 
                pRect->right - pRect->left, 
                pRect->bottom - pRect->top);
        }
        OLE_CATCH
    }    
}

HRESULT BrJComponent::SendIEEvent(
    int iId,
    LPTSTR lpName, 
    LPTSTR lpValue,
    _bstr_t &bsResult)
{
    OLE_DECL
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    if(NULL==env){
        OLE_HR = E_FAIL;
    } else {   
        jstring jsName = JNU_NewStringPlatform(env, lpName);
        if(NULL==jsName){
            OLE_HR = E_OUTOFMEMORY;
        } else {
            jstring jsValue = JNU_NewStringPlatform(env, lpValue);
            if(NULL==jsValue){
                OLE_HR = E_OUTOFMEMORY;
            } else {
                jstring jsRes = (jstring)env->CallObjectMethod(
                    m_this, 
                    ms_jcidWBrComponentPeer_postEvent,
                    iId, 
                    jsName, 
                    jsValue);
                if( NULL!=jsRes ){
                    bsResult = JStringBuffer(env, jsRes);
                    env->DeleteLocalRef(jsRes);
                }
                env->DeleteLocalRef(jsValue);
            }
            env->DeleteLocalRef(jsName);
        }
    }
    OLE_RETURN_HR                                 
}

LRESULT BrJComponent::NewIEProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    LRESULT lRes = 0;
    switch(msg){
    case WM_SETFOCUS:
        setTransparent(false);
        SendIEEvent(-1, _T("OnFocusMove"), _T("true"));
        STRACE0(_T("WM_SETFOCUS"));
        break;
    case WM_KILLFOCUS:
        SendIEEvent(-1, _T("OnFocusMove"), _T("false"));
        STRACE0(_T("WM_KILLFOCUS"));
        setTransparent(true);
        break;
    case WM_KEYDOWN:
    case WM_KEYUP:
    case WM_SYSKEYDOWN:
    case WM_SYSKEYUP:
    case WM_CHAR:
    case WM_SYSCHAR:
    //case WM_INPUT:
        lRes = CBrIELWControl::NewIEProc(hWnd, msg, wParam, lParam);
        return lRes;
    case WM_SETCURSOR:    
        lRes = CBrIELWControl::NewIEProc(hWnd, msg, wParam, lParam);
        {
            //POINT pt;
            //if( GetCursorPos(&pt) && hWnd == WindowFromPoint(pt) ){
                JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
                if( NULL!=env ) {
                    jobject target = env->GetObjectField(m_this, ms_jcidWBrComponentPeer_target);
                    if(NULL!=target){
                        jobject ocursor = env->CallObjectMethod(
                            target, 
                            ms_jcidWBrComponent_getCursor);
                        if(NULL!=ocursor){
                            jlong pData = env->GetLongField(ocursor, ms_jcidCursor_pData);
                            if(0!=pData){
                                //Warning:HACK!!!
                                //pData is a pointer to AwtCursor
                                *(HCURSOR *)((LPBYTE)pData + 0x44) = GetCursor();
                                //STRACE1(_T("SET_CURSOR"));
                            }
                            env->DeleteLocalRef(ocursor);
                        }
                        env->DeleteLocalRef(target);
                    }    
                }
            //}
        }
        return lRes;

    case WM_MOUSEACTIVATE:

    case WM_MOUSEMOVE: 
    case WM_NCLBUTTONDBLCLK:
    case WM_NCLBUTTONDOWN:
    case WM_NCLBUTTONUP:

    case WM_NCRBUTTONDBLCLK:
    case WM_NCRBUTTONDOWN:
    case WM_NCRBUTTONUP:

    case WM_NCMBUTTONDBLCLK:
    case WM_NCMBUTTONDOWN:
    case WM_NCMBUTTONUP:

    case WM_LBUTTONDBLCLK:
    case WM_LBUTTONDOWN:
    case WM_LBUTTONUP:

    case WM_RBUTTONDBLCLK:
    case WM_RBUTTONDOWN:
    case WM_RBUTTONUP:

    case WM_MBUTTONDBLCLK: 
    case WM_MBUTTONDOWN:
    case WM_MBUTTONUP: 

    case WM_MOUSEWHEEL:
        //AwtComponent::WindowProc(msg, wParam, lParam);
        STRACE0(_T("mouse msg:%08x"), msg);
        if( !m_bBlockNativeInputHandler ) {
           lRes = CBrIELWControl::NewIEProc(hWnd, msg, wParam, lParam);
        }
        return lRes;
    default:
        break;
    }
    lRes = CBrIELWControl::NewIEProc(hWnd, msg, wParam, lParam);
    return lRes;
}

jintArray CopyDIBBytes(
    int iWidth, 
    int iHeight,
    void *pPoints)
{
    // copy pixels into Java array
    SEP0(_T("CopyDIBBytes"));
    JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
    int iDIBSize = iWidth*iHeight;
    jintArray jaiGPoints = NULL;
    jintArray jaiLPoints = env->NewIntArray(iDIBSize + 2);
    if(NULL != jaiLPoints) {
        env->SetIntArrayRegion(jaiLPoints, 0, iDIBSize, (jint*)pPoints);
        env->SetIntArrayRegion(jaiLPoints, iDIBSize, 1, (jint*)&iWidth);
        env->SetIntArrayRegion(jaiLPoints, iDIBSize + 1, 1, (jint*)&iHeight);

        jaiGPoints = (jintArray)env->NewGlobalRef(jaiLPoints);
        env->DeleteLocalRef(jaiLPoints);
    }    
    return jaiGPoints;
}

jintArray BrJComponent::NativeDraw(LPRECT prcDraw, BOOL bToImage)
{
    SEP(_T("NativeDraw"));
    jintArray jaiGPoints = NULL;
    if( bool(m_spIWebBrowser2) ){
        OLE_TRY
        /*
        IViewObjectPtr spViewObject(m_spIWebBrowser2);
        OLE_HRT( spViewObject->Freeze(
            DVASPECT_CONTENT,
            -1, 
            NULL,
            &m_dwKey
        ));
        */
        UpdateWindowRect();
        RECT rcP = *prcDraw;
        prcDraw->left += m_rcIE2.left;
        prcDraw->right += m_rcIE2.left;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?