Thread: DLL Hell

    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    15
    Rep Power
    0

    DLL Hell


    I recently created a dll for Final Fantasy 8 PC that injects into the main process, and then loads a form. The form contains a timer and plays music through calls to bass.dll. All of this is trivial anyway because none of that is the cause of the issue.

    Basically, I need to open a form without focus. So the focus will stay on the game. I can't use setforegroundwindow because by that time, focus has already been lost and the game minimizes. At the moment I am being forced to use showmodal as follows:

    Code:
    CreateThread(nil,0,@funcStart,nil,0,dwtemp);
    
    and
    
    procedure funcStart;
    begin
    
    form1:=Tform1.Create(nil);
    TRY
    form1.showmodal;
    FINALLY
    Form1.close;
    END;
    
    end;
    The problem is showmodal will always take the focus (unless there is some way to override that behaviour?). So next I tried:

    Code:
    procedure funcStart;
    begin
    
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);     
    ShowWindow(Form1.Handle, SW_SHOWNOACTIVATE);
    Application.Run;  
    
    end;
    This indeed works, but then the issue is when the game is closed down, an exception is always raised saying that the window handle is invalid.

    So... anyone have any idea how I can show a form from a dll without it gaining focus away from the game? I am forced to use these methods because with a normal show method, the thread ends.
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Location
    South Africa
    Posts
    59
    Rep Power
    11
    Hi, my most humble opinion.

    Using your code example:

    procedure funcStart;
    begin
    Application.CreateForm(TForm1, Form1);

    form1.Show;
    form1.SendToBack;

    repeat
    Application.HandleMessage;
    until Form1.CanClose;

    Form1.Close;


    end;
    Do a .show within your thread and immediately thereafter start a repeat until loop which will only evaluate to true once the form is closed. This way you don't have to use showmodal (hence not gaining the focus unnecessarily) - assuming the show doesn't take focus.

    i first tried with app.processmessages but noticed it will eat up a lot op cpu cycles. Then tried checking what showmodal usually does and it seems to use .handlemessage instead.

    hope it helps.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Dec 2013
    Posts
    15
    Rep Power
    0
    Thank you! Finally, this is solved. This is what I did...

    Code:
    form1:=Tform1.Create(nil);
    form1.visible:=true; (so it doesn't override the shownoactivate)
    
    repeat
    Application.HandleMessage;
    until form1cancloseflag;
    
    Form1.Close;
    Then, in the oncreate of form1:

    Code:
    ShowWindow(Handle, SW_SHOWNOACTIVATE);
    This has no error message on game close (from what I can see the error only happens with XP anyway), and it solves all other issues.

    Thanks again!
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2004
    Location
    South Africa
    Posts
    59
    Rep Power
    11
    awesome!

IMN logo majestic logo threadwatch logo seochat tools logo