Help for Tune Smithy Koch snowflake icon.gif

How to show a dialog full screen

From Tune Smithy

(Difference between revisions)
Jump to: navigation, search
(New page: First, the problem. It is easy to show a normal window full screen, in various ways. But for a dialog created using e.g. CreateDialog, then the problem is that it normally gets created wit...)
Line 10: Line 10:
<source lang="c">
<source lang="c">
-
#include<stdio.h>
 
  switch(message)
  switch(message)
  {
  {
  case WM_GETMINMAXINFO:
  case WM_GETMINMAXINFO:
 +
  // bIsFullScreenDialog(..)
 +
  // returns TRUE if the
 +
  // dialog has been set to full screen
 +
  if(!bIsFullScreenDialog(hDlg))
 +
  break;
   {
   {
-
   // This is where I got the idea:
+
   // http://msdn.microsoft.com/en-us/library/ms632626%28VS.85%29.aspx
-
   // http://msdn.microsoft.com/en-us/magazine/cc188910.aspx
+
   // see also http://msdn.microsoft.com/en-us/magazine/cc188910.aspx
   MINMAXINFO *pmmi=(MINMAXINFO *)lParam;
   MINMAXINFO *pmmi=(MINMAXINFO *)lParam;
 +
  // Pointer to a MINMAXINFO structure that contains the default maximized position and dimensions, and the default minimum and maximum tracking sizes. An application can override the defaults by setting the members of this structure.
 +
  // Now work out the border size - this will depend on your dialog - and you can over estimate
 +
  // since this is only for situation bIsFullScreenDialog(hDlg);
   int xborder=GetSystemMetrics(SM_CXEDGE)+GetSystemMetrics(SM_CXSIZEFRAME);
   int xborder=GetSystemMetrics(SM_CXEDGE)+GetSystemMetrics(SM_CXSIZEFRAME);
   int yborder=GetSystemMetrics(SM_CYEDGE)+GetSystemMetrics(SM_CYSIZEFRAME);
   int yborder=GetSystemMetrics(SM_CYEDGE)+GetSystemMetrics(SM_CYSIZEFRAME);
   int ytitle_bar=GetSystemMetrics(SM_CYCAPTION)+(GetMenu(hDlg)?GetSystemMetrics(SM_CYMENU):0);
   int ytitle_bar=GetSystemMetrics(SM_CYCAPTION)+(GetMenu(hDlg)?GetSystemMetrics(SM_CYMENU):0);
-
   pmmi->ptMaxSize.x=GetSystemMetrics(SM_CXSCREEN)+xborder*2;
+
   // The maximum tracking size is the largest window size that can be produced by using the borders to size the window. The minimum tracking size is the smallest window size that can be produced by using the borders to size the window.
-
  pmmi->ptMaxSize.y=GetSystemMetrics(SM_CYSCREEN)+yborder*2+ytitle_bar;
+
   pmmi->ptMaxTrackSize.x=GetSystemMetrics(SM_CXVIRTUALSCREEN)+xborder*2;
   pmmi->ptMaxTrackSize.x=GetSystemMetrics(SM_CXVIRTUALSCREEN)+xborder*2;
   pmmi->ptMaxTrackSize.y=GetSystemMetrics(SM_CYVIRTUALSCREEN)+yborder*2+ytitle_bar;
   pmmi->ptMaxTrackSize.y=GetSystemMetrics(SM_CYVIRTUALSCREEN)+yborder*2+ytitle_bar;
Line 29: Line 35:
   }
   }
   break;
   break;
-
}
+
}
 +
</source>
 +
 
 +
Now resize the dialog so that it is larger than the screen. To take account of multiple monitors, detect which monitor the dialog is in first
 +
 
 +
<source lang="c">
 +
if(bIsFullScreenDialog(hDlg))
 +
{
 +
  RECT rcmon;
 +
  char do_topmost=0;
 +
  char cover_start_menu=hide_start_menu_for_full_screen;
 +
  RECT rcNewWin;
 +
  rcNewWin=rcmon=rcRectMonitorForRect(&rcWas,MONITOR_WORKAREA);
 +
  if(cover_start_menu)
 +
  {
 +
  rcmon=rcRectMonitorForRect(&rcWas,MONITOR_AREA);
 +
  if(!SameRect(&rcmon,&rcNewWin))
 +
    do_topmost=1;
 +
  rcNewWin=rcmon;
 +
  }
 +
  rcNewWin.top-=GetSystemMetrics(SM_CYSIZEFRAME);
 +
  rcNewWin.bottom+=GetSystemMetrics(SM_CYSIZEFRAME);
 +
  rcNewWin.left-=GetSystemMetrics(SM_CXSIZEFRAME);
 +
  rcNewWin.right+=GetSystemMetrics(SM_CXSIZEFRAME);
 +
  rcNewWin.top-=GetSystemMetrics(SM_CYEDGE);
 +
  rcNewWin.bottom+=GetSystemMetrics(SM_CYEDGE);
 +
  rcNewWin.left-=GetSystemMetrics(SM_CXEDGE);
 +
  rcNewWin.right+=GetSystemMetrics(SM_CXEDGE);
 +
  rcNewWin.top-=GetSystemMetrics(SM_CYCAPTION);
 +
  if(GetMenu(hDlg)&&bHideMenuForFullScreenDialog(hDlg))
 +
  {
 +
      int cy_menu=GetSystemMetrics(SM_CYMENU);
 +
  rcNewWin.top-=cy_menu;
 +
  }
 +
  OkMoveWindow(hDlg,rcNewWin.left,rcNewWin.top,rcNewWin.right-rcNewWin.left,rcNewWin.bottom-rcNewWin.top,bTF);
 +
  if(clip_to_monitor_for_full_screen_dialog)
 +
  {
 +
  // Clip by edges showing outside the window
 +
            HRGN hRgn=CreateRectRgn(rcmon.left-rcNewWin.left,rcmon.top-rcNewWin.top,rcmon.right-rcNewWin.left
 +
    ,rcmon.bottom-rcNewWin.top);
 +
            SetWindowRgn(hDlg,hRgn,FALSE);
 +
  }
 +
  if(do_topmost&&do_full_screen_dialogs_topmost)
 +
  SetWindowPosNoActivateEtc(hDlg,HWND_TOPMOST);
 +
  return;
 +
}
</source>
</source>

