Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: DirectX - How can I disable Alt+Tab / Crashes

  1. #1

    DirectX - How can I disable Alt+Tab / Crashes

    Just wondered if anyone knew of a quick easy way to handle my DirectX app loosing fullscreen status? It crashes when it minimizes, ideally I would like to stop Alt+Tab, and make it fullscreen until closed. Can you stop other applications from popping up and minimizing it?
    http://www.c5software.co.uk (site is being developed at the moment)

  2. #2

    DirectX - How can I disable Alt+Tab / Crashes

    In theory... Yes, I have seen applications do it, however in most games I have seen it done it made the window lose the focus and therefor the mouse and keys.

    Not sure if it can be handled in a good way. Knowing a bit of the windows API there's probably a way the upperhand for your window. Stay On Top could be a step in the right direction, but it will only solve 1% of what you want accomplished !
    Do it by the book, but be the author!
    <br />
    <br />Visit the Lion Productions website at:
    <br />http://lionprod.f2o.org

  3. #3

    DirectX - How can I disable Alt+Tab / Crashes

    You can do it, BUT the way I know, only works for Windows 9x/ME so it is not much of an option anymore?

  4. #4

    DirectX - How can I disable Alt+Tab / Crashes

    OK, so I can't easily disable alt+tab, but can I detect that the app has lost focus? Checking if WindowState = wsMinimized doesn't work...
    http://www.c5software.co.uk (site is being developed at the moment)

  5. #5

    DirectX - How can I disable Alt+Tab / Crashes

    I surgestion could be that you ask Windows what the topmost windows is, and campare that handle with the handle of your application, or your mainwindow? I cannot remember the exact procedure calls, but I think it is something with: GetTopMostWindow or something like that?

  6. #6

    DirectX - How can I disable Alt+Tab / Crashes

    Out of my head this would be done in VCL with something like

    function ActivateApp(lparam, wparam : Integer) : Integer message WM_ACTIVATEAPP;

  7. #7

    DirectX - How can I disable Alt+Tab / Crashes

    You don't want to be disabling alt-tab, because it annoys users unnecessarily (like my brother, who's always alt-tabbing out to do other stuff in the middle of his games). The first question: are you using D3D or DirectDraw, because the way to restore stuff is different in each (and I can't say that I've used D3D, so someone else [e.g. Jarrod] will have to fill in the blanks).

    In DirectDraw, all surfaces are messed up once you alt-tab and you have to regenerate them. This is easy enough. In addition, any surface that's sitting in video memory must have its picture reloaded because it'll be blanked out.

    The trick here is to catch the WM_ACTIVATEAPP message. Windows passed this when your app is activated/deactivated (note that a similar message, WM_ACTIVATE, exists, but you don't deal with that - it handles individual windows in your app getting/losing focus, rather than the main app itself). So... you maintain whether the app has focus. Don't do too much that's hard work if deactivated (no CPU hogging!), minimal drawing if required (maybe, maybe not).

    You could handle the WM_ACTIVATEAPP message in a couple of ways -- writing a specific message handler function for it or by catching Application.OnMessage (be careful to not do too much here, since that'll be called for any message that passes through your system).

    I won't detail the above since I don't know what system you're using. Instead, I'll go over the general process that I've used and that seems to work (no idea if it doesn't deal with special cases, but never mind.).

    Here's the message handling in my WndProc for WM_ACTIVATEAPP:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000][number=#C00000][reserved=#000000][string=#00C000] WM_ACTIVATEAPP:
    begin
    bActive := LongBool(wParam);
    Result := 0;

    // we have to handle ALT-Tabbing from the user or other ways to lose
    // the focus. DirectDraw gets rid of our surfaces when this happens
    // so we have to restore them and then reload anything on the bitmaps
    // themselves
    //
    // todo: double-check this works!
    if bActive and (DD7 <> nil) then
    begin
    if g_FullScreen then
    begin
    DD7.SetCooperativeLevel(Globals.g_Handle, DDSCL_EXCLUSIVE or
    DDSCL_FULLSCREEN or
    DDSCL_ALLOWREBOOT);
    end;

    while DD7.TestCooperativeLevel <> DD_OK do
    begin
    Sleep(0);
    end;

    ReloadAllImages;
    end;

    //etc[/pascal]
    DD7 is my IDirectDraw7 interface, bActive is a boolean that refers to whether the app's running (side note: I really should eliminate that hungarian notation, sigh), and Globals.g_Handle is the window handle for the window.

    First, I take a note of whether the app's activation status -- it's passed as a boolean in wParam. A typecast is required to convert it into a boolean value, since it's passed as something of type wParam. Now we know whether the app is doing stuff.

    If we're active then it means we've been switched back from an inactive state -- in this case, we have to restore everything!

    It's often the case that we'll lose exclusive mode when running fullscreen once the user alt-tabs. Therefore, the next step is to set the cooperative level back to the wanted value (exclusive, fullscreen). This takes some time, unfortunately, so we have to sit around and wait to see whether it works. I added a sleep(0) in there while we're waiting. We can use the TestCooperativeLevel method of IDirectDraw7, which returns whether the exclusive mode is set yet. There may be a better method to waste time than Sleep(0); investigate this.

    Once we've done that, we have to restore the surfaces. This is done in my function "ReloadAllImages." First, we can use IDirectDraw7.RestoreAllSurfaces, which does the hard part for us. The only task left here is reload images for surfaces that are in video memory (system memory ones won't be wiped out).

    The above is how I do it and it seems to work fine. Any corrections are much appreciated. Of course, it's based on my non-component-based stuff rather than a specific set. Making this relevant to your app is left as an exercise (to be done in public so we all learn from it, of course ).

    Now, I haven't used D3D yet, so I can't answer that case. I'll let one of the other dudes answer it -- I think there's an equivalent TestCooperativeLevel method somewhere and I remember something about D3DPOOL_MANAGED (or something similar) textures being reloaded by the system. I also remember something about a reset method that must be called for something. This is all vague, but hopefully it's not wrong and will give someone an idea of where to begin.

    Remember that you'll have to re-acquire DirectInput things. This should not be a problem if you check for the appropriate "not acquired" return values for the important functions.
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  8. #8

    DirectX - How can I disable Alt+Tab / Crashes

    1) First point - you should not prevent users from "Alt-Tab"-bing
    2) Second isssue - WinNT based OS'es will not let you prevent user from AltTab

    Now how to correcly handle Alt-Tabbing, Printer Box pop-up's, Fast User switching, Suspendig, etc...

    Yes, WM_ACTIVATEAPP in most cased will do the trick, but to ensure what your suggestion is correct you should check result of Present/Blit/Flip function for "device lost" situation.

    Code snippet below is from D3D9 render procedure code:
    [pascal][background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000] function Render3DEnvironment: HRESULT;
    var
    ...
    begin
    if fDeviceLost then
    begin
    // Test the cooperative level to see if it's okay to render
    Result := D3DDevice.TestCooperativeLevel;
    if FAILED(Result) then
    begin
    // If the device was lost, do not render until we get it back
    if (D3DERR_DEVICELOST = Result) then
    begin
    Result := S_OK;
    Exit;
    end;

    // Check if the device needs to be reset.
    if (D3DERR_DEVICENOTRESET = Result) then
    begin
    // If we are windowed, read the desktop mode and use the same format for
    // the back buffer
    if fWindowed then
    begin
    // Setup back buffer format
    ...
    end;

    Result:= Reset3DEnvironment; // inside this function we call to D3DDevice.Reset
    if FAILED(Result) then Exit;
    end;
    Exit;
    end;
    fDeviceLost := False;
    end;
    ...
    // Render the scene as normal
    Result := Render;
    if FAILED(Result) then Exit;
    ...
    // Show the frame on the primary surface.
    Result:= m_pd3dDevice.Present(nil, nil, 0, nil);
    if (D3DERR_DEVICELOST = Result) then fbDeviceLost := True;

    Result := S_OK;
    end;[/pascal]
    Code from D3DFramework: http://clootie.narod.ru/delphi/downl...l#D3Dex_Common
    There are only 10 types of people in this world; those who understand binary and those who don't.

  9. #9

    DirectX - How can I disable Alt+Tab / Crashes

    Thanks for that, it answers my question I am using DirectDraw, I will go away and make the changes and let you know how I get on...

    http://www.c5software.co.uk (site is being developed at the moment)

  10. #10

    DirectX - How can I disable Alt+Tab / Crashes

    Thanks a lot for the help, it works (sort of...)

    For the moment I have set it to close the application if they alt+tab, this isn't how I want to leave it, but it's stopped the crashing for the moment.

    I seem to have a problem in the logic of my app. My main loop is in the AppOnIdle event, and I think that it may be causing the SetCoop to fail, or hang for a very long time when going back into the application. Spent a few hours trying to work out why it wouldn't go back into fullscreen. I suspect its that main loop that needs to be halted.

    Another related question:-

    What should I be using WndProc for other than this? Anything else that you would recommend using the message handler for?
    http://www.c5software.co.uk (site is being developed at the moment)

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •