⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xmessagebox.cpp

📁 读取XML信息
💻 CPP
📖 第 1 页 / 共 5 页
字号:


						::WritePrivateProfileString(_T("DoNotAsk"),		// section name
													szKey,				// key name
													szData,				// string to add
													szPathName);		// initialization file
#endif	// XMESSAGEBOX_USE_PROFILE_FILE



#ifdef _DEBUG
						// verify that we can read data

						DWORD dwData = 0;

#ifndef XMESSAGEBOX_USE_PROFILE_FILE

						// read from registry 

						dwData = ReadRegistry(Me->m_szCompanyName, szKey);
						TRACE(_T("dwData=0x%08X\n"), dwData);

#else
						// read from ini file

						TCHAR szBuf[100];
						::GetPrivateProfileString(_T("DoNotAsk"),	// section name
												  szKey,			// key name
												  _T(""),			// default string
												  szBuf,			// destination buffer
												  countof(szBuf)-1,	// size of destination buffer
												  szPathName);		// initialization file name

						dwData = _tcstoul(szBuf, NULL, 16);
						TRACE(_T("szBuf=<%s>  dwData=0x%08X\n"), szBuf, dwData);

#endif	// XMESSAGEBOX_USE_PROFILE_FILE

						_ASSERTE(dwData == (DWORD) wParam);

#endif	// _DEBUG
					}
#endif	// #ifndef XMESSAGEBOX_DO_NOT_SAVE_CHECKBOX

					::EndDialog(hwnd, wParam);

					return FALSE;
			}
		}

		case WM_LBUTTONDOWN:
		case WM_NCLBUTTONDOWN:
		{
			// user clicked on dialog or titlebar - stop the timer
			::KillTimer(hwnd, 1);

			if (Me->GetDefaultButtonId())
			{
				HWND hwndDefButton = ::GetDlgItem(hwnd, Me->GetDefaultButtonId());
				if (hwndDefButton && ::IsWindow(hwndDefButton))
				{
					if (Me->m_szDefaultButton[0] != _T('\0'))
					{
						::SetWindowText(hwndDefButton, Me->m_szDefaultButton);
					}
				}
			}

			return FALSE;
		}

		case WM_TIMER:		// used for timeout
		{
			TRACE(_T("in WM_TIMER\n"));

			if (wParam == 1)			// timeout timer
			{
				if (Me->m_nTimeoutSeconds <= 0)
				{
					::KillTimer(hwnd, wParam);

					// time's up, select default button
					::SendMessage(hwnd, WM_COMMAND, Me->GetDefaultButtonId() | MB_TIMEOUT, 0);

					return FALSE;
				}

				if (Me->GetDefaultButtonId() == 0)
					return FALSE;

				HWND hwndDefButton = ::GetDlgItem(hwnd, Me->GetDefaultButtonId());
				if (hwndDefButton == NULL || !::IsWindow(hwndDefButton))
					return FALSE;

				if (Me->m_szDefaultButton[0] == _T('\0'))
				{
					// first time - get text of default button
					::GetWindowText(hwndDefButton, Me->m_szDefaultButton, 
						MaxButtonStringSize);
				}

				TCHAR szButtonText[MaxButtonStringSize*2];
				_stprintf(szButtonText, XMESSAGEBOX_TIMEOUT_TEXT_FORMAT, 
					Me->m_szDefaultButton, Me->m_nTimeoutSeconds);

				::SetWindowText(hwndDefButton, szButtonText);

				Me->m_nTimeoutSeconds--;
			}
			else if (wParam == 2)		// disabled timer
			{
				::KillTimer(hwnd, wParam);

				for (UINT nID = 1; nID <= ID_XMESSAGEBOX_LAST_ID; nID++)
				{
					hwndChild = ::GetDlgItem(hwnd, nID);
					if (hwndChild && ::IsWindow(hwndChild))
					{
						// enable all buttons
						TCHAR szClassName[MAX_PATH];
						::GetClassName(hwndChild, szClassName, countof(szClassName)-2);
						if (_tcsicmp(szClassName, _T("Button")) == 0)
						{
							LONG nStyle = ::GetWindowLong(hwndChild, GWL_STYLE);
							nStyle &= ~WS_DISABLED;
							::SetWindowLong(hwndChild, GWL_STYLE, nStyle);
						}
					}
				} // for

				if (Me->Option(CancelOrOkButton))
					::EnableMenuItem(GetSystemMenu(hwnd, FALSE), SC_CLOSE, MF_ENABLED);

				::RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW);
			}
		}
	}

	return FALSE;
}