Revision as of 08:46, 23 February 2010

First, the problem. It is easy to show a normal window full screen, in various ways. But for a dialog created using e.g. CreateDialog, then the problem is that it normally gets created with a border and title bar. So how to show it full screen without them?

The idea is to resize the dialog so that its edges and title bar go outside the monitor. Then - so that you can't see the extra bits of it on a multiple monitor setup - clip the window to the client area.

This technique can also be used to make a dialog that is draggable without a title bar - clip in the same way, and make it draggable using the HTCAPTION trick - see How to make any part of a window or dialog draggable

First of all, we need to tell Windows that our dialog can be resized larger than the screen, otherwise it will helpfully resize it to fit the screen whenever we try.

So - in the dialog proc for the window use:

switch(message)
 {
 case WM_GETMINMAXINFO:
  // bIsFullScreenDialog(..)
  // returns TRUE if the 
  // dialog has been set to full screen
  if(!bIsFullScreenDialog(hDlg))
   break;
  {
   // http://msdn.microsoft.com/en-us/library/ms632626%28VS.85%29.aspx
   // see also http://msdn.microsoft.com/en-us/magazine/cc188910.aspx
   MINMAXINFO *pmmi=(MINMAXINFO *)lParam;
   // Pointer to a MINMAXINFO structure that contains the default maximized position and dimensions, and the default minimum and maximum tracking sizes. An application can override the defaults by setting the members of this structure.
   // Now work out the border size - this will depend on your dialog - and you can over estimate
   // since this is only for situation bIsFullScreenDialog(hDlg);
   int xborder=GetSystemMetrics(SM_CXEDGE)+GetSystemMetrics(SM_CXSIZEFRAME);
   int yborder=GetSystemMetrics(SM_CYEDGE)+GetSystemMetrics(SM_CYSIZEFRAME);
   int ytitle_bar=GetSystemMetrics(SM_CYCAPTION)+(GetMenu(hDlg)?GetSystemMetrics(SM_CYMENU):0);
   // The maximum tracking size is the largest window size that can be produced by using the borders to size the window. The minimum tracking size is the smallest window size that can be produced by using the borders to size the window.
   pmmi->ptMaxTrackSize.x=GetSystemMetrics(SM_CXVIRTUALSCREEN)+xborder*2;
   pmmi->ptMaxTrackSize.y=GetSystemMetrics(SM_CYVIRTUALSCREEN)+yborder*2+ytitle_bar;
   pmmi->ptMaxPosition.x=-xborder;
   pmmi->ptMaxPosition.y=-yborder;
  }
  break;
 }

Now resize the dialog so that it is larger than the screen. To take account of multiple monitors, detect which monitor the dialog is in first

if(bIsFullScreenDialog(hDlg))
 {
  RECT rcmon;
  char do_topmost=0;
  char cover_start_menu=hide_start_menu_for_full_screen;
  RECT rcNewWin;
  rcNewWin=rcmon=rcRectMonitorForRect(&rcWas,MONITOR_WORKAREA);
  if(cover_start_menu)
  {
   rcmon=rcRectMonitorForRect(&rcWas,MONITOR_AREA);
   if(!SameRect(&rcmon,&rcNewWin))
    do_topmost=1;
   rcNewWin=rcmon;
  }
  rcNewWin.top-=GetSystemMetrics(SM_CYSIZEFRAME);
  rcNewWin.bottom+=GetSystemMetrics(SM_CYSIZEFRAME);
  rcNewWin.left-=GetSystemMetrics(SM_CXSIZEFRAME);
  rcNewWin.right+=GetSystemMetrics(SM_CXSIZEFRAME);
  rcNewWin.top-=GetSystemMetrics(SM_CYEDGE);
  rcNewWin.bottom+=GetSystemMetrics(SM_CYEDGE);
  rcNewWin.left-=GetSystemMetrics(SM_CXEDGE);
  rcNewWin.right+=GetSystemMetrics(SM_CXEDGE);
  rcNewWin.top-=GetSystemMetrics(SM_CYCAPTION);
  if(GetMenu(hDlg)&&bHideMenuForFullScreenDialog(hDlg))
  {
      int cy_menu=GetSystemMetrics(SM_CYMENU);
   rcNewWin.top-=cy_menu;
  }
  OkMoveWindow(hDlg,rcNewWin.left,rcNewWin.top,rcNewWin.right-rcNewWin.left,rcNewWin.bottom-rcNewWin.top,bTF);
  if(clip_to_monitor_for_full_screen_dialog)
  {
   // Clip by edges showing outside the window
            HRGN hRgn=CreateRectRgn(rcmon.left-rcNewWin.left,rcmon.top-rcNewWin.top,rcmon.right-rcNewWin.left
    ,rcmon.bottom-rcNewWin.top);
            SetWindowRgn(hDlg,hRgn,FALSE);
  }
  if(do_topmost&&do_full_screen_dialogs_topmost)
   SetWindowPosNoActivateEtc(hDlg,HWND_TOPMOST);
  return;
 }
Personal tools
Namespaces
Variants
Actions
Navigation
How to use the wiki
More
Toolbox