Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];

Вниз

Требуется разъяснение команды 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.083 c
15-1339284234
alexdn
2012-06-10 03:23
2013.03.22
Ориентация планшетов


2-1334754032
andrewtitoff
2012-04-18 17:00
2013.03.22
Картинки в массив и обратно


15-1347085902
Опять я
2012-09-08 10:31
2013.03.22
H.264


2-1333011642
Вася
2012-03-29 13:00
2013.03.22
При нажатии правой кнопки мыши на DBgrid не меняется активная стр


15-1341261002
Юрий
2012-07-03 00:30
2013.03.22
С днем рождения ! 3 июля 2012 вторник





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский