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

📄 dlgprop.cpp

📁 vc6.0完整版
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}

/////////////////////////////////////////////////////////////////////////////
// CPropertySheet -- a tabbed "dialog" (really a popup-window)

BEGIN_MESSAGE_MAP(CPropertySheet, CWnd)
	//{{AFX_MSG_MAP(CPropertySheet)
	ON_WM_CTLCOLOR()
	ON_WM_NCCREATE()
	ON_MESSAGE(WM_INITDIALOG, HandleInitDialog)
	ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
	ON_WM_CLOSE()
	ON_WM_SYSCOMMAND()
	ON_MESSAGE(DM_SETDEFID, OnSetDefID)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

AFX_STATIC_DATA const int _afxPropSheetIDs[4] = { ID_WIZNEXT, ID_WIZFINISH, ID_WIZBACK, IDCANCEL };

AFX_OLDPROPSHEETHEADER* CPropertySheet::GetPropSheetHeader()
{
	CPropertySheetEx* pSheetEx = DYNAMIC_DOWNCAST(CPropertySheetEx, this);
	if (pSheetEx != NULL)
		return (AFX_OLDPROPSHEETHEADER*)&pSheetEx->m_psh;
	else
		return &m_psh;
}

LRESULT CPropertySheet::OnSetDefID(WPARAM wParam, LPARAM lParam)
{
	// WINBUG -- A wrong or invalid ID may be passed in here.  If this is the
	// case, then look for a valid one.
	HWND hWnd;
	if (IsWizard() &&
		(
			((hWnd = ::GetDlgItem(m_hWnd, wParam)) == NULL) ||
			!(::GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE) ||
			!::IsWindowEnabled(hWnd)
		))
	{

		for (int i = 0; i < 4; i++)
		{
			// find first button that is visible and  enabled
			HWND hWnd = ::GetDlgItem(m_hWnd, _afxPropSheetIDs[i]);
			if ((GetWindowLong(hWnd, GWL_STYLE) & WS_VISIBLE) &&
				::IsWindowEnabled(hWnd))
			{
				//WINBUG -- focus could be incorrect as well in this case
				// so ... let's set it to the default button
				HWND hWndFocus = ::GetFocus();
				if (!::IsWindowEnabled(hWndFocus))
					::SetFocus(hWnd);
				return DefWindowProc(DM_SETDEFID, _afxPropSheetIDs[i], lParam);
			}
		}
	}
	return Default();
}

CPropertySheet::CPropertySheet()
{
	CommonConstruct(NULL, 0);
}

CPropertySheet::CPropertySheet(UINT nIDCaption, CWnd* pParentWnd,
	UINT iSelectPage)
{
	ASSERT(nIDCaption != 0);

	VERIFY(m_strCaption.LoadString(nIDCaption) != 0);
	CommonConstruct(pParentWnd, iSelectPage);
}

CPropertySheet::CPropertySheet(LPCTSTR pszCaption, CWnd* pParentWnd,
	UINT iSelectPage)
{
	ASSERT(pszCaption != NULL);

	m_strCaption = pszCaption;
	CommonConstruct(pParentWnd, iSelectPage);
}

void CPropertySheet::Construct(UINT nIDCaption, CWnd* pParentWnd,
	UINT iSelectPage)
{
	ASSERT(nIDCaption != 0);

	VERIFY(m_strCaption.LoadString(nIDCaption) != 0);
	CommonConstruct(pParentWnd, iSelectPage);
}

void CPropertySheet::Construct(LPCTSTR pszCaption, CWnd* pParentWnd,
	UINT iSelectPage)
{
	ASSERT(pszCaption != NULL);

	m_strCaption = pszCaption;
	CommonConstruct(pParentWnd, iSelectPage);
}

void CPropertySheet::CommonConstruct(CWnd* pParentWnd, UINT iSelectPage)
{
	memset(&m_psh, 0, sizeof(m_psh));
	m_psh.dwSize = sizeof(m_psh);
	m_psh.dwFlags = PSH_PROPSHEETPAGE;
	m_psh.pszCaption = m_strCaption;
	m_psh.nStartPage = iSelectPage;
	m_bStacked = TRUE;
	m_bModeless = FALSE;

	if (AfxHelpEnabled())
		m_psh.dwFlags |= PSH_HASHELP;

	m_pParentWnd = pParentWnd;  // m_psh.hwndParent set in DoModal/create
}

void CPropertySheet::EnableStackedTabs(BOOL bStacked)
{
	m_bStacked = bStacked;
}

