[ Delphi / Pascal ] — начинающим: задаем вопросы (архивная - 2015)

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by banned, 6 May 2007.

Thread Status:
Not open for further replies.
  1. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    cardons, типичная ошибка, уже тут на форуме не раз задавали подобный вопрос, чужое приложение ничего не знает о твоей переменной Rect - ее нет в адресном пространстве чужого приложения, поэтому SendMessage(HndControl,LVM_GETITEMRECT,0, LongInt(@Rect)); и не будет отрабатывать как надо (link), и слать лучше PostMessage или SendMessageTimeout, иначе в случае, если что-то пойдет не так в чужом приложении, ты можешь так и не дождаться возвращения управления после вызова SendMessage
     
  2. k0tt0d

    k0tt0d Member

    Joined:
    19 Nov 2009
    Messages:
    52
    Likes Received:
    20
    Reputations:
    4
    процедура для обхода всех файлов на диске
    Code:
    procedure obxod1(path:string);
    var
    FD : TWin32FindData;
    FH : THandle;
    begin
    FH := FindFirstFile(PChar(path+'*.*'), FD);
    repeat
      if (FH<>INVALID_HANDLE_VALUE) and (FD.cFileName<>string('.')) and (FD.cFileName<>string('..')) then
      begin
      if FD.dwFileAttributes=FILE_ATTRIBUTE_DIRECTORY then
                                                      begin
                                                      obxod1(path+FD.cFileName+'\');
                                                      end;
     
      end;
    until FindNextFile(FH, FD) = false;
    end;  
    вызываю

    Code:
    obxod1('С:\')
    но программа не заходит в папки Users, Windows, Program Files. Как можно исправить?
     
    #9562 k0tt0d, 11 Jun 2014
    Last edited: 11 Jun 2014
  3. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    Отключить UAC и дать программе админские права
     
  4. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Вообще-то для чтения этих директорий не нужно повышать права.

    И, по-моему, я уже в этой теме отвечал на похожий вопрос...

    FD.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY
    заменить на
    (FD.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY

    Потому что dwFileAttributes - это DWORD, содержащий массив бит (флагов), и если бит FILE_ATTRIBUTE_DIRECTORY установлен, то файл является директорией... НО другие флаги тоже могут быть установлены, а вы проверяете точное сходство с одним флагом.
     
    1 person likes this.
  5. cardons

    cardons Elder - Старейшина

    Joined:
    19 Jul 2005
    Messages:
    778
    Likes Received:
    324
    Reputations:
    83

    Спасибо за совет. Вроде решил это так. Но выделенных теперь 2 элемента 1 и тот что я указал. Первый всегда выделен по умолчанию и должен сниматься при выделении другого.Теперь необходимо на выделенном элементе кликнуть 2 раза левой клавишой мыши... Подскажи если знаешь.

    Code:
              GetWindowThreadProcessId(HndControl, pid);
    
              if pid <> 0 then
              begin
                hProcess := OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, TRUE, pid);
                lpMem := VirtualAllocEx(hProcess, nil, sizeof(LV_ITEM), MEM_COMMIT, PAGE_READWRITE);
    
                LV.state := LVIS_FOCUSED or LVIS_SELECTED;
                LV.mask := LVIS_FOCUSED or LVIS_SELECTED;
                LV.stateMask := LVIS_FOCUSED or LVIS_SELECTED;
    
    
                WriteProcessMemory(hProcess, lpMem, @LV, sizeof(LV_ITEM), cdWrite);
                PostMessage(HndControl, LVM_SETITEMSTATE, WPARAM(15), LPARAM(lpMem));
                //VirtualFreeEx(hProcess, lpMem, 0, MEM_RELEASE);
                CloseHandle(hProcess);
              end;
    
     
    #9565 cardons, 11 Jun 2014
    Last edited: 11 Jun 2014
  6. alexey-m

    alexey-m Elder - Старейшина

    Joined:
    15 Jul 2009
    Messages:
    518
    Likes Received:
    100
    Reputations:
    37
    точно сказать сложно, потому что не известно какие и как обрабатываются сообщения в другом приложении, но можно попробовать послать мессагу NM_DBLCLK с указанием нужного индекса элемента, либо изучать List-View Control Reference
    а выделение с других элементов попробовать снять макросом:
    Code:
    ListView_SetItemState(ListView, index, 0x0, LVIS_SELECTED);
    где index либо конкретный элемент, либо -1, тогда изменения должны примениться ко всем элементам ( link )
    и код, наверное, я бы так сделал
    Code:
      if (pid <> 0) then begin
    
        hProcess:= OpenProcess(PROCESS_VM_WRITE or PROCESS_VM_OPERATION, TRUE, pid); try
    
          lpMem:= VirtualAllocEx(hProcess, nil, sizeof(LV_ITEM), MEM_COMMIT, PAGE_READWRITE); try
    
            LV.state := LVIS_FOCUSED or LVIS_SELECTED;
            LV.mask := LVIS_FOCUSED or LVIS_SELECTED;
            LV.stateMask := LVIS_FOCUSED or LVIS_SELECTED;
    
            if WriteProcessMemory(hProcess, lpMem, @LV, sizeof(LV_ITEM), cdWrite) then begin
    
                iRes:= SendMessageTimeout(HndControl, LVM_SETITEMSTATE, WPARAM(15), LPARAM(lpMem), SMTO_ABORTIFHUNG, 5000, lpdwResult);
    
                if (iRes = 0) and (GetLastError = ERROR_TIMEOUT) then
                  ShowMessageFmt('Error: SendMessage timeout (pid: %d window: %d)', [pid, HndControl]);
    
            end;
          finally
            VirtualFreeEx(hProcess, lpMem, 0, MEM_RELEASE);
          end;
        finally
          CloseHandle(hProcess);
        end;
      end;
     
    #9566 alexey-m, 11 Jun 2014
    Last edited: 11 Jun 2014
    2 people like this.
  7. cardons

    cardons Elder - Старейшина

    Joined:
    19 Jul 2005
    Messages:
    778
    Likes Received:
    324
    Reputations:
    83
    Гуглил так и не понял как правильно в Delphi отправить NM_DBLCLK. Уже все перепробовал. Думал с помощью Enter выбирать нужный элемент. А фиг там... Выключен выбор с помощью него. Именно нужен дабл клик по определенному пункту. Пункты я считываю. Фокус на нужный элемент устанавливаю... А вот дабл клик...
     
  8. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    Code:
    uses CommCtrl;
    var
    it:TNMITEMACTIVATE;
    HW:DWORD; //main form
    MyCtrl:DWORD; //control
    begin
    it.hdr.code:=NM_DBLCLK;
    SendMessage(HW, WM_NOTIFY, MyCtrl, Integer(@it));
    
    типа того
     
  9. .Light.

    .Light. Member

    Joined:
    12 Jul 2010
    Messages:
    195
    Likes Received:
    5
    Reputations:
    0
    Столкнулся с проблемой!Один очень хороший человек подсказал как ее решить но опыта не хватает, по этому прошу помощи как реализовать такое:
    1 - после запуска проверяем папку где мы находимся, например if ExtractFilePath(ParamStr(o)) = 'c:\TargetFolder' then {ничего не делаем}:
    2 - если мы в какой-то другой папке, то проверям есть ли уже скопированное приложение в TargetFolder
    3 - если есть - ничего не делаем и закрываемся, если нет - копируем себя туда и запускаем
     
  10. Protocoler

    Protocoler Elder - Старейшина

    Joined:
    10 Oct 2012
    Messages:
    51
    Likes Received:
    54
    Reputations:
    81
    Попробуйте так : if extractfilepath(Application.ExeName) ...



    Мой вопрос :



    Есть список строк , часто одинаковых, нужен сортировщик по исключениям , то есть вносишь образцы которые если есть сортировщик НЕ кидает в мемо.



    Сам код :


    memo1 - сам строки которые будут сортировать
    memo2 - выведенные строки
    mmo1 - исключения, которые надо пропускать

    Code:
     for i:=0 to memo1.lines.Count-1 do  
        begin
          
           for j:=0 to mmo1.Lines.Count-1 do
            begin
                  if pos(mmo1.Lines[j], memo1.Lines.Strings[i])=0 then
                 begin
         
                  memo2.Lines.Add(memo1.Lines[i]);
                  end
                  else
                  begin
                 
                 end;
    end;
    end;

    Пробовал по разному , может у меня что-то с логикой ?
     
  11. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    ParamStr принимает индекс аргумента (число), а у вас там буква "o".
    ParamStr(0) вернёт полный адрес до приложения.

    Code:
    uses
      SysUtils, Windows, ShellAPI;
    
    procedure CheckInstall;
    const
      DestPath = 'C:\TargetFolder\';
    var
      DestName: String;
    begin
      if ExtractFilePath(ParamStr(0)) = DestPath then begin
        // уже запущены из нужной папки
        Writeln('No installation required');
        Exit;
      end;
      DestName := ExtractFileName(ParamStr(0));
      if FileExists(DestPath + DestName) then begin
        // уже скопированы в нужную папку
        Writeln('Already installed');
        Exit;
      end;
      if not CopyFile(PChar(ParamStr(0)), PChar(DestPath + DestName), False)
      then begin
        // не удалось скопироваться
        Writeln('CopyFile failed (error ', GetLastError(), ')');
        Exit;
      end;
      // запускаемся
      ShellExecute(0, 'open', PChar(DestPath + DestName),
        nil, PChar(DestPath), SW_SHOWDEFAULT);
      // примечание: функция ShellExecute не ожидает завершения запущенного процесса
      // если нужно ждать - используйте CreateProcess в паре с WaitForSingleObject
    end;
    Для консольного приложения или DLL такой способ не прокатит. ParamStr(0) в данном случае очень удобен.
     
  12. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    Что-то не очень понял суть, объясните на примере.
     
  13. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    А вот мой легковесный вариант, без использования тяжелого SysUtils и ShellApi. Экономия в размере 24,5кб :)

    PHP:
    program Project2;

    {
    $APPTYPE CONSOLE}

    const
      
    GENERIC_READ          = $80000000;
      
    FILE_SHARE_READ       = $00000001;
      
    OPEN_EXISTING         3;
      
    FILE_ATTRIBUTE_NORMAL = $00000080;
      
    SW_SHOWNORMAL         1;

    function 
    GetCommandLineA:PAnsiCharexternal 'kernel32.dll';
    function 
    CreateFileA(lpFileNamePAnsiChardwDesiredAccessdwShareModeLongWord;  lpSecurityAttributespointerdwCreationDispositiondwFlagsAndAttributesLongWordhTemplateFileTHandle): THandlestdcall external 'kernel32.dll';
    function 
    CloseHandle(hObjectTHandle): BOOLEANstdcall external 'kernel32.dll';
    function 
    CopyFileA(lpExistingFileNamelpNewFileNamePAnsiCharbFailIfExistsBOOLEAN): BOOLEANstdcall external 'kernel32.dll';
    function 
    ShellExecuteA(hWndLongWordOperationFileNameParametersDirectoryPCharShowCmdInteger): HINSTstdcall external 'shell32.dll';

    var
      
    CommandLine:string;
      
    h:LongWord;

    const
      
    TargetFile='C:\mustbethere\myexe.exe';

    begin
      CommandLine
    :=GetCommandLineA();
      
    CommandLine:=copy(CommandLine,2,length(CommandLine)-3);

      if 
    pos(TargetFile,CommandLine)=0
      Then begin
           h
    :=CreateFileA(TargetFileGENERIC_READFILE_SHARE_READnilOPEN_EXISTINGFILE_ATTRIBUTE_NORMAL0);
           
    CloseHandle(h);

           if 
    h=$FFFFFFFF
           then begin
                CopyFileA
    (PChar(CommandLine), TargetFilefalse);
                
    ShellExecuteA(0'Open'TargetFile''''SW_SHOWNORMAL);
                
    end;
           
    end;
    end.
     
    1 person likes this.
  14. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    Memo1 - Строки для сортировки
    Memo2 - Строки исключения
    Memo3 - Вывод результата

    PHP:
    procedure TForm1.Button1Click(SenderTObject);
    var
      
    i,j:integer;
      
    exclude:boolean;
    begin
      
    for i:=0 to Memo1.Lines.Count
      
    do begin
          exclude
    :=false;
          for 
    j:=0 to Memo2.Lines.Count
          
    do begin
             
    If Memo2.Lines.Strings[j]=Memo1.Lines.Strings[i]
             
    Then exclude:=true;
          
    end;

          If 
    exclude=true
          Then 
    continue
          Else 
    Memo3.Lines.Add(Memo1.Lines.Strings[i])
      
    end;
    end;
     
  15. .Light.

    .Light. Member

    Joined:
    12 Jul 2010
    Messages:
    195
    Likes Received:
    5
    Reputations:
    0
    copyfile(PAnsiChar(Paramstr(0))),(P AnsiChar('C:\ProgramData\Microsoft. NET'+ExtractFileName(Paramstr(0)))) ;
    что сдесь не так?
     
  16. #colorblind

    #colorblind Moderator

    Joined:
    31 Jan 2014
    Messages:
    634
    Likes Received:
    246
    Reputations:
    42
    Вероятно это:
    copyfile(PAnsiChar(Paramstr(0))),(P AnsiChar('C:\ProgramData\Microsoft. NET\'+ExtractFileName(Paramstr(0)))) ;

    Ну и в Paramstr(0) тоже может быть :)
     
  17. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    1. Скобки не так. Даже не представляю, почему вы расставили их именно так... :D

    2. И вы точно уверены, что PAnsiChar? Если вызываете CopyFileA, то да. А если CopyFileW, то PWideChar.

    3. В любом случае, я зачастую пишу просто PChar, т.к. это совместимо со всеми версиями Delphi (ANSI и Unicode).

    4. "Microsoft. NET" - вы уверены в правильности названия папки? По-моему "Microsoft.NET"

    5. В конце названия папки нужно ставить "\", поскольку ExtractFileName вернёт строку, не содержащую этот символ в начале.

    copyfile(PChar(Paramstr(0)), PChar('C:\ProgramData\Microsoft.NET\' + ExtractFileName(Paramstr(0))));

    После всех исправлений, я начинаю задаваться вопросом, действительно ли это вам нужно...
     
  18. .Light.

    .Light. Member

    Joined:
    12 Jul 2010
    Messages:
    195
    Likes Received:
    5
    Reputations:
    0
    Да очень нужно!)))Но опять ошибка
    [Error] Unit1.pas(30): Not enough actual parameters
     
  19. binarymaster

    binarymaster Elder - Старейшина

    Joined:
    11 Dec 2010
    Messages:
    4,717
    Likes Received:
    10,195
    Reputations:
    126
    А, забыл. Допишите третий аргумент False.
     
  20. .Light.

    .Light. Member

    Joined:
    12 Jul 2010
    Messages:
    195
    Likes Received:
    5
    Reputations:
    0
    Все отлично!Но почемуто копия получается битая!Моя программа посылает обычный гет запрос!Но при запуске копии она этого не делает в чем проблема?
    вот код
    begin
    if not FileExists('C:\ProgramData\Microsof t.NET\' + ExtractFileName(Paramstr(0))) then
    begin
    copyfile(PAnsiChar(Paramstr(0)), PAnsiChar('C:\ProgramData\Microsoft .NET\' + ExtractFileName(Paramstr(0))), False);
    ShellExecute(Handle, nil, PAnsiChar('C:\ProgramData\Microsoft .NET\' + ExtractFileName(Paramstr(0))), nil, nil, SW_SHOW);
    sl:= TStringList.Create;

    sl.Text:= idhttp1.Get('http://111111111.txt');

    for i:= 0 to sl.Count-1 {??? ??????? ????, ????. 5} do
    (FindComponent('Edit' + IntToStr(i+1)) as TEdit).Text:= sl;
    sl.Free;
     
Thread Status:
Not open for further replies.