Forma cały czas na pierwszym planie (na wierzchu)

0

Witam,

mam problem, a mianowicie, robię koledze program, którego forma po przyciśnięciu przycisku ma być cały czas widoczna (A szczególnie przed grą "League of Legends", w którą gra z 6 h dziennie). Nie wiem jak to zrobić, czy ktoś mógłby mi pomóc? Mam Delphi 7 Persolal

Z góry Dziękuję za pomoc,
Counter

0

Od razu dodam, że StayOnTop nie działa na grze.

0

to ci nie zadziała ;] zobacz czy możesz rysować po tym (zakładasz uchwyt i canvas)
ta poza tym jak to zrobisz to możesz mi dać bo mnie brat tym lol'em wkur**a ;]

0
Counter napisał(a)

Od razu dodam, że StayOnTop nie działa na grze.

A czy ta gra jest rozciągnięta na pełny ekran (tryb "full screen") tak, jak to ma miejsce np. w WoW? Bo jeżeli nie, jak uruchamia się w oknie, które można zminimalizować, to StayOnTop powinno zadziałać (ale pod warunkiem, że okno gry ma tę właściwość wyłączoną);

Mój brat też napierdziela w to godzinami, na szczęście mam swojego notebook'a i nie mam problemu; Czasem jedynie sieć obciąża i mi się forum wolno ładuje... :P Już nawet siostra mnie prosiła, żebym rootkit'a napisał żeby skończyć z tą grą...

0

Chciałem pomóc pytającemu, ale nie trawie rpgów żadnych in real i komputerowych z wyjątkiem może klasyka i świetnej gry jaką był Moonstone na Amidze. Pobrałem ten "lol-crap", ale po założeniu konta nie wpuszcza mnie na serwer twierdząć, że źle podałem login i hasło. Raz mi przyjął, ale napisał że server busy. Szkoda marnować czas na tibiopodobne bzdety. Poza tym gra do momentu rozgrywki jest w oknie. Jedyne co mogę doradzić pytającemu to spróbowac zrobić dialog w WinAPI, a następnie wstrzykiwac dllkę z tym dialogiem przez moduł afxcodehook.pas. Dla niektórych gier na przykład starej przygodówki "Wacki - Kosmiczna rozgrywka", które są pod DitectX, a nie SDL taki kod zadziałał i okno jakie stworzyłem było na wierzchu i okno głowne gry nie traciło focusa.

//..
const
  IDI_MAINICON = 100;
  IDC_MAINFORM = 1001;
//...
var
  vvv : boolean;
//...
  GamePid : DWORD;
  GameWindowHandle : HWND;
//...

var // Te trzy zmienne koniecznie muszą być globalnie i użyte w funkcji PidToHwnd:
  PidNumTmp : DWORD;
  TempHandle : HWND;
  TmpClassName : string;
// Koniec zmiennych koniecznie globalnych ;)
  POrigProcessWinFunc, POwnProcessWinFunc : Pointer;
//...

function PidToHWnd(DestPid : DWORD; AClassName : string) : HWND;

  function EnumProcess(AHWnd : HWND; lParam : integer) : boolean; stdcall;
  var
    PPid : DWORD;
  begin
    Result := (AHWnd <> 0);
    if Result = True then
    begin
      GetWindowThreadProcessId(AHWnd, PPid);
      if PPid = PidNumTmp then
      begin
        if (GetWindowLong(AHWnd, GWL_HWNDPARENT) = 0)
          and (IsWindowVisible(AHWnd) or IsIconic(AHWnd)) then
        begin
          if (GetControlClassName(AHWnd) = TmpClassName) then
          begin
            TempHandle := AHWnd;
          end;
        end;
      end;
    end;
    Result := True;
  end;

begin
  PidNumTmp := DestPid;
  TmpClassName := AClassName;
  EnumWindows(@EnumProcess, 0);
  Result := TempHandle;
end;

function MainDlgProc(AHWnd : HWND; Msg : UINT; wParam : wParam; lParam : lParam) : BOOL; stdcall;
// obsługa komunikatów okna
end;

function ProcessCapturedWinFunc(AHWnd : HWND; UMsg : UINT; AWParam : WParam; ALParam : LParam) : integer; stdcall;
var
  Msg : TMsg;
  DlgH : HWND;
