runtimedlg.cpp

来自「管理项目进度工具的原代码」· C++ 代码 · 共 911 行 · 第 1/2 页

CPP
911
字号
		TRACE("CreateWindowEx(%s) failed. GetLastError returned %08X\n", szClass, GetLastError());
	
	return hwnd;
}

HWND CRuntimeDlg::CreateRichEdit(LPCTSTR szClass, LPCTSTR szCaption, DWORD dwStyle, DWORD dwExStyle, 
								 int x, int y, int cx, int cy, HWND hwndParent)
{
	CRichEditHelper::InitRichEdit();
	
	ASSERT (CWinClasses::IsRichEditControl(szClass));
	
	HWND hwnd = ::CreateWindowEx(dwExStyle, szClass, szCaption, dwStyle, x, y, cx, cy, hwndParent, NULL, NULL, NULL);
	
	// if it failed and its not richedit10 then try richedit10
	if (!hwnd && !CWinClasses::IsClass(szClass, WC_RICHEDIT))
		hwnd = ::CreateWindowEx(dwExStyle, WC_RICHEDIT, szCaption, dwStyle, x, y, cx, cy, hwndParent, NULL, NULL, NULL);
	
	return hwnd;
}

BOOL CRuntimeDlg::CreateControl(CWnd* pWnd, LPCTSTR szCaption, DWORD dwStyle, DWORD dwExStyle, 
								int x, int y, int cx, int cy, UINT nID, BOOL bDLU, UINT nIconID)
{
	ASSERT (!pWnd->GetSafeHwnd());
	
	if (pWnd->GetSafeHwnd())
		return FALSE;
	
	CString sClass = GetControlClassName(pWnd);
	
	if (sClass.IsEmpty())
		return FALSE;
	
	HWND hwnd = CreateControl(sClass, szCaption, dwStyle, dwExStyle, x, y, cx, cy, nID, bDLU, nIconID);
	
	if (hwnd)
		return pWnd->SubclassWindow(hwnd);
	
	// else
	return FALSE;
}


BOOL CRuntimeDlg::CreateControl(const RTCONTROL& rtc)
{
	if (rtc.m_pWnd)
		return CreateControl(rtc.m_pWnd, rtc.m_sCaption, rtc.m_dwStyle, rtc.m_dwExStyle, 
		rtc.m_rect.left, rtc.m_rect.top, rtc.m_rect.Width(), rtc.m_rect.Height(), 
		rtc.m_nID, rtc.m_bDLU, rtc.m_nIconID);
	
	else if (!rtc.m_sClass.IsEmpty())
		return (NULL != CreateControl(rtc.m_sClass, rtc.m_sCaption, rtc.m_dwStyle, rtc.m_dwExStyle, 
		rtc.m_rect.left, rtc.m_rect.top, rtc.m_rect.Width(), rtc.m_rect.Height(), 
		rtc.m_nID, rtc.m_bDLU, rtc.m_nIconID));
	
	else
		return FALSE;
}

void CRuntimeDlg::CreateControls()
{
	ASSERT (GetSafeHwnd());
	
	if (!GetSafeHwnd())
		return;
	
	POSITION pos = m_lstControls.GetHeadPosition();
	
	while (pos)
		CreateControl(m_lstControls.GetNext(pos));
}

CString CRuntimeDlg::GetClassName(CWnd* pWnd)
{
	ASSERT (pWnd);
	
	if (!pWnd)
		return "";
	
	CString sName;
	
	::GetClassName(*pWnd, sName.GetBuffer(128), 127);
	sName.ReleaseBuffer();
	
	return sName;
}

CString CRuntimeDlg::GetControlClassName(CWnd* pWnd)
{
	ASSERT (pWnd);
	
	if (!pWnd)
		return "";
	
	// if there is no permanent mapping to this CWnd just return GetClassName()
	// but only if it has a window handle attached else it must be a real CWnd
	if (pWnd->GetSafeHwnd() && CWnd::FromHandlePermanent(*pWnd) != pWnd)
		return GetClassName(pWnd);
	
	CRuntimeClass* pRTClass = pWnd->GetRuntimeClass();
	
	// work our way up the derivation chain till we find a match
	while (pRTClass)
	{
		CString sWinClass, sRTClass = pRTClass->m_lpszClassName;
		
		if (s_mapClasses.Lookup(sRTClass, sWinClass))
			return sWinClass;
		
		// try ancestor
#ifdef _AFXDLL
		pRTClass = (*pRTClass->m_pfnGetBaseClass)();
#else
		pRTClass = pRTClass->m_pBaseClass;
#endif
	}
	
	// means we did not find anything
	ASSERT (0);
	return "";
}

