Projects‎ > ‎Code‎ > ‎

c++ win32 Toggle Title bar on and off

I recently embarked on a direct2d adventure. I wanted to make a small app to function as a screen saver that could be played on idle monitors. One of the main design criteria was that the window would need to be easily movable from one monitor to another. The simplest solution is to leave the title bar intact and use its innate ability to control the window size and move it around. Of course, its no good as a screen saver if it has a large static portion, so I needed to be able to turn the title bar off and on with the click of a mouse. Enough talk. Lets see the code.

LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

    case WM_RBUTTONUP:
            //hasTitlebar is just a boolean indicating the titlebar state

                ::SetWindowLong(pDemoApp->m_hwnd, GWL_STYLE, 
                    ::GetWindowLong(pDemoApp->m_hwnd, GWL_STYLE) 
                    & ~(WS_BORDER | WS_DLGFRAME | WS_THICKFRAME));
                ::SetWindowLong(pDemoApp->m_hwnd, GWL_EXSTYLE, 
                    ::GetWindowLong(pDemoApp->m_hwnd, GWL_EXSTYLE)
                    & ~WS_EX_DLGMODALFRAME);

                ::SetWindowLong(pDemoApp->m_hwnd, GWL_STYLE, 
                ::GetWindowLong(pDemoApp->m_hwnd, GWL_STYLE)|(WS_OVERLAPPEDWINDOW));

Pretty simple. Here is whats going on with the removal:

First we have ~(WS_BORDER | WS_DLGFRAME | WS_THICKFRAME). This takes several window style options, and combines them into a single long (12845056) using bitwise OR. It then inverts the bits (-12845057) using a bitwise NOT.

The next step is to perform a bitwise AND operation between the current window style and the result of the bitwise NOT. This will effectively unset the bits for the styles (WS_BORDER | WS_DLGFRAME | WS_THICKFRAME), since a bit will only be 1 if both bits are 1.

In binary this operation looks like this:
(WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)) :: 00000110001000000000000000000
~(WS_BORDER | WS_DLGFRAME | WS_THICKFRAME)):: 11111001110111111111111111111
GetWindowLong(pDemoApp->m_hwnd, GWL_STYLE) :: 10100110011110000000000000000
GetWindowLong(...current)& ~(...options)   :: 10100000010110000000000000000

To restore the title bar, we simply restore the bits using a bitwise OR of the current window style and WS_OVERLAPPEDWINDOW, which is of course itself a macro combining several styles. (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)

What is an overlapped window? Asked nobody, probably. MSDN tells us that "An overlapped window is a top-level window that has a title bar, border, and client area; it is meant to serve as an application's main window."