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

Вниз

EnumChildWindows   Найти похожие ветки 

 
Сережа550 ©   (2004-04-20 10:57) [0]

Уважаемые знатоки, подскажите пожалуйста, как можно через EnumChildWindows положить хендлы объектов дочернего окна в массив? Дескриптор родительского окна известен. Массив, например, array [0..255] of HWND;


 
SPeller ©   (2004-04-20 11:32) [1]

В параметре CallBack функции передавай объект своей формы. Или любой другой объект, который содержит этот самый массив.


 
Сережа550 ©   (2004-04-20 11:45) [2]

Может я чего-то не понял (опыта с winapi было мало)... Но, объясню по другому:
Есть TGroupBox, в нем лежат какие-то объекты (кнопки, edit"ы и т.п.) - но я не знаю сколько их, как они называются и т.п. Вот мне и нужно с помощью EnumChildWindows - указать в качестве родительского окна - GroupBox1.Handle, а далее забить в массив хендлы всех дочерних этому GroupBox"у объектов. Но как это сделать, я, к сожалению, не знаю... Если можно, небольшой (или большой) пример.


 
int64   (2004-04-20 11:47) [3]

Какой практический смысл?
Не пришлось бы заполнять дерево.


 
easy ©   (2004-04-20 11:57) [4]

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls, ComCtrls;

type
 TForm1 = class(TForm)
   Button1: TButton;
   TreeView1: TTreeView;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}
function GetWindowTitle(hwnd: HWND): string;
begin
 SetLength(Result, 255);
 SetLength(Result, GetWindowText(hwnd, PChar(Result), 255));
end;

function GetWindowClass(hwnd: HWND): string;
begin
 SetLength(Result, 255);
 SetLength(Result, GetClassName(hwnd, PChar(Result), 255));
end;

function GetWindowInfo(hwnd: HWND): string;
begin
 Result := GetWindowTitle(hwnd) + " [" + GetWindowClass(hwnd) +
   "] (" + IntToStr(hwnd) + ")";
end;

function EnumChildProc(hwnd: HWND; lParam: Integer): BOOL; stdcall;
var
 NewNode, ParentNode: TTreeNode;
begin
 Result := True;
 ParentNode := TTreeNode(lParam);
 NewNode := ParentNode.Owner.AddChild(ParentNode,
   GetWindowInfo(hwnd));
 EnumChildWindows(hwnd, @EnumChildProc, Integer(NewNode));
end;

function EnumWindowsProc(hwnd: HWND; lParam: Integer): BOOL; stdcall;
var
 NewNode: TTreeNode;
begin
 Result := True;
 NewNode := TTreeView(lParam).Items.Add(nil, GetWindowInfo(hwnd));
 EnumChildWindows(hwnd, @EnumChildProc, Integer(NewNode));
end;

procedure EnumWindowsTree(Tree: TTreeView);
begin
 EnumWindows(@EnumWindowsProc, Integer(Tree));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 TreeView1.Items.Clear;
 EnumWindowsTree(TreeView1);
end;

end.


 
Сережа550 ©   (2004-04-20 11:58) [5]

Я просто написал упрощенный пример, чтобы не возникало дополнительных трудностей. На самом деле необходимо следующее: На форме есть TWebBrowser, в него загружен определенный сайт. На сайте есть куча Flash-объектов. Я так понимаю, что все flash-объекты данного сайта являются как бы дочерними окнами WebBrowser"а и мне необходимо узнать Handl"ы этих объектов, чтобы затем послать им сообщение о нажатии на него левой кнопкой мышки:

PostMessage(Handle этого объекта, WM_LBUTTONDOWN, 0, MAKELPARAM(1,1));
PostMessage(Handle этого объекта, WM_LBUTTONUP, 0, MAKELPARAM(1,1));

Если есть другой вариант каким-то образом нажать на Flash-объект, буду очень благодарен... :)


 
int64   (2004-04-20 12:06) [6]

Откуда такая уверенность, что Flash-объект будет обрабатывать ваши сообщения.

function GetFirstFlashFomFirstHWND_IE: HWND;
begin
 Result := FindWindow("IEFrame", nil);
 Result := FindWindowEX(Result, 0, "Shell DocObject View", nil);
 Result := FindWindowEX(Result, 0, "Internet Explorer_Server", nil);
 Result := FindWindowEX(Result, 0, "MacromediaFlashPlayerActiveX", nil);
end;


Не лучше ли получить СОМ-интерфейс к флешу.


 
Сережа550 ©   (2004-04-20 12:59) [7]

Я в этом не особенно разбираюсь. Может напишешь небольшой примерчик "получения COM-интерфейса к флешу". Необходимость та же - на загруженной страничке кликать флэшки в определенные координаты... На самом деле, необходимость в этом очень большая, я уже 3 недели мучаюсь...


 
int64   (2004-04-20 13:53) [8]

Через интефейсы сможешь делать что-то типа Play, Stop...
Для твоей задачи не подойдет.
Тогда уж лучше PostMessage.

Как получить интерфейс:

function GetFlash(WB: IWebbrowser2; FlashNumber: Integer): IShockwaveFlash;
var
 OleContainer: IOleContainer;
 enum: IEnumUnknown;
 TempUnk: IUnknown;
 Fetched: PLongint;
 ObjNo, FlasNo: integer;
 Coll: HTMLElementCollection;
