/* This compares two variants for equality */ static int com_objects_compare(zval *object1, zval *object2) { php_com_dotnet_object *obja, *objb; int ret; /* strange header bug problem here... the headers define the proto without the * flags parameter. However, the MSDN docs state that there is a flags parameter, * and my VC6 won't link unless the code uses the version with 4 parameters. * So, we have this declaration here to fix it */ STDAPI VarCmp(LPVARIANT pvarLeft, LPVARIANT pvarRight, LCID lcid, DWORD flags); obja = CDNO_FETCH(object1); objb = CDNO_FETCH(object2); switch (VarCmp(&obja->v, &objb->v, LOCALE_SYSTEM_DEFAULT, 0)) { case VARCMP_LT: ret = -1; break; case VARCMP_GT: ret = 1; break; case VARCMP_EQ: ret = 0; break; default: /* either or both operands are NULL... * not 100% sure how to handle this */ ret = -2; } return ret; }
HRESULT STDMETHODCALLTYPE TextAreaTextRange::FindAttribute(_In_ TEXTATTRIBUTEID textAttributeId, _In_ VARIANT val, _In_ BOOL searchBackward, _Outptr_result_maybenull_ ITextRangeProvider **retVal) { HRESULT hr = S_OK; *retVal = NULL; EndPoint start = searchBackward ? _range.end : _range.begin; EndPoint finish = searchBackward ? _range.begin : _range.end; EndPoint current = start; // This will loop until 'current' passes or is equal to the end while (QuickCompareEndpoints(searchBackward ? finish : current, searchBackward ? current : finish) < 0) { int walked; EndPoint next = Walk(current, !searchBackward, TextUnit_Format, textAttributeId, 1, &walked); VARIANT curValue = _control->GetAttributeAtPoint(searchBackward ? current : next, textAttributeId); hr = VarCmp(&val, &curValue, LOCALE_NEUTRAL); if (hr == VARCMP_EQ) { Range found; found.begin = searchBackward ? next : current; // For line based attributes, the start character will be the end of the previous line // bump it up one to make it an even line for (int i = 0; i < ARRAYSIZE(lineVariableAttributes); i++) { if (textAttributeId == lineVariableAttributes[i]) { if (found.begin.character > 0) { found.begin.character = 0; found.begin.line++; } break; } } // If next is past the end of the current range, end at the end of the current range instead if (QuickCompareEndpoints(searchBackward ? finish : next, searchBackward ? next : finish) > 0) { found.end = finish; } else { found.end = searchBackward ? current : next; } *retVal = new TextAreaTextRange(_hwnd, _control, found); if (*retVal == NULL) { hr = E_OUTOFMEMORY; } break; } current = next; } return hr; }
int CXTPReportRecordItemVariant::Compare(CXTPReportColumn*, CXTPReportRecordItem* pItem) { if (GetSortPriority() != -1 || pItem->GetSortPriority() != -1) return GetSortPriority() - pItem->GetSortPriority(); CXTPReportRecordItemVariant* pItemVariant = DYNAMIC_DOWNCAST(CXTPReportRecordItemVariant, pItem); if (!pItemVariant) return 0; ULONG dwFlags = m_pRecord->GetRecords()->IsCaseSensitive() ? 0 : NORM_IGNORECASE; LCID lcidnSortLocale = m_nSortLocale; if (lcidnSortLocale == LOCALE_USER_DEFAULT) { lcidnSortLocale = CXTPReportControlLocale::GetActiveLCID(); } return VarCmp(m_oleValue, pItemVariant->m_oleValue, lcidnSortLocale, dwFlags) - VARCMP_EQ; }
bool TextAreaTextRange::CheckEndPointIsUnitEndpoint(_In_ EndPoint check, _In_ TextUnit unit, _In_ TEXTATTRIBUTEID specificAttribute) { if (unit == TextUnit_Character) { return true; } EndPoint next; EndPoint prev; if (!_control->StepCharacter(check, true, &next) || !_control->StepCharacter(check, false, &prev)) { // If we're at the beginning or end, we're at an endpoint return true; } else if (unit == TextUnit_Word) { if (IsWhiteSpace(prev) && !IsWhiteSpace(check)) { return true; } return false; } else if (unit == TextUnit_Line || unit == TextUnit_Paragraph) { return check.line != next.line; } // TextUnit_Page and TextUnit_Document are covered by the initial beginning/end check else if (unit == TextUnit_Page || unit == TextUnit_Document) { return false; } else if (unit == TextUnit_Format) { bool matching = true; bool checkedLineBoundary = false; // There are limited attributes that vary in this control // If its not one of those attributes, then it is not an Endpoint // unless it's the document start or end, which is checked above for (int i = 0; i < ARRAYSIZE(lineVariableAttributes); i++) { if (specificAttribute == 0 || specificAttribute == lineVariableAttributes[i]) { if (!checkedLineBoundary) { if (!CheckEndPointIsUnitEndpoint(check, TextUnit_Paragraph, 0)) { break; } checkedLineBoundary = true; } VARIANT varC = _control->GetAttributeAtPoint(check, lineVariableAttributes[i]); VARIANT varN = _control->GetAttributeAtPoint(next, lineVariableAttributes[i]); HRESULT hr = VarCmp(&varC, &varN, LOCALE_NEUTRAL); VariantClear(&varC); VariantClear(&varN); if (hr != VARCMP_EQ) { matching = false; break; } } } for (int i = 0; i < ARRAYSIZE(charVariableAttributes); i++) { if (specificAttribute == 0 || specificAttribute == charVariableAttributes[i]) { int *annotationIds; int annotationCount; if (GetAnnotationsAtPoint(check, &annotationIds, &annotationCount)) { int *prevAnnotationIds; int prevAnnotationCount; if (GetAnnotationsAtPoint(prev, &prevAnnotationIds, &prevAnnotationCount)) { if (annotationCount != prevAnnotationCount) { matching = false; } // Since all our annotations are the same type, if the number matches, // then the UIA_AnnotationTypesAttributeId all match else if (charVariableAttributes[i] == UIA_AnnotationObjectsAttributeId) { for (int j = 0; j < annotationCount; j++) { if (annotationIds[j] != prevAnnotationIds[j]) { matching = false; } } } delete [] prevAnnotationIds; } delete [] annotationIds; } } } return !matching; } return false; }