void CRuntimeDlg::BuildClassMap()
{
	if (s_mapClasses.GetCount())
		return; // already done
	
	s_mapClasses["CStatic"]         = WC_STATIC;
	s_mapClasses["CButton"]         = WC_BUTTON;
	s_mapClasses["CListBox"]        = WC_LISTBOX;
	s_mapClasses["CComboBox"]       = WC_COMBOBOX;
	s_mapClasses["CEdit"]           = WC_EDIT;
	s_mapClasses["CScrollBar"]      = WC_SCROLLBAR;
	s_mapClasses["CListCtrl"]       = WC_LISTVIEW;
	s_mapClasses["CTreeCtrl"]       = WC_TREEVIEW;
	s_mapClasses["CSpinButtonCtrl"] = WC_SPIN;
	s_mapClasses["CHeaderCtrl"]     = WC_HEADER;
	s_mapClasses["CSliderCtrl"]     = WC_SLIDER;
	s_mapClasses["CProgressCtrl"]   = WC_PROGRESS;
	s_mapClasses["CHotKeyCtrl"]     = WC_HOTKEY;
	s_mapClasses["CToolTipCtrl"]    = WC_TOOLTIPS;
	s_mapClasses["CTabCtrl"]        = WC_TABCONTROL;
	s_mapClasses["CAnimateCtrl"]    = WC_ANIMATE;
	s_mapClasses["CToolBarCtrl"]    = WC_TOOLBAR;
	s_mapClasses["CStatusBarCtrl"]  = WC_STATUSBAR;
	s_mapClasses["CRichEditCtrl"]   = WC_RICHEDIT20;
	s_mapClasses["CIPAddressCtrl"]  = WC_IPADDRESS;
	s_mapClasses["CDateTimeCtrl"]   = WC_DATETIMEPICK;
	s_mapClasses["CMonthCalCtrl"]   = WC_MONTHCAL;
	s_mapClasses["CReBar"]          = WC_REBAR;
	//	s_mapClasses[""] = "";
}

void CRuntimeDlg::SetBorders(int nLeft, int nTop, int nRight, int nBottom)
{
	m_rBordersDLU.SetRectEmpty();
	m_rBorders.SetRect(max(0, nLeft), max(0, nTop), max(0, nRight), max(0, nBottom));
}

void CRuntimeDlg::SetBordersDLU(int nLeft, int nTop, int nRight, int nBottom)
{
	if (GetSafeHwnd())
	{
		CDlgUnits dlu(*this);
		
		dlu.ToPixels(nLeft, nTop);
		dlu.ToPixels(nRight, nBottom);
		
		SetBorders(nLeft, nTop, nRight, nBottom);
	}
	else
	{
		m_rBorders.SetRectEmpty();
		m_rBordersDLU.SetRect(max(0, nLeft), max(0, nTop), max(0, nRight), max(0, nBottom));
	}
}

// static
CRect CRuntimeDlg::OffsetCtrl(CWnd* pParent, UINT nCtrlID, int x, int y)
{
	CWnd* pCtrl = pParent->GetDlgItem(nCtrlID);
	
	if (pCtrl)
	{
		CRect rChild;
		pCtrl->GetWindowRect(rChild);
		pParent->ScreenToClient(rChild);
		
		if (x || y)
		{
			rChild.OffsetRect(x, y);
			pCtrl->MoveWindow(rChild);
		}
		
		return rChild;
	}
	
	return CRect(0, 0, 0, 0);
}

