Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
65 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Full Screen and Back

Another feature we'll want from our CDxWindowImpl class is the ability to support both windowed and full screen applications. We'll also want the ability to switch between the two at runtime. I won't go into the details of how this is accomplished, it's just basic Windows API programming, but I'll list the functions here. Simply make the following changes to the CDxWindowImpl class.

[listing 2.13]

typedef CWinTraits<WS_OVERLAPPEDWINDOW,0> CDxAppWinTraits;

template <class T, class TBase = CWindow, class TWinTraits = CDxAppWinTraits>
class CDxWindowImpl : public CWindowImpl<T,TBase,TWinTraits>
{
public:

// ... Some code left out to save space

  HWND Create(HWND hWndParent, RECT& rcPos, LPCTSTR szWindowName = NULL,
                            DWORD dwStyle = 0, DWORD dwExStyle = 0,
                            UINT nID = 0, LPVOID lpCreateParam = NULL)
  {
    if(PreviousInstanceFound(GetWndClassInfo().m_wc.lpszClassName,szWindowName) &&
       !AllowMultipleInstances())
      return NULL;

    HWND hwnd = CWindowImpl<T,TBase,TWinTraits>::Create(hWndParent,
                      rcPos,szWindowName,dwStyle,dwExStyle,nID,lpCreateParam);

    if(!hwnd)
      return NULL;

    wndStyles = GetWindowLong(GWL_STYLE);
    wndExStyles = GetWindowLong(GWL_EXSTYLE);
    GetWindowRect(&wndRect);

    return hwnd;
  }

  BOOL FullScreen()
  {
    BOOL retval;

    //  Save the styles and position of the window
    GetWindowRect(&wndRect);
    wndStyles = GetWindowLong(GWL_STYLE);
    wndExStyles = GetWindowLong(GWL_EXSTYLE);


    ShowWindow(SW_HIDE);
    SetWindowLong(GWL_STYLE,WS_POPUP);

    retval =  SetWindowPos(HWND_TOPMOST,0,0,GetSystemMetrics(SM_CXSCREEN),
                           GetSystemMetrics(SM_CYSCREEN),SWP_SHOWWINDOW);
    ShowWindow(SW_SHOW);

    return retval;
  }

  BOOL Windowed()
  {
    BOOL retval;

    ShowWindow(SW_HIDE);
    SetWindowLong(GWL_STYLE,wndStyles);
    SetWindowLong(GWL_EXSTYLE,wndExStyles);

    retval = SetWindowPos(HWND_NOTOPMOST,&wndRect,SWP_DRAWFRAME);
    ShowWindow(SW_SHOW);

    return retval;
  }

// ...  More left out

private:

  LONG wndStyles;
  LONG wndExStyles;
  RECT wndRect;
};

It doesn't matter where in the class they're included so long as they're there. Basically FullScreen() saves the styles and position of the window and Windowed() restores them. If you need to reposition or resize the window use SetWindowPos() or ResizeClient().

The complete CDxWindowImpl template class contains two message handlers not listed in this article. One stops screensavers and the other calls virtual functions when the application becomes active or inactive. The complete CDxWindowImpl template class can be found in the accompanying source.

Conclusion

Well, that wraps up this installment. I expect we'll be able to finish up what's left in the next article, but it may stretch on to a fourth. You'll find in the source that accompanies this article two additional functions. They allow CDxWindowImpl to provide window styles suitable for both windowed and full screen DirectX applications. You can even switch between the two at runtime.

In the next article we'll finally get to message loops and idle processing, and also implement our own version of CAppModule that'll initialize and create the Direct3D object. In the meantime I can be reached by emailing rmack005@hotmail.com or by posting a comment in this articles discussion forum.

Acknowledgements

I'd like to thank Ben "Kylotan" Sizer, Jim Nasche, and Ranthalion for the feedback they provided. Their comments were a great help. And again, I'd like to thank the staff at Gamedev.net for providing both a home and an audience for this article. Thanks again everyone.

Notes

1 Technically speaking, there are actually two version of a few of the WTL classes and functions, an ANSI version and a Unicode version. Here I remove the 'A' and 'W' suffixes for the sake of clarity since SomeClassOrFunction is SomeClassOrFunctionW if _UNICODE is defined or SomeClassOrFunctionA if it is not.

2 For the curious: line 2933 for AtlModuleRegisterWndClassInfoA and line 2995 for AtlModuleRegisterWndClassInfoW.

3 I may change my mind about super classing and cursors and write an article covering them. Their use would more likely be seen in game tools like map editors and such than in an actual game. If I get to them, they'll be in a supplemental article which would likely cover using the WTL to create game development tools.

4 AtlGetStockBrush() checks to make sure the value passed is a valid brush type and casts the value returned by GetStockObject() to HBRUSH. You'll find it, along with a few other functions like it, in atlmisc.h.

References

[1] Michael Park, "ATL 3.0 Window Classes: An Introduction", MSDN. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvc60/html/atlwindow.asp





Contents
  Introduction
  Window Traits
  Window Class Registration
  Full Screen and Back

  Source code
  Printable version
  Discuss this article

The Series
  Getting Started
  Windowing