void CPropertySheet::SetTitle(LPCTSTR lpszText, UINT nStyle)
{
	ASSERT((nStyle & ~PSH_PROPTITLE) == 0); // only PSH_PROPTITLE is valid
	ASSERT(lpszText == NULL || AfxIsValidString(lpszText));

	if (m_hWnd == NULL)
	{
		AFX_OLDPROPSHEETHEADER* psh = GetPropSheetHeader();
		// set internal state
		m_strCaption = lpszText;
		psh->pszCaption = m_strCaption;
		psh->dwFlags &= ~PSH_PROPTITLE;
		psh->dwFlags |= nStyle;
	}
	else
	{
		// set external state
		SendMessage(PSM_SETTITLE, nStyle, (LPARAM)lpszText);
	}
}

CPropertySheet::~CPropertySheet()
{
	delete[] (PROPSHEETPAGE*)m_psh.ppsp;
}

BOOL CPropertySheet::PreTranslateMessage(MSG* pMsg)
{
	ASSERT_VALID(this);

	// allow tooltip messages to be filtered
	if (CWnd::PreTranslateMessage(pMsg))
		return TRUE;

	// allow sheet to translate Ctrl+Tab, Shift+Ctrl+Tab,
	//  Ctrl+PageUp, and Ctrl+PageDown
	if (pMsg->message == WM_KEYDOWN && GetAsyncKeyState(VK_CONTROL) < 0 &&
		(pMsg->wParam == VK_TAB || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT))
	{
		if (SendMessage(PSM_ISDIALOGMESSAGE, 0, (LPARAM)pMsg))
			return TRUE;
	}

	// handle rest with IsDialogMessage
	return PreTranslateInput(pMsg);
}

BOOL CPropertySheet::OnCmdMsg(UINT nID, int nCode, void* pExtra,
	AFX_CMDHANDLERINFO* pHandlerInfo)
{
	if (CWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
		return TRUE;

	if ((nCode != CN_COMMAND && nCode != CN_UPDATE_COMMAND_UI) ||
			!IS_COMMAND_ID(nID) || nID >= 0xf000)
	{
		// control notification or non-command button or system command
		return FALSE;       // not routed any further
	}

	// if we have an owner window, give it second crack
	CWnd* pOwner = GetParent();
	if (pOwner != NULL)
	{
#ifdef _DEBUG
		if (afxTraceFlags & traceCmdRouting)
			TRACE1("Routing command id 0x%04X to owner window.\n", nID);
#endif
		ASSERT(pOwner != this);
		if (pOwner->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
			return TRUE;
	}

	// last crack goes to the current CWinThread object
	CWinThread* pThread = AfxGetThread();
	if (pThread != NULL)
	{
#ifdef _DEBUG
		if (afxTraceFlags & traceCmdRouting)
			TRACE1("Routing command id 0x%04X to app.\n", nID);
#endif
		if (pThread->OnCmdMsg(nID, nCode, pExtra, pHandlerInfo))
			return TRUE;
	}

#ifdef _DEBUG
	if (afxTraceFlags & traceCmdRouting)
	{
		TRACE2("IGNORING command id 0x%04X sent to %hs dialog.\n", nID,
				GetRuntimeClass()->m_lpszClassName);
	}
#endif
	return FALSE;
}

CPropertyPage* CPropertySheet::GetActivePage() const
{
	ASSERT_VALID(this);

	CPropertyPage* pPage;
	if (m_hWnd != NULL)
		pPage = STATIC_DOWNCAST(CPropertyPage,
			CWnd::FromHandle((HWND)::SendMessage(m_hWnd, PSM_GETCURRENTPAGEHWND, 0, 0)));
	else
		pPage = GetPage(GetActiveIndex());
	return pPage;
}

BOOL CPropertySheet::ContinueModal()
{
	// allow CWnd::EndModalLoop to be used
	if (!CWnd::ContinueModal())
		return FALSE;

	// when active page is NULL, the modal loop should end
	ASSERT(::IsWindow(m_hWnd));
	BOOL bResult = SendMessage(PSM_GETCURRENTPAGEHWND);
	return bResult;
}

int CPropertySheet::DoModal()
{
	ASSERT_VALID(this);
	ASSERT(m_hWnd == NULL);

	// register common controls
	VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));
	AfxDeferRegisterClass(AFX_WNDCOMMCTLSNEW_REG);

	// finish building PROPSHEETHEADER structure
	BuildPropPageArray();

	// allow OLE servers to disable themselves
	CWinApp* pApp = AfxGetApp();
	if (pApp != NULL)
		pApp->EnableModeless(FALSE);

	// find parent HWND
	HWND hWndTop;
	HWND hWndParent = CWnd::GetSafeOwner_(m_pParentWnd->GetSafeHwnd(), &hWndTop);
	AFX_OLDPROPSHEETHEADER* psh = GetPropSheetHeader();
	psh->hwndParent = hWndParent;
	BOOL bEnableParent = FALSE;
	if (hWndParent != NULL && ::IsWindowEnabled(hWndParent))
	{
		::EnableWindow(hWndParent, FALSE);
		bEnableParent = TRUE;
	}
	HWND hWndCapture = ::GetCapture();
	if (hWndCapture != NULL)
		::SendMessage(hWndCapture, WM_CANCELMODE, 0, 0);

	// setup for modal loop and creation
	m_nModalResult = 0;
	m_nFlags |= WF_CONTINUEMODAL;

	// hook for creation of window
	AfxHookWindowCreate(this);
	psh->dwFlags |= PSH_MODELESS;
	m_nFlags |= WF_CONTINUEMODAL;
	HWND hWnd = (HWND)::PropertySheet((PROPSHEETHEADER*)psh);
#ifdef _DEBUG
	DWORD dwError = ::GetLastError();
#endif
	psh->dwFlags &= ~PSH_MODELESS;
	AfxUnhookWindowCreate();

	// handle error
	if (hWnd == NULL || hWnd == (HWND)-1)
	{
		TRACE1("PropertySheet() failed: GetLastError returned %d\n", dwError);
		m_nFlags &= ~WF_CONTINUEMODAL;
	}

	int nResult = m_nModalResult;
	if (ContinueModal())
	{
		// enter modal loop
		DWORD dwFlags = MLF_SHOWONIDLE;
		if (GetStyle() & DS_NOIDLEMSG)
			dwFlags |= MLF_NOIDLEMSG;
		nResult = RunModalLoop(dwFlags);
	}

	// hide the window before enabling parent window, etc.
	if (m_hWnd != NULL)
	{
		SetWindowPos(NULL, 0, 0, 0, 0, SWP_HIDEWINDOW|
			SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE|SWP_NOZORDER);
	}
	if (bEnableParent)
		::EnableWindow(hWndParent, TRUE);
	if (hWndParent != NULL && ::GetActiveWindow() == m_hWnd)
		::SetActiveWindow(hWndParent);

	// cleanup
	DestroyWindow();

	// allow OLE servers to enable themselves
	if (pApp != NULL)
		pApp->EnableModeless(TRUE);
	if (hWndTop != NULL)
		::EnableWindow(hWndTop, TRUE);

	return nResult;
}