// static
CRect CRuntimeDlg::MoveCtrl(CWnd* pParent, UINT nCtrlID, int x, int y)
{
	CWnd* pCtrl = pParent->GetDlgItem(nCtrlID);
	
	if (pCtrl)
	{
		CRect rChild;
		pCtrl->GetWindowRect(rChild);
		pParent->ScreenToClient(rChild);
		
		if (x || y)
		{
			rChild.OffsetRect(x - rChild.left, y - rChild.top);
			pCtrl->MoveWindow(rChild);
		}
		
		return rChild;
	}
	
	return CRect(0, 0, 0, 0);
}

// static
CRect CRuntimeDlg::ResizeCtrl(CWnd* pParent, UINT nCtrlID, int cx, int cy)
{
	CWnd* pCtrl = pParent->GetDlgItem(nCtrlID);
	
	if (pCtrl)
	{
		CRect rChild, rParent;
		pCtrl->GetWindowRect(rChild);
		pParent->ScreenToClient(rChild);
		pParent->GetClientRect(rParent);
		
		if (cx || cy)
		{
			rChild.right += cx;
			rChild.bottom += cy;
			
			// make sure it also intersects with parent
			if (rChild.IntersectRect(rChild, rParent))
				pCtrl->MoveWindow(rChild);
		}
		
		return rChild;
	}
	
	return CRect(0, 0, 0, 0);
}

CRect CRuntimeDlg::OffsetCtrl(UINT nCtrlID, int x, int y)
{
	return OffsetCtrl(this, nCtrlID, x, y);
}

CRect CRuntimeDlg::MoveCtrl(UINT nCtrlID, int x, int y)
{
	return MoveCtrl(this, nCtrlID, x, y);
}

CRect CRuntimeDlg::ResizeCtrl(UINT nCtrlID, int cx, int cy)
{
	return ResizeCtrl(this, nCtrlID, cx, cy);
}

int CRuntimeDlg::AddRCControls(const CString& sRCControls)
{
	CRCCtrlParser rccp(sRCControls);
	
	return rccp.GetRCControls(m_lstControls);
}

BOOL CRuntimeDlg::PreTranslateMessage(MSG* pMsg)
{
   BOOL bChild = (GetStyle() & WS_CHILD);
   BOOL bTab = (pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB);
   
	// don't handle the enter/cancel keys in child dialogs
/*
	if (bChild)
	{
		if (pMsg->message == WM_KEYDOWN && (pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
			return FALSE;
	}
*/
	
	// also filter out what look like accelerator keys 
 	if (pMsg->message == WM_KEYDOWN)
 	{
 		if (pMsg->wParam != VK_CONTROL && (GetKeyState(VK_CONTROL) & 0x8000))
 			return FALSE;
 	}
	
	// filter out mouse moves because CDialog::PreTranslateMessage
	// eats them and prevents tooltips working
//	else if (pMsg->message == WM_MOUSEMOVE)
//		return FALSE;
	
   return (bChild && !bTab) ? CWnd::PreTranslateMessage(pMsg) : CDialog::PreTranslateMessage(pMsg);
}

void CRuntimeDlg::SetControlState(CWnd* pParent, UINT nCtrlID, RT_CTRLSTATE nState)
{
	SetControlState(::GetDlgItem(*pParent, nCtrlID), nState);
}

void CRuntimeDlg::SetControlsState(CWnd* pParent, UINT nCtrlIDFrom, UINT nCtrlIDTo, RT_CTRLSTATE nState)
{
	ASSERT (pParent);
	
	for (UINT nID = nCtrlIDFrom; nID <= nCtrlIDTo; nID++)
		SetControlState(::GetDlgItem(*pParent, nID), nState);
}

void CRuntimeDlg::SetControlState(HWND hCtrl, RT_CTRLSTATE nState)
{
	if (hCtrl)
	{
		switch (nState)
		{
		case RTCS_ENABLED:
			::EnableWindow(hCtrl, TRUE);
			
			if (IsEdit(hCtrl))
				::SendMessage(hCtrl, EM_SETREADONLY, FALSE, 0);
			break;
			
		case RTCS_DISABLED:
			::EnableWindow(hCtrl, FALSE);
			break;
			
		case RTCS_READONLY:
			if (IsEdit(hCtrl))
			{
				::EnableWindow(hCtrl, TRUE);
				::SendMessage(hCtrl, EM_SETREADONLY, TRUE, 0);
			}
			else
			{
				BOOL bStatic = CWinClasses::IsClass(hCtrl, "static");
				::EnableWindow(hCtrl, bStatic);
			}
			break;
		}
	}
}

