windows-nt/Source/XPSP1/NT/shell/themes/test/framemetrics/framemetrics.cpp

498 lines
16 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
// FrameMetrics.cpp : Defines the entry point for the application.
//
#include "stdafx.h"
#include "resource.h"
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
enum {
NCCAPTION,
NCBORDERS,
NCMENUBAR,
NCSCROLLBARS,
NCCLOSEBUTTON,
NCMAXBUTTON,
NCMINBUTTON,
NCHELPBUTTON,
NCSYSICON,
_cNCXXX,
};
BOOL _rgf[_cNCXXX] = {FALSE};
HBRUSH _rghbr[_cNCXXX] = {0};
COLORREF _rgrgb[_cNCXXX] = {
RGB(255,0,255),
RGB(0,255,255),
RGB(255,255,0),
RGB(0,0,255),
RGB(0,255,255),
RGB(0,255,255),
RGB(0,255,255),
RGB(0,255,255),
RGB(0,255,255),
};
// Foward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// TODO: Place code here.
MSG msg;
HACCEL hAccelTable;
// Initialize global strings
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadString(hInstance, IDC_FRAMEMETRICS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
for( int i=0; i<ARRAYSIZE(_rghbr); i++ )
{
_rghbr[i] = CreateSolidBrush(_rgrgb[i]);
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_FRAMEMETRICS);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
for( i=0; i<ARRAYSIZE(_rghbr); i++ )
{
DeleteObject(_rghbr[i]);
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// This function and its usage is only necessary if you want this code
// to be compatible with Win32 systems prior to the 'RegisterClassEx'
// function that was added to Windows 95. It is important to call this function
// so that the application will get 'well formed' small icons associated
// with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FRAMEMETRICS);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = (LPCTSTR)IDC_FRAMEMETRICS;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
return RegisterClassEx(&wcex);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
HWND hwnd;
hInst = hInstance; // Store instance handle in our global variable
hwnd = CreateWindowEx( WS_EX_CONTEXTHELP, szWindowClass, szTitle, WS_OVERLAPPEDWINDOW|WS_HSCROLL|WS_VSCROLL,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
if (!hwnd)
{
return FALSE;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
return TRUE;
}
//-------------------------------------------------------------------------//
//
// GetWindowBorders() - port from win32k, rtl\winmgr.c
//
// Computes window border dimensions based on style bits.
//
int _GetWindowBorders(LONG lStyle, DWORD dwExStyle )
{
int cBorders = 0;
//
// Is there a 3D border around the window?
//
if( TESTFLAG(dwExStyle, WS_EX_WINDOWEDGE) )
cBorders += 2;
else if ( TESTFLAG(dwExStyle, WS_EX_STATICEDGE) )
++cBorders;
//
// Is there a single flat border around the window? This is true for
// WS_BORDER, WS_DLGFRAME, and WS_EX_DLGMODALFRAME windows.
//
if( TESTFLAG(lStyle, WS_CAPTION) || TESTFLAG(dwExStyle, WS_EX_DLGMODALFRAME) )
++cBorders;
//
// Is there a sizing flat border around the window?
//
if( TESTFLAG(lStyle, WS_THICKFRAME) )
{
NONCLIENTMETRICS ncm; ncm.cbSize = sizeof(ncm);
if( SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, FALSE ) )
cBorders += ncm.iBorderWidth;
else
cBorders += GetSystemMetrics( SM_CXBORDER );
}
return(cBorders);
}
BOOL NcPaint(HWND hwnd, HRGN hrgnUpdate)
{
BOOL fRet = FALSE;
int cPaint = 0;
for( int i = 0; i < ARRAYSIZE(_rgf); i++ )
{
if( _rgf[i] )
cPaint++;
}
if( 0 == cPaint )
return FALSE;
// private GetDCEx #defines from user
#define DCX_USESTYLE 0x00010000L
#define DCX_NODELETERGN 0x00040000L
HDC hdc = (hrgnUpdate != NULL) ?
GetDCEx( hwnd, hrgnUpdate, DCX_USESTYLE|DCX_WINDOW|DCX_LOCKWINDOWUPDATE|
DCX_INTERSECTRGN|DCX_NODELETERGN ) :
GetDCEx( hwnd, NULL, DCX_USESTYLE|DCX_WINDOW|DCX_LOCKWINDOWUPDATE );
if( hdc )
{
WINDOWINFO wi;
wi.cbSize = sizeof(wi);
const RECT rcNil = {0};
if( GetWindowInfo(hwnd, &wi) )
{
NONCLIENTMETRICS ncm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, FALSE );
int cxEdge = GetSystemMetrics( SM_CXEDGE );
int cyEdge = GetSystemMetrics( SM_CYEDGE );
int cxBtn = GetSystemMetrics( SM_CXSIZE );
int cyBtn = GetSystemMetrics( SM_CYSIZE );
int cyCaption = GetSystemMetrics( SM_CYCAPTION );
int cyMenu = GetSystemMetrics( SM_CYMENU );
int cnBorders = _GetWindowBorders( wi.dwStyle, wi.dwExStyle );
RECT rcWnd, rcCaption, rcMenuBar, rcHscroll, rcVscroll, rcSys;
rcWnd = wi.rcWindow;
OffsetRect( &rcWnd, -wi.rcWindow.left, -wi.rcWindow.top );
rcCaption = rcMenuBar = rcWnd;
rcHscroll = rcVscroll = rcNil;
rcCaption.bottom = rcCaption.top + ncm.iCaptionHeight ;
rcMenuBar.bottom = rcMenuBar.top + cyMenu;
OffsetRect( &rcCaption, 0, cnBorders );
OffsetRect( &rcMenuBar, 0, rcCaption.top + cyCaption );
rcCaption.left += cnBorders;
rcMenuBar.left += cnBorders;
rcCaption.right -= cnBorders;
rcMenuBar.right -= cnBorders;
if( TESTFLAG(wi.dwStyle, WS_HSCROLL) )
{
rcHscroll = rcWnd;
rcHscroll.top = rcHscroll.bottom - GetSystemMetrics(SM_CYHSCROLL);
OffsetRect( &rcHscroll, 0, -cnBorders );
rcHscroll.left += cnBorders;
rcHscroll.right -= (cnBorders + (TESTFLAG(wi.dwStyle, WS_VSCROLL) ? GetSystemMetrics(SM_CXVSCROLL) : 0));
}
if( TESTFLAG(wi.dwStyle, WS_VSCROLL) )
{
rcVscroll = rcWnd;
rcVscroll.left = rcVscroll.right - GetSystemMetrics(SM_CXVSCROLL);
OffsetRect( &rcVscroll, -cnBorders, 0 );
rcVscroll.top = rcMenuBar.bottom;
rcVscroll.bottom -= (cnBorders + (TESTFLAG(wi.dwStyle, WS_HSCROLL) ? GetSystemMetrics(SM_CYHSCROLL) : 0));
}
// buttons
RECT rcClose, rcMin, rcMax, rcHelp;
rcClose.top = rcMin.top = rcMax.top = rcHelp.top = rcCaption.top;
rcClose.bottom = rcMin.bottom = rcMax.bottom = rcHelp.bottom = rcCaption.top + (cyBtn - (cyEdge * 2));
rcSys.top = rcCaption.top;
rcSys.bottom = rcSys.top + GetSystemMetrics(SM_CYSMICON);
rcSys.left = rcCaption.left + cxEdge; rcSys.right = rcSys.left + GetSystemMetrics(SM_CXSMICON);
rcClose.right = rcCaption.right - cxEdge; rcClose.left = rcClose.right - (cxBtn - cxEdge);
rcMax.right = rcClose.left - cxEdge; rcMax.left = rcMax.right - (cxBtn - cxEdge);
rcMin.right = rcMax.left; rcMin.left = rcMin.right - (cxBtn - cxEdge);
rcHelp = rcMax;
// vertically center
OffsetRect( &rcSys, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcSys))/2 );
OffsetRect( &rcClose, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcClose))/2 );
OffsetRect( &rcMax, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcMax))/2 );
OffsetRect( &rcMin, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcMin))/2 );
OffsetRect( &rcHelp, 0, (ncm.iCaptionHeight - RECTHEIGHT(&rcHelp))/2 );
DefWindowProc( hwnd, WM_NCPAINT, (WPARAM)hrgnUpdate, 0L );
GdiSetBatchLimit(1);
if( _rgf[NCCAPTION] )
{
FillRect( hdc, &rcCaption, _rghbr[NCCAPTION] );
}
if( _rgf[NCMENUBAR] )
{
FillRect( hdc, &rcMenuBar, _rghbr[NCMENUBAR] );
}
if( _rgf[NCSCROLLBARS] )
{
FillRect( hdc, &rcHscroll, _rghbr[NCSCROLLBARS] );
FillRect( hdc, &rcVscroll, _rghbr[NCSCROLLBARS] );
}
if( _rgf[NCBORDERS] )
{
RECT rcBorders = rcWnd;
for( int i=0; i<cnBorders; i++ )
{
FrameRect( hdc, &rcBorders, _rghbr[NCBORDERS] );
GetLastError();
InflateRect( &rcBorders, -1, -1 );
}
}
if( _rgf[NCCLOSEBUTTON] )
FillRect( hdc, &rcClose, _rghbr[NCCLOSEBUTTON] );
if( _rgf[NCMAXBUTTON] && TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
FillRect( hdc, &rcMax, _rghbr[NCMAXBUTTON] );
if( _rgf[NCMINBUTTON] && TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
FillRect( hdc, &rcMin, _rghbr[NCMINBUTTON] );
if( _rgf[NCHELPBUTTON] && !TESTFLAG(wi.dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) )
FillRect( hdc, &rcHelp, _rghbr[NCHELPBUTTON] );
if( _rgf[NCSYSICON] && TESTFLAG(wi.dwStyle, WS_SYSMENU) )
FillRect( hdc, &rcSys, _rghbr[NCSYSICON] );
GdiSetBatchLimit(0) ;
ReleaseDC( hwnd, hdc );
fRet = TRUE;
}
}
return fRet;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
LRESULT lRet = 0;
int wmId, wmEvent;
switch (message)
{
case WM_COMMAND:
{
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
BOOL fSwp = FALSE;
// Parse the menu selections:
switch (wmId)
{
#define IMPLEMENT_NCCOMMANDID(cmd) \
case ID_##cmd: _rgf[NC##cmd] = !_rgf[NC##cmd]; fSwp = TRUE; break;
IMPLEMENT_NCCOMMANDID(CAPTION)
IMPLEMENT_NCCOMMANDID(MENUBAR)
IMPLEMENT_NCCOMMANDID(BORDERS)
IMPLEMENT_NCCOMMANDID(SCROLLBARS)
IMPLEMENT_NCCOMMANDID(CLOSEBUTTON)
IMPLEMENT_NCCOMMANDID(MAXBUTTON)
IMPLEMENT_NCCOMMANDID(MINBUTTON)
IMPLEMENT_NCCOMMANDID(HELPBUTTON)
IMPLEMENT_NCCOMMANDID(SYSICON)
case ID_NONE:
case ID_ALL:
for( int i = 0; i<ARRAYSIZE(_rgf); i++ )
{
_rgf[i] = wmId == ID_ALL;
}
fSwp = TRUE;
break;
case ID_THICKFRAME:
{
DWORD dwStyle = GetWindowLong( hwnd, GWL_STYLE );
if( TESTFLAG( dwStyle, WS_THICKFRAME ) )
dwStyle &= ~WS_THICKFRAME;
else
dwStyle |= WS_THICKFRAME;
SetWindowLong( hwnd, GWL_STYLE, dwStyle );
fSwp = TRUE;
break;
}
case ID_MINMAX:
{
DWORD dwStyle = GetWindowLong( hwnd, GWL_STYLE );
if( TESTFLAG( dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX ) )
dwStyle &= ~(WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
else
dwStyle |= (WS_MINIMIZEBOX|WS_MAXIMIZEBOX);
SetWindowLong( hwnd, GWL_STYLE, dwStyle );
fSwp = TRUE;
break;
}
case IDM_ABOUT:
DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hwnd, (DLGPROC)About);
break;
case IDM_EXIT:
DestroyWindow(hwnd);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
if( fSwp )
SetWindowPos( hwnd, NULL, 0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE|SWP_NOZORDER|SWP_DRAWFRAME );
break;
}
case WM_NCPAINT:
if( !NcPaint(hwnd, (HRGN)wParam) )
lRet = DefWindowProc( hwnd, message, wParam, lParam );
break;
case WM_NCACTIVATE:
lRet = DefWindowProc( hwnd, message, wParam, lParam );
NcPaint(hwnd, NULL);
break;
case WM_INITMENUPOPUP:
{
CheckMenuItem( (HMENU)wParam, ID_CAPTION, MF_BYCOMMAND | (_rgf[NCCAPTION] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_MENUBAR, MF_BYCOMMAND | (_rgf[NCMENUBAR] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_BORDERS, MF_BYCOMMAND | (_rgf[NCBORDERS] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_SCROLLBARS, MF_BYCOMMAND | (_rgf[NCSCROLLBARS] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_CLOSEBUTTON, MF_BYCOMMAND | (_rgf[NCCLOSEBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_MAXBUTTON, MF_BYCOMMAND | (_rgf[NCMAXBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_MINBUTTON, MF_BYCOMMAND | (_rgf[NCMINBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_HELPBUTTON, MF_BYCOMMAND | (_rgf[NCHELPBUTTON] ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_SYSICON, MF_BYCOMMAND | (_rgf[NCSYSICON] ? MF_CHECKED : MF_UNCHECKED) );
ULONG dwStyle = GetWindowLong(hwnd, GWL_STYLE);
CheckMenuItem( (HMENU)wParam, ID_THICKFRAME, MF_BYCOMMAND | (TESTFLAG(dwStyle, WS_THICKFRAME) ? MF_CHECKED : MF_UNCHECKED) );
CheckMenuItem( (HMENU)wParam, ID_MINMAX, MF_BYCOMMAND | (TESTFLAG(dwStyle, WS_MINIMIZEBOX|WS_MAXIMIZEBOX) ? MF_CHECKED : MF_UNCHECKED) );
break;
}
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, message, wParam, lParam);
}
return lRet;
}
// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}