| View previous topic :: View next topic |
| Author |
Message |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Wed Dec 11, 2013 1:45 pm Post subject: dll and forms with Delphi 7 |
|
|
Hello. I have added OST music into Final Fantasy 8 as part of a mod over at Qhimm forums. The mod has been released but there are a few things I am unsure about, and a problem has arisen with the Steam release because of this.
| Code: | procedure funcStart;
begin
form1 :=Tform1.Create(nil);
form1.showmodal;
end; |
| Code: | | CreateThread(nil,0,@funcStart,nil,0,dwtemp); |
Firstly, is there any way to show form1 without it having to be modal? At the moment, the thread closes if I use show. And I'd rather use show.
Secondly, the reason I am having a problem is, when the dll is injected into FF8's main executable, the form opens and then that causes FF8 to lose focus, resulting in the game minimizing on start. What I need is a way to open the form WITHOUT focus. I looked up the api...
| Code: | ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
Form1.Visible := True; |
Apparently this would do it... the problem is... again the thread will close down because this is not a modal window.
So the bottom line is, I need a way to show form1 without it gaining any focus and without it closing automatically because the thread ends. Ideas?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Wed Dec 11, 2013 2:09 pm Post subject: |
|
|
try this inside funcStart
| Code: |
Application.Initialize;
Application.ShowMainForm:=false;
Application.CreateForm(TForm1, Form1);
ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
Application.Run;
|
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Wed Dec 11, 2013 2:27 pm Post subject: |
|
|
Thanks!
That opens the form and makes it stay without losing focus. Downside is some of the labels and so forth on the form do not show up and then an error:
The exception unknown software exception occurred in the appliction at location 0x7c812afb
It's worth noting that I have a timer on that form (initially set to false) that reads memory values and then bass.dll is called to play various musics too.
The form is also inside the dll which is then injected.
edit. Well, it's nothing to do with the timer or bass... the dll just hates the use of "application" in the create process. It doesnt show the form right and then an error happens on game close.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Wed Dec 11, 2013 3:48 pm Post subject: |
|
|
Try this.
I'm not sure if it works on delphi, but I use this method in a lazarus dll
| Code: |
MainThreadID:=GetCurrentThreadId;
Application.Initialize;
Application.ShowMainForm:=false;
Application.CreateForm(TForm1, Form1);
ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
Application.Run;
|
Also, try commenting out Application.ShowMainForm:=false; and remove that showWindow. Perhaps it just doesn't like being shown without proper initialization
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Wed Dec 11, 2013 4:53 pm Post subject: |
|
|
| Code: | MainThreadID:=GetCurrentThreadId;
Application.Initialize;
Application.CreateForm(TForm1, Form1);
ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
Application.Run; |
This indeed works, thanks a bunch! Now the only thing is, an error pops up when the game is closed down. I assume that's because I am not freeing the form properly. On the onclose of the form I do free the resources and use "action:=cafree" but do I have to use a try finally statement here? If so, how with the above code. (I am used to using try finally with normal show modal).
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Wed Dec 11, 2013 5:25 pm Post subject: |
|
|
It's better to not free the form and just close it. (Default behavior for application is to quit when the main form closes)
I think application.run does something with the main form before it exits. So if it's freed it might cause a problem
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Wed Dec 11, 2013 5:45 pm Post subject: |
|
|
| In that case, how do I close it? I mean, the user can close the entire game down by pressing close button (and thus the dll and forms will be closed with it), but at the moment, there's an error whenever that happens. How do I handle a form created by a dll when I have no control over the actual game close.
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Wed Dec 11, 2013 5:50 pm Post subject: |
|
|
No idea where the crash comes from
It depends on how the game closes.
If not all the threads are closed, the program will keep running. (e.g the dll should just keep running if nothing closes that form)
Of course, if the program makes use of TerminateProcess or ExitProcess or something similar, then the dll thread will close as well.
If the dll does more than just play sound, but also reads out memory, then that can cause a problem (reading memory that isn't there)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Wed Dec 11, 2013 5:53 pm Post subject: |
|
|
I see... well yeah it does read memory through a timer but with the original showmodal code I had there was no error on exiting the game. With application.run there is... I terminate the timer on form close (but obviously if the game is being terminated suddenly it may not be getting there).
nope...
its just giving an error regardless. Even with no timer or other code.
The error is "Invalid handle".
edit
1 last question...
How do hooks work? This is what I have:
thehook:=SetWindowsHookEx(WH_KEYBOARD, @KeyboardHookProc,hinstance,0);
I have this on the forms oncreate. It's a global hook... acts like one too.
thing is... if I click away from the game and onto the desktop and press any key a few times, it crashes explorer and the whole thing goes whacko. I thought that if I am setting up a hook on a forms oncreate thats where the hook code should be?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Thu Dec 12, 2013 3:58 pm Post subject: |
|
|
Hooks like that are system wide. It might be easier to just change the wndproc address of the window to your own function, which then calls the original
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Thu Dec 12, 2013 10:53 pm Post subject: |
|
|
I got rid of the hook altogether and used GetAsyncKeyState. Those hooks are more trouble than they are worth.
In any case... there are 2 different ff8 games. The 2000 original and the new Steam 2013. The Steam 2013 does not give any error on close, but the 2000 does.
The error is
EOSerror
"Invalid window handle"
Error code: 1400
This only happens with:
Application.CreateForm(TForm1, Form1);
and not with the other create method.
Any ideas why this would be happening?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Fri Dec 13, 2013 2:57 am Post subject: |
|
|
No idea. Perhaps the 2000 version enumerates all non-modal windows at closing time and uses a specific api call on it(perhaps as part of a copy protection scheme back then?),which then fails and the game doesn't understand that there can be other windows it didn't create, so throws that error.
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Fri Dec 13, 2013 11:55 am Post subject: |
|
|
Well looks like both versions have the issue... although my tester didn't get the error which is strange. Somehow the form is being referenced when the game has closed... maybe for a split second. And that's leading to an invalid window handle exception. How have you implemented "Application.createform" in your dll? Is there anything I may have missed?
If not, is there any way I can suppress the error?
|
|
| Back to top |
|
 |
Dark Byte Site Admin
Reputation: 471
Joined: 09 May 2003 Posts: 25819 Location: The netherlands
|
Posted: Fri Dec 13, 2013 12:17 pm Post subject: |
|
|
It depends what shows that message. The game or the dll.
If the dll then you could set application.onException to point to an empty function that doesn't do anything
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
| Back to top |
|
 |
dlpb Advanced Cheater
Reputation: 0
Joined: 11 Dec 2013 Posts: 78
|
Posted: Fri Dec 13, 2013 5:09 pm Post subject: |
|
|
OK final question...
If I do do that... will the form be freed properly. I mean, when the game is shut down, is the form being freed. The dll that was injected will obviously be killed, and the form will be killed, but is it being freed from mem?
|
|
| Back to top |
|
 |
|