int CALLBACK
AfxPropSheetCallback(HWND, UINT message, LPARAM lParam)
{
	switch (message)
	{
	case PSCB_PRECREATE:
		{
			_AFX_THREAD_STATE* pState = AfxGetThreadState();
			LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE)lParam;
			if (lpTemplate->style != pState->m_dwPropStyle ||
				lpTemplate->dwExtendedStyle != pState->m_dwPropExStyle)
			{
				// Mark the dialog template as read-write.
				DWORD dwOldProtect;
				VirtualProtect(lpTemplate, sizeof(DLGTEMPLATE), PAGE_READWRITE, &dwOldProtect);

				// Ensure DS_SETFONT is set correctly.
				lpTemplate->style = lpTemplate->style & DS_SETFONT ?
									pState->m_dwPropStyle | DS_SETFONT :
									pState->m_dwPropStyle & ~DS_SETFONT;

				lpTemplate->dwExtendedStyle = pState->m_dwPropExStyle;
				return TRUE;
			}
			return FALSE;
		}
	}

	return 0;
}

BOOL CPropertySheet::Create(CWnd* pParentWnd, DWORD dwStyle, DWORD dwExStyle)
{
	_AFX_THREAD_STATE* pState = AfxGetThreadState();

	// Calculate the default window style.
	if (dwStyle == (DWORD)-1)
	{
		pState->m_dwPropStyle = DS_MODALFRAME | DS_3DLOOK | DS_CONTEXTHELP |
								DS_SETFONT | WS_POPUP | WS_VISIBLE | WS_CAPTION;

		// Wizards don't have WS_SYSMENU.
		if (!IsWizard())
			pState->m_dwPropStyle |= WS_SYSMENU;
	}
	else
	{
		pState->m_dwPropStyle = dwStyle;
	}
	pState->m_dwPropExStyle = dwExStyle;

	ASSERT_VALID(this);
	ASSERT(m_hWnd == NULL);

	VERIFY(AfxDeferRegisterClass(AFX_WNDCOMMCTLS_REG));
	AfxDeferRegisterClass(AFX_WNDCOMMCTLSNEW_REG);

	// finish building PROPSHEETHEADER structure
	AFX_OLDPROPSHEETHEADER* psh = GetPropSheetHeader();

	BuildPropPageArray();
	m_bModeless = TRUE;
	psh->dwFlags |= (PSH_MODELESS|PSH_USECALLBACK);
	psh->pfnCallback = AfxPropSheetCallback;
	psh->hwndParent = pParentWnd->GetSafeHwnd();

	// hook the window creation process
	AfxHookWindowCreate(this);
	HWND hWnd = (HWND)PropertySheet((PROPSHEETHEADER*)psh);
#ifdef _DEBUG
	DWORD dwError = ::GetLastError();
#endif

	// cleanup on failure, otherwise return TRUE
	if (!AfxUnhookWindowCreate())
		PostNcDestroy();    // cleanup if Create fails

	if (hWnd == NULL || hWnd == (HWND)-1)
	{
		TRACE1("PropertySheet() failed: GetLastError returned %d\n", dwError);
		return FALSE;
	}

	ASSERT(hWnd == m_hWnd);
	return TRUE;
}