begin
 FlasNo := 0;
 with WB do
   begin
     while ReadyState <> READYSTATE_COMPLETE do
       Forms.Application.ProcessMessages;
     if Assigned(document) then
       begin
         Coll := HTMLElementCollection(HTMLDocument(Document).All.Tags("OBJECT"));
         for ObjNo := 0 to Coll.length - 1 do
           if HtmlObjectElement(Coll.item(ObjNo, varEmpty)).classid =
             "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" then
             begin
               if FlasNo = FlashNumber then
                 break;
               inc(FlasNo);
             end;
         Fetched := nil;
         OleContainer := Document as IOleContainer;
         OleContainer.EnumObjects(OLECONTF_EMBEDDINGS, Enum);
         Enum.Skip(ObjNo);
         Enum.Next(1, TempUnk, Fetched);
         Result := TempUnk as IShockwaveFlash;
       end
     else
       Result := nil;
   end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 Flash: IShockwaveFlash;
begin
 Flash := GetFlash(WebBrowser1.ControlInterface, 0);
 if Assigned(Flash) then
   Flash.Zoom(2);
end;


Не забудь импортировать Shockwave Flash (Flash.ocx).


 
Сережа550 ©   (2004-04-20 14:14) [9]

1. Через PostMessage не удается - все работает: без проблем эмулируется событие клика правой кнопки мыши, закрывается, а при посыле сообщения клика левой кнопкой мышки - ничего не происходит... В чем может быть проблема?
2. Этот код у меня, к сожалению, не работает... В функции GetFlash строка "Result := TempUnk as IShockwaveFlash" вызывает ошибку - Interface Not Supported. В чем может быть проблема?


 
int64   (2004-04-20 14:40) [10]

1. Я так и предполагал. Не нужны им левые сообщения.
2. У меня работает. Может дело в Д6. Попробуй так:
TempUnk.QueryInterface(IShockwaveFlash, Result);


 
Сережа550 ©   (2004-04-20 17:50) [11]

1. Я так и предполагал. Не нужны им левые сообщения.
Самое странное, что "левое" сообщение правого клика работает, а левого клика - уже нет. :(

2. У меня работает. Может дело в Д6. Попробуй так:
TempUnk.QueryInterface(IShockwaveFlash, Result);
Теперь ошибки не происходит, но Assigned(Flash) остается False. Да, и к тому же, ты прав - если я даже загружу флешку в ShockwaveFlash - то это врядли поможет мне решить мою задачу...

Нет, все таки - каким же образом можно программно кликнуть по Flash-баннеру? С меня ящик пива за правильный ответ! ПОМОГИТЕ! :)


 
nikkie ©   (2004-04-20 20:58) [12]

имитировать действия мышью можно с помощью mouse_event


 
Сережа550 ©   (2004-04-21 10:08) [13]

Спасибо, этот способ, к сожалению, не решит моей задачи, потому что мне не надо двигать мышь к объекту, а затем нажимать на него, мне надо на него лишь нажать (даже если окно с этим объектом свернуто). Окон с эксплорерами будет очень много, многие из них будут свернуты. Вообщем, я уже обдумывал этот метод и он, к моему огромному сожалению, мне не подходит...


 
MetalFan ©   (2004-04-21 10:14) [14]


> int64   (20.04.04 14:40) [10]
> 1. Я так и предполагал. Не нужны им левые сообщения.
> 2. У меня работает. Может дело в Д6. Попробуй так:
> TempUnk.QueryInterface(IShockwaveFlash, Result);

TempUnk.QueryInterface(IID_IShockwaveFlash, Result);


 
Сережа550 ©   (2004-04-21 10:38) [15]

Вообще, откровенно говоря, мне необходимо следующее: необязательно кликать на флешки - мне надо узнать, на какой сайт эти флешки ведут. Но так, как флеш - может содержать кучу кнопок, каждая из которых ведет на свой сайт, (или никуда не ведет, а выполняет какое-то действие), то я хотел прокликать по всем координатам флешки, отловить все URL куда браузер переходит и дальше уже работать с полученными данными... А если еще учесть, что флешки бывают: с прописанными в коде страницы URL"ами, вшитыми в них URL"ами, URL"ами, грузящимися из Java-script"ов, то единственный универсальный способ понять, куда ведет флешка - это только кликнуть на нее... И именно с этим я и мучаюсь уже три недели к ряду... Молю всех о помощи.

2 MetalFan: Спасибо большое за код, но как я уже писал, это не поможет решить мне мою задачу... :(



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

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

Наверх




Память: 0.51 MB
Время: 0.128 c
1-1084720501
Lammo
2004-05-16 19:15
2004.05.30
Использование PChar в dll


9-1074884494
iudjen
2004-01-23 22:01
2004.05.30
эллектронное пианино


4-1081727678
Matveyev
2004-04-12 03:54
2004.05.30
Drag &amp; Drop с Провоодником Windows


7-1082383492
Super-Mario
2004-04-19 18:04
2004.05.30
Инжектор, ЭБУ


6-1082015337
Dmitrij_K
2004-04-15 11:48
2004.05.30
Опять про NETSEND