2011-11-15 1 views
0

모두에 문제가 있습니다. ATL로 ActiveX 프로그래밍에 약간의 문제가 있습니다. 나는 http 서버에서 로컬 폴더로 async 다운로드 파일을 할 수있는 액티브 X를 만들려고 노력하고 다운로드 후에 자바 스크립트 콜백 함수를 호출 할 것이다. 내 솔루션 : 다운로드 스레드 D를 모니터링하기 위해 스레드 M을 실행합니다. D가 작업을 마칠 때 M은 터미널 자체로 이동하여 IDispatch inferface를 호출하여 javascript 함수를 호출합니다. * ** * ** ** * ** * * ** * MY CODE THERE IS : * ** * ** * ** * ** * ** *ActiveX 멀티 스레드 호출 자바 스크립트 콜백 루틴

,
/* javascript code */ 
funciton download() { 
    var xfm = new ActiveXObject("XFileMngr.FileManager.1"); 
    xfm.download(
    'http://somedomain/somefile','localdev:\\folder\localfile',function(msg){alert(msg);}); 
} 

/* C++ code */ 

// main routine 
STDMETHODIMP CFileManager::download(BSTR url, BSTR local, VARIANT scriptCallback) 
{ 
    CString csURL(url); 
    CString csLocal(local); 

    CAsyncDownload download; 
    download.Download(this, csURL, csLocal, scriptCallback); 

    return S_OK; 
} 

// parts of CAsyncDownload.h 
typedef struct tagThreadData { 
    CAsyncDownload* pThis; 
} THREAD_DATA, *LPTHREAD_DATA; 

class CAsyncDownload : 
    public IBindStatusCallback 
{ 
private: 
    LPUNKNOWN pcaller; 
    CString csRemoteFile; 
    CString csLocalFile; 
    CComPtr<IDispatch> spCallback; 
public: 
    void onDone(HRESULT hr); 

    HRESULT Download(LPUNKNOWN caller, CString& csRemote, CString& csLocal, VARIANT callback); 

    static DWORD __stdcall ThreadProc(void* param); 
}; 
// parts of CAsyncDownload.cpp 
void CAsyncDownload::onDone(HRESULT hr) { 
    if(spCallback) { 
     TRACE(TEXT("invoke callback function\n")); 
     CComVariant vParams[1]; 
     vParams[0] = "callback is working!"; 

     DISPPARAMS params = { vParams, NULL, 1, 0 }; 

     HRESULT hr = spCallback->Invoke(0, 
      IID_NULL, 
      LOCALE_USER_DEFAULT, 
      DISPATCH_METHOD, 
      &params, NULL, NULL, NULL); 

     if(FAILED(hr)) { 
      CString csBuffer; 
      csBuffer.Format(TEXT("invoke failed, result value: %d \n"),hr); 
      TRACE(csBuffer); 
     }else { 
      TRACE(TEXT("invoke was successful\n")); 
     } 
    } 
} 

HRESULT CAsyncDownload::Download(LPUNKNOWN caller, CString& csRemote, CString& csLocal, VARIANT callback) { 
    CoInitializeEx(NULL, COINIT_MULTITHREADED); 

    csRemoteFile = csRemote; 
    csLocalFile = csLocal; 
    pcaller = caller; 

    switch(callback.vt){ 
     case VT_DISPATCH: 
     case VT_VARIANT:{ 
      spCallback = callback.pdispVal; 
     } 
     break; 
     default:{ 
      spCallback = NULL; 
     } 
    } 

    LPTHREAD_DATA pData = new THREAD_DATA; 
    pData->pThis = this; 

    // create monitor thread M 
    HANDLE hThread = CreateThread(NULL, 0, ThreadProc, (void*)(pData), 0, NULL); 

    if(!hThread) { 
     delete pData; 
     return HRESULT_FROM_WIN32(GetLastError()); 
    } 

    WaitForSingleObject(hThread, INFINITE); 
    CloseHandle(hThread); 

    CoUninitialize(); 

    return S_OK; 
} 


DWORD __stdcall CAsyncDownload::ThreadProc(void* param) { 
    LPTHREAD_DATA pData = (LPTHREAD_DATA)param; 

    // here, we will create http download thread D 
    // when download job is finish, call onDone method; 

    pData->pThis->onDone(S_OK); 

    delete pData; 

    return 0; 
} 

** ** * * ** * ** * ** * * CODE FINISH ** * * ** * ** * ** * ** * 위 소스 코드의 일부입니다. 서브 스레드에서 onDone 메서드를 호출하면 OLE ERROR (-2147418113 (8000FFFF) Catastrophic failure)가 발생합니다. 내가 뭔가를 놓쳤습니까? 알아 내도록 도와주세요.

답변

2

IE의 JavaScript 엔진은 단일 스레드이므로 ATL의 이벤트 발생 코드도 마찬가지입니다. 서브 스레드가 ActiveX가 생성 된 스레드 (예 : ActiceX 창의 핸들)에 메시지를 게시 한 다음 이벤트를 발생시킵니다.

+0

그는 나를 때리면 ... COM은 일반적으로 한 스레드에서 작동합니다. 다른 스레드를 설정하여 COM을 사용하고 스레드간에 개체를 정렬 할 수 있도록 다른 방법이 있지만 여기에 언급 된 방법은 훨씬 간단합니다 (실제로 다른 스레드를 수행하는 방법을 알지 못합니다. 그냥 할 수 있다는 것을 알고). – taxilian

+0

고마워, 장. 그것은 보이지 않는 ActiveX 개체입니다, 조용히 하드웨어와 통신 할 것입니다. 그래서 기다리는 신호에 대한 스레드를 만듭니다. 신호가 있으면 스크립트 콜백 함수를 호출합니다. 원하는 것입니다. ActiveX 메인 스레드가 스레드 읽기를 기다리는 경우 브라우저 응답을 차단하고 IWebBrowser2 (스크립트 호출 인터페이스를 가져 오려면) 또는 COM 연결 지점 (COM 이벤트)이 작동한다고 생각합니다. – code0tt

+0

주제가 발견되었습니다. 작성자가 동일한 스레드에서 javascript를 호출하는 예제를 수행했으며 그는 말했습니다. CoMarshalInterface 및 CoUnmarshalInterface는 다중 스레드 스크립트 콜백을 알아낼 수 있지만 Taxilian의 아이디어와 동일합니까? – code0tt