brjcomponent.cpp

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

CPP
1,409
字号
        prcDraw->top += m_rcIE2.top;
        prcDraw->bottom += m_rcIE2.top;

        RECT rc;
        if( 
            (prcDraw->left >= prcDraw->right) || 
            (prcDraw->top >= prcDraw->bottom) ||
            !IntersectRect(&rc, prcDraw, &m_rcIE2)
        )
            return NULL; //nothing to do - empty area or null-object        

#if 0
            //reserved branch - never compiled
            HDC hdc = ::GetDC(m_hwndParent); //TODO: pParent->GetDCFromComponent();
            if(hdc) {
                OLE_NEXT_TRY
                CDCHolder shPicture;
                HDC hdcPaintTo = hdc;
                if(bToImage){
                    shPicture.Create(
                        hdc, 
                        rc.right - rc.left,
                        rc.bottom - rc.top,
                        TRUE
                    );
                    OLE_HRW32_BOOL( ::SetViewportOrgEx(
                        shPicture, 
                        -rc.left, 
                        -rc.top, 
                        NULL ));
                    hdcPaintTo = shPicture;
                }
                STRACE0(_T("Draw in %dx%d"), rc.right - rc.left, rc.bottom - rc.top);

                OLE_HRT( CBrIELWControl::OnPaint(
                    hdcPaintTo, 
                    &rc ));
                if(bToImage && NULL!=shPicture.m_pPoints){
                    jaiGPoints = CopyDIBBytes(
                        shPicture.m_iWidth, 
                        shPicture.m_iHeight,
                        shPicture.m_pPoints
                    );
                }
                OLE_CATCH
                ::ReleaseDC(m_hwndParent, hdc);
            }
#else 
        if(PAINT_NATIVE == m_ePaintAlgorithm){
            PaintScreenShort();
            //InvalidateRect(GetParent(), prcDraw, FALSE);
            //InvalidateRect(GetTopWnd(), NULL, FALSE);
            //UpdateWindow(GetTopWnd());
            //return NULL;
        }

        //PaintScreenShort();

        if(bToImage){
            CDCHolder shPicture;
            shPicture.Create(
                (HDC)m_shScreen, 
                rc.right - rc.left,
                rc.bottom - rc.top,
                TRUE
            );

            OLE_HRW32_BOOL( ::BitBlt(
                (HDC)shPicture, 
                0,
                0,
                shPicture.m_iWidth, 
                shPicture.m_iHeight,
                (HDC)m_shScreen,
                rc.left - m_rcIE2.left,
                rc.top - m_rcIE2.top,
                SRCCOPY ));                      

            if(NULL!=shPicture.m_pPoints){
                jaiGPoints = CopyDIBBytes(
                    shPicture.m_iWidth, 
                    shPicture.m_iHeight,
                    shPicture.m_pPoints
                );
            }
        } else {
            HDC hdc = ::GetDC(m_hwndParent); //TODO: pParent->GetDCFromComponent();
            if(hdc){
                OLE_NEXT_TRY
                OLE_HRW32_BOOL( ::BitBlt(
                    hdc, 
                    0,
                    0,
                    rc.right - rc.left,
                    rc.bottom - rc.top,
                    (HDC)m_shScreen,
                    rc.left - m_rcIE2.left,
                    rc.top - m_rcIE2.top,
                    SRCCOPY ));                      
                OLE_CATCH
                ::ReleaseDC(m_hwndParent, hdc);
            }
        }
#endif
        //IViewObjectPtr spViewObject(m_spIWebBrowser2); 
        //OLE_HRT( spViewObject->Unfreeze(m_dwKey) );
        OLE_CATCH
    }
    return jaiGPoints;
}

struct JavaInputStream : public CStubStream
{
    static jclass ms_jcidInputStream;
    static jmethodID ms_jcidInputStream_readBytes; 

