📄 dlgdata.cpp
字号:
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (C) 1992-1998 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 "occimpl.h"
#ifdef AFX_CORE3_SEG
#pragma code_seg(AFX_CORE3_SEG)
#endif
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDataExchange member functions (contructor is in wincore.cpp for swap tuning)
HWND CDataExchange::PrepareEditCtrl(int nIDC)
{
HWND hWndCtrl = PrepareCtrl(nIDC);
ASSERT(hWndCtrl != NULL);
m_bEditLastControl = TRUE;
return hWndCtrl;
}
HWND CDataExchange::PrepareCtrl(int nIDC)
{
ASSERT(nIDC != 0);
ASSERT(nIDC != -1); // not allowed
HWND hWndCtrl;
m_pDlgWnd->GetDlgItem(nIDC, &hWndCtrl);
if (hWndCtrl == NULL)
{
TRACE1("Error: no data exchange control with ID 0x%04X.\n", nIDC);
ASSERT(FALSE);
AfxThrowNotSupportedException();
}
m_hWndLastControl = hWndCtrl;
m_bEditLastControl = FALSE; // not an edit item by default
ASSERT(hWndCtrl != NULL); // never return NULL handle
return hWndCtrl;
}
void CDataExchange::Fail()
{
if (!m_bSaveAndValidate)
{
TRACE0("Warning: CDataExchange::Fail called when not validating.\n");
// throw the exception anyway
}
else if (m_hWndLastControl != NULL)
{
// restore focus and selection to offending field
::SetFocus(m_hWndLastControl);
if (m_bEditLastControl) // select edit item
::SendMessage(m_hWndLastControl, EM_SETSEL, 0, -1);
}
else
{
TRACE0("Error: fail validation with no control to restore focus to.\n");
// do nothing more
}
AfxThrowUserException();
}
/////////////////////////////////////////////////////////////////////////////
// Notes for implementing dialog data exchange and validation procs:
// * always start with PrepareCtrl or PrepareEditCtrl
// * always start with 'pDX->m_bSaveAndValidate' check
// * pDX->Fail() will throw an exception - so be prepared
// * avoid creating temporary HWNDs for dialog controls - i.e.
// use HWNDs for child elements
// * validation procs should only act if 'm_bSaveAndValidate'
// * use the suffices:
// DDX_ = exchange proc
// DDV_ = validation proc
//
/////////////////////////////////////////////////////////////////////////////
// only supports '%d', '%u', '%sd', '%su', '%ld' and '%lu'
AFX_STATIC BOOL AFXAPI _AfxSimpleScanf(LPCTSTR lpszText,
LPCTSTR lpszFormat, va_list pData)
{
ASSERT(lpszText != NULL);
ASSERT(lpszFormat != NULL);
ASSERT(*lpszFormat == '%');
lpszFormat++; // skip '%'
BOOL bLong = FALSE;
BOOL bShort = FALSE;
if (*lpszFormat == 'l')
{
bLong = TRUE;
lpszFormat++;
}
else if (*lpszFormat == 's')
{
bShort = TRUE;
lpszFormat++;
}
ASSERT(*lpszFormat == 'd' || *lpszFormat == 'u');
ASSERT(lpszFormat[1] == '\0');
while (*lpszText == ' ' || *lpszText == '\t')
lpszText++;
TCHAR chFirst = lpszText[0];
long l, l2;
if (*lpszFormat == 'd')
{
// signed
l = _tcstol(lpszText, (LPTSTR*)&lpszText, 10);
l2 = (int)l;
}
else
{
// unsigned
if (*lpszText == '-')
return FALSE;
l = (long)_tcstoul(lpszText, (LPTSTR*)&lpszText, 10);
l2 = (unsigned int)l;
}
if (l == 0 && chFirst != '0')
return FALSE; // could not convert
while (*lpszText == ' ' || *lpszText == '\t')
lpszText++;
if (*lpszText != '\0')
return FALSE; // not terminated properly
if (bShort)
{
if ((short)l != l)
return FALSE; // too big for short
*va_arg(pData, short*) = (short)l;
}
else
{
ASSERT(sizeof(long) == sizeof(int));
ASSERT(l == l2);
*va_arg(pData, long*) = l;
}
// all ok
return TRUE;
}
AFX_STATIC void AFX_CDECL _Afx_DDX_TextWithFormat(CDataExchange* pDX, int nIDC,
LPCTSTR lpszFormat, UINT nIDPrompt, ...)
// only supports windows output formats - no floating point
{
va_list pData;
va_start(pData, nIDPrompt);
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
TCHAR szT[32];
if (pDX->m_bSaveAndValidate)
{
// the following works for %d, %u, %ld, %lu
::GetWindowText(hWndCtrl, szT, _countof(szT));
if (!_AfxSimpleScanf(szT, lpszFormat, pData))
{
AfxMessageBox(nIDPrompt);
pDX->Fail(); // throws exception
}
}
else
{
wvsprintf(szT, lpszFormat, pData);
// does not support floating point numbers - see dlgfloat.cpp
AfxSetWindowText(hWndCtrl, szT);
}
va_end(pData);
}
/////////////////////////////////////////////////////////////////////////////
// Simple formatting to text item
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, BYTE& value)
{
int n = (int)value;
if (pDX->m_bSaveAndValidate)
{
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_BYTE, &n);
if (n > 255)
{
AfxMessageBox(AFX_IDP_PARSE_BYTE);
pDX->Fail(); // throws exception
}
value = (BYTE)n;
}
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_BYTE, n);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, short& value)
{
if (pDX->m_bSaveAndValidate)
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%sd"), AFX_IDP_PARSE_INT, &value);
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%hd"), AFX_IDP_PARSE_INT, value);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, int& value)
{
if (pDX->m_bSaveAndValidate)
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, &value);
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, value);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, UINT& value)
{
if (pDX->m_bSaveAndValidate)
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_UINT, &value);
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_UINT, value);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, long& value)
{
if (pDX->m_bSaveAndValidate)
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%ld"), AFX_IDP_PARSE_INT, &value);
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%ld"), AFX_IDP_PARSE_INT, value);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, DWORD& value)
{
if (pDX->m_bSaveAndValidate)
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%lu"), AFX_IDP_PARSE_UINT, &value);
else
_Afx_DDX_TextWithFormat(pDX, nIDC, _T("%lu"), AFX_IDP_PARSE_UINT, value);
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, CString& value)
{
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
if (pDX->m_bSaveAndValidate)
{
int nLen = ::GetWindowTextLength(hWndCtrl);
::GetWindowText(hWndCtrl, value.GetBufferSetLength(nLen), nLen+1);
value.ReleaseBuffer();
}
else
{
AfxSetWindowText(hWndCtrl, value);
}
}
void AFXAPI DDX_Text(CDataExchange* pDX, int nIDC, LPTSTR value, int nMaxLen)
{
ASSERT(nMaxLen != 0);
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
if (pDX->m_bSaveAndValidate)
{
int nLen = ::GetWindowTextLength(hWndCtrl);
int nRetrieved = ::GetWindowText(hWndCtrl, value, nMaxLen);
if (nLen > nRetrieved)
TRACE1("Text in control ID %d is too long. Call DDV_MaxChars()!\n", nIDC);
}
else
{
AfxSetWindowText(hWndCtrl, value);
}
}
/////////////////////////////////////////////////////////////////////////////
// Data exchange for special control
void AFXAPI DDX_Check(CDataExchange* pDX, int nIDC, int& value)
{
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
if (pDX->m_bSaveAndValidate)
{
value = (int)::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L);
ASSERT(value >= 0 && value <= 2);
}
else
{
if (value < 0 || value > 2)
{
TRACE1("Warning: dialog data checkbox value (%d) out of range.\n",
value);
value = 0; // default to off
}
::SendMessage(hWndCtrl, BM_SETCHECK, (WPARAM)value, 0L);
}
}
void AFXAPI DDX_Radio(CDataExchange* pDX, int nIDC, int& value)
// must be first in a group of auto radio buttons
{
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
ASSERT(::GetWindowLong(hWndCtrl, GWL_STYLE) & WS_GROUP);
ASSERT(::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON);
if (pDX->m_bSaveAndValidate)
value = -1; // value if none found
// walk all children in group
int iButton = 0;
do
{
if (::SendMessage(hWndCtrl, WM_GETDLGCODE, 0, 0L) & DLGC_RADIOBUTTON)
{
// control in group is a radio button
if (pDX->m_bSaveAndValidate)
{
if (::SendMessage(hWndCtrl, BM_GETCHECK, 0, 0L) != 0)
{
ASSERT(value == -1); // only set once
value = iButton;
}
}
else
{
// select button
::SendMessage(hWndCtrl, BM_SETCHECK, (iButton == value), 0L);
}
iButton++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -