Самым сложным случаем является свойство объектного типа. Нормальным поведением будет возврат интерфейса IDispatch, позволяющего OLE обращаться к методам класса, на который ссылается свойство. Однако, для некоторых классов, имеющих свойства «по умолчанию», таких как TStrings и TCollection свойство может быть запрошено с индексом. В этом случае надо выдать соответствующий индексу элемент. В то же время, будучи запрошено без индекса, свойство должно выдать интерфейс IDispatch для работы с экземпляром TCollection или TStrings.
Code: |
tkClass: begin // Получаем значение свойства P := TPersistent(GetOrdProp(FOwner, PropInfo)); if Assigned(P) and (P is TCollection) and (dps.cArgs = 1) then begin // Запрошен элемент коллекции с индексом (есть параметр) if ValidType(dps.rgvarg^[pDispIds^[0]], VT_BSTR, FALSE) then begin // Параметр строковый, ищем элемент по свойству // DisplayName S := dps.rgvarg^[pDispIds^[0]].bstrVal; P1 := NIL; for I := 0 to Pred(TCollection(P).Count) do if CompareText(S, TCollection(P).Items[I].DisplayName) = 0 then begin P1 := TCollection(P).Items[I]; Break; end; if Assigned(P1) then // Найден - возвращаем интерфейс IDispatch Value := FScriptControl.GetProxy(P1) else // Не найден Result := DISP_E_MEMBERNOTFOUND; end else begin // Параметр целый, возвращаем элемент по индексу I := IntValue(dps.rgvarg^[pDispIds^[0]]); if (I >= 0) and (I < TCollection(P).Count) then begin P := TCollection(P).Items[I]; Value := FScriptControl.GetProxy(P); end else Result := DISP_E_MEMBERNOTFOUND; end; end |
Для класса TStrings результатом будет не интерфейс, а строка, выбранная по имени или по индексу
Code: |
else if Assigned(P) and (P is TStrings) and (dps.cArgs = 1) then begin // Запрошен элемент из Strings с индексом (есть параметр) if ValidType(dps.rgvarg^[pDispIds^[0]], VT_BSTR, FALSE) then begin // Параметр строковый - возвращаем значение свойства // Values S := dps.rgvarg^[pDispIds^[0]].bstrVal; Value := TStrings(P).Values[S]; end else begin // Параметр целый, возвращаем строку по индексу I := IntValue(dps.rgvarg^[pDispIds^[0]]); if (I >= 0) and (I < TStrings(P).Count) then Value := TStrings(P)[I] else Result := DISP_E_MEMBERNOTFOUND; end; end else // Общий случай, возвращаем интерфейс IDispatch свойства if Assigned(P) then Value := FScriptControl.GetProxy(P) else // Или Unassigned, если оно = NIL Value := Unassigned; end; |
Просьба писать ваши замечания, наблюдения и все остальное,
что поможет улучшить предоставляемую информацию на этом сайте.
ВСЕ КОММЕНТАРИИ МОДЕРИРУЮТСЯ ВРУЧНУЮ, ТАК ЧТО СПАМИТЬ БЕСПОЛЕЗНО!