///////////////////////////////////////////////////////////////////////////////
// CXDialogTemplate::AddItem
void CXDialogTemplate::AddItem(CXDialogItem::Econtroltype cType,
							   UINT nID,
							   CXRect* prect,
							   LPCTSTR pszCaption)
{
	_ASSERTE(m_pDlgItemArray[m_dlgTempl.cdit] == NULL);

	CXDialogItem::Econtroltype ct = cType;

	if (ct == CXDialogItem::CHECKBOX)
		ct = CXDialogItem::BUTTON;

	m_pDlgItemArray[m_dlgTempl.cdit] = new CXDialogItem(ct);
	_ASSERTE(m_pDlgItemArray[m_dlgTempl.cdit]);

	m_pDlgItemArray[m_dlgTempl.cdit]->AddItem(*this, cType, nID, prect, pszCaption);

	m_dlgTempl.cdit++;
	_ASSERTE(m_dlgTempl.cdit < MaxItems);
}

///////////////////////////////////////////////////////////////////////////////
// CXDialogTemplate::Display
int CXDialogTemplate::Display()
{
	// The first step is to allocate memory to define the dialog. The information to be
	// stored in the allocated buffer is the following:
	//
	// 1. DLGTEMPLATE structure
	//    typedef struct
	//    {
	//       DWORD style;
	//       DWORD dwExtendedStyle;
	//       WORD cdit;
	//       short x;
	//       short y;
	//       short cx;
	//       short cy;
	//    } DLGTEMPLATE;
	// 2. 0x0000 (Word) indicating the dialog has no menu
	// 3. 0x0000 (Word) Let windows assign default class to the dialog
	// 4. (Caption) Null terminated unicode string
	// 5. 0x000B (size of the font to be used)
	// 6. "MS Sans Serif" (name of the typeface to be used)
	// 7. DLGITEMTEMPLATE structure for the button (HAS TO BE DWORD ALIGNED)
	//    typedef struct
	//    {
	//       DWORD style;
	//       DWORD dwExtendedStyle;
	//       short x;
	//       short y;
	//       short cx;
	//       short cy;
	//       WORD id;
	//    } DLGITEMTEMPLATE;
	// 8. 0x0080 to indicate the control is a button
	// 9. (Title). Unicode null terminated string with the caption
	// 10. 0x0000 0 extra bytes of data for this control
	// 11. DLGITEMTEMPLATE structure for the Static Text (HAS TO BE DWORD ALIGNED)
	// 12. 0x0081 to indicate the control is static text
	// 13. (Title). Unicode null terminated string with the text
	// 14. 0x0000. 0 extra bytes of data for this control


	int rc = IDCANCEL;

	TCHAR szTitle[1024];
	_tcsncpy(szTitle, m_lpszCaption, countof(szTitle)-1);
	szTitle[countof(szTitle)-1] = _T('\0');
	size_t nTitleLen = _tcslen(szTitle);

	int i = 0;

	size_t nBufferSize = sizeof(DLGTEMPLATE) +
		(2 * sizeof(WORD)) + // menu and class
		((nTitleLen + 1) * sizeof(WCHAR));

	// NOTE - font is set in MsgBoxDlgProc

	nBufferSize = (nBufferSize + 3) & ~3; // adjust size to make
	// first control DWORD aligned

	// loop to calculate size of buffer we need -
	// add size of each control:
	// sizeof(DLGITEMTEMPLATE) +
	// sizeof(WORD) + // atom value flag 0xFFFF
	// sizeof(WORD) + // ordinal value of control's class
	// sizeof(WORD) + // no. of bytes in creation data array
	// sizeof title in WCHARs
	for (i = 0; i < m_dlgTempl.cdit; i++)
	{
		size_t nItemLength = sizeof(DLGITEMTEMPLATE) + 3 * sizeof(WORD);

#ifdef _UNICODE
		size_t nActualChars = _tcslen(m_pDlgItemArray[i]->m_pszCaption) + 1;	//+++1.5;
#else
		int nActualChars = MultiByteToWideChar(CP_ACP, 0,
								(LPCSTR)m_pDlgItemArray[i]->m_pszCaption, 
								-1, NULL, 0);	//+++1.5
#endif

		ASSERT(nActualChars > 0);
		nItemLength += nActualChars * sizeof(WCHAR);

		if (i != m_dlgTempl.cdit - 1) // the last control does not need extra bytes
		{
			nItemLength = (nItemLength + 3) & ~3; // take into account gap
		} // so next control is DWORD aligned

		nBufferSize += nItemLength;
	}

	HLOCAL hLocal = LocalAlloc(LHND, nBufferSize);
	_ASSERTE(hLocal);
	if (hLocal == NULL)
		return IDCANCEL;

	BYTE* pBuffer = (BYTE*)LocalLock(hLocal);
	_ASSERTE(pBuffer);
	if (pBuffer == NULL)
	{
		LocalFree(hLocal);
		return IDCANCEL;
	}

	BYTE* pdest = pBuffer;

	// transfer DLGTEMPLATE structure to the buffer
	memcpy(pdest, &m_dlgTempl, sizeof(DLGTEMPLATE));
	pdest += sizeof(DLGTEMPLATE);

	*(WORD*)pdest = 0;		// no menu
	pdest += sizeof(WORD);	//+++1.5
	*(WORD*)pdest = 0;		// use default window class		//+++1.5
	pdest += sizeof(WORD);	//+++1.5

	// transfer title
	WCHAR * pchCaption = new WCHAR[nTitleLen + 100];
	memset(pchCaption, 0, nTitleLen*2 + 2);

#ifdef _UNICODE
	memcpy(pchCaption, szTitle, nTitleLen * sizeof(TCHAR));
	size_t nActualChars = nTitleLen + 1;
#else
	size_t nActualChars = MultiByteToWideChar(CP_ACP, 0,
			(LPCSTR)szTitle, -1, pchCaption, nTitleLen + 1);
#endif

	_ASSERTE(nActualChars > 0);
	memcpy(pdest, pchCaption, nActualChars * sizeof(WCHAR));
	pdest += nActualChars * sizeof(WCHAR);
	delete [] pchCaption;		//+++1.5

	// will now transfer the information for each one of the item templates
	for (i = 0; i < m_dlgTempl.cdit; i++)
	{
		pdest = (BYTE*)(((UINT_PTR)pdest + 3) & ~3);	// make the pointer DWORD aligned
		memcpy(pdest, (void *)&m_pDlgItemArray[i]->m_dlgItemTemplate,
			sizeof(DLGITEMTEMPLATE));
		pdest += sizeof(DLGITEMTEMPLATE);
		*(WORD*)pdest = 0xFFFF;						// indicating atom value
		pdest += sizeof(WORD);
		*(WORD*)pdest = (WORD)m_pDlgItemArray[i]->m_controltype;	// atom value for the control
		pdest += sizeof(WORD);

		// transfer the caption even when it is an empty string

		size_t nChars = _tcslen(m_pDlgItemArray[i]->m_pszCaption) + 1;	//+++1.5

		WCHAR * pchCaption = new WCHAR[nChars+100];

#ifdef _UNICODE
		memset(pchCaption, 0, nChars*sizeof(TCHAR) + 2);
		memcpy(pchCaption, m_pDlgItemArray[i]->m_pszCaption, nChars * sizeof(TCHAR));	//+++1.5
		size_t nActualChars = nChars;
#else
		size_t nActualChars = MultiByteToWideChar(CP_ACP, 0,
			(LPCSTR)m_pDlgItemArray[i]->m_pszCaption, -1, pchCaption, nChars);	//+++1.5
#endif

		_ASSERTE(nActualChars > 0);
		memcpy(pdest, pchCaption, nActualChars * sizeof(WCHAR));
		pdest += nActualChars * sizeof(WCHAR);
		delete [] pchCaption;	//+++1.5

		*(WORD*)pdest = 0; // How many bytes in data for control
		pdest += sizeof(WORD);
	}

	_ASSERTE((size_t)(pdest - pBuffer) <= nBufferSize); //+++1.5 // just make sure we did not overrun the heap
	HINSTANCE hInstance = GetModuleHandle(NULL);

	rc = ::DialogBoxIndirectParam(hInstance, (LPCDLGTEMPLATE) pBuffer, m_hWnd, 
				MsgBoxDlgProc, (LPARAM)this);

	LocalUnlock(hLocal);
	LocalFree(hLocal);

	return rc;
}


