Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 08.07.2012, 01:30   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,442
По умолчанию Из функции вернуть данные через входящие параметры. Не возвращает, хоть тресни.

Доброго времмени суток!

Имеем функцию:
Код:
{Нужен psapi}
function ProcessExists(aName:string; var aFullPath: string; aPID: Cardinal): boolean;
var
  aProcess: array [0 .. 1024] of DWORD;
  BytesNum: DWORD;
  i, iCount: integer;
  sPath: string;
  dPath:string;
  dID:DWORD;
begin
  Result := False;
  if EnumProcesses(@aProcess, SizeOf(aProcess), BytesNum) then
  begin
    iCount := BytesNum div SizeOf(DWORD);

    for i := 0 to iCount do
    begin
      sPath := GetProcessPath(aProcess[i]);
      if not(aProcess[i] = 0) then
      begin
        if (CompareStr(Trim(LowerCase(aName)),
          Trim(LowerCase(ExtractFileName(sPath)))) = 0) then
        begin
          Result := True;
          dID := aProcess[i];
          dPath:= sPath;
          Break;
        end;

      end;
    end;
  end;
  {
 Думал из-за цикла, вынес передачу данных сюды
 Танцы с бубном.
  }
  aFullPath:=dPath; //в AfullPath передается строка
  aPID:=dID;// Сюда передается идентификатор
end;
А вот и код:
Код:
var
  sPath: string;
  iPID: DWORD;
begin
  iPID:=0;
...
    if ProcessExists(name, sPath, iPID) then
    begin
   //в sPath и iPID не возвращается значение
...
    end;
    ..
  end;
..

end;
Не могу понять, где глюк. Раньше работало, а сейчас перестало

Дайте пожалуйста, правильный бубен

Последний раз редактировалось Человек_Борща; 08.07.2012 в 01:33.
Человек_Борща вне форума Ответить с цитированием
Старый 08.07.2012, 03:11   #2
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

1)
Код:
function ProcessExists(aName:string; var aFullPath: string; var aPID: Cardinal): boolean;
В твоем случае, там копия параметра создается...
2) Лучше возвращать через out параметр, а не через var
3) А в клиентский код не приходят значения, т.к. вероятнее всего либо функция возвращает False, либо не выполняется какое-то из условий, что приводит к невозможности назначить данные в параметры...Вобщем под отладкой стоит посмотреть...(думал глянуть, но нету функции GetProcessPath())
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Старый 08.07.2012, 10:07   #3
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,792
По умолчанию

Цитата:
В твоем случае, там копия параметра создается...
Чего это так?
Цитата:
правильный бубен
А тарссировка что показывает?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.07.2012, 11:21   #4
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,238
По умолчанию

Цитата:
Сообщение от Stilet
Чего это так?
потому как пропущен параметер var в описании функции для параметра aPid!
Поэтому что-то присваивать aPid в теле функции можно, но это не выйдет за пределы функции...
Serge_Bliznykov вне форума Ответить с цитированием
Старый 08.07.2012, 14:05   #5
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

Вот Serge_Bliznykov ответил вобщем-то уже...Добавлю только, что для объектов это не действует - т.е. там все же ссылка будет передаваться...
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Старый 08.07.2012, 14:53   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,442
По умолчанию

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

spamer,
функция отрабатывает как надо. Не возвращает значения через бубен.

Вот полный вариант функции:
Код:

uses
  Winapi.Windows,
  System.StrUtils,
  System.SysUtils,
  Winapi.PsAPI,

function GetProcessPath(aPID: Cardinal): string;
function DevicePathToWin32Path(path: string): string;

function GetProcessImageFileName(hProcess: DWORD; lpImageFileName: LPTSTR;
  nSize: DWORD): DWORD; stdcall;
  external 'PSAPI.dll' name 'GetProcessImageFileNameW';

implementation