    static void initIDs(
        IN JNIEnv *env)
    {
        if(NULL==ms_jcidInputStream){
            ms_jcidInputStream = getGlobalJavaClazz(
                env,
                "java/io/InputStream"
            );
            ms_jcidInputStream_readBytes = env->GetMethodID(ms_jcidInputStream, "read", "([BII)I");
        }
    }

    JavaInputStream(
        IN JNIEnv *env,
        IN jobject jis
    ): CStubStream(),
       m_jis(jis),
       m_env(env)
    {
        initIDs(env);
    }

    virtual  HRESULT STDMETHODCALLTYPE Read(
        OUT void *pv,
        IN  ULONG cb,
        OUT ULONG *pcbRead)
    {
        OLE_DECL
        //java read
        //No more exceptions here!
        jbyteArray jba = m_env->NewByteArray( jsize(cb) );
        if( NULL == jba ){
            OLE_HR = E_OUTOFMEMORY;
        } else {
            jint ret = 0, read;
            while(0 < cb){
                read = m_env->CallIntMethod(
                    m_jis, 
                    ms_jcidInputStream_readBytes,
                    jba,
                    ret,
                    cb);
                if( m_env->ExceptionCheck() ){
                    OLE_HR = E_JAVAEXCEPTION;
                    break;
                }
                if( -1 == read ){
                    break;
                }
                cb -= read;
                ret += read;
            }

            //copy to stream
            if(SUCCEEDED(OLE_HR)){
                jbyte *pSrc = m_env->GetByteArrayElements(jba, NULL);
                if(NULL==pSrc){
                    OLE_HR = E_OUTOFMEMORY;
                } else {
                    memcpy(pv, pSrc, ret);
                    if(pcbRead){
                        *pcbRead = ret;
                    }
                    m_env->ReleaseByteArrayElements(jba, pSrc, JNI_ABORT);
                }
            }
            m_env->DeleteLocalRef(jba);
        }  
        return S_OK;
    }

    jobject m_jis;
    JNIEnv *m_env; 
};

jclass JavaInputStream::ms_jcidInputStream = NULL;
jmethodID JavaInputStream::ms_jcidInputStream_readBytes = NULL;


HRESULT BrJComponent::Connect(
    IN BSTR bsURL, 
    IN JNIEnv *env, 
    IN jobject jis)
{
    OLE_DECL
    if(NULL!=jis){
        OLE_NEXT_TRY
        IHTMLDocument2Ptr doc;     
        OLE_HRT( m_spIWebBrowser2->get_Document((LPDISPATCH *)&doc) )
        OLE_CHECK_NOTNULLSP(doc)
        IPersistStreamInitPtr ipsi(doc);
        JavaInputStream is(env, jis);
	OLE_HRT( ipsi->InitNew() )
	OLE_HRT( ipsi->Load(&is) )
        OLE_CATCH
    }else{
        OLE_HR = CBrIELWControl::Connect(bsURL);
    }
    OLE_RETURN_HR
}

/************************************************************************
 * WBrComponentPeer native methods
 */