begin
  if not vvv then
  begin
    vvv := True;
    DlgH := CreateDialog(hInstance, MAKEINTRESOURCE(IDC_MAINFORM), AHwnd, @MainDlgProc);
    ShowWindow(DlgH, SW_SHOW);
  end;
  Result := CallWindowProc(POrigProcessWinFunc, AHWnd, uMsg, AWParam, ALParam);
end;
//...
  GamePid := GetCurrentProcessid;
  GameWindowHandle := PidToHWnd(GamePid, 'Wacki');
  Sleep(3000);
  vvv := False;
  POwnProcessWinFunc := @ProcessCapturedWinFunc;
  POrigProcessWinFunc := Pointer(SetWindowLong(GameWindowHandle, GWL_WNDPROC, Integer(POwnProcessWinFunc)));
//...

Nie wrzucam kodu całego projektu, bo robiłem to na bazie trainera do Horde, ale na przykład z DosBoxem tak się nie da, bo pojawienie się takiego okna powoduje utrate focusa przez okno DosBoxa. Przykładowy injector wstrzykujący dllkę będącą w zasobach:

program injector;

{$R *.res}

{$APPTYPE GUI)}

{$R 'a_trainer.res' 'a_trainer.rc'}

uses
  Windows, Messages, TlHelp32,
  afxcodehook in 'afxcodehook.pas';

const
  GameProcessName = 'wacki.exe';
  Resource_Name = 'dll_to_inject';
  Msg_Name = 'Restore_DOSBox_Horde_Trainer_v2_App';
  App_Class = 'DOSBox_Horde_Trainer_v2_loader_by_olesio';
  App_Title = 'Horde - trainer version 2 - loader by olesio';

var
  GamePid : DWORD;
  App_Handle : HWND;

function AnsiUpperCase(const S : string) : string;
var
  Len : Integer;
begin
  Len := Length(S);
  SetString(Result, PChar(S), Len);
  if Len > 0 then
  begin
    CharUpperBuff(Pointer(Result), Len);
  end;
end;

function ExtractFileName(FileName : string) : string;
var
  I : integer;