function ProcessExists(aName:string; var aFullPath: string; aPID: Cardinal): boolean;
var
  aProcess: array [0 .. 1024] of DWORD;
  BytesNum: DWORD;
  i, iCount: integer;
  sPath: string;
  dPath:string;
  dID:DWORD;
begin
  Result := False;
  if EnumProcesses(@aProcess, SizeOf(aProcess), BytesNum) then
  begin
    iCount := BytesNum div SizeOf(DWORD);

    for i := 0 to iCount do
    begin
      sPath := GetProcessPath(aProcess[i]);
      if not(aProcess[i] = 0) then
      begin
        if (CompareStr(Trim(LowerCase(aName)),
          Trim(LowerCase(ExtractFileName(sPath)))) = 0) then
        begin
          Result := True;
          dID := aProcess[i];
          dPath:= sPath;
          Break;
        end;

      end;
    end;
  end;
  aFullPath:=dPath;
  aPID:=dID;
end;

function GetProcessPath(aPID: Cardinal): string;
var
  cPath: array [0 .. MAX_PATH] of Char;
  hProcess: THandle;
begin
  Result := '';
  hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
    False, aPID);
  try
    if (hProcess > 0) then
    begin
      if GetProcessImageFileName(hProcess, @cPath, SizeOf(cPath)) <> 0 then
        Result := DevicePathToWin32Path(cPath);
    end;
  finally
    CloseHandle(hProcess)
  end;
end;

function DevicePathToWin32Path(path: string): string;
var
  c: Char;
  s: string;
  i: integer;
  _path: string;
begin
  _path := path;
  i := posex('\', path, 2);
  i := posex('\', path, i + 1);
  Result := copy(path, i, Length(path));
  delete(path, i, Length(path));
  for c := 'A' to 'Z' do
  begin
    SetLength(s, 1000);
    if querydosdevice(PChar(string(c) + ':'), PChar(s), 1000) <> 0 then
    begin
      s := PChar(s);
      if sametext(path, s) then
      begin
        Result := c + ':' + Result;
        Exit;
      end;
    end;
  end;
  Result := _path;
end;
Добавил

Serge_Bliznykov, в данном случае через var ничего не вернулось ни в одну из переменных. Сделал через out и заработало.
Код:
function ProcessExists(aName:string; out aFullPath: string; out aPID: Cardinal): boolean;
Гм, чуть не повился когда узнал что константы можно делать записываемыми...
{$WRITEABLECONST ON}

Последний раз редактировалось Человек_Борща; 08.07.2012 в 15:02.
Человек_Борща вне форума Ответить с цитированием
Старый 08.07.2012, 22:35   #7
spamer
Software Developer
Старожил
 
Аватар для spamer
 
Регистрация: 19.12.2008
Сообщений: 2,070
По умолчанию

Странно как-то у тебя оно работает - через var не возвращает, но через out возвращает...
Вот только, что попробовал вернуть через var - все работает...
Цитата:
Сделал через out и заработало.
Только учти, что out параметры могут быть не инициализированы перед передачей в функцию(т.е. об этом заботится сама функция), в то время как var параметры принято инициализировать до передачи в функцию...

Цитата:
{$WRITEABLECONST ON}
Полезно при реализации Singleton'а...
Будь проще и люди к тебе потянутся
spamer вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сделать снимок экрана и отправить на email (Хоть тресни не коннектится) Sinkl Работа с сетью в Delphi 8 13.03.2012 22:03
Реализовать программу через параметры-значений и параметры-ссылок bufalo C# (си шарп) 3 14.12.2011 17:10
Функция не возвращает данные. Abuhamed JavaScript, Ajax 4 26.10.2011 10:33
TrackPopupMenuEx возвращает 87 ошибку (неверные входные параметры) TitoAlehandro Win Api 0 27.09.2011 11:01
Как лучше проверять входящие данные nitrofox PHP 3 20.07.2011 07:19