Code:

var

Hinst : THandle;

WndArr : array of THandle;

Wnd : THandle;

 

......

 

Procedure KillDelphiWndTimers(const AppCaption:string);

var i : integer;

function GetTimerWindows(Handle: HWND; Info: Pointer): BOOL; stdcall;

const

sClName ='TPUtilWindow';

var

s : String;

begin

Result := True;

SetLength(s,Length(sClName)+1);

GetClassName(Handle, PChar(s),Length(s));

SetLength(s,Length(sClName)); // E?aeo caieoeaaou neaie #0 :)

if (GetWindowLong(Handle, GWL_HINSTANCE) =  Hinst )  and (s=sClName)

then

begin

   SetLength(WndArr,High(WndArr)+2);

   WndArr[High(WndArr)]:=Handle;

end;

end;

 

begin

Wnd:=FindWindow(nil,Pchar(AppCaption));

if Wnd=0 then Exit;

hinst:=GetWindowLong(Wnd, GWL_HINSTANCE);

EnumWindows(@GetTimerWindows,0);

for i:=0 to High(WndArr) do KillTimer(WndArr[i],1);

end;

 

 

Приложение может проверить, если окно отвечает на сообщения путем отправки сообщения WM_NULL с функцией SendMessageTimeout

 

 

Code:

Function SendString(TargetWnd, SourceWnd: THandle; N: Integer; Const S: String): Integer;

Var

CD: TCopyDataStruct;

Begin

CD.dwData := N;

CD.cbData := Length(S);

If CD.cbData = 0 Then

   CD.lpData := NIL

Else CD.lpData := @S[1];

Result := SendMessage(TargetWnd, WM_COPYDATA, SourceWnd, Integer(@CD));

End;

...

Procedure WMCopyData(Var Msg: TWMCopyData); Message WM_COPYDATA;

...

Procedure TForm1.WMCopyData(var Msg: TWMCopyData);

Var

{ Строка }

S: String;

{ Число }

N: Integer;

Begin

If (Msg.CopyDataStruct^).lpData = NIL Then S := '';

SetLength(S,Msg.CopyDataStruct^.cbData);

S := String((Msg.CopyDataStruct^).lpData);

N := (Msg.CopyDataStruct^).dwData;

End;

 

Автор: Rrader

 

Code:

////////////////////////////////////////////////////////////////////////////////

//

//  Автор: Александр (Rouse_) Багель

 

 

//  Данный код приведен лишь для демонстрации

//  А простой вариант поиска Handle Ричедита выглядит так

//  var

//    Handle : HWND;

//  begin

//    Handle:= FindWindowEx(FindWindow(Название формы например 'Form1',nil), 0, Название элемента например 'Button1',  nil),  0, true);

 

unit Unit1;

 

interface

 

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

ComCtrls;

 

type

TMainForm = class(TForm)

   TreeView1: TTreeView;

   procedure FormCreate(Sender: TObject);

   procedure Sys_Windows_Tree(Node: TTreeNode; Handle: HWND);

end;

 

var

MainForm: TMainForm;

 

implementation

 

{$R *.DFM}

 

////////////////////////////////////////////////////////////////////////////////

//

//  Стартовая функция, запускаем рекуссию используя хэндл рабочего стола

//

 

procedure TMainForm.FormCreate(Sender: TObject);

var

StartHandle : THandle;

begin

//Если требуется найти только данные по одному приложению

//замени 2 строки в функциях их закоментированными аналогами

StartHandle := GetDeskTopWindow;

//StartHandle := 67324;//FindWindow(PChar(Caption), nil);  //На примере Винампа

Sys_Windows_Tree(nil, StartHandle);

end;

 

////////////////////////////////////////////////////////////////////////////////

//

//  Рекурсивная функция, строит дерево всех открытых окон, кнопок, едитов и т.д.

//  В качестве входных данных получает узел дерева и Хэндл окна

//

 

