/*----------------------------------------------------------------------
Copyright (c) Gipsysoft. All Rights Reserved.
Please see the file "licence.txt" for licencing details.
File: AddCheckbox.cpp
Owner: russf@gipsysoft.com
Purpose: Adds the "never show this again" type checkbox to the messagebox
----------------------------------------------------------------------*/
#include "stdafx.h"
#include "InternalStructures.h"
static const g_knButtonID = 19671;
static void GetCheckSize( HFONT hFont, LPCTSTR pcszText, SIZE &size )
{
HDC hdc = GetDC( NULL );
VAPI( hdc );
HDC hdc2 = CreateCompatibleDC( hdc );
VAPI( hdc );
hFont = (HFONT)SelectObject( hdc2, hFont );
VAPI( GetTextExtentPoint32( hdc2, pcszText, _tcslen( pcszText ), &size ) );
hFont = (HFONT)SelectObject( hdc2, hFont );
VAPI( DeleteDC( hdc2 ) );
VAPI( ReleaseDC( NULL, hdc ) );
size.cx += GetSystemMetrics( SM_CXMENUCHECK ) + 5;
size.cy = max( size.cy, GetSystemMetrics( SM_CYMENUCHECK ) );
}
void AddCheckbox( HWND hwnd, SWindowData *pwnddata )
{
HINSTANCE hInstance = reinterpret_cast<HINSTANCE>( GetWindowLong( hwnd, GWL_HINSTANCE ) );
RECT rcWindow;
VAPI( GetWindowRect( hwnd, &rcWindow ) );
pwnddata->m_uCheckBoxID = g_knButtonID;
//
// Get the font so we can measure and use it in our new control.
HFONT hfont = (HFONT)SendMessage( hwnd, WM_GETFONT, 0, 0 );
//
// Get the size of the checkbox to be...
SIZE sizeCheckbox;
GetCheckSize( hfont, pwnddata->m_MsgOpt.pcszCheckBoxText, sizeCheckbox );
//
// Determine where the checkbox is going...
RECT rcStatic;
VAPI( GetWindowRect( pwnddata->m_hwndStatic, &rcStatic ) );
POINT pt = { rcStatic.left, rcStatic.bottom };
VAPI( MapWindowPoints( NULL, hwnd, &pt, 1 ) );
RECT rcDLUs = { 0, 0, 0, 2 };
VAPI( MapDialogRect( hwnd, &rcDLUs ) );
pt.y += rcDLUs.bottom;
int nYToAdd = sizeCheckbox.cy + ( rcDLUs.bottom * 2 );
VAPI( SetWindowPos( hwnd, NULL, rcWindow.left, rcWindow.top, rcWindow.right - rcWindow.left, (rcWindow.bottom - rcWindow.top) + nYToAdd, SWP_NOZORDER ) );
//
// Move all buttons by the delta between the new and old size of the dialog
HWND hwndButton = GetWindow( hwnd, GW_CHILD );
static const TCHAR szButton[] = _T("BUTTON");
TCHAR szTest[] = _T(" ");
while( hwndButton )
{
if( GetClassName( hwndButton, szTest, countof( szTest ) ) )
{
if( !_tcsnicmp( szTest, szButton, countof( szTest ) - 1 ) )
{
RECT rcButton;
GetWindowRect( hwndButton, &rcButton );
OffsetRect( &rcButton, 0, nYToAdd );
MapWindowPoints( HWND_DESKTOP, hwnd, reinterpret_cast<LPPOINT>(&rcButton.left), 2 );
SetWindowPos( hwndButton, NULL, rcButton.left, rcButton.top, 0, 0, SWP_NOZORDER | SWP_NOSIZE | SWP_NOSENDCHANGING );
}
}
hwndButton = GetWindow( hwndButton, GW_HWNDNEXT );
}
HWND hwndCheck = CreateWindowEx( 0, _T("Button"), pwnddata->m_MsgOpt.pcszCheckBoxText, WS_TABSTOP | WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, pt.x, pt.y, sizeCheckbox.cx, sizeCheckbox.cy, hwnd, (HMENU)g_knButtonID, hInstance, NULL );
SendMessage( hwndCheck, WM_SETFONT, (WPARAM)hfont, 0 );
if( *pwnddata->m_MsgOpt.puValue )
{
SendMessage( hwndCheck, BM_SETCHECK, BST_CHECKED, 0 );
}
//
// NOTE: We don't need to alter the Z-Order of the new checkbox because the static doesn't have it and it will *appear*
// like it's correctly placed simply due to the fact that it appears after the buttons.
}