extern "C" {

/*
 * Class:     org_jdic_web_peer_WBrComponentPeer
 * Method:    initIDs
  */
JNIEXPORT void JNICALL Java_org_jdic_web_peer_WBrComponentPeer_initIDs(
    JNIEnv *env, 
    jclass cls)
{
    BrJComponent::initIDs(env, cls);
}

/*
 * Class:     org_jdic_web_peer_WBrComponentPeer
 * Method:    create
  */
struct CreateAction : public BrowserAction
{
    HWND    m_parent;
    BrJComponent *m_pThis;
    int m_ePaintAlgorithm;

    CreateAction(
        BrJComponent *pThis,
        HWND parent,
        int ePaintAlgorithm)
    : m_pThis(pThis),
      m_parent(parent),
      m_ePaintAlgorithm(ePaintAlgorithm)
    {}

    virtual HRESULT Do(JNIEnv *env){
        return m_pThis->create(env, m_parent, m_ePaintAlgorithm);
    }
};

JNIEXPORT jlong JNICALL Java_org_jdic_web_peer_WBrComponentPeer_create(
    JNIEnv *env, 
    jobject self,
    jlong parent,
    jint  ePaintAlgorithm)
{
    BrJComponent *pThis = new BrJComponent(env, self);
    if(pThis){
        OLE_TRY
        OLE_HRT(pThis->GetThread()->MakeAction(
            env,
            "Browser create error",
            CreateAction(
                pThis,
                (HWND)parent,
                ePaintAlgorithm)));
        OLE_CATCH
        if(FAILED(OLE_HR)){
            pThis->destroy(env);
            delete pThis;
            pThis = NULL;
        }
    }
    return jlong(pThis);
}

/*
 * Class:     org_jdic_web_peer_WBrComponentPeer
 * Method:    destroy
  */
struct DestroyAction : public BrowserAction
{
    BrJComponent *m_pThis;
    DestroyAction(BrJComponent *pThis)
    : m_pThis(pThis)
    {}

    virtual HRESULT Do(JNIEnv *env){
        m_pThis->destroy(env);
        return S_OK;
    }
};
JNIEXPORT void JNICALL Java_org_jdic_web_peer_WBrComponentPeer_destroy(
    JNIEnv *env, 
    jobject self)
{
    BrJComponent *pThis = (BrJComponent *)env->GetLongField(self, BrJComponent::ms_jcidWBrComponentPeer_data);
    if(pThis){
        pThis->GetThread()->MakeAction(
            env,
            "Browser destroy error",
            DestroyAction(pThis));
        delete pThis;
        env->SetLongField(self, BrJComponent::ms_jcidWBrComponentPeer_data, 0L);
    }
}

/*
 * Class:     sun.awt.windows.WBrComponentPeer
 * Method:    execJS
 */
struct ExecJSAction : public BrowserAction
{
    BrJComponent *m_pThis;
    JStringBuffer m_jstCode;
    _bstr_t m_bsResult;

    ExecJSAction(
        BrJComponent *pThis,
        JNIEnv *env,
        jstring jsCode
    ): m_pThis(pThis),
       m_jstCode(env, jsCode),
       m_bsResult(_T("error:Null interface"))
    {}

    virtual HRESULT Do(JNIEnv *env)
    {
        SEP(_T("_ExecJS"))
        LPTSTR pCode = (LPTSTR)m_jstCode;
        STRACE(_T("code:%s"), pCode);
        if(NULL==pCode){
            return S_FALSE;
        } else if( 0==_tcsncmp(pCode, _T("##"), 2) ){
            if( 0==_tcscmp(pCode, _T("##stop")) ){
                OLE_TRY
                OLE_HRT( m_pThis->m_spIWebBrowser2->Stop() );
                OLE_CATCH
                OLE_RETURN_HR
            } else if( 0==_tcsncmp(pCode, _T("##setFocus"), 10) ){
                OLE_TRY
                STRACE0(_T("##setFocus"));
                IOleObjectPtr spOleObject(m_pThis->m_spIWebBrowser2);
                OLE_CHECK_NOTNULLSP(spOleObject)
                OLE_HRT( spOleObject->DoVerb(
                    OLEIVERB_UIACTIVATE, 
                    NULL, 
                    m_pThis, 
                    0, 
                    NULL, 
                    NULL))
                if( 0!=_tcscmp(pCode, _T("##setFocus(false)")) ){
                    HWND hwnd = m_pThis->GetIEWnd();
                    if(NULL==hwnd)
                        hwnd = m_pThis->GetTopWnd();
                    SendMessage(hwnd, WM_KEYDOWN, VK_TAB, 0x0000000);
                    SendMessage(hwnd, WM_KEYUP, VK_TAB, 0xc000000);
                }
                //::OLE_CoPump();//Flash hole. Dead circle if is.
                OLE_CATCH
                OLE_RETURN_HR
            } else if( 0==_tcsncmp(pCode, _T("##setNativeDraw("), 16) ) {
                m_pThis->m_ePaintAlgorithm = pCode[17] - _T('0'); 
                //STRACE(_T(">>>>>>>>NativeDraw %d"), m_pThis->m_ePaintAlgorithm);
                return S_OK;
            } else if( 0==_tcsncmp(pCode, _T("##showCaret"), 11) ) {
                OLE_TRY
                IWebBrowser2Ptr br(m_pThis->m_spIWebBrowser2);
                OLE_CHECK_NOTNULLSP(br)

                IHTMLDocument2Ptr doc;     
                OLE_HRT( br->get_Document((LPDISPATCH *)&doc) )
                OLE_CHECK_NOTNULLSP(doc)
                
                IDisplayServicesPtr ds(doc);                     
                OLE_CHECK_NOTNULLSP(ds)

                IHTMLCaretPtr cr;                     
                OLE_HRT( ds->GetCaret(&cr) )
                OLE_CHECK_NOTNULLSP(cr)

                if( 0==_tcscmp(pCode, _T("##showCaret(true)")) ){
                   OLE_HRT( cr->Show(FALSE) )
                   STRACE1(_T("{Show------"));
                } else {
                   OLE_HRT( cr->Hide() )
                   STRACE1(_T("}Hide------"));
                }
                OLE_CATCH
                OLE_RETURN_HR
            }
            return S_FALSE;
        }
        OLE_TRY
        IWebBrowser2Ptr br(m_pThis->m_spIWebBrowser2);
        OLE_CHECK_NOTNULLSP(br)

        //that can be any type of document
        //Acrobat Reader for example
        IDispatchPtr docO;     
        OLE_HRT( br->get_Document(&docO) )

        //we are trying customize it to HTML document
        //empty document is a valid argument
        IHTMLDocument2Ptr doc(docO);     
        OLE_CHECK_NOTNULLSP(doc)

        IHTMLWindow2Ptr wnd;
        OLE_HRT( doc->get_parentWindow(&wnd) )
        OLE_CHECK_NOTNULLSP(wnd)

        _variant_t vtResult;
        STRACE0(_T("makeScript"));
        _bstr_t bsEval( ('#'!=*pCode && ':'!=*pCode)
            ? (_B(L"document.documentElement.setAttribute(\'javaEval\', eval(\'") + pCode + L"\'))")
            : _B(pCode+1)
        );
        
        STRACE0(_T("execScript"));
        OLE_HRT( wnd->execScript( bsEval, _B(""), &vtResult) )
        vtResult.Clear();

        if( ':'!=*pCode ){
            IHTMLDocument3Ptr doc3(doc);     
            OLE_CHECK_NOTNULLSP(doc3)
            
            IHTMLElementPtr el;
            OLE_HRT( doc3->get_documentElement(&el))
            OLE_CHECK_NOTNULLSP(el)

            OLE_HRT( el->getAttribute(_B("javaEval"), 0, &vtResult) )
        }

        if(VT_NULL!=vtResult.vt){
            m_bsResult = vtResult;
        } else {
            m_bsResult = "";
        }
        STRACE0(_T("result:%s"), (LPCTSTR)m_bsResult);
        OLE_CATCH
        if(FAILED(OLE_HR)){
            m_bsResult = _T("error:");
            m_bsResult += _B(_V(OLE_HR));
            m_bsResult += _T("code:");
            m_bsResult += pCode;
        }
        OLE_RETURN_HR
    }
};

JNIEXPORT jstring JNICALL Java_org_jdic_web_peer_WBrComponentPeer_execJS(
    JNIEnv *env, 
    jobject self,
    jstring jsCode)
{
    BrJComponent *pThis = (BrJComponent *)env->GetLongField(self, BrJComponent::ms_jcidWBrComponentPeer_data);
    if(pThis){
        OLE_TRY
        ExecJSAction a(
            pThis,
            env,
            jsCode);

⌨️ 快捷键说明

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