Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Требуется разъяснение команды AS   Найти похожие ветки 

 
alfa ©   (2012-09-16 12:25) [0]

Не программист, понять описание порой очень сложно. Стояла задача читать содержимое окошек класса DirectUIHWND. Подсказали пример:
function AccessibleChildren(paccContainer : Pointer; iChildStart : LONGINT; cChildren : LONGINT; out rgvarChildren : OleVariant; out pcObtained : LONGINT) : HRESULT; stdcall;
 stdcall; external "oleacc.dll";

procedure TForm1.DisplayInfo(const aAccessible : IAccessible; const aOffset : string);

 procedure ProcessChild(const aChild : OleVariant);
 var
   ChildAccessible : IAccessible;
   ChildDispatch : IDispatch;
 begin
   ChildDispatch := nil;
   case VarType(aChild) of
     varInteger : aAccessible.Get_accChild(aChild, ChildDispatch);
     varDispatch : ChildDispatch := aChild;
   end;
   if (ChildDispatch <> nil) and (ChildDispatch.QueryInterface(IAccessible, ChildAccessible) = S_OK) then
     DisplayInfo(ChildAccessible, aOffset + " ")
 end;

var
 Child, CurrentChild : OleVariant;
 ChildArray : array of OleVariant;
 dwNum : DWord;
 Enum : IEnumVARIANT;
 i, iChildCount, iObtained : Integer;
 wsText : WideString;
begin
 if aAccessible <> nil then begin
     if aAccessible.get_AccName(CHILDID_SELF, wsText) = S_OK then
       Memo1.Lines.Add(aOffset + "Name: " + wsText)
     else
       Memo1.Lines.Add(aOffset + "Name: Empty");
     if aAccessible.get_AccValue(CHILDID_SELF, wsText) = S_OK then
       Memo1.Lines.Add(aOffset + " Value: " + wsText);
     if aAccessible.get_AccDescription(CHILDID_SELF, wsText) = S_OK then
       Memo1.Lines.Add(aOffset + " Description: " + wsText);

     if (aAccessible.Get_accChildCount(iChildCount) = S_OK) and (iChildCount > 0) then begin
         Form1.Memo1.Lines.Add(aOffset + " Children: " + IntToStr(iChildCount));
         SetLength(ChildArray, iChildCount);
         if AccessibleChildren(Pointer(aAccessible), 0, iChildCount, ChildArray[0], iObtained) = S_OK then begin
             for i := 0 to iObtained - 1 do
               ProcessChild(ChildArray[i])
           end else if aAccessible.QueryInterface(IEnumVARIANT, Enum) = S_OK then begin
             Enum := aAccessible as IEnumVARIANT;
             for i := 0 to iChildCount - 1 do
               if Enum.Next(1, Child, dwNum) = S_OK then
                 ProcessChild(Child);
           end else begin
             if aAccessible.accNavigate(NAVDIR_FIRSTCHILD, CHILDID_SELF, CurrentChild) = S_OK then begin
                 repeat
                   ProcessChild(CurrentChild)
                 until aAccessible.accNavigate(NAVDIR_NEXT, CurrentChild, CurrentChild) <> S_OK;
               end
           end
       end
   end
end;

-------------------------------------------------------------------------------------
var
 Accessible : IAccessible;
 hWindow : HWnd;
begin
 Memo1.Lines.Clear;
 hWindow := FindWindowA("CabinetWClass", nil);
 if AccessibleObjectFromWindow(hWindow, 0, IID_IAccessible, Accessible) = S_OK then
 DisplayInfo(Accessible, "");
-------------------------------------------------------------------------------------

Мы не уверены, видимо "ваш", дельфийский. У нас язык совсем другой, и малознаменитый, с малым количеством талантливых поклонников, у кого можно проконсультироваться. Так вот собственно вопрос: при портировании кода на наш язык, возникла непонятка с использованием вашей хитрющей функцией "AS". Может ли кто подробно рассказать что за операция происходит в делфи в этой части кода:
Enum := aAccessible as IEnumVARIANT;
Судя по описанию приведение одного "формата" в другой. Но вся эта операция делается в дельфи "за кадром" можно ли поподробнее получить консультацию как это происходит в развернутом виде?

И второй вопрос по этому же семплу:
   case VarType(aChild) of
     varInteger : aAccessible.Get_accChild(aChild, ChildDispatch);
     varDispatch : ChildDispatch := aChild;
   end;
   if (ChildDispatch <> nil) and (ChildDispatch.QueryInterface(IAccessible, ChildAccessible) = S_OK) then

Идет case, название переменной, которую мы исследуем - aChild, и варианты значения. Так вот вопрос - здесь имеется два разных значения?
     varInteger : aAccessible.Get_accChild(aChild, ChildDispatch); - первый вариант значения aChild
     varDispatch : ChildDispatch := aChild; - второй вариант значения aChild
