Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];
ВнизИспользование SetLength и динамических массивов. Найти похожие ветки
← →
ANB © (2005-03-01 17:12) [0]Обрабатываю в цикле динамический массив, каждый раз обнуляя и заполняя его заново. Для нескольких проходов - все нормально, но если цикл продолжается минут 10, то кончается память. Место ошибки - SetLength() при увеличении длинны.
Подскажите - это нерешаемая проблема массива и его надо чем то заменить (и чем лучше) ? Или с этим можно бороться ? (С массивом код понятнее).
← →
Димон (2005-03-01 17:16) [1]ты бы код привел:))
← →
XP (2005-03-01 17:21) [2]Проблемы с фрагментацией памяти.
Установите - изначально - для массива максимальную длину.
← →
ANB © (2005-03-01 17:24) [3]Так я ее не знаю :(((
Код :function FindWindowAndSetContext(AParam : array of String; fmLog : TfmLog;
InOtherProcess : Boolean = False) : String;
var tmStart : TDateTime;
i, n : Integer;
sClassName, sWinText : String;
tmWait : Integer;
begin
Result := "";
if (High(AParam) < 1) then begin
Result := "FindWindowAndSetContext : Должно быть 2 или 3 параметра.";
Exit;
end;
// Разберем параметры
sClassName := ParamToStr(AParam[0]);
sWinText := ParamToStr(AParam[1]);
if (High(AParam) >= 2)
then begin
tmWait := StrToIntDef(AParam[2], -1);
if (tmWait = -1) then begin
Result := "FindWindowAndSetContext : 3-й параметр "
+"должен быть числом миллисекунд задержки.";
Exit;
end;
end else begin
tmWait := StdWinWait;
end;
if (dwProcessID = -1) then begin
Result := "Форма "+AParam[0]+"."+AParam[1]+" - не установлен контекст приложения.";
Exit;
end;
{Ожидание формы}
// Сбросим старый контекст
hWindow := -1;
try
// Запомним время старта
tmStart := Now;
repeat
// Получим список всех форм
SetLength(ObjectList, 0);
Sleep(20);
EnumWindows(@ParentTree, 0);
// Пройдемся по нему и поищем форму с нужным классом,
// именем и Handle процесса
n := High(WindowList);
for i := 0 to n do begin
// Если найдем :
if ((WindowList[i].ClassName = sClassName)
and (WindowList[i].WinText = sWinText)
and (InOtherProcess or (WindowList[i].dwProcessID = dwProcessID))
and IsWindowVisible(WindowList[i].Handle))
then begin
hWindow := WindowList[i].Handle;
// Ждем, пока окно нарисуется
SendMessage(hWindow, SW_SHOW, 0, 0);
Sleep(StdDelay);
WaitForInputIDLE(hWindow, INFINITE);
// Формируем контекст
EnumChildWindows(hWindow, @ChildTree, 0);
// Если другое приложение - то сменим ID процесса
GetWindowThreadProcessId(hWindow, @dwProcessID);
// Выходим
Exit;
end;
if (fmLog.bStop) then Break;
end;
// Повторяем в цикле поиск формы, пока не выйдет время
// Или пользователь не передумает
if (fmLog.bStop) then Break;
// Пауза
Sleep(StdDelay*2);
if (fmLog.bStop) then Break;
until (TimeIntervalToMiliSec(Now - tmStart) > tmWait);
// Так и не нашли
Result := "Окно "+sClassName+"."+sWinText+" - не найдено."
finally
// Почистим память
SetLength(WindowList, 0);
end;
end;
function ParentTree(Handle: HWND; Info: Pointer): BOOL; stdcall;
var Buff : array [0..1023] of Char;
i : Integer;
ProcID : THandle;
begin
Result:= True;
// Откинем невидимые окна
if (not IsWindowVisible(Handle)) then Exit;
i := High(WindowList);
Inc(i);
try
SetLength(WindowList, i + 1);
except
on E: Exception do begin
fmLog.AddErr("ParentTree: "+E.Message);
raise;
end;
end;
WindowList[i].Handle := Handle;
GetClassName(Handle, Buff, 1024);
WindowList[i].ClassName := PChar(@Buff);
GetWindowText(Handle, Buff, 1024);
WindowList[i].WinText := PChar(@Buff);
GetWindowThreadProcessId(Handle, @ProcId);
WindowList[i].dwProcessID := ProcID;
end;
на fmLog можно внимания не обращать, это для возможности выхода.
← →
ANB © (2005-03-01 17:46) [4]Аууу ?
← →
XP (2005-03-01 17:50) [5]Это Вы про AParam: array of string?
Используйте TStringList
← →
novice_man © (2005-03-01 17:55) [6]
> SetLength(ObjectList, 0);
> SetLength(WindowList, 0);
Как декларированы эти масивы?
И еще не более правильно ли так
> function FindWindowAndSetContext(const AParam : array of String; fmLog : TfmLog; InOtherProcess : Boolean = False) : String;
← →
ANB © (2005-03-01 18:00) [7]Не глючил WindowList. Я уже нашел. Перед вызовом EnumWindows(@ParentTree, 0); я не тот массив очищал. Сейчас поправил и все ок. Память вообще не дергается.
← →
ANB © (2005-03-01 18:01) [8]Не глючил WindowList. Я уже нашел. Перед вызовом EnumWindows(@ParentTree, 0); я не тот массив очищал. Сейчас поправил и все ок. Память вообще не дергается.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.13;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.04 c