void CPropertySheet::BuildPropPageArray()
{
	// delete existing prop page array
	delete[] (PROPSHEETPAGE*)m_psh.ppsp;
	m_psh.ppsp = NULL;

	// build new prop page array
	AFX_OLDPROPSHEETPAGE* ppsp = new AFX_OLDPROPSHEETPAGE[m_pages.GetSize()];
	m_psh.ppsp = (LPPROPSHEETPAGE)ppsp;
	BOOL bWizard = (m_psh.dwFlags & (PSH_WIZARD | PSH_WIZARD97));
	for (int i = 0; i < m_pages.GetSize(); i++)
	{
		CPropertyPage* pPage = GetPage(i);
		memcpy(&ppsp[i], &pPage->m_psp, sizeof(pPage->m_psp));
		pPage->PreProcessPageTemplate((PROPSHEETPAGE&)ppsp[i], bWizard);
	}
	m_psh.nPages = m_pages.GetSize();
}

////////////////////////////////////////////////////////////////////////////

int CPropertySheet::GetPageCount() const
{
	ASSERT_VALID(this);

	if (m_hWnd == NULL)
		return m_pages.GetSize();

	CTabCtrl* pTab = GetTabControl();
	ASSERT_VALID(pTab);
	return pTab->GetItemCount();
}

int CPropertySheet::GetActiveIndex() const
{
	if (m_hWnd == NULL)
		return ((CPropertySheet*)this)->GetPropSheetHeader()->nStartPage;

	CTabCtrl* pTab = GetTabControl();
	ASSERT_VALID(pTab);
	return pTab->GetCurSel();
}

BOOL CPropertySheet::SetActivePage(int nPage)
{
	if (m_hWnd == NULL)
	{
		GetPropSheetHeader()->nStartPage = nPage;
		return TRUE;
	}
	return (BOOL)SendMessage(PSM_SETCURSEL, nPage);
}

int CPropertySheet::GetPageIndex(CPropertyPage* pPage)
{
	for (int i = 0; i < GetPageCount(); i++)
	{
		if (GetPage(i) == pPage)
			return i;
	}
	return -1;  // pPage not found
}

BOOL CPropertySheet::SetActivePage(CPropertyPage* pPage)
{
	ASSERT_VALID(this);
	ASSERT(pPage != NULL);
	ASSERT_KINDOF(CPropertyPage, pPage);

	int nPage = GetPageIndex(pPage);
	ASSERT(pPage >= 0);

	return SetActivePage(nPage);
}

void CPropertySheet::AddPage(CPropertyPage* pPage)
{
	ASSERT_VALID(this);
	ASSERT(pPage != NULL);
	ASSERT_KINDOF(CPropertyPage, pPage);
	ASSERT_VALID(pPage);

	// add page to internal list
	m_pages.Add(pPage);

	// add page externally
	if (m_hWnd != NULL)
	{
		// build new prop page array
		AFX_OLDPROPSHEETPAGE *ppsp = new AFX_OLDPROPSHEETPAGE[m_pages.GetSize()];
		memcpy(ppsp, m_psh.ppsp, sizeof(AFX_OLDPROPSHEETPAGE) * (m_pages.GetSize()-1));
		delete[] (PROPSHEETPAGE*)m_psh.ppsp;
		m_psh.ppsp = (PROPSHEETPAGE*)ppsp;
		ppsp += m_pages.GetSize()-1;

		// copy processed PROPSHEETPAGE struct to end
		memcpy(ppsp, &pPage->m_psp, sizeof(pPage->m_psp));
		pPage->PreProcessPageTemplate((PROPSHEETPAGE&)*ppsp, IsWizard());
		HPROPSHEETPAGE hPSP = CreatePropertySheetPage((PROPSHEETPAGE*)ppsp);
		if (hPSP == NULL)
			AfxThrowMemoryException();

		if (!SendMessage(PSM_ADDPAGE, 0, (LPARAM)hPSP))
		{
			DestroyPropertySheetPage(hPSP);
			AfxThrowMemoryException();
		}

⌨️ 快捷键说明

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