то есть если одно значение сошлось, то второе не проверяется. или имелось ввиду на любое значение aChild произвести две операции. сначала aAccessible.Get_accChild(aChild, ChildDispatch), а следом ChildDispatch := aChild?

Мы попытались перевести это как:
Select *aChild\vt    
   Case #VT_INT ; varInteger
     *aAccessible\get_accChild(*aChild, @*ChildDispatch)
   Case #VT_DISPATCH ; varDispatch
     *ChildDispatch = *aChild\pdispVal
EndSelect
Но у меня сомнения. Во первых может там были две операции по каждому значению, а не разделение на две операции, взависимости от входящего значения. А во вторых *aChild\vt вроде как должен иметь всего два значения VT_DISPATCH (9) или VT_I4 (3), VT_INT (22) вроде как в этом описании отсутствует: http://msdn.microsoft.com/en-us/library/windows/desktop/dd318448(v=vs.85).aspx

Простите за сумбур, попытался объяснить своими словами, как сам понимаю происходящее, то есть "не программистким" языком. Структуры, указатели, интерфейсы - темный лес.


 
Inovet ©   (2012-09-16 13:05) [1]

> [0] alfa ©   (16.09.12 12:25)
> Мы не уверены, видимо "ваш", дельфийский. У нас язык совсем
> другой, и малознаменитый

> [0] alfa ©   (16.09.12 12:25)
> попытался объяснить своими словами, как сам понимаю происходящее,
> то есть "не программистким" языком.

Так всё-таки какой ваш язык?


 
alfa ©   (2012-09-16 15:22) [2]

На котором пишем - PureBasic. Которым пытаемся объяснить что нам надо - "не программисткий", то есть не профессиональный, терминами и понятиями толком не владеем. Потому и интересуемся подробностями как это происходит в дельфи, а потом уже будем дальше обмозговывать как это правильно конвертануть. Сейчас пытаемся так:

       Protected Child.VARIANT
       Protected dwNum.l

       If *aAccessible\QueryInterface(@IID_IEnumVARIANT, @*enum) = #S_OK  
           *enum = *aAccessible
           For i = 0 To count - 1                
               If *enum\Next(1, @Child, @dwnum) = #S_OK
                   ProcessChild(*aAccessible, aOffset$, @Child)
               EndIf
           Next
       Endif

есть одна структура, объявляем вторую, пока пустую. а после
вторая = первой, в надежде что данные встанут куда надо. Но видимо не верно.

Поясняю что нужно:
Есть две структуры - одна и вторая. Одна состоит из трех элементов, вторая к примеру из пяти. И вроде как нам надо взять первое значение в первой структруре и помножить на что-то, и это будет первый элемент второй структуры. берем второе значение первой и третье значение первой, складываем - это получается второе значение второй структуры. И так далее. Это грубый пример, как там на самом деле обстоит дело с командой AS я не знаю. Но хотелось бы узнать каким образом она конвертирует один в другой, то есть узнать что делает делфи "за кадром" при применении этой команды.


 
RWolf ©   (2012-09-16 16:35) [3]

ничего не конвертируется, данные вообще не меняются; as — просто приведение типа объекта/интерфейса к типу его предка или потомка, или взятие интерфейса у объекта.


 
alfa ©   (2012-09-16 17:13) [4]

А насчет case? Правил синтаксиса дельфи не знаем. Это два разных значения и выполняется только одно при срабатывании, или же там обе команды исполняются друг за другом?


 
Германн ©   (2012-09-16 17:43) [5]

выполняется только одно


 
Dimka Maslov ©   (2012-09-16 19:45) [6]

AS это оператор приведения типов. Похож на dynamic_cast в С++, с той разницей, что генерирует исключение, если типы несовместимы. Но для интерфейсов он работает следующим образом:

Enum := aAccessible as IEnumVARIANT это то же самое что

if aAccessible.QueryInterface(IID_IEnumVARIANT, Enum) != S_OK then raise EКакое-тоТамException.Create(SНетуИнтерфейсаБуквальноВообще)

А вообще для понимания что она там делает за кадром - очень хорошая штука пошаговый отладчик с дизассемблером.


 
Юрий Зотов ©   (2012-09-16 19:46) [7]

Или ни одного.

Насчет AS см. [3], но сначала выполняется проверка. Если приведение невозможно, то генерится исключение.



Страницы: 1 вся ветка

Текущий архив: 2013.03.22;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.064 c
15-1353270605
Юрий
2012-11-19 00:30
2013.03.22
С днем рождения ! 19 ноября 2012 понедельник


15-1331018645
Unknown user
2012-03-06 11:24
2013.03.22
TStringList.AddObject добавление строки вместо TObject


15-1351157222
Empleado
2012-10-25 13:27
2013.03.22
DB с четырьмя таблицами


15-1350406340
stas
2012-10-16 20:52
2013.03.22
FireMonkey приложение под ios


15-1341317088
Eu
2012-07-03 16:04
2013.03.22
Настройки SVN