/// returns processor register BYTE GetRegister(RegisterID enRegisterID) { ATLASSERT(enRegisterID <= regLast); return m_abRegister[enRegisterID]; }
/// sets new parent index void ParentIndex(int iParentIndex) throw() { ATLASSERT(iParentIndex >= -1); m_iParentIndex = iParentIndex; }
void SplitBezier( const gmVector2& P00, const gmVector2& P01, const gmVector2& P02, const gmVector2& P03, double t, gmVector2& P10, gmVector2& P11, gmVector2& P12, gmVector2& P20, gmVector2& P21, gmVector2& P30) { double ratio = 1.0 - t; ATLASSERT((ratio >= 0.0) && (ratio <= 1.0)); // CFPoint P00, P01, P02, P03; /* CFPoint P10, P11, P12; CFPoint P20, P21; CFPoint P30; */ /* // P00 = &m_pointArray[n+0]; // P01 = &m_pointArray[n+1]; // P02 = &m_pointArray[n+2]; // P03 = &m_pointArray[n+3]; /* De Casteljau algorithme [Advanced Animation & Randering Technics / Alan & Mark WATT] [ADDISON WESLEY ref 54412] Iteratif way of drawing a Bezier curve by geometrical approch P0x represent the four controls points ( anchor / control /control /anchor ) P30 represent the new anchor point to add on the curve P2x represent the new control points of P30 P1x represent the new values of the control points P01 and P02 so if we moves ratio from 0 to 1 we draw the all curve between P00 and P03 */ P10[0] = ((1-ratio)*P00[0] + ratio * P01[0]); P10[1] = ((1-ratio)*P00[1] + ratio * P01[1]); P11[0] = (1-ratio)*P01[0] + ratio * P02[0]; P11[1] = (1-ratio)*P01[1] + ratio * P02[1]; P12[0] = (1-ratio)*P02[0] + ratio * P03[0]; P12[1] = (1-ratio)*P02[1] + ratio * P03[1]; P20[0] = (1-ratio)*P10[0] + ratio * P11[0]; P20[1] = (1-ratio)*P10[1] + ratio * P11[1]; P21[0] = (1-ratio)*P11[0] + ratio * P12[0]; P21[1] = (1-ratio)*P11[1] + ratio * P12[1]; P30[0] = (1-ratio)*P20[0] + ratio * P21[0]; P30[1] = (1-ratio)*P20[1] + ratio * P21[1]; // // P01.x = P10.x; // P01.y = P10.y; // P02.x = P12.x; // P02.y = P12.y; /* seg1->put_x1(P21.x); seg1->put_y1(P21.y); seg1->put_x2(P12.x); seg1->put_y2(P12.y); */ /* All the computes are done, let's insert the new point on the curve */ /* CComQIPtr<ISVGPathSegCurvetoCubicAbs> curveto; path->createSVGPathSegCurvetoCubicAbs( P30.x, P30.y, P10.x, P10.y, // x1,y1 P20.x, P20.y, &curveto ); seglist->insertItemBefore(curveto, segindex, NULL); // CDblPoint apt1; // apt1.x = P20.x; apt1.y = P20.y; // CAPoint apt2; // apt2.x = P30.x; apt2.y = P30.y; // CAPoint apt3; // apt3.x = P21.x; apt3.y = P21.y; /* m_pointArray.InsertAt(n+2, apt1); m_pointArray.InsertAt(n+3, apt2); m_pointArray.InsertAt(n+4, apt3); seglist->UnlockUpdate(); */ }
BOOL CNBLogicalDevice::InitConnectionInfo(PNDASCOMM_CONNECTION_INFO ci, BOOL bWriteAccess) { ATLASSERT(m_mapUnitDevices.size()); return PrimaryUnitDevice()->InitConnectionInfo(ci, bWriteAccess); }
BOOL CNBLogicalDevice::IsGroup() { ATLASSERT(m_mapUnitDevices.size()); return PrimaryUnitDevice()->IsGroup(); }
DWORD CALLBACK ThreadProc(PVOID pv) { HANDLE hEvent = *(PHANDLE)pv; HANDLE hEvents[PIPES]; OVERLAPPEDEX Ovlxs[PIPES]; SID_IDENTIFIER_AUTHORITY sia = SECURITY_WORLD_SID_AUTHORITY; PSID psid = NULL; ATLASSERT(::AllocateAndInitializeSid( &sia, 1, SECURITY_WORLD_RID, 0, 0, 0, 00, 0, 0, 0, &psid)); EXPLICIT_ACCESS ea = { 0 }; ea.grfAccessPermissions = FILE_ALL_ACCESS; ea.grfAccessMode = SET_ACCESS; ea.grfInheritance = NO_INHERITANCE; ea.Trustee.TrusteeForm = TRUSTEE_IS_SID; ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPTSTR)psid; PACL pacl = NULL; ATLASSERT(::SetEntriesInAcl(1, &ea, NULL, &pacl) == ERROR_SUCCESS); PSECURITY_DESCRIPTOR psd = ::LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); ATLASSERT(::InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION)); ATLASSERT(::SetSecurityDescriptorDacl(psd, TRUE, pacl, FALSE)); SECURITY_ATTRIBUTES sa = { 0 }; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = psd; sa.bInheritHandle = FALSE; for (int i = 0; i < PIPES; i++) { ZeroMemory(&Ovlxs[i], sizeof(OVERLAPPEDEX)); Ovlxs[i].hPipe = (CHandle)::CreateNamedPipe( NAMED_PIPE, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_WAIT | PIPE_READMODE_MESSAGE | PIPE_TYPE_MESSAGE, PIPES, BUF_SIZE, BUF_SIZE, 2500, &sa); //::_tprintf(_T("CreateNamedPipe(): %ld\n"), ::GetLastError()); ATLASSERT(Ovlxs[i].hPipe != INVALID_HANDLE_VALUE); hEvents[i] = Ovlxs[i].Ovl.hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL); //::_tprintf(_T("CreateEvent(): %ld\n"), ::GetLastError()); ATLASSERT(hEvents[i] != NULL); ATLASSERT(::ConnectNamedPipe(Ovlxs[i].hPipe, (LPOVERLAPPED)&Ovlxs[i]) == 0); //::_tprintf(_T("ConnectNamedPipe(): %ld\n"), ::GetLastError()); ATLASSERT(::GetLastError() == ERROR_IO_PENDING); } ::SetEvent(hEvent); TCHAR szBuf[BUF_SIZE]; while (::_tcscmp(szBuf, _T("QUIT"))) { //::_tprintf(_T("Connecting...\n")); DWORD dwIndex = ::WaitForMultipleObjects(PIPES, hEvents, FALSE, INFINITE) - WAIT_OBJECT_0; //::_tprintf(_T("Connected.\n")); DWORD dwBytes = 0; BOOL bRes = ::GetOverlappedResult(Ovlxs[dwIndex].hPipe, (LPOVERLAPPED)&Ovlxs[dwIndex], &dwBytes, FALSE); bRes = ::ReadFile(Ovlxs[dwIndex].hPipe, szBuf, sizeof(szBuf), &dwBytes, NULL); if (bRes && dwBytes > 0) ::_tprintf(_T("[%s]\n"), szBuf); ATLASSERT(::DisconnectNamedPipe(Ovlxs[dwIndex].hPipe)); ATLASSERT(::ConnectNamedPipe(Ovlxs[dwIndex].hPipe, (LPOVERLAPPED)&Ovlxs[dwIndex]) == 0); ATLASSERT(::GetLastError() == ERROR_IO_PENDING); } for (int i = 0; i < PIPES; i++) { ::DisconnectNamedPipe(Ovlxs[i].hPipe); ::CloseHandle(Ovlxs[i].Ovl.hEvent); } ::FreeSid(psid); ::LocalFree(pacl); ::LocalFree(psd); return 0; }
UINT CNBLogicalDevice::GetSelectIconIndex(const UINT *anIconIDs, int nCount) { ATLASSERT(m_mapUnitDevices.size()); return GetIconIndex(anIconIDs, nCount); }
STDMETHODIMP CCUBRIDRowset::DeleteRows(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBROWSTATUS rgRowStatus[]) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::DeleteRows\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetChange), L"This object is in a zombie state"); CHECK_UPDATABILITY(DBPROPVAL_UP_DELETE); if(cRows==0) return S_OK; if(rghRows==NULL && cRows>=1) return RaiseError(E_INVALIDARG, 0, __uuidof(IRowsetChange)); // Determine if we're in immediate or deferred mode bool bDeferred = IsDeferred(this); int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); BOOL bSuccess = false; BOOL bFailed = false; for(DBCOUNTITEM i=0;i<cRows;i++) { HROW hRow = rghRows[i]; // Attempt to locate the row in our map CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRow, pRow); if(!bFound || pRow==NULL) { // invalid handle bFailed = true; if(rgRowStatus) rgRowStatus[i] = DBROWSTATUS_E_INVALID; continue; } } if(pRow->m_status==DBPENDINGSTATUS_DELETED) { // already deleted if(rgRowStatus) rgRowStatus[i] = DBROWSTATUS_E_DELETED; bFailed = true; continue; } ATLASSERT( pRow->m_iRowset==(ULONG)-1 || pRow->m_iRowset<m_rgRowData.GetCount() ); DBROWSTATUS rowStat = DBROWSTATUS_S_OK; // mark the row as deleted if(pRow->m_status==DBPENDINGSTATUS_INVALIDROW) { bFailed = true; // unsigned high bit signified neg. number if(pRow->m_dwRef & 0x80000000) rowStat = DBROWSTATUS_E_INVALID; else rowStat = DBROWSTATUS_E_DELETED; } else if(pRow->m_iRowset==(ULONG)-1 && pRow->m_status!=DBPENDINGSTATUS_NEW) { // 새로 삽입되었고 Storage로 전송됐다. bFailed = true; rowStat = DBROWSTATUS_E_NEWLYINSERTED; } else { bSuccess = true; rowStat = DBROWSTATUS_S_OK; if(pRow->m_status==DBPENDINGSTATUS_NEW) MakeRowInvalid(this, pRow); else pRow->m_status = DBPENDINGSTATUS_DELETED; } if(!bDeferred && pRow->m_status==DBPENDINGSTATUS_DELETED) { // 변화를 지금 적용 // CCUBRIDRowsetRow의 delete는 ReleaseRows에서 이루어진다. HRESULT hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if(FAILED(hr)) return hr; MakeRowInvalid(this, pRow); } if(rgRowStatus) rgRowStatus[i] = rowStat; } if(!bDeferred) DoCommit(this); // commit if(bFailed) { if(bSuccess) return DB_S_ERRORSOCCURRED; else return RaiseError(DB_E_ERRORSOCCURRED, 0, __uuidof(IRowsetChange)); } else return S_OK; }
CLocalResult() { ATLASSERT(false); }
STDMETHODIMP CCUBRIDRowset::Undo(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBCOUNTITEM *pcRowsUndone, HROW **prgRowsUndone, DBROWSTATUS **prgRowStatus) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::Undo\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetUpdate), L"This object is in a zombie state"); CHECK_RESTART(__uuidof(IRowsetUpdate)); DBCOUNTITEM ulRows = 0; // undo할 row 수 bool bNotIgnore = true; // prgRowsUndone, prgRowStatus를 무시할지 여부를 나타냄 // the following lines are used to fix the two _alloca calls below. Those calls are risky // because we may be allocating huge amounts of data. So instead I'll allocate that data on heap. // But if you use _alloca you don't have to worry about cleaning this memory. So we will use these // temporary variables to allocate memory on heap. As soon as we exit the function, the memory will // be cleaned up, just as if we were using alloca. So now, instead of calling alloca, I'll alloc // memory on heap using the two smnart pointers below, and then assing it to the actual pointers. CHeapPtr<HROW> spTempRowsUndone; CHeapPtr<DBROWSTATUS> spTempRowStatus; if(cRows || pcRowsUndone) { if(prgRowsUndone) *prgRowsUndone = NULL; if(prgRowStatus) *prgRowStatus = NULL; } else { bNotIgnore = false; // Don't do status or row arrays } // Check to see how many changes we'll undo if(pcRowsUndone) { *pcRowsUndone = NULL; if(prgRowsUndone==NULL) return E_INVALIDARG; } if(cRows) { if(rghRows==NULL) return E_INVALIDARG; ulRows = cRows; } else ulRows = (DBCOUNTITEM)m_rgRowHandles.GetCount(); // NULL out pointers { if(prgRowsUndone && ulRows && bNotIgnore) { // Make a temporary buffer as we may not fill up everything // in the case where cRows == 0 if(cRows) *prgRowsUndone = (HROW*)CoTaskMemAlloc(ulRows * sizeof(HROW)); else { spTempRowsUndone.Allocate(ulRows); *prgRowsUndone = spTempRowsUndone; } if (*prgRowsUndone==NULL) return E_OUTOFMEMORY; } if(prgRowStatus && ulRows && bNotIgnore) { if(cRows) *prgRowStatus = (DBROWSTATUS*)CoTaskMemAlloc(ulRows * sizeof(DBROWSTATUS)); else { spTempRowStatus.Allocate(ulRows); *prgRowStatus = spTempRowStatus; } if(*prgRowStatus==NULL) { if(cRows) CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; return E_OUTOFMEMORY; } } } bool bSucceeded = false; bool bFailed = false; ULONG ulUndone = 0; // undo된 row 수 POSITION pos = m_rgRowHandles.GetStartPosition(); for (ULONG ulUndoRow = 0; ulUndoRow < ulRows; ulUndoRow++) { ULONG ulCurrentRow = ulUndone; HROW hRowUndo = NULL; // 현재 undo할 row의 handle { if(cRows) { // row handle이 주어졌음 hRowUndo = rghRows[ulUndoRow]; } else { // 모든 row에 대해 undo // ATLASSERT(ulUndoRow < (ULONG)m_rgRowHandles.GetCount()); // delete된 row가 있으면 성립하지 않는다. ATLASSERT( pos != NULL ); MapClass::CPair* pPair = m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); hRowUndo = pPair->m_key; } } if(prgRowsUndone && bNotIgnore) (*prgRowsUndone)[ulCurrentRow] = hRowUndo; // Fetch the RowClass and determine if it is valid CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRowUndo, pRow); if (!bFound || pRow == NULL) { if (prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_INVALID; bFailed = true; ulUndone++; continue; } } // If cRows is zero we'll go through all rows fetched. We shouldn't // increment the count for rows that haven't been modified. if (cRows != 0 || (pRow != NULL && pRow->m_status != 0 && pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != DBPENDINGSTATUS_INVALIDROW)) ulUndone++; else continue; if(cRows==0) pRow->AddRefRow(); switch (pRow->m_status) { case DBPENDINGSTATUS_INVALIDROW: // 메모리와 storage 모두 존재하지 않는 row { // provider templates에서는 DELETED인데 // INVALID가 더 맞지 않을까 싶기도 한다. if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED; bFailed = true; } break; case DBPENDINGSTATUS_NEW: // 메모리 상에만 존재하는 row { // If the row is newly inserted, go ahead and mark its // row as INVALID (according to the specification). if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; MakeRowInvalid(this, pRow); bSucceeded = true; } break; case DBPENDINGSTATUS_CHANGED: case DBPENDINGSTATUS_DELETED: // storage의 데이터를 가져와야 하는 경우 // delete 된 경우 메모리에 데이터가 있지만, CHANGED->DELETED 인 경우도 있을 수 있다. { // read data back pRow->ReadData(GetRequestHandle()); pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; default: // 0, DBPENDINGSTATUS_UNCHANGED, // storage의 데이터를 가져올 필요가 없는 경우 { pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; } // Check if we need to release the row because it's ref was 0 // See the IRowset::ReleaseRows section in the spec for more // information if (pRow->m_dwRef == 0) { pRow->AddRefRow(); // Artifically bump this to remove it if( FAILED( RefRows(1, &hRowUndo, NULL, NULL, false) ) ) return E_FAIL; } } // Set the output for rows undone. if(pcRowsUndone) *pcRowsUndone = ulUndone; if(ulUndone==0) { if(prgRowsUndone) { CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; } if(prgRowStatus) { CoTaskMemFree(*prgRowStatus); *prgRowStatus = NULL; } } else if(cRows==0) { // In the case where cRows == 0, we need to allocate the final // array of data. if(prgRowsUndone && bNotIgnore) { HROW *prgRowsTemp = (HROW *)CoTaskMemAlloc(ulUndone*sizeof(HROW)); if(prgRowsTemp==NULL) return E_OUTOFMEMORY; memcpy(prgRowsTemp, *prgRowsUndone, ulUndone*sizeof(HROW)); *prgRowsUndone = prgRowsTemp; } if(prgRowStatus && bNotIgnore) { DBROWSTATUS *prgRowStatusTemp = (DBROWSTATUS *)CoTaskMemAlloc(ulUndone*sizeof(DBROWSTATUS)); if(prgRowStatusTemp==NULL) { CoTaskMemFree(*prgRowsUndone); *prgRowsUndone = NULL; return E_OUTOFMEMORY; } memcpy(prgRowStatusTemp, *prgRowStatus, ulUndone*sizeof(DBROWSTATUS)); *prgRowStatus = prgRowStatusTemp; } } // Send the return value if(!bFailed) return S_OK; else { return bSucceeded ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } }
STDMETHODIMP CCUBRIDRowset::Update(HCHAPTER hReserved, DBCOUNTITEM cRows, const HROW rghRows[], DBCOUNTITEM *pcRows, HROW **prgRows, DBROWSTATUS **prgRowStatus) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::Update\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetUpdate), L"This object is in a zombie state"); CHECK_RESTART(__uuidof(IRowsetUpdate)); DBCOUNTITEM ulRows = 0; // update할 row 수 bool bNotIgnore = true; // prgRows, prgRowStatus를 무시할지 여부를 나타냄 // the following lines are used to fix the two _alloca calls below. Those calls are risky // because we may be allocating huge amounts of data. So instead I'll allocate that data on heap. // But if you use _alloca you don't have to worry about cleaning this memory. So we will use these // temporary variables to allocate memory on heap. As soon as we exit the function, the memory will // be cleaned up, just as if we were using alloca. So now, instead of calling alloca, I'll alloc // memory on heap using the two smnart pointers below, and then assing it to the actual pointers. CHeapPtr<HROW> spTempRows; CHeapPtr<DBROWSTATUS> spTempRowStatus; if(cRows || pcRows) { if(prgRows) *prgRows = NULL; if(prgRowStatus) *prgRowStatus = NULL; } else { bNotIgnore = false; // Don't do status or row arrays } // Check to see how many changes we'll undo if(pcRows) { *pcRows = NULL; if(prgRows==NULL) return E_INVALIDARG; } if(cRows) { if(rghRows==NULL) return E_INVALIDARG; ulRows = cRows; } else ulRows = (DBCOUNTITEM)m_rgRowHandles.GetCount(); int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); // NULL out pointers { if(prgRows && ulRows && bNotIgnore) { // Make a temporary buffer as we may not fill up everything // in the case where cRows == 0 if(cRows) *prgRows = (HROW*)CoTaskMemAlloc(ulRows * sizeof(HROW)); else { spTempRows.Allocate(ulRows); *prgRows = spTempRows; } if (*prgRows==NULL) return E_OUTOFMEMORY; } if(prgRowStatus && ulRows && bNotIgnore) { if(cRows) *prgRowStatus = (DBROWSTATUS*)CoTaskMemAlloc(ulRows * sizeof(DBROWSTATUS)); else { spTempRowStatus.Allocate(ulRows); *prgRowStatus = spTempRowStatus; } if(*prgRowStatus==NULL) { if(cRows) CoTaskMemFree(*prgRows); *prgRows = NULL; return E_OUTOFMEMORY; } } } bool bSucceeded = false; bool bFailed = false; ULONG ulCount = 0; // update된 row 수 POSITION pos = m_rgRowHandles.GetStartPosition(); for (ULONG ulRow = 0; ulRow < ulRows; ulRow++) { ULONG ulCurrentRow = ulCount; bool bDupRow = false; // 중복된 row ULONG ulAlreadyProcessed = 0; // 중복된 row의 handle의 위치 HROW hRowUpdate = NULL; // 현재 update할 row의 handle { if(cRows) { // row handle이 주어졌음 hRowUpdate = rghRows[ulRow]; for (ULONG ulCheckDup = 0; ulCheckDup < ulRow; ulCheckDup++) { if (hRowUpdate==rghRows[ulCheckDup] || IsSameRow(hRowUpdate, rghRows[ulCheckDup]) == S_OK) { ulAlreadyProcessed = ulCheckDup; bDupRow = true; break; } } } else { // 모든 row에 대해 update //ATLASSERT(ulRow < (ULONG)m_rgRowHandles.GetCount()); // delete된 row가 있으면 성립하지 않는다. ATLASSERT( pos != NULL ); MapClass::CPair* pPair = m_rgRowHandles.GetNext(pos); ATLASSERT( pPair != NULL ); hRowUpdate = pPair->m_key; } } if(prgRows && bNotIgnore) (*prgRows)[ulCurrentRow] = hRowUpdate; if(bDupRow) { // We've already set the row before, just copy status and // continue processing if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = (*prgRowStatus)[ulAlreadyProcessed]; ulCount++; continue; } // Fetch the RowClass and determine if it is valid CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRowUpdate, pRow); if (!bFound || pRow == NULL) { if (prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_INVALID; bFailed = true; ulCount++; continue; } } // If cRows is zero we'll go through all rows fetched. We // shouldn't increment the attempted count for rows that are // not changed if (cRows != 0 || (pRow != NULL && pRow->m_status != 0 && pRow->m_status != DBPENDINGSTATUS_UNCHANGED && pRow->m_status != DBPENDINGSTATUS_INVALIDROW)) ulCount++; else continue; if(cRows==0) pRow->AddRefRow(); switch (pRow->m_status) { case DBPENDINGSTATUS_INVALIDROW: // Row is bad or deleted { if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_E_DELETED; bFailed = true; } break; case DBPENDINGSTATUS_UNCHANGED: case 0: { // If the row's status is not changed, then just put S_OK // and continue. The spec says we should not transmit the // request to the data source (as nothing would change). if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; } break; default: { DBORDINAL cCols; ATLCOLUMNINFO *pColInfo = GetColumnInfo(this, &cCols); HRESULT hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if(FAILED(hr)) { DBROWSTATUS stat = DBROWSTATUS_E_FAIL; if(hr==DB_E_INTEGRITYVIOLATION) stat = DBROWSTATUS_E_INTEGRITYVIOLATION; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = stat; bFailed = true; } else { //// m_iRowset을 적당히 조정한다. //if(pRow->m_status==DBPENDINGSTATUS_NEW) //{ // // NEW인 row는 항상 rowset의 뒤에 몰려있다. // // 그 row 중 가장 작은 m_iRowset이 update 된 row의 m_iRowset이 되면 된다. // CCUBRIDRowsetRow::KeyType key = pRow->m_iRowset; // POSITION pos = m_rgRowHandles.GetStartPosition(); // while(pos) // { // CCUBRIDRowset::MapClass::CPair *pPair = m_rgRowHandles.GetNext(pos); // ATLASSERT(pPair); // CCUBRIDRowsetRow *pCheckRow = pPair->m_value; // if( pCheckRow && pCheckRow->m_iRowset < key ) // { // if(pCheckRow->m_iRowset<pRow->m_iRowset) // pRow->m_iRowset = pCheckRow->m_iRowset; // pCheckRow->m_iRowset++; // } // } // // TODO: 북마크 업데이트가 필요한데 어떻게 해야 할지 모르겠다. // // 새로 추가된 Row의 OID를 읽어들인다. // pRow->ReadData(GetRequestHandle(), true); //} if(pRow->m_status==DBPENDINGSTATUS_DELETED) MakeRowInvalid(this, pRow); else pRow->m_status = DBPENDINGSTATUS_UNCHANGED; if(prgRowStatus && bNotIgnore) (*prgRowStatus)[ulCurrentRow] = DBROWSTATUS_S_OK; bSucceeded = true; // Check if we need to release the row because it's ref was 0 // See the IRowset::ReleaseRows section in the spec for more // information if (pRow->m_dwRef == 0) { pRow->AddRefRow(); // Artifically bump this to remove it if( FAILED( RefRows(1, &hRowUpdate, NULL, NULL, false) ) ) return E_FAIL; } } } break; } } // Set the output for rows undone. if(pcRows) *pcRows = ulCount; if(ulCount==0) { if(prgRows) { CoTaskMemFree(*prgRows); *prgRows = NULL; } if(prgRowStatus) { CoTaskMemFree(*prgRowStatus); *prgRowStatus = NULL; } } else if(cRows==0) { // In the case where cRows == 0, we need to allocate the final // array of data. if(prgRows && bNotIgnore) { HROW *prgRowsTemp = (HROW *)CoTaskMemAlloc(ulCount*sizeof(HROW)); if(prgRowsTemp==NULL) return E_OUTOFMEMORY; memcpy(prgRowsTemp, *prgRows, ulCount*sizeof(HROW)); *prgRows = prgRowsTemp; } if(prgRowStatus && bNotIgnore) { DBROWSTATUS *prgRowStatusTemp = (DBROWSTATUS *)CoTaskMemAlloc(ulCount*sizeof(DBROWSTATUS)); if(prgRowStatusTemp==NULL) { CoTaskMemFree(*prgRows); *prgRows = NULL; return E_OUTOFMEMORY; } memcpy(prgRowStatusTemp, *prgRowStatus, ulCount*sizeof(DBROWSTATUS)); *prgRowStatus = prgRowStatusTemp; } } DoCommit(this); // commit // Send the return value if(!bFailed) return S_OK; else { return bSucceeded ? DB_S_ERRORSOCCURRED : DB_E_ERRORSOCCURRED; } }
STDMETHODIMP CCUBRIDRowset::GetPendingRows(HCHAPTER hReserved, DBPENDINGSTATUS dwRowStatus, DBCOUNTITEM *pcPendingRows, HROW **prgPendingRows, DBPENDINGSTATUS **prgPendingStatus) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::GetPendingRows\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetUpdate), L"This object is in a zombie state"); bool bPending = false; CCUBRIDRowsetRow *pRow = NULL; if(pcPendingRows) { *pcPendingRows = 0; if(prgPendingRows) *prgPendingRows = NULL; if(prgPendingStatus) *prgPendingStatus = NULL; } // Validate input parameters if ((dwRowStatus & ~(DBPENDINGSTATUS_NEW | DBPENDINGSTATUS_CHANGED | DBPENDINGSTATUS_DELETED)) != 0) return E_INVALIDARG; // Determine how many rows we'll need to return POSITION pos = m_rgRowHandles.GetStartPosition(); while( pos != NULL ) { MapClass::CPair* pPair = m_rgRowHandles.GetNext( pos ); ATLASSERT( pPair != NULL ); // Check to see if a row has a pending status pRow = pPair->m_value; if (pRow->m_status & dwRowStatus) { if (pcPendingRows != NULL) (*pcPendingRows)++; bPending = true; } } // In this case, there are no pending rows that match, just exit out if (!bPending) { // There are no pending rows so exit immediately return S_FALSE; } else { // Here' the consumer just wants to see if there are pending rows // we know that so we can exit if (pcPendingRows == NULL) return S_OK; } // Allocate arrays for pending rows { if (prgPendingRows != NULL) { *prgPendingRows = (HROW*)CoTaskMemAlloc(*pcPendingRows * sizeof(HROW)); if (*prgPendingRows == NULL) { *pcPendingRows = 0; return E_OUTOFMEMORY; } } if (prgPendingStatus != NULL) { *prgPendingStatus = (DBPENDINGSTATUS*)CoTaskMemAlloc(*pcPendingRows * sizeof(DBPENDINGSTATUS)); if (*prgPendingStatus == NULL) { *pcPendingRows = 0; CoTaskMemFree(*prgPendingRows); *prgPendingRows = NULL; return E_OUTOFMEMORY; } memset(*prgPendingStatus, 0, *pcPendingRows * sizeof(DBPENDINGSTATUS)); } } if (prgPendingRows || prgPendingStatus) { ULONG ulRows = 0; pos = m_rgRowHandles.GetStartPosition(); while( pos != NULL ) { MapClass::CPair* pPair = m_rgRowHandles.GetNext( pos ); ATLASSERT( pPair != NULL ); pRow = pPair->m_value; if (pRow->m_status & dwRowStatus) { // Add the output row pRow->AddRefRow(); if (prgPendingRows) ((*prgPendingRows)[ulRows]) = /*(HROW)*/pPair->m_key; if (prgPendingStatus) ((*prgPendingStatus)[ulRows]) = (DBPENDINGSTATUS)pRow->m_status; ulRows++; } } if (pcPendingRows != NULL) *pcPendingRows = ulRows; } // Return code depending on return S_OK; }
STDMETHODIMP CCUBRIDRowset::SetData(HROW hRow, HACCESSOR hAccessor, void *pData) { ATLTRACE(atlTraceDBProvider, 2, "CCUBRIDRowset::SetData\n"); ClearError(); if(m_nStatus==1) return RaiseError(E_UNEXPECTED, 1, __uuidof(IRowsetChange), L"This object is in a zombie state"); // cci_cursor_update를 이용하면 질의를 재실행할 때까지 SetData를 실행할 수 없다. // SQL and cci_execute를 이용하면 가능하다. CHECK_RESTART(__uuidof(IRowsetChange)); CHECK_UPDATABILITY(DBPROPVAL_UP_CHANGE); // Determine if we're in immediate or deferred mode bool bDeferred = IsDeferred(this); // Attempt to locate the row in our map CCUBRIDRowsetRow *pRow; { bool bFound = m_rgRowHandles.Lookup((ULONG)hRow, pRow); if(!bFound || pRow==NULL) return RaiseError(DB_E_BADROWHANDLE, 0, __uuidof(IRowsetChange)); } ATLASSERT( pRow->m_iRowset==(ULONG)-1 || pRow->m_iRowset<m_rgRowData.GetCount() ); // 이미 지워진 row if(pRow->m_status==DBPENDINGSTATUS_DELETED || pRow->m_status==DBPENDINGSTATUS_INVALIDROW) return RaiseError(DB_E_DELETEDROW, 0, __uuidof(IRowsetChange)); // 새로 삽입되었고 Storage로 전송됐다. if(pRow->m_iRowset==(ULONG)-1 && pRow->m_status!=DBPENDINGSTATUS_NEW) return DB_E_NEWLYINSERTED; // 바인딩 정보를 구함 ATLBINDINGS *pBinding; { bool bFound = m_rgBindings.Lookup((ULONG)hAccessor, pBinding); if(!bFound || pBinding==NULL) return RaiseError(DB_E_BADACCESSORHANDLE, 0, __uuidof(IRowsetChange)); if(!(pBinding->dwAccessorFlags & DBACCESSOR_ROWDATA)) return RaiseError(DB_E_BADACCESSORTYPE, 0, __uuidof(IRowsetChange)); // row accessor 가 아니다. if(pData==NULL && pBinding->cBindings!=0) return RaiseError(E_INVALIDARG, 0, __uuidof(IRowsetChange)); } HRESULT hr = pRow->ReadData(pBinding, pData, m_uCodepage); if(FAILED(hr)) return hr; // 새로 삽입된 row는 변경이 있어도 그냥 새로 삽입된 것으로 표시 if(pRow->m_status!=DBPENDINGSTATUS_NEW) pRow->m_status = DBPENDINGSTATUS_CHANGED; if(!bDeferred) { // 변화를 지금 적용 int hConn = GetSessionPtr()->GetConnection(); UINT uCodepage = GetSessionPtr()->GetCodepage(); hr = pRow->WriteData(hConn, uCodepage, GetRequestHandle(), m_strTableName); if (hr == DB_E_INTEGRITYVIOLATION) return RaiseError(DB_E_INTEGRITYVIOLATION, 0, __uuidof(IRowsetChange)); if(FAILED(hr)) return RaiseError(DB_E_ERRORSOCCURRED, 0, __uuidof(IRowsetChange)); pRow->m_status = 0; // or UNCHANGED? DoCommit(this); // commit } return hr; // S_OK or DB_S_ERRORSOCCURRED }
/// sets processor register void SetRegister(RegisterID enRegisterID, BYTE bValue) { ATLASSERT(enRegisterID <= regLast); m_abRegister[enRegisterID] = bValue; }
void CStatistic::ReplacePlaceholders( CString & szUrl, const CString & szType, const CString & szAction ) { if (szUrl.IsEmpty()) { ATLASSERT(FALSE); return; } if (m_szPID.IsEmpty()) { m_szPID = GetPID(); } if (m_szMID.IsEmpty()) { GetMID(m_szMID.GetBufferSetLength(MAX_PATH), MAX_PATH); } if (m_szAppVer.IsEmpty()) { WCHAR szFile[MAX_PATH] = {}; GetModuleFileName(g_hModule, szFile, MAX_PATH); PathRemoveFileSpec(szFile); PathRemoveFileSpec(szFile); PathAppend(szFile, APP_NAME); GetFileVer(szFile, m_szAppVer.GetBufferSetLength(MAX_PATH), MAX_PATH); } if (m_szModVer.IsEmpty()) { WCHAR szFile[MAX_PATH] = {}; GetModuleFileName(g_hModule, szFile, MAX_PATH); GetFileVer(szFile, m_szModVer.GetBufferSetLength(MAX_PATH), MAX_PATH); } if (szUrl.Find(URL_PID) > 0) { szUrl.Replace(URL_PID, m_szPID); } if (szUrl.Find(URL_MID) > 0) { szUrl.Replace(URL_MID, m_szMID); } if (szUrl.Find(URL_APP_VER) > 0) { szUrl.Replace(URL_APP_VER, m_szAppVer); } if (szUrl.Find(URL_MOD_VER) > 0) { szUrl.Replace(URL_MOD_VER, m_szModVer); } if (szUrl.Find(URL_TYPE) > 0) { szUrl.Replace(URL_TYPE, szType); } if (szUrl.Find(URL_ACTION) > 0) { szUrl.Replace(URL_ACTION, szAction); } }
CMsgOnlyWnd::~CMsgOnlyWnd() { ATLASSERT(NULL == hwnd_); }
int _tmain(int argc, _TCHAR* argv[]) { { //TP_CALLBACK_ENVIRON cbe = { 0 }; //::InitializeThreadpoolEnvironment(&cbe); //PTP_POOL ptpp = ::CreateThreadpool(NULL); //ATLASSERT(ptpp != NULL); //::SetThreadpoolThreadMaximum(ptpp, 16); //::SetThreadpoolCallbackPool(&cbe, ptpp); //PTP_CLEANUP_GROUP ptpcg = ::CreateThreadpoolCleanupGroup(); //::SetThreadpoolCallbackCleanupGroup(&cbe, ptpcg, NULL); //PTP_WORK ptpw = ::CreateThreadpoolWork(&WorkCallback1, (PVOID)&cbe, &cbe); //::SubmitThreadpoolWork(ptpw); { CHandle hEvent = (CHandle)::CreateEvent(NULL, TRUE, FALSE, NULL); DWORD dwThreadId = 0; CHandle hThread = (CHandle)::CreateThread(NULL, 0, &ThreadProc, (PVOID)&hEvent, 0, &dwThreadId); ::WaitForSingleObject(hEvent, INFINITE); ::InstallHook(); ::_getch(); ::UninstallHook(); CHandle hPipe = (CHandle)::CreateFile( NAMED_PIPE, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); DWORD dwLastError = ::GetLastError(); ATLASSERT(hPipe != INVALID_HANDLE_VALUE); DWORD dwMode = PIPE_READMODE_MESSAGE; ATLASSERT(::SetNamedPipeHandleState(hPipe, &dwMode, NULL, NULL)); TCHAR szBuf[BUF_SIZE]; DWORD dwBytes = 0; ::_stprintf_s(szBuf, _T("QUIT")); ::WriteFile(hPipe, szBuf, sizeof(szBuf), &dwBytes, NULL); ::FlushFileBuffers(hPipe); ::DisconnectNamedPipe(hPipe); ::WaitForSingleObject(hThread, INFINITE); } //::WaitForThreadpoolWorkCallbacks(ptpw, FALSE); //::CloseThreadpoolCleanupGroupMembers(ptpcg, FALSE, NULL); //::CloseThreadpoolCleanupGroup(ptpcg); //::CloseThreadpool(ptpp); } ::_getch(); return 0; }
HRESULT ThreadController::Resume(_In_ BREAKRESUMEACTION breakResumeAction, _In_ ERRORRESUMEACTION errorResumeAction) { ATLENSURE_RETURN_HR(ThreadHelpers::IsOnDispatchThread(m_dispatchThreadId), E_UNEXPECTED); if (!this->IsConnected() || !this->IsAtBreak()) { return E_NOT_VALID_STATE; } HRESULT hr = S_OK; // Scope for the CallFrame lock, the local smart pointer's addref will keep it alive after the lock CComPtr<IRemoteDebugApplicationThread> spDebugThreadKeepAlive; { // Lock the callstack, so that we are thread safe CComCritSecLock<CComAutoCriticalSection> lock(m_csCallFramesLock); // Create a local smart pointer to addRef so that it won't be released by the other thread while we are using it spDebugThreadKeepAlive = m_spCurrentBrokenThread; } if (spDebugThreadKeepAlive.p != nullptr) { // Since we are about to resume, we clear all the current break information this->ClearBreakInfo(); // By default we abort any errors so that exceptions execute the expected path. // If we want to support 'continue from exception' such as after using setNextStatement during an exception break, // we should pass in ERRORRESUMEACTION_SkipErrorStatement, // But we should not do that by default as it changes the behavior of exceptions when running under the debugger and should only be // enabled through a user action. unique_ptr<ResumeFromBreakpointInfo> spResumeFromBreakpointInfo(new ResumeFromBreakpointInfo()); spResumeFromBreakpointInfo->spDebugThread = spDebugThreadKeepAlive; spResumeFromBreakpointInfo->breakResumeAction = breakResumeAction; spResumeFromBreakpointInfo->errorResumeAction = errorResumeAction; // Get the IRemoteDebugApplication using our helper function that keeps it thread safe CComPtr<IRemoteDebugApplication> spDebugAppKeepAlive; hr = this->GetRemoteDebugApplication(spDebugAppKeepAlive); // We need to check if spDebugAppKeepAlive is null, since the debugger may have been activated // while debugging was disabled (e.g.: after the profiler started). // If that happened, then m_spDebugApplication would be null when we tried to AddRef it. if (hr == S_OK && spDebugAppKeepAlive.p != nullptr) { // Get the IDebugApplicationThread interface used to make the actual thread switch call #ifdef _WIN64 CComQIPtr<IDebugApplicationThread64> spDebugThread(spDebugThreadKeepAlive); #else CComQIPtr<IDebugApplicationThread> spDebugThread(spDebugThreadKeepAlive); #endif ATLENSURE_RETURN_HR(spDebugThread.p != nullptr, E_NOINTERFACE); CComQIPtr<IDebugApplication> spDebugApp(spDebugAppKeepAlive); ATLENSURE_RETURN_HR(spDebugApp.p != nullptr, E_NOINTERFACE); // Create an object for thread switching on to the debugger thread CComObject<PDMThreadCallback>* pCall; hr = CComObject<PDMThreadCallback>::CreateInstance(&pCall); BPT_FAIL_IF_NOT_S_OK(hr); // We need to make sure that all pending 'Eval' calls have been completed on the current thread before we resume, otherwise the PDM will attempt // to dequeue and execute an eval after we have resumed, causing chakra to assert that the debugging session has changed (eval started on previous break) // Queuing a request onto the Sync Queue in the PDM will make sure that the Async evals have completed before we execute our resume. // This is because the PDM executes all Async requests before any Sync ones (see CProcessThread::DoRequest() - debugger\pdm\scpthred.cpp) CComObjPtr<PDMThreadCallback> spCall(pCall); hr = spDebugThread->SynchronousCallIntoThread(spCall, (DWORD)PDMThreadCallbackMethod::CompleteEvals, (DWORD_PTR)spDebugApp.p, (DWORD_PTR)nullptr); ATLASSERT(hr == S_OK); // We want to try a resume even if this fails (in retail bits) } // We need to call resume on the debugger thread so that we get the internal pdm locks in the correct order: // m_csCrossThreadCallLock then m_csBreakPoint // If we call ResumeFromBreakPoint directly, we will end up getting the locks in the reverse order which can cause a deadlock. hr = this->CallDebuggerThread(PDMThreadCallbackMethod::Resume, (DWORD_PTR)nullptr, (DWORD_PTR)spResumeFromBreakpointInfo.release()); // This could fail if we already disconnected, so don't assert, but do return the hr } else { // We are no longer at a break return E_NOT_VALID_STATE; } // The synchronous call to resume can occasionally cause a PDM break, if that happens, we will still be at a break here, so don't update IE if (!this->IsAtBreak()) { // Inform the BHO that we have resumed from the break // We need to use send message to make sure that the pipe handler has sent the message to the BHO before we // continue processing messages ::SendMessageW(m_hwndDebugPipeHandler, WM_BREAKMODECHANGED, /*IsAtBreak=*/ FALSE, NULL); } return hr; }
/// converts opaque data source pointer to IStream static Stream::IStream& ToStream(void* datasource) { ATLASSERT(datasource != NULL); return *reinterpret_cast<Stream::IStream*>(datasource); }
/* void SetPaneWidths(int* arrWidths, int nPanes) { // find the size of the borders int arrBorders[3]; m_status.GetBorders(arrBorders); // calculate right edge of default pane (0) arrWidths[0] += arrBorders[2]; for (int i = 1; i < nPanes; i++) arrWidths[0] += arrWidths[i]; // calculate right edge of remaining panes (1 thru nPanes-1) for (int j = 1; j < nPanes; j++) arrWidths[j] += arrBorders[2] + arrWidths[j - 1]; // set the pane widths m_status.SetParts(m_status.m_nPanes, arrWidths); } */ LRESULT CMainFrame::OnCreate(LPCREATESTRUCT /*lParam*/) { // // create command bar window // HWND hWndCmdBar = m_CmdBar.Create( m_hWnd, rcDefault, NULL, ATL_SIMPLE_CMDBAR_PANE_STYLE); // attach menu m_CmdBar.AttachMenu(GetMenu()); // load command bar images m_CmdBar.SetImageSize(CSize(9,9)); // m_CmdBar.LoadImages(IDR_MAINFRAME); // remove old menu SetMenu(NULL); // set title WTL::CString strTitle; strTitle.LoadString( IDS_APPLICATION ); SetWindowText(strTitle); // // setting up a tool bar // HWND hWndToolBar = CreateSimpleToolBarCtrl( m_hWnd, IDR_MAINFRAME, FALSE, ATL_SIMPLE_TOOLBAR_PANE_STYLE | TBSTYLE_LIST); m_wndToolBar.Attach( hWndToolBar ); m_wndToolBar.SetExtendedStyle( TBSTYLE_EX_MIXEDBUTTONS | TBSTYLE_EX_DRAWDDARROWS ); // // patria: // // Some bitmaps are distorted when used with TB_ADDBITMAP // which is sent from CreateSimpleToolBarCtrl when the bitmap is not true color. // This is the case with IO-DATA's tool bar image. // As an workaround, we can directly create a image list directly // and replace the image list of the tool bar, which corrects such misbehaviors. // { CImageList imageList; WORD wWidth = 32; // we are using 32 x 32 buttons imageList.CreateFromImage( IDR_MAINFRAME, wWidth, 1, CLR_DEFAULT, IMAGE_BITMAP, LR_CREATEDIBSECTION | LR_DEFAULTSIZE); m_wndToolBar.SetImageList(imageList); } TBBUTTON tbButton = { 0 }; TBBUTTONINFO tbButtonInfo = { 0 }; TBREPLACEBITMAP replaceBitmap = { 0 }; // Add strings to the tool bar m_wndToolBar.SetButtonStructSize(sizeof(TBBUTTON)); for ( int i=0; i < m_wndToolBar.GetButtonCount(); i++ ) { WTL::CString strCommand; m_wndToolBar.GetButton( i, &tbButton ); tbButtonInfo.cbSize = sizeof(TBBUTTONINFO); tbButtonInfo.dwMask = TBIF_STYLE; m_wndToolBar.GetButtonInfo( tbButton.idCommand, &tbButtonInfo ); tbButtonInfo.dwMask = TBIF_TEXT | TBIF_STYLE; strCommand.LoadString( tbButton.idCommand ); strCommand = strCommand.Right( strCommand.GetLength() - strCommand.Find('\n') - 1 ); tbButtonInfo.pszText = const_cast<LPTSTR>(static_cast<LPCTSTR>(strCommand)); tbButtonInfo.cchText = strCommand.GetLength(); tbButtonInfo.fsStyle |= BTNS_SHOWTEXT | BTNS_AUTOSIZE; m_wndToolBar.AddString( tbButton.idCommand ); m_wndToolBar.SetButtonInfo( tbButton.idCommand, &tbButtonInfo ); } // // Modify mirror button as drop down button // { TBBUTTON tb; m_wndToolBar.GetButton( m_wndToolBar.CommandToIndex(IDM_AGGR_MIRROR), &tb); TBBUTTONINFO tbi = {0}; tbi.cbSize = sizeof(TBBUTTONINFO); tbi.dwMask = TBIF_STYLE; m_wndToolBar.GetButtonInfo(IDM_AGGR_MIRROR, &tbi); tbi.fsStyle |= TBSTYLE_DROPDOWN; m_wndToolBar.SetButtonInfo( IDM_AGGR_MIRROR, &tbi); } #define ATL_CUSTOM_REBAR_STYLE \ ((ATL_SIMPLE_REBAR_STYLE & ~RBS_AUTOSIZE) | CCS_NODIVIDER) // // patria: reason to use ATL_CUSTOM_REBAR_STYLE // // ATL_SIMPLE_REBAR_STYLE (not a NO_BRODER style) has a problem // with theme-enabled Windows XP, // rendering some transparent lines above the rebar. // CreateSimpleReBar(ATL_CUSTOM_REBAR_STYLE); AddSimpleReBarBand(hWndCmdBar); AddSimpleReBarBand(m_wndToolBar.m_hWnd, NULL, TRUE); CReBarCtrl reBar = m_hWndToolBar; DWORD cBands = reBar.GetBandCount(); for (DWORD i = 0; i < cBands; ++i) { REBARBANDINFO rbi = {0}; rbi.cbSize = sizeof(REBARBANDINFO); rbi.fMask = RBBIM_STYLE; reBar.GetBandInfo(i, &rbi); rbi.fStyle |= RBBS_NOGRIPPER; reBar.SetBandInfo(i, &rbi); } // work on status bar, progress bar CreateSimpleStatusBar(); RECT rectRefreshProgress; ::GetClientRect(m_hWndStatusBar, &rectRefreshProgress); rectRefreshProgress.right = 300; m_wndRefreshProgress.Create(m_hWndStatusBar, &rectRefreshProgress, NULL, WS_CHILD | WS_VISIBLE); m_wndRefreshProgress.SetRange32(0, 100); m_wndRefreshProgress.SetPos(50); m_wndRefreshProgress.ShowWindow(SW_HIDE); m_viewTreeList.Create( *this, rcDefault, NULL, WS_BORDER | WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); m_viewTreeList.Initialize(); m_hWndClient = m_viewTreeList; UIAddToolBar(m_wndToolBar); UISetCheck(ID_VIEW_TOOLBAR, 1); UISetCheck(ID_VIEW_STATUS_BAR, 1); // TODO : It will be better if we display splash window while // the treeview is initialized m_bRefreshing = FALSE; ::InitializeCriticalSection(&m_csThreadRefreshStatus); PostMessage(WM_COMMAND, IDM_AGGR_REFRESH, 0); m_hEventCallback = ::NdasRegisterEventCallback(pNdasEventProc,m_hWnd); // register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); // FIXME : We need to remember the window size CRect rectResize; GetClientRect( rectResize ); rectResize = CRect( rectResize.TopLeft(), CSize(500, 500) ); ClientToScreen( rectResize ); MoveWindow( rectResize ); CenterWindow(); return 0; }
BOOL CNBLogicalDevice::GetCommandAbility(int nID) { if (IsGroup()) { switch(nID) { case IDM_TOOL_BIND: return TRUE; case IDM_TOOL_UNBIND: // Cannot unbind devices in use. return !(GetStatus() & NDASBIND_LOGICAL_DEVICE_STATUS_MOUNTED); case IDM_TOOL_ADDMIRROR: return FALSE; case IDM_TOOL_MIGRATE: return ( IsHDD() && IsMigrationRequired() && IsOperatableAll() && !HasMissingMember()); case IDM_TOOL_REPLACE_DEVICE: return FALSE; case IDM_TOOL_USE_AS_MEMBER: return FALSE; case IDM_TOOL_SPAREADD: return (IsFaultTolerant() && !IsMigrationRequired() && IsOperatableAll() && IsHealthy() && DevicesSpare(FALSE)==0); case IDM_TOOL_RESET_BIND_INFO: return FALSE; case IDM_TOOL_CLEAR_DEFECTIVE: return FALSE; case IDM_TOOL_USE_AS_BASIC: return FALSE; case IDM_TOOL_REMOVE_FROM_RAID: return FALSE; default: ATLASSERT(FALSE); return FALSE; } } else { // Basic disk type. switch(nID) { case IDM_TOOL_BIND: return TRUE; case IDM_TOOL_UNBIND: return FALSE; case IDM_TOOL_ADDMIRROR: return (IsHDD() && IsOperatableAll()); case IDM_TOOL_MIGRATE: return FALSE; case IDM_TOOL_REPLACE_DEVICE: return FALSE; case IDM_TOOL_USE_AS_MEMBER: return FALSE; case IDM_TOOL_SPAREADD: return FALSE; case IDM_TOOL_RESET_BIND_INFO: return (IsHDD() && IsOperatable()); case IDM_TOOL_CLEAR_DEFECTIVE: return FALSE; case IDM_TOOL_USE_AS_BASIC: return FALSE; case IDM_TOOL_REMOVE_FROM_RAID: return FALSE; default: ATLASSERT(FALSE); return FALSE; } } return FALSE; }
void CMainFrame::OnContextMenu(HWND /*hWnd*/, CPoint pos) { if(m_bRefreshing) return; ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); int selectedItemData; // get selectedItemData CRect rect; CPoint posInView; HTREEITEM hItemSelected; // if clicked on tree, we need to change selection if (m_viewTreeList.GetWindowRect( rect ) && rect.PtInRect(pos) ) { CTreeViewCtrlEx ctrlTree = m_viewTreeList.GetTreeControl(); CHeaderCtrl ctrlHeader = m_viewTreeList.GetHeaderControl(); CRect rectHeader; ctrlHeader.GetClientRect(rectHeader); // clicked point is inside the tree control // Change screen coordinates to client coordinates posInView = pos - rect.TopLeft(); posInView.y -= rectHeader.Height(); if(NULL == (hItemSelected = ctrlTree.HitTest(posInView, NULL))) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; } ctrlTree.SelectItem(hItemSelected); } selectedItemData = m_viewTreeList.GetSelectedItemData(); // Display context menu CMenu menu; CMenuHandle subMenu; CDiskObjectPtr obj = m_mapObject[selectedItemData]; ATLASSERT( obj.get() != NULL ); menu.LoadMenu( MAKEINTRESOURCE(IDR_CONTEXT_MENU) ); subMenu = menu.GetSubMenu(0); CObjectUIHandler::GetUIHandler(obj)->InsertMenu(obj, subMenu); ATLTRACE(_T("Menu Count : %d"), subMenu.GetMenuItemCount()); subMenu.RemoveMenu(IDM_AGGR_PROPERTY, MF_BYCOMMAND); // subMenu.RemoveMenu(MF_BYPOSITION, subMenu.GetMenuItemCount()); subMenu.TrackPopupMenu( TPM_LEFTALIGN | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, pos.x, pos.y, m_hWnd ); LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; }
BOOL CNBUnitDevice::GetCommandAbility(int nID) { switch(nID) { case IDM_TOOL_BIND: return TRUE; case IDM_TOOL_UNBIND: return FALSE; case IDM_TOOL_ADDMIRROR: // Should be single logical device return FALSE; case IDM_TOOL_MIGRATE: // Should be single logical device return FALSE; case IDM_TOOL_REMOVE_FROM_RAID: if (!(NDASBIND_UNIT_DEVICE_STATUS_MOUNTED & GetStatus()) && IsFaultTolerant() && GetLogicalDevice()->DevicesSpare() && GetLogicalDevice()->IsOperatable() && !(GetRaidStatus() & NDAS_RAID_MEMBER_FLAG_IRRECONCILABLE)) { // Available only for redundant RAID with spare disk. return TRUE; } return FALSE; case IDM_TOOL_REPLACE_DEVICE: if (!(NDASBIND_UNIT_DEVICE_STATUS_MOUNTED & GetStatus()) && IsFaultTolerant() && GetLogicalDevice()->IsOperatable() && !(GetRaidStatus() & NDAS_RAID_MEMBER_FLAG_IRRECONCILABLE)) { // // Available only for redundant RAID. More check is required by OnReplaceDevice // // Later we may add replace device for aggregation/RAID0 by copying disk contents and reconfiguration. // return TRUE; } return FALSE; case IDM_TOOL_USE_AS_MEMBER: if (IsFaultTolerant() && IsOperatable() && (GetRaidStatus() & NDAS_RAID_MEMBER_FLAG_INVALID_MEMBER) && GetLogicalDevice()->IsOperatable()&& !(GetRaidStatus() & NDAS_RAID_MEMBER_FLAG_IRRECONCILABLE)) { // This command is available only for the disk that is online and has no physical error but is currently not a member. // And logical device is not in use. return TRUE; } return FALSE; // case IDM_TOOL_SINGLE: // return (IsHDD() && IsOperatable()); case IDM_TOOL_SPAREADD: return FALSE; case IDM_TOOL_RESET_BIND_INFO: return FALSE; case IDM_TOOL_CLEAR_DEFECTIVE: if (IsOperatable() && IsDefective() && GetLogicalDevice()->IsOperatable()) { return TRUE; } return FALSE; case IDM_TOOL_USE_AS_BASIC: if (IsFaultTolerant() && IsOperatable() && !IsMissingMember() && GetLogicalDevice()->IsOperatable()) { return TRUE; } return FALSE; // case IDM_TOOL_SPAREREMOVE: // return (IsFaultTolerant() && IsSpare() && m_pLogicalDevice->IsOperatableAll()); default: ATLASSERT(FALSE); return TRUE; } }
void CMainFrame::OnAddMirror(UINT /*wNotifyCode*/, int /*wID*/, HWND /*hwndCtl*/) { ENTER_CRITICAL_SECTION(&m_csThreadRefreshStatus); int iItemSelected = m_viewTreeList.GetSelectedItemData(); if (-1 == iItemSelected) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); return; } CDiskObjectList singleDisks; CUnitDiskObjectPtr sourceDisk; sourceDisk = boost::dynamic_pointer_cast<CUnitDiskObject>( m_mapObject[iItemSelected] ); ATLASSERT( sourceDisk.get() != NULL ); CFindIfVisitor<FALSE> singleDiskFinder; singleDisks = singleDiskFinder.FindIf(m_pRoot, IsWritableUnitDisk); singleDisks.remove( sourceDisk ); if ( singleDisks.size() == 0 ) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); // TODO : No disk is available WTL::CString strMsg; strMsg.LoadString( IDS_MAINFRAME_NO_DISK_TO_MIRROR ); WTL::CString strTitle; strTitle.LoadString(IDS_APPLICATION); MessageBox( strMsg, strTitle, MB_OK | MB_ICONWARNING ); return; } DWORD UnitNo = 0; CSelectMirDlg dlgSelDisk(IDD_ADDMIR); dlgSelDisk.SetSingleDisks( singleDisks ); dlgSelDisk.SetSourceDisk( sourceDisk ); if ( dlgSelDisk.DoModal() == IDOK ) { CUnitDiskObjectPtr mirDisk = dlgSelDisk.GetSelectedDisk(); // Bind & Synchronize NDASCOMM_CONNECTION_INFO ConnectionInfo[2]; ZeroMemory(&ConnectionInfo[0], sizeof(NDASCOMM_CONNECTION_INFO)); ConnectionInfo[0].address_type = NDASCOMM_CONNECTION_INFO_TYPE_ADDR_LPX; ConnectionInfo[0].login_type = NDASCOMM_LOGIN_TYPE_NORMAL; ConnectionInfo[0].UnitNo = sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber; ConnectionInfo[0].bWriteAccess = TRUE; ConnectionInfo[0].ui64OEMCode = NULL; ConnectionInfo[0].bSupervisor = FALSE; ConnectionInfo[0].protocol = NDASCOMM_TRANSPORT_LPX; CopyMemory(ConnectionInfo[0].AddressLPX, sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, LPXADDR_NODE_LENGTH); ZeroMemory(&ConnectionInfo[1], sizeof(NDASCOMM_CONNECTION_INFO)); ConnectionInfo[1].address_type = NDASCOMM_CONNECTION_INFO_TYPE_ADDR_LPX; ConnectionInfo[1].login_type = NDASCOMM_LOGIN_TYPE_NORMAL; ConnectionInfo[1].UnitNo = mirDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber; ConnectionInfo[1].bWriteAccess = TRUE; ConnectionInfo[1].ui64OEMCode = NULL; ConnectionInfo[1].bSupervisor = FALSE; ConnectionInfo[1].protocol = NDASCOMM_TRANSPORT_LPX; CopyMemory(ConnectionInfo[1].AddressLPX, mirDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, LPXADDR_NODE_LENGTH); UINT32 BindResult = NdasOpBind( 2, ConnectionInfo, NMT_SAFE_RAID1); if(2 != BindResult) { LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); WTL :: CString strMsg; DWORD dwLastError = ::GetLastError(); switch(dwLastError) { case NDASCOMM_ERROR_RW_USER_EXIST: case NDASOP_ERROR_ALREADY_USED: case NDASOP_ERROR_DEVICE_FAIL: case NDASOP_ERROR_NOT_SINGLE_DISK: case NDASOP_ERROR_DEVICE_UNSUPPORTED: strMsg.FormatMessage(IDS_BIND_FAIL_AT_SINGLE_NDAS_FMT, (BindResult == 0) ? sourceDisk->GetTitle() : mirDisk->GetTitle()); break; default: strMsg.LoadString(IDS_BIND_FAIL); break; } ShowErrorMessageBox(strMsg); return; } CNdasHIXChangeNotify HixChangeNotify(pGetNdasHostGuid()); BOOL bResults = HixChangeNotify.Initialize(); if(bResults) { NDAS_UNITDEVICE_ID unitDeviceId; CopyMemory(unitDeviceId.DeviceId.Node, sourceDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, sizeof(unitDeviceId.DeviceId.Node)); unitDeviceId.UnitNo = sourceDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber; HixChangeNotify.Notify(unitDeviceId); CopyMemory(unitDeviceId.DeviceId.Node, mirDisk->GetLocation()->GetUnitDiskLocation()->MACAddr, sizeof(unitDeviceId.DeviceId.Node)); unitDeviceId.UnitNo = mirDisk->GetLocation()->GetUnitDiskLocation()->UnitNumber; HixChangeNotify.Notify(unitDeviceId); } CRecoverDlg dlgRecover(FALSE, IDS_LOGDEV_TYPE_DISK_RAID1, IDS_RECOVERDLG_TASK_ADD_MIRROR); dlgRecover.SetMemberDevice(mirDisk); dlgRecover.DoModal(); OnRefreshStatus(NULL, NULL, NULL); } LEAVE_CRITICAL_SECTION(&m_csThreadRefreshStatus); }
UINT32 CNBLogicalDevice::GetType() { ATLASSERT(m_mapUnitDevices.size()); return DIB()->iMediaType; }
UINT pCacheMsiToSystem( ISetupUI* pSetupUI, LPCTSTR szMsiFile, LPTSTR szCachedMsiFile, DWORD cchMax) { TCHAR szMsiFileFullPath[MAX_PATH] = {0}; LPTSTR lpFilePart = NULL; DWORD nChars = ::GetFullPathName( szMsiFile, MAX_PATH, szMsiFileFullPath, &lpFilePart); if (0 == nChars) { DWORD dwErr = GetLastError(); DBGPRT_ERR_EX(_FT("GetFullPathName %s failed: "), szMsiFile); return dwErr; } TCHAR szCacheFile[MAX_PATH] = {0}; // nChars = GetSystemWindowsDirectory(szCacheFile, MAX_PATH); nChars = GetWindowsDirectory(szCacheFile, MAX_PATH); if (0 == nChars) { DWORD dwErr = GetLastError(); DBGPRT_ERR_EX(_FT("GetSystemWindowsDirectory failed: ")); return dwErr; } HRESULT hr = StringCchCat(szCacheFile, MAX_PATH, _T("\\")); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); return HRESULT_CODE(hr); } hr = StringCchCat(szCacheFile, MAX_PATH, MSICACHE_DIRECTORY); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); return HRESULT_CODE(hr); } LPTSTR szPackageCode = pGetMsiPackageCode(szMsiFile); if (NULL == szPackageCode) { DWORD dwErr = GetLastError(); return dwErr; } if (szPackageCode[0] != _T('\0')) { hr = StringCchCat(szCacheFile, MAX_PATH, _T("\\")); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); GlobalFree((HGLOBAL)szPackageCode); return HRESULT_CODE(hr); } hr = StringCchCat(szCacheFile, MAX_PATH, szPackageCode); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); GlobalFree((HGLOBAL)szPackageCode); return HRESULT_CODE(hr); } GlobalFree((HGLOBAL)szPackageCode); } hr = StringCchCat(szCacheFile, MAX_PATH, _T("\\")); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); return HRESULT_CODE(hr); } hr = StringCchCat(szCacheFile, MAX_PATH, lpFilePart); if (FAILED(hr)) { DBGPRT_ERR_EX(_FT("StringCchCat failed: ")); return HRESULT_CODE(hr); } SHFILEOPSTRUCT shop; shop.hwnd = pSetupUI->GetCurrentWindow(); shop.wFunc = FO_COPY; shop.pFrom = szMsiFileFullPath; // doubly NULL-terminated!! shop.pTo = szCacheFile; shop.fFlags = FOF_FILESONLY | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOCOPYSECURITYATTRIBS | FOF_SILENT; INT iRet = SHFileOperation(&shop); if (ERROR_SUCCESS != iRet) { DWORD dwErr = GetLastError(); CString str; str.FormatMessage(IDS_ERR_CACHING_TO_SYSTEM_FMT,szCacheFile); pSetupUI->PostErrorMessageBox(GetLastError(),str); return dwErr; } hr = StringCchCopy(szCachedMsiFile, cchMax, szCacheFile); ATLASSERT(SUCCEEDED(hr)); return ERROR_SUCCESS; }
LRESULT CMainDlg::OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/) { // center the dialog on the screen CenterWindow(); // Set window icon SetIcon(::LoadIcon(_Module.GetResourceInstance(), MAKEINTRESOURCE(IDR_MAINFRAME)), 0); // Load heading icon HMODULE hExeModule = LoadLibrary(m_sImageName); if(hExeModule) { // Use IDR_MAINFRAME icon which is the default one for the crashed application. m_HeadingIcon = ::LoadIcon(hExeModule, MAKEINTRESOURCE(IDR_MAINFRAME)); } // If there is no IDR_MAINFRAME icon in crashed EXE module, use IDI_APPLICATION system icon if(m_HeadingIcon == NULL) { m_HeadingIcon = ::LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION)); } m_link.SubclassWindow(GetDlgItem(IDC_LINK)); m_link.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON); m_linkMoreInfo.SubclassWindow(GetDlgItem(IDC_MOREINFO)); m_linkMoreInfo.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON); m_statEmail = GetDlgItem(IDC_STATMAIL); m_editEmail = GetDlgItem(IDC_EMAIL); m_statDesc = GetDlgItem(IDC_DESCRIBE); m_editDesc = GetDlgItem(IDC_DESCRIPTION); m_statCrashRpt = GetDlgItem(IDC_CRASHRPT); m_statHorzLine = GetDlgItem(IDC_HORZLINE); m_btnOk = GetDlgItem(IDOK); m_btnCancel = GetDlgItem(IDCANCEL); CRect rc1, rc2; m_linkMoreInfo.GetWindowRect(&rc1); m_statHorzLine.GetWindowRect(&rc2); m_nDeltaY = rc1.bottom+15-rc2.top; LOGFONT lf; memset(&lf, 0, sizeof(LOGFONT)); lf.lfHeight = 25; lf.lfWeight = FW_NORMAL; lf.lfQuality = ANTIALIASED_QUALITY; _TCSCPY_S(lf.lfFaceName, 32, _T("Tahoma")); m_HeadingFont.CreateFontIndirect(&lf); ShowMoreInfo(FALSE); m_dlgProgress.Create(m_hWnd); // register object for message filtering and idle updates CMessageLoop* pLoop = _Module.GetMessageLoop(); ATLASSERT(pLoop != NULL); pLoop->AddMessageFilter(this); pLoop->AddIdleHandler(this); UIAddChildWindowContainer(m_hWnd); return TRUE; }
// // Caller should free the resource for non-NULL return values // with GlobalFree // static LPTSTR pGetMsiPackageCode(LPCTSTR szMsiFile) { MSIHANDLE hSummaryInfo = 0; CMsiApi msiApi; BOOL fSuccess = msiApi.Initialize(); if (!fSuccess) { DBGPRT_ERR(_FT("MSIAPI functions are not available.\n")); SetLastError(ERROR_PROC_NOT_FOUND); return NULL; } UINT uiRet = msiApi.GetSummaryInformation(0, szMsiFile, 0, &hSummaryInfo); if (ERROR_SUCCESS != uiRet) { SetLastError(uiRet); DBGPRT_ERR_EX(_FT("MsiGetSummaryInformation failed: ")); return NULL; } UINT uiDataType; INT iValue; FILETIME ftValue; DWORD cchMax = 0; // // Get Package Code (PID_REVNUMBER) // uiRet = msiApi.SummmaryInfoGetProperty( hSummaryInfo, PID_REVNUMBER, &uiDataType, &iValue, &ftValue, _T(""), // do not pass NULL &cchMax); ATLASSERT(VT_LPSTR == uiDataType); if (ERROR_SUCCESS == uiRet) { ATLASSERT(FALSE); return _T(""); } else if (ERROR_MORE_DATA != uiRet) { SetLastError(uiRet); DBGPRT_ERR_EX(_FT("MsiSummaryInfoGetProperty PID_REVNUMBER failed: ")); return NULL; } ++cchMax; // Add NULL LPTSTR szPackageCode = (LPTSTR) ::GlobalAlloc(GPTR, (cchMax) * sizeof(TCHAR)); if (NULL == szPackageCode) { DBGPRT_ERR_EX(_FT("GlobalAlloc %d chars failed: "), cchMax ); return NULL; } uiRet = msiApi.SummmaryInfoGetProperty( hSummaryInfo, PID_REVNUMBER, &uiDataType, &iValue, &ftValue, szPackageCode, &cchMax); ATLASSERT(VT_LPSTR == uiDataType); if (ERROR_SUCCESS != uiRet) { DBGPRT_ERR_EX(_FT("SummmaryInfoGetProperty PID_REVNUMBER failed for %d chars: "), cchMax); ::GlobalFree((HGLOBAL)szPackageCode); return NULL; } return szPackageCode; }
STDMETHODIMP CLHTMLWindow2::GetIDsOfNames( REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid ) { HRESULT hr; hr = IDispatchExImpl<CLHTMLWindow2, DispILHTMLWindow, &IID_DispILHTMLWindow, &LIBID_LHTMLLib>::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (SUCCEEDED(hr)) { return hr; } ATLASSERT(0); #if 0 // TODO have this if (m_pActiveDocument->m_containerScriptDispatch) { hr = m_pActiveDocument->m_containerScriptDispatch->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (SUCCEEDED(hr)) { ATLASSERT(rgdispid[0] >= 0); rgdispid[0] += 2000; return hr; } } #endif return hr; #if 0 for (int i = 0; i < cNames; i++) { DISPID dispid; hr = IDispatchImpl<DispILHTMLWindow, &IID_DispILHTMLWindow, &LIBID_LHTMLLib>::GetIDsOfNames(riid, &rgszNames[i], 1, lcid, &dispid); if (SUCCEEDED(hr)) { rgdispid[i] = dispid; continue; } hr = m_pActiveDocument->m_containerScriptDispatch->GetIDsOfNames(riid, &rgszNames[i], 1, lcid, &dispid); if (SUCCEEDED(hr)) { ATLASSERT(dispid >= 0); rgdispid[i] = dispid+2000; continue; } } #endif #if 0 hr = m_pFrame->m_pHTMLWindowImpl->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (FAILED(hr)) hr = m_pFrame->m_pHTMLDialogImpl->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (FAILED(hr)) { hr = m_pFrame->m_pScriptDisp->GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); if (SUCCEEDED(hr)) { if (*rgdispid < 100) ATLASSERT(0); } } #endif return hr; }
void CRunView::AddMenuItems(HMENU hMenu, IDrawMenu* pMenu, int& nIndex, int nCount, int nDepth) { USES_CONVERSION; HTREEITEM hItem = NULL; while (nIndex < nCount) { CComBSTR bstrItemText; pMenu->GetItemText(nIndex + 1, &bstrItemText); int nItemDepth = 0; LPCWSTR p = bstrItemText; while (*p++ == '.') nItemDepth++; if (nItemDepth < nDepth) { nIndex--; break; } int nNextItemDepth = nItemDepth; if (nIndex + 1 < nCount) { nNextItemDepth = 0; CComBSTR bstrNextItemText; pMenu->GetItemText(nIndex + 2, &bstrNextItemText); LPCWSTR p = bstrNextItemText; while (*p++ == '.') nNextItemDepth++; } if (nNextItemDepth > nItemDepth) { HMENU hNewMenu = CreatePopupMenu(); ATLASSERT(hNewMenu != NULL); AddMenuItems(hNewMenu, pMenu, ++nIndex, nCount, nDepth + 1); AppendMenu(hMenu, MF_POPUP, (UINT)hNewMenu, OLE2T(bstrItemText + nItemDepth)); } else { CString strItemText = bstrItemText + nItemDepth; if (strItemText == _T("-")) { AppendMenu(hMenu, MF_SEPARATOR, 0, 0); } else { long lShift = 0; pMenu->GetItemAccelShift(nIndex + 1, &lShift); long lKeyCode = 0; pMenu->GetItemAccelKeyCode(nIndex + 1, &lKeyCode); ACCEL accel; accel.fVirt = FVIRTKEY; if ((lShift & 1) != 0) accel.fVirt |= FSHIFT; if ((lShift & 2) != 0) accel.fVirt |= FCONTROL; if ((lShift & 4) != 0) accel.fVirt |= FALT; accel.key = (USHORT)lKeyCode; accel.cmd = nIndex + 1; m_arrAccels.Add(accel); CString strAccel = GetAccelKeyName(lShift, lKeyCode); if (!strAccel.IsEmpty()) { strItemText += _T("\t"); strItemText += strAccel; } AppendMenu(hMenu, MF_STRING | MF_BYCOMMAND, nIndex + 1, strItemText); } } nIndex++; } }