procedure TMainForm.Sys_Windows_Tree(Node: TTreeNode; Handle: HWND);

const

MAX = 128;

var

TmpArray  : array[0..MAX - 1] of Char;

Result    : String;

szFileName : array[0..255] of Char;

iSize : Integer;

PID: Cardinal;

begin

//Запускаем цикл пока не закончатся окна

while Handle <> 0 do

begin

   //Получаем имя класса окна

   GetClassName(Handle, @TmpArray, MAX);

   Result := String(TmpArray);

   //Получаем текст (Его Caption) окна

   GetWindowText(Handle, @TmpArray, MAX);

   // Получаем имя модуля

   if GetwindowModuleFilename(Handle, szFileName, SizeOf(szFileName)) = 0 then

     ZeroMemory(@szFileName[0], 256);

   GetWindowThreadProcessId(Handle, PID);

   Result := Result + ' [' + String(szFileName) + '] (' + String(TmpArray) +

     '): Handle = '+ IntToStr(Handle) + ', PID = ' + IntToStr(PID);

   //В следующей процедуре, в скобках, добавляем результат

   //в дерево, получаем хэндл дочернего окна и с результатами

   //выполнения этих двух функций выполняем процедуру Sys_Windows_Tree

   Sys_Windows_Tree(TreeView1.Items.AddChild(Node, Result),

     GetWindow(Handle, GW_CHILD));

   //Получаем хэндл следующего (не дочернего) окна

   Handle := GetNextWindow(Handle, GW_HWNDNEXT);

   //Handle := 0;

end;

end;

 

 

end.

 

Вам потребуется OpenDialog для открытия ехе-файлов и Memo для показа информации о файле.

Требуется нажать в "другом" приложении пару кнопок (button). (кнопки не имеют hotkeys). Ищу окно так (Дельфи):

Code:

if FindWindow(nil, 'Advanced Dialer')<> 0 then

ShowMessage('OK');

 

 

...я также имею проблемы с другими функциями DLL, которые ведут себя иначе, чем при первом обращении к ним!

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

 Главное, что нужно помнить при разработке DLL - вы не должны допускать ситуацию, при которой любое исключение осталось бы неперехваченным (спасибо Pat Ritchey за столь мудрый совет). В теле экспортируемых функций "заверните" все в блоки try..except (которые замечательно обрабатываются Delphi).

 

 

Данная функция позволяет завершить выполнение любой активной программы по её classname или заголовку окна.

Code:

procedure KillProgram(Classname : string; WindowTitle : string);

const

PROCESS_TERMINATE = $0001;

var

ProcessHandle : THandle;

ProcessID: Integer;

TheWindow : HWND;

begin

TheWindow := FindWindow(Classname, WindowTitle);

GetWindowThreadProcessID(TheWindow, @ProcessID);

ProcessHandle := OpenProcess(PROCESS_TERMINATE, FALSE, ProcessId);

TerminateProcess(ProcessHandle,4);

end;

 

 

Делаешь текстовый файл с ресурсами, типа

 

--my.rc--

STRINGTABLE

{

00001, "My String #1"

00002, "My String #2"

}

 

 

Пример использования:

Code:

// После этого можно смотреть информация о таких системных модулях как:

//winlogon.exe и servises.exe и д.р.

EnableDebugPrivilege(True); // вкрючить

 

EnableDebugPrivilege(False); // выключить

 

Иногда на форуме проскакивает такой вопрос: "Как можно поглядеть экспортируемые ф-ии какой либо длл'ины?".

Можно конечно же воспользоваться стандартными утилитами, но можно попробовать написать и что нить свое.

Сейчас я попробую показать такой пример. Напишем пример, который делает именно это - вытаскивает экспорт модуля.

Подробно расписывать тут ничего не буду, тут идет разбор элементов PE заголовка - нахождение таблицы экспорта,

перечисление ф-ий. Недостаток этого примера в том, что он работает уже с подгруженными модулями, т.к. для нахождения

базы используется GetModuleHandle().