2025-04-27 07:49:33 -04:00

357 lines
9.9 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// buttondi.cpp : implementation file
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1995 Microsoft Corporation
// All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "resource.h"
#include "buttondi.h"
#include "strings.h"
#include "wordpad.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#ifndef DS_CONTEXTHELP
#define DS_CONTEXTHELP 0x2000L
#endif
static const int nFontSize = 10;
/////////////////////////////////////////////////////////////////////////////
// CButtonDialog dialog
INT_PTR CButtonDialog::DisplayMessageBox(LPCTSTR lpszText, LPCTSTR lpszCaption,
LPCTSTR lpszButtons, WORD wStyle, int nDef, int nCancel,
DWORD* pHelpIDs, CWnd* pParentWnd)
{
CButtonDialog dlg(lpszText, lpszCaption, lpszButtons, wStyle, pHelpIDs,
pParentWnd);
dlg.SetDefault(nDef);
dlg.SetCancel(nCancel);
return dlg.DoModal();
}
CButtonDialog::CButtonDialog(LPCTSTR lpszText, LPCTSTR lpszCaption,
LPCTSTR lpszButtons, WORD wStyle, DWORD* pHelpIDs ,
CWnd* pParentWnd) : CCSDialog()
{
ASSERT(lpszText != NULL);
ASSERT(lpszCaption != NULL);
if (HIWORD(lpszText) == 0)
VERIFY(m_strText.LoadString(LOWORD(lpszText)));
else
m_strText = lpszText;
if (HIWORD(lpszCaption) == 0)
VERIFY(m_strCaption.LoadString(LOWORD(lpszCaption)));
else
m_strCaption = lpszCaption;
if (lpszButtons != NULL)
AddButtons(lpszButtons);
m_pParentWnd = pParentWnd;
m_nDefButton = 0;
m_nCancel = -1;
m_pButtons = NULL;
m_wStyle = wStyle;
m_nBaseID = nFontSize; // don't use IDOK, IDCANCEL, etc
m_hDlgTmp = NULL;
LOGFONT lf;
memcpy(&lf, &theApp.m_lf, sizeof(LOGFONT));
lf.lfWeight = FW_NORMAL;
lf.lfWidth = 0;
VERIFY(m_font.CreateFontIndirect(&lf));
m_pHelpIDs = pHelpIDs;
}
CButtonDialog::~CButtonDialog()
{
delete [] m_pButtons;
if (m_hDlgTmp != NULL)
GlobalFree(m_hDlgTmp);
}
BEGIN_MESSAGE_MAP(CButtonDialog, CCSDialog)
//{{AFX_MSG_MAP(CButtonDialog)
ON_WM_CREATE()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CButtonDialog message handlers
int CButtonDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (m_pHelpIDs != NULL)
{
for (int i=0;i<m_strArray.GetSize();i++)
m_pHelpIDs[i*2] = i+m_nBaseID;
}
if (CCSDialog::OnCreate(lpCreateStruct) == -1)
return -1;
SetWindowText(m_strCaption);
m_pButtons = new CButton[(size_t)m_strArray.GetSize()];
CRect rect(0, 0, 10, 10);
if (!m_staticIcon.Create(NULL,
SS_ICON | WS_GROUP | WS_CHILD | WS_VISIBLE, rect, this))
{
return -1;
}
m_staticIcon.SetIcon(::LoadIcon(NULL, GetIconID(m_wStyle)));
if (!m_staticText.Create(m_strText, SS_LEFT | SS_NOPREFIX | WS_GROUP |
WS_CHILD | WS_VISIBLE, rect, this))
{
return -1;
}
m_staticText.SetFont(&m_font);
for (int i=0;i<m_strArray.GetSize();i++)
{
if (!m_pButtons[i].Create(m_strArray[i], WS_TABSTOP | WS_CHILD |
WS_VISIBLE | ((i == 0) ? WS_GROUP : 0) |
((i == m_nDefButton) ? BS_DEFPUSHBUTTON : BS_PUSHBUTTON),
rect, this, i+m_nBaseID))
{
return -1;
}
m_pButtons[i].SetFont(&m_font);
}
PositionControls();
return 0;
}
BOOL CButtonDialog::OnInitDialog()
{
CCSDialog::OnInitDialog();
if (m_pHelpIDs == NULL) // no context help
ModifyStyleEx(WS_EX_CONTEXTHELP, 0); //remove
m_pButtons[m_nDefButton].SetFocus();
return FALSE; // return TRUE unless you set the focus to a control
}
/////////////////////////////////////////////////////////////////////////////
// CButtonDialog operations
void CButtonDialog::AddButtons(LPCTSTR lpszButton)
{
CString str, strButtons;
int i=0;
if (HIWORD(lpszButton) == 0)
strButtons.LoadString(LOWORD(lpszButton));
else
strButtons = lpszButton;
while (AfxExtractSubString(str, strButtons, i++, '\n'))
AddButton(str);
}
#ifndef DS_3DLOOK
#define DS_3DLOOK 0x4
#endif
void CButtonDialog::FillInHeader(LPDLGTEMPLATE lpDlgTmp)
{
USES_CONVERSION;
lpDlgTmp->style = DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE |
WS_CAPTION | WS_SYSMENU;
if (theApp.m_bWin4)
lpDlgTmp->style |= DS_CONTEXTHELP;
lpDlgTmp->dwExtendedStyle = 0;
lpDlgTmp->cdit = 0;
lpDlgTmp->x = 0;
lpDlgTmp->y = 0;
lpDlgTmp->cx = 100;
lpDlgTmp->cy = 100;
LPWSTR lpStr = (LPWSTR)(lpDlgTmp + 1); /* Move ptr to the variable fields */
*lpStr++ = 0; /* No Menu resource for Message Box */
*lpStr++ = 0; /* No Class name for MessageBox */
int nLen = m_strCaption.GetLength();
wcscpy(lpStr, T2CW(m_strCaption));
lpStr += nLen+1;
WORD* pWord = (WORD*)lpStr;
*pWord = 10; // 10 pt font
pWord++;
lpStr = (LPWSTR) pWord;
wcscpy(lpStr, T2W(theApp.m_lf.lfFaceName));
}
/////////////////////////////////////////////////////////////////////////////
// CButtonDialog overridables
BOOL CButtonDialog::OnCommand(WPARAM wParam, LPARAM /*lParam*/)
{
if (wParam == IDCANCEL && m_nCancel != -1)
{
EndDialog(m_nCancel);
return TRUE;
}
if (::GetDlgItem(m_hWnd, (int)wParam) == NULL)
return FALSE;
EndDialog((int)(wParam-m_nBaseID));
return TRUE;
}
INT_PTR CButtonDialog::DoModal()
{
ASSERT(m_strArray.GetSize() != 0);
if (m_strArray.GetSize() == 0)
return (m_nCancel != -1) ? m_nCancel : 0;
// compute size of header
// Fixed portions of DLG template header = sizeof(DLGTEMPLATE);
// One null byte for menu name and one for class name = 2
// Caption text plus NULL = m_strCaption.GetLength()+1
int nSize = sizeof(DLGTEMPLATE);
nSize += (2 + m_strCaption.GetLength()+1+lstrlen(theApp.m_lf.lfFaceName)+1)*2 +sizeof(WORD);
m_hDlgTmp = GlobalAlloc(GPTR, nSize);
if (m_hDlgTmp == NULL)
return IDCANCEL;
LPDLGTEMPLATE lpDlgTmp = (LPDLGTEMPLATE)GlobalLock(m_hDlgTmp);
FillInHeader(lpDlgTmp);
GlobalUnlock(m_hDlgTmp);
InitModalIndirect(m_hDlgTmp);
return CCSDialog::DoModal();
}
/////////////////////////////////////////////////////////////////////////////
// CButtonDialog implementation
void CButtonDialog::PositionControls()
{
CSize sizeBase = GetBaseUnits();
int nButtonHeight = (sizeBase.cy*14)/8;
int nHeight = 0;
int nSep,nLeftMargin,nRightMargin,nTopMargin,nBottomMargin;
int nButtonAdj;
int nWidth = 0;
CRect rectText;
// a) 5/8 screen Width
// b) Caption
// c) nLeftMargin ICON nSep TEXT nRightMargin
// d) nLeftMargin Button1 nSep Button2 ... nRightMargin
// client width is max(b,d, min(c,a))
CSize sizeIcon(GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON));
nSep = sizeIcon.cx/2;
nLeftMargin = nSep;
nRightMargin = nSep;
nTopMargin = nSep;
nBottomMargin = nSep;
CClientDC dc(this);
CFont* pOldFont = dc.SelectObject(&m_font);
nButtonAdj = dc.GetTextExtent(_T("XXX"),3).cx; // padding on buttons
int nScreenWidth58 = dc.GetDeviceCaps(HORZRES)*5/8;
int nCaptionWidth = dc.GetTextExtent(m_strCaption, m_strCaption.
GetLength()).cx;
CSize sizeText = dc.GetTextExtent(m_strText,m_strText.GetLength());
int nTextIconWidth = nLeftMargin+sizeIcon.cx+nSep+sizeText.cx+nRightMargin;
int nButtons = (int)m_strArray.GetSize();
int nButtonsWidth = nLeftMargin+nRightMargin+(nButtons-1)*nSep;
for (int i=0;i<nButtons;i++)
{
nButtonsWidth +=
dc.GetTextExtent(m_strArray[i],m_strArray[i].GetLength()).cx+
nButtonAdj*2;
}
nWidth = min(nTextIconWidth,nScreenWidth58);
nWidth = max(nWidth, nCaptionWidth);
nWidth = max(nWidth, nButtonsWidth);
m_staticIcon.SetWindowPos(NULL, nLeftMargin, nTopMargin, sizeIcon.cx,
sizeIcon.cy, SWP_NOZORDER);
if (sizeText.cx > nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep)
{
sizeText.cx = nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep;
// int nTextWidth = nWidth-nLeftMargin-nRightMargin-sizeIcon.cx-nSep;
// rectText.SetRect(0, 0, nTextWidth, 32767);
rectText.SetRect(0, 0, sizeText.cx, 32767);
/* Ask DrawText for the right cy */
sizeText.cy = dc.DrawText(m_strText, m_strText.GetLength(), &rectText,
DT_CALCRECT | DT_WORDBREAK | DT_EXPANDTABS | DT_NOPREFIX);
}
m_staticText.SetWindowPos(NULL, nSep+sizeIcon.cx+nSep, nTopMargin,
sizeText.cx, sizeText.cy, SWP_NOZORDER);
sizeText.cy = max(sizeText.cy, sizeIcon.cy); // at least icon height
nHeight = nTopMargin + sizeText.cy + nSep + nButtonHeight + nBottomMargin;
CRect rect;
rect.left = (nWidth - (nButtonsWidth - nLeftMargin - nRightMargin))/2;
rect.top = nTopMargin + sizeText.cy + nSep;
rect.bottom = rect.top + nButtonHeight;
for (i=0;i<m_strArray.GetSize();i++)
{
rect.right = rect.left + dc.GetTextExtent(m_strArray[i],m_strArray[i].GetLength()).cx +
2*nButtonAdj;
m_pButtons[i].MoveWindow(&rect);
rect.left = rect.right + nSep;
}
rect.SetRect(0,0,nWidth,nHeight);
CalcWindowRect(&rect);
SetWindowPos(NULL, (dc.GetDeviceCaps(HORZRES)-rect.Width())/2,
(dc.GetDeviceCaps(VERTRES)-rect.Height())/2, rect.Width(), rect.Height(),
SWP_NOZORDER|SWP_NOACTIVATE);
if(m_nCancel == -1) // no cancel button
{
// CMenu* pMenu = GetSystemMenu(FALSE);
// if (pMenu != NULL)
// pMenu->DeleteMenu(SC_CLOSE, MF_BYCOMMAND);
}
dc.SelectObject(pOldFont);
}
CSize CButtonDialog::GetBaseUnits()
{
CDisplayIC dc;
CFont* pFont = dc.SelectObject(&m_font);
TEXTMETRIC tm;
VERIFY(dc.GetTextMetrics(&tm));
dc.SelectObject(pFont);
return CSize(tm.tmAveCharWidth, tm.tmHeight);
}
LPCTSTR CButtonDialog::GetIconID(WORD wFlags)
{
LPCTSTR lpszIcon = NULL;
wFlags &= MB_ICONMASK;
if (wFlags == MB_ICONHAND)
lpszIcon = IDI_HAND;
else if (wFlags == MB_ICONQUESTION)
lpszIcon = IDI_QUESTION;
else if (wFlags == MB_ICONEXCLAMATION)
lpszIcon = IDI_EXCLAMATION;
else if (wFlags == MB_ICONASTERISK)
lpszIcon = IDI_ASTERISK;
return lpszIcon;
}