begin
  ExtractFileName := FileName;
  for I := Length(FileName) downto 1 do
  begin
    if (FileName[I] = '\') then
    begin
      ExtractFileName := Copy(FileName, I + 1, MaxInt);
      Break;
    end;
  end;
end;

function ProcessExists(ExeFileName : string; var PIDResult : Cardinal) : boolean;
var
  ContinueLoop : BOOL;
  FSnapshotHandle : THandle;
  FProcessEntry32 : TProcessEntry32;
begin
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
  Result := False;
  while Integer(ContinueLoop) <> 0 do
  begin
    if ((AnsiUpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      AnsiUpperCase(ExeFileName)) or (AnsiUpperCase(FProcessEntry32.szExeFile) =
      AnsiUpperCase(ExeFileName))) then
    begin
      Result := True;
      PIDResult := FProcessEntry32.th32ProcessID;
    end;
    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;

function CheckGameProcessRuning : boolean;
begin
  Result := ProcessExists(GameProcessName, GamePid);
  if not Result then
  begin
    MessageBox(App_Handle, 'Cannot find process "' + GameProcessName +
      '"! Please run "Horde" under DOSBox and start new game or load saved game.',
      App_Title, MB_ICONERROR + MB_OK);
  end;
end;

procedure LoadDllFromResourcesAndInjectIt;
var
  ResPtr : Pointer;
  HGlobal, HResInfo : THandle;
begin
  HResInfo := FindResource(HInstance, Resource_Name, RT_RCDATA);
  if HResInfo = 0 then
  begin
    MessageBox(App_Handle, PChar('Cannot find resource named "' + Resource_Name +
      '"! with dll library to inject!' + #13#10 + 'Please check trainer''s ' +
      'source code and recompile it.'), App_Title, MB_ICONWARNING + MB_OK);
  end
  else
  begin
    HGlobal := LoadResource(HInstance, HResInfo);
    ResPtr := PChar(LockResource(HGlobal));
    InjectLibrary(OpenProcess(PROCESS_ALL_ACCESS, False, GamePid), ResPtr);
  end;
end;

function WndProc(Wnd : HWND; uMsg : UINT; wPar : WPARAM; lPar : LPARAM) : LRESULT; stdcall;
begin
  Result := 0;
  App_Handle := Wnd;
  case UMsg of
    WM_CREATE :
      begin
        SetWindowLong(Wnd, GWL_EXSTYLE, WS_EX_TOOLWINDOW and not WS_EX_APPWINDOW);
        if CheckGameProcessRuning then
        begin
          LoadDllFromResourcesAndInjectIt;
        end;
        SendMessage(App_Handle, WM_DESTROY, 0, 0);
      end;
    WM_DESTROY :
      begin
        PostQuitMessage(0);
      end;
  else
    begin
      Result := DefWindowProc(Wnd, uMsg, wPar, lPar);
    end;
  end;
end;

var
  Msg : TMsg;
  Wnd : TWndClass;
  WindowHandle : HWND;
begin
  with Wnd do
  begin
    lpfnWndProc := @WndProc;
    hInstance := hInstance;
    lpszClassName := App_Class;
    hbrBackground := COLOR_WINDOW;
  end;
  RegisterClass(Wnd);
  WindowHandle := CreateWindow(App_Class, App_Title, WS_POPUP, 100, 100,
    0, 0, 0, 0, hInstance, nil);
  ShowWindow(WindowHandle, SW_SHOW);
  while GetMessage(Msg, 0, 0, 0) do
  begin
    DispatchMessage(Msg);
  end;
end.

Nazwę klasy okna gry ustalisz dołączonym programikiem w archiwum wininfo_by_olesio.rar. Takie kombinacje z oknem klasy były konieczne dla DosBoxa oraz innych procesów, które mają tworzone więcej niż jedno głowne okno gry. Mam nadzieję, że na coś się to Tobie przyda. Kombinuj, ale tak jak pisali poprzednicy wiele się wykombinować nie da. Można w razie czego przecież napisać program działający w tle i korzystający z Hooka na klawiaturę i za pomoca jakiś tam klawiszy dokonujący zmian w procesie gry, jeżeli chodzi Tobie o napisanie na przykład trainera czy jakiegoś cheatu. Ale do takich rzeczy jak cheaty też wykorzystuje się injekcje dllki, ponieważ wtedy wstrzyknięta dllka ma dostep do okna programu, ponieważ jest ona traktowana jak część procesu i można podmienić procedurę obsługi komunikatów, tak jak to widzisz powyżej. Więcej znajdziesz w google. Powodzenia.

0

Dzięki za pomoc, ale jednak te sposoby nie działają akurat na tą grę, co do innych gier i programów to działa fenomenalnie, ale niestety nie na tą grą, coś tam czytałem, że w niej jest zapętlone odświeżanie, co daje jedynie efekt migotania formy, która usiłuje się przebić na pierwszy plan. Chyba jednak nie ma sposobu, żeby coś na to poradzić ;/

0

Nie wiem czy na pewno ale lol korzysta z OpenGL przez niego musiał byś rysować...

0

No sprawdziłem, LoL korzysta na 100% z OpenGL, czy ktoś mógłby mi powiedzieć, jak założyć uchwyt?
Z góry dziękuję ;)

0

Oczywiście nie chodzi mi o to jak założyć uczwyt normalnie w Delphi, tylko o to, jak założyć uchwut na okno OpenGL, aby można było po nim rysować...

0

ja cie nie odpowiem bo ja się grafiką nie bawiłem...
może edytować coś w bibliotekach gry jest takie narzędzie co rozkłada dll na hex i można skompilować zmodyfikowaną w D7

0

ja cie nie odpowiem bo ja się grafiką nie bawiłem...

No to po co odpowiadasz?...

może edytować coś w bibliotekach gry jest takie narzędzie co rozkłada dll na hex

O widzicie, macie już kolegę który poświęci się i będzie po kolei opcody rozkładać.

Kolego proqix, może nie wypowiadaj się skoro nie wiesz... Każdy wie że są narzędzia które otwierają pliki w hexie, nawet są takie co analizują kod wykonywalny (IDA). poza tym sądzę że ta gra nie będzie lubić jeżeli ktoś się będzie babrać w jej kodach i zbanuje takiego ludzia. Więc osobiście uważam taką akcję jak zakładanie hooków, injectowanie DLL itd. za dosyć groźną, bo równie łatwo jak to można zrobić, można to wykryć, a to się zapewne skończy banem.

0

No dokładnie 123, to może się się skończyć banem, jeśli bym grzebał w plikach, chodzi mi o programik, który działa całkowicie niezależnie od gry, nic nie ma zmieniać ani modyfikować, tylko chodzi o wyświetlanie tam czasu odliczającego np: od 60 sekund.

1 użytkowników online, w tym zalogowanych: 0, gości: 1