void CStructure::CompleteConstruction() { m_bConstructing = false; if (DigitanksGame()->GetUpdateGrid()) { for (size_t x = 0; x < UPDATE_GRID_SIZE; x++) { for (size_t y = 0; y < UPDATE_GRID_SIZE; y++) { if (GetDigitanksPlayer()->HasDownloadedUpdate(x, y)) DownloadComplete(x, y); } } } }
STDMETHODIMP DWebBrowserEventsImpl::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) { switch (dispIdMember) { ///////////////////////////////////////////////////////// // The parameters for this DISPID are as follows: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: IDispatch* - Pointer to an IDispatch interface. // You can set this parameter to the IDispatch of // a WebBrowser Control that you've created. When // you pass back an IDispatch like this, MSHTML will // use the control you've given it to open the link. // case DISPID_NEWWINDOW2: { NewWindow2(pDispParams->rgvarg[1].ppdispVal, pDispParams->rgvarg[0].pboolVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID are as follows: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: HTTP headers - VT_BYREF|VT_VARIANT // [2]: Address of HTTP POST data - VT_BYREF|VT_VARIANT // [3]: Target frame name - VT_BYREF|VT_VARIANT // [4]: Option flags - VT_BYREF|VT_VARIANT // [5]: URL to navigate to - VT_BYREF|VT_VARIANT // [6]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // // User clicked a link or launched the browser. // case DISPID_BEFORENAVIGATE2: { BeforeNavigate2(pDispParams->rgvarg[6].pdispVal, pDispParams->rgvarg[5].pvarVal, pDispParams->rgvarg[4].pvarVal, pDispParams->rgvarg[3].pvarVal, pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal, pDispParams->rgvarg[0].pboolVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: URL navigated to - VT_BYREF|VT_VARIANT // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // // Fires after a navigation to a link is completed on either // a window or frameSet element. // case DISPID_NAVIGATECOMPLETE2: { NavigateComplete2(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); // Check if m_lpDocCompleteDisp is NULL. If NULL, that means it is // the top level NavigateComplete2. Save the LPDISPATCH if (!m_lpDocCompleteDisp) { VARIANTARG varDisp = pDispParams->rgvarg[1]; m_lpDocCompleteDisp = varDisp.pdispVal; } } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: New status bar text - VT_BSTR // case DISPID_STATUSTEXTCHANGE: { StatusTextChange(pDispParams->rgvarg[0].bstrVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Maximum progress - VT_I4 // [1]: Amount of total progress - VT_I4 // case DISPID_PROGRESSCHANGE: { ProgressChange(pDispParams->rgvarg[1].intVal, pDispParams->rgvarg[0].intVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: URL navigated to - VT_BYREF|VT_VARIANT // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // // Fires when a document has been completely loaded and initialized. // Unreliable -- currently, the DWebBrowserEvents2::DocumentComplete // does not fire when the IWebBrowser2::Visible property of the // WebBrowser Control is set to false (see Q259935). Also, multiple // DISPID_DOCUMENTCOMPLETE events can be fired before the final // READYSTATE_COMPLETE (see Q180366). // case DISPID_DOCUMENTCOMPLETE: { DocumentComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); VARIANTARG varDisp = pDispParams->rgvarg[1]; if (m_lpDocCompleteDisp && m_lpDocCompleteDisp == varDisp.pdispVal) { // if the LPDISPATCH are same, that means // it is the final DocumentComplete. Reset m_lpDocCompleteDisp m_lpDocCompleteDisp = NULL; // Handle new doc. DocumentReallyComplete(pDispParams->rgvarg[1].pdispVal, pDispParams->rgvarg[0].pvarVal); } } break; /////////////////////////////////////////////////////////// // No parameters // // Fires when a navigation operation is beginning. // case DISPID_DOWNLOADBEGIN: DownloadBegin(); break; /////////////////////////////////////////////////////////// // No parameters // // Fires when a navigation operation finishes, is halted, or fails. // case DISPID_DOWNLOADCOMPLETE: DownloadComplete(); break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Enabled state - VT_BOOL // [1]: Command identifier - VT_I4 // case DISPID_COMMANDSTATECHANGE: { CommandStateChange(pDispParams->rgvarg[1].intVal, pDispParams->rgvarg[0].boolVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Document title - VT_BSTR // [1]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // case DISPID_TITLECHANGE: { TitleChange(pDispParams->rgvarg[0].bstrVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Name of property that changed - VT_BSTR // case DISPID_PROPERTYCHANGE: { PropertyChange(pDispParams->rgvarg[0].bstrVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: Child Window (created from script) - VT_BOOL // // case DISPID_WINDOWCLOSING: { WindowClosing(pDispParams->rgvarg[1].boolVal, pDispParams->rgvarg[0].pboolVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Cancel flag - VT_BYREF|VT_BOOL // // case DISPID_FILEDOWNLOAD: { FileDownload(pDispParams->rgvarg[0].pboolVal); } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID are as follows: // [0]: Cancel flag - VT_BYREF|VT_BOOL // [1]: Error status code - VT_BYREF|VT_VARIANT // [2]: Target frame name - VT_BYREF|VT_VARIANT // [3]: URL where navigate failed - VT_BYREF|VT_VARIANT // [4]: An object that evaluates to the top-level or frame // WebBrowser object corresponding to the event. // // case DISPID_NAVIGATEERROR: { NavigateError(pDispParams->rgvarg[4].pdispVal, pDispParams->rgvarg[3].pvarVal, pDispParams->rgvarg[2].pvarVal, pDispParams->rgvarg[1].pvarVal, pDispParams->rgvarg[0].pboolVal); m_lpDocCompleteDisp = NULL; } break; /////////////////////////////////////////////////////////// // The parameters for this DISPID: // [0]: Visible - VT_BOOL // case DISPID_ONVISIBLE: { OnVisible(pDispParams->rgvarg[0].boolVal); } break; /////////////////////////////////////////////////////////// // No parameters // // The BHO docs in MSDN say to use DISPID_QUIT, but this is an error. // The BHO never gets a DISPID_QUIT and thus the browser connection // never gets unadvised and so the BHO never gets the FinalRelease(). // This is bad. So use DISPID_ONQUIT instead and everything is cool -- // EXCEPT when you exit the browser when viewing a page that launches // a popup in the onunload event! In that case the BHO is already // unadvised so it does not intercept the popup. So the trick is to // navigate to a known page (I used the about:blank page) that does // not have a popup in the onunload event before unadvising. // case DISPID_ONQUIT: OnQuit(); break; default: { } break; } return NOERROR; }
HRESULT CAssemblyDownload::KickOffDownload(BOOL bFirstDownload) { HRESULT hr = S_OK; LPWSTR pwzUrl = NULL; WCHAR wzFilePath[MAX_PATH]; BOOL bIsFileUrl = FALSE; CCriticalSection cs(&_cs); CCriticalSection csDownload(&g_csDownload); wzFilePath[0] = L'\0'; // If we're aborted, or done, we can't do anything here hr = cs.Lock(); if (FAILED(hr)) { goto Exit; } if (_state == ADLSTATE_DONE) { hr = S_FALSE; goto Exit; } // Dupe detection. If we end up hitting a dupe, then the CClientBinding // that was keeping a refcount on us, releases us, and adds itself as // a client to the duped download. In this case, we'll come back, and // this download object could be destroyed--that's why we AddRef/Release // around the dupe checking code. if (bFirstDownload) { // This is a top-level download (ie. not a probe download called from // DownloadNextCodebase AddRef(); hr = CheckDuplicate(); if (hr == E_PENDING) { cs.Unlock(); Release(); goto Exit; } Release(); // Not a duplicate. Add ourselves to the global download list. hr = csDownload.Lock(); if (FAILED(hr)) { goto Exit; } AddRef(); g_pDownloadList->AddTail(this); csDownload.Unlock(); } // Careful! PrepNextDownload/CompleteAll call the client back! cs.Unlock(); hr = GetNextCodebase(&bIsFileUrl, wzFilePath, MAX_PATH); if (hr == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) { // This must have been a case where all remaining probing URLs were file://, // and none of them existed. That is, we never get here (KickOffDownload) // unless the codebase list is non-empty, so this return result // from GetNextCodebase could only have resulted because we rejected // all remaining URLs. hr = DownloadComplete(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), NULL, NULL, FALSE); // Not really pending, just tell client the result is reported via // bind sink. if (SUCCEEDED(hr)) { hr = E_PENDING; } goto Exit; } else if (FAILED(hr)) { DEBUGOUT1(_pdbglog, 1, ID_FUSLOG_CODEBASE_RETRIEVE_FAILURE, hr); goto Exit; } DEBUGOUT1(_pdbglog, 0, ID_FUSLOG_ATTEMPT_NEW_DOWNLOAD, _pwzUrl); if (bIsFileUrl) { hr = DownloadComplete(S_OK, wzFilePath, NULL, FALSE); // We're not really pending, but E_PENDING means that the client // will get the IAssembly via the bind sink (not the ppv returned // in the call to BindToObject). if (SUCCEEDED(hr)) { hr = E_PENDING; } goto Exit; } else { hr = HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED); goto Exit; } Exit: SAFEDELETEARRAY(pwzUrl); if (FAILED(hr) && hr != E_PENDING) { LISTNODE listnode; CCriticalSection cs(&g_csDownload); // Fatal error! // If we added ourselves to the download list, we should remove // ourselves immediately! HRESULT hrLock = cs.Lock(); if (FAILED(hrLock)) { return hrLock; } listnode = g_pDownloadList->Find(this); if (listnode) { g_pDownloadList->RemoveAt(listnode); // release ourselves since we are removing from the global dl list Release(); } cs.Unlock(); } return hr; }