BOOL CRuntimeDlg::IsEdit(HWND hCtrl)
{
	CString sClass = CWinClasses::GetClass(hCtrl);
	
	return (CWinClasses::IsClass(sClass, WC_EDIT) ||
		CWinClasses::IsClass(sClass, WC_RICHEDIT) ||
		CWinClasses::IsClass(sClass, WC_RICHEDIT20));
}

BOOL CRuntimeDlg::IsEdit(CWnd* pParent, UINT nCtrlID) 
{ 
	ASSERT (pParent);
	
	return IsEdit(::GetDlgItem(*pParent, nCtrlID)); 
}

void CRuntimeDlg::ShowControls(CWnd* pParent, UINT nCtrlIDFrom, UINT nCtrlIDTo, BOOL bShow)
{
	ASSERT (pParent);
	
	for (UINT nID = nCtrlIDFrom; nID <= nCtrlIDTo; nID++)
		ShowControl(pParent, nID, bShow);
}

void CRuntimeDlg::ShowControl(CWnd* pParent, UINT nCtrlID, BOOL bShow)
{
	ShowControl(pParent->GetDlgItem(nCtrlID), bShow);
}

void CRuntimeDlg::ShowControl(CWnd* pCtrl, BOOL bShow)
{
	if (!pCtrl)
		return;
	
	pCtrl->ShowWindow(bShow ? SW_SHOW : SW_HIDE);
}

void CRuntimeDlg::ExcludeControls(CWnd* pParent, CDC* pDC, UINT nCtrlIDFrom, UINT nCtrlIDTo)
{
	ASSERT (pParent);
	
	for (UINT nID = nCtrlIDFrom; nID <= nCtrlIDTo; nID++)
	{
		if (::IsWindowVisible(::GetDlgItem(*pParent, nID)))
			pDC->ExcludeClipRect(OffsetCtrl(pParent, nID));
	}
}

void CRuntimeDlg::ShowControls(UINT nCtrlIDFrom, UINT nCtrlIDTo, BOOL bShow)
{
	ShowControls(this, nCtrlIDFrom, nCtrlIDTo, bShow);
}

void CRuntimeDlg::ExcludeControls(CDC* pDC, UINT nCtrlIDFrom, UINT nCtrlIDTo)
{
	ExcludeControls(this, pDC, nCtrlIDFrom, nCtrlIDTo);
}

void CRuntimeDlg::OnSetFocus(CWnd* pOldWnd) 
{
	CDialog::OnSetFocus(pOldWnd);
	
	CWnd* pChild = GetWindow(GW_CHILD);
	
	if (pChild)
		pChild->SetFocus();
}

void CRuntimeDlg::SetFont(CFont* pFont, BOOL bRedraw)
{
	SetFont(pFont ? (HFONT)pFont->GetSafeHandle() : NULL, bRedraw);
}

void CRuntimeDlg::SetFont(HFONT hFont, BOOL bRedraw)
{
	CDialogHelper::SetFont(this, hFont, bRedraw);
}

int CRuntimeDlg::CalcLinesRequired(const CString& sText, int nWidthDLU)
{
	// iterate the text by segment (\n) and add up the number of lines
	// each segment takes up
	int nStart = 0;
	int nCR = sText.Find('\n', nStart);
	int nLines = 0;

	while (nCR != -1)
	{
		int nSegLenDLU = (nCR - nStart) * 4;

		if (nSegLenDLU)
			nLines += (nSegLenDLU / nWidthDLU) + ((nSegLenDLU % nWidthDLU) ? 1 : 0);
		else
			nLines++; // empty line

		nStart = nCR + 1;
		nCR = sText.Find('\n', nStart);
	}

	// handle last segment
	int nSegLenDLU = (sText.GetLength() - nStart) * 4;
	nLines += (nSegLenDLU / nWidthDLU) + ((nSegLenDLU % nWidthDLU) ? 1 : 0);

	return nLines;
}

⌨️ 快捷键说明

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