///////////////////////////////////////////////////////////////////////////////
// CXDialogItem class

///////////////////////////////////////////////////////////////////////////////
// CXDialogItem ctor
CXDialogItem::CXDialogItem(CXDialogItem::Econtroltype ctrlType) :
	m_controltype(ctrlType),
	m_pszCaption(NULL)		//+++1.5
{
}

///////////////////////////////////////////////////////////////////////////////
// CXDialogItem dtor
CXDialogItem::~CXDialogItem()
{
	if (m_pszCaption)
		delete [] m_pszCaption;
}

///////////////////////////////////////////////////////////////////////////////
// CXDialogItem::AddItem
void CXDialogItem::AddItem(CXDialogTemplate& dialog,
						   Econtroltype ctrltype,
						   UINT nID,
						   CXRect* prect,
						   LPCTSTR lpszCaption)
{
	short hidbu = HIWORD(GetDialogBaseUnits());
	short lodbu = LOWORD(GetDialogBaseUnits());

	// first fill in the type, location and size of the control
	m_controltype = ctrltype;

	if (m_controltype == CHECKBOX)
		m_controltype = BUTTON;

	if (prect != NULL)
	{
		m_dlgItemTemplate.x = (short)((prect->left * 4) / lodbu);
		m_dlgItemTemplate.y = (short)((prect->top * 8) / hidbu);
		m_dlgItemTemplate.cx = (short)((prect->Width() * 4) / lodbu);
		m_dlgItemTemplate.cy = (short)((prect->Height() * 8) / hidbu);
	}
	else
	{
		m_dlgItemTemplate.x = 0;
		m_dlgItemTemplate.y = 0;
		m_dlgItemTemplate.cx = 10; // some useless default
		m_dlgItemTemplate.cy = 10;
	}

	m_dlgItemTemplate.dwExtendedStyle = 0;
	m_dlgItemTemplate.id = (WORD)nID;

	switch (ctrltype)
	{
		case ICON:
			m_dlgItemTemplate.style = WS_CHILD | SS_ICON | WS_VISIBLE;
			break;

		case BUTTON:
			dialog.GetButtonCount()++;
			m_dlgItemTemplate.style = WS_VISIBLE | WS_CHILD | WS_TABSTOP;
			if (dialog.GetButtonCount() == dialog.GetDefaultButton())
			{
				m_dlgItemTemplate.style |= BS_DEFPUSHBUTTON;
				dialog.SetDefaultButtonId(nID);
			}
			else
			{
				m_dlgItemTemplate.style |= BS_PUSHBUTTON;
			}
			break;

		case CHECKBOX:
			m_dlgItemTemplate.style = WS_VISIBLE | WS_CHILD | WS_TABSTOP | BS_AUTOCHECKBOX;
			break

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -