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

📄 mtluser.h

📁 一个使用wtl写的完整的多窗口浏览器
💻 H
📖 第 1 页 / 共 3 页
字号:
// Methods
	void UpdateMDIFrameTitle()// no effect
	{
		T* pT = static_cast<T*>(this);
		BOOL bMaximized = FALSE;
		HWND hWndActive = pT->MDIGetActive(&bMaximized);
		if (hWndActive == NULL || bMaximized == FALSE) {
			return;
		}

		MtlSetWindowText(pT->m_hWnd, _Make_UpsideDownTitle(hWndActive));
	}

// Message map and handlers
	BEGIN_MSG_MAP(CMDIFrameTitleUpsideDownMessageHandler)
//		MESSAGE_HANDLER(WM_GETTEXTLENGTH, OnGetTextLength) no need, cuz original buffer size is always larger.
//		MESSAGE_HANDLER(WM_SETTEXT, OnSetText) never called by MDI system
		MESSAGE_HANDLER(WM_GETTEXT, OnGetText)
	END_MSG_MAP()

	LRESULT OnGetText(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		UINT cchTextMax = (UINT)wParam;   // number of characters to copy 
		LPTSTR lpszText = (LPTSTR)lParam;
		bHandled = FALSE;

		if (!m_bValid)
			return 0;

		T* pT = static_cast<T*>(this);
		// first, find the mdi child's title
		BOOL bMaximized = FALSE;
		HWND hWndActive = pT->MDIGetActive(&bMaximized);
		if (hWndActive == NULL || bMaximized == FALSE)
			return 0;		

		CString strApp; strApp.LoadString(IDR_MAINFRAME);
		CString strTitle = MtlGetWindowText(hWndActive) + _T(" - ") + strApp;
		::lstrcpyn(lpszText, strTitle, cchTextMax);	

		bHandled = TRUE;
		return min(strTitle.GetLength(), cchTextMax);
	}

	CString _Make_UpsideDownTitle(HWND hWndMDIChild)
	{
		CString strChild = MtlGetWindowText(hWndMDIChild);
		CString strApp; strApp.LoadString(IDR_MAINFRAME);
		return strChild + _T(" - ") + strApp;
	}

	LRESULT OnSetText(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		CString strText = (LPCTSTR)lParam;

		// first, find the mdi child's title
		int nFirstIndex = strText.Find(_T('['));
		int nLastIndex = strText.ReverseFind(_T(']'));

		if (nFirstIndex > nLastIndex || nFirstIndex == -1 || nFirstIndex == -1) {
			bHandled = FALSE;
			return FALSE;
		}

		CString strChild = strText.Mid(nFirstIndex, nLastIndex - nFirstIndex + 1);

		// second, find the application's title
		CString strApp; strApp.LoadString(IDR_MAINFRAME);
		strText = strChild + _T(" - ") + strApp;
		
 
		T* pT = static_cast<T*>(this);
		return pT->DefWindowProc(uMsg, wParam, (LPARAM)(LPCTSTR)strText);
	}
};

template <class T>
class CHelpMessageLine
{
public:
	BEGIN_MSG_MAP(CHelpMessageLine)
		MESSAGE_HANDLER(WM_MENUSELECT, OnMenuSelect)
	END_MSG_MAP()

	LRESULT OnMenuSelect(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		T* pT = static_cast<T*>(this);

		if(pT->m_hWndStatusBar == NULL)
			return pT->DefWindowProc(uMsg, wParam, lParam);

		HMENU hMenu = (HMENU)lParam;
		WORD wFlags = HIWORD(wParam);
		UINT uItem = (UINT)LOWORD(wParam);   // menu item or submenu index 

		CString strHelp;
		if(wFlags == 0xFFFF && hMenu == NULL) {	// menu closing
			::SendMessage(pT->m_hWndStatusBar, SB_SIMPLE, FALSE, 0L);
		}
		else {
			if(!(wFlags & MF_POPUP)) {
				WORD wID = LOWORD(wParam);
				// check for special cases
				if(wID >= 0xF000 && wID < 0xF1F0)				// system menu IDs
					wID = (WORD)(((wID - 0xF000) >> 4) + ATL_IDS_SCFIRST);
				else if(wID >= ID_FILE_MRU_FIRST && wID <= ID_FILE_MRU_LAST)	// MRU items
					wID = ATL_IDS_MRU_FILE;
				else if(wID >= ATL_IDM_FIRST_MDICHILD)				// MDI child windows
					wID = ATL_IDS_MDICHILD;

				strHelp.LoadString(wID);
				int nStart = strHelp.Find(_T('\t'));
				int nLast = strHelp.Find(_T('\n'));

				if (nStart == -1 && nLast != -1) {
					strHelp = strHelp.Mid(0, nLast);
				}
				else if (nStart != -1 && nLast == -1) {
					strHelp = strHelp.Right(strHelp.GetLength() - nStart - 1);
				}
				else if (nStart != -1 && nLast != -1) {
					ATLASSERT(nStart < nLast);
					strHelp = strHelp.Mid(nStart + 1, nLast - nStart - 1);
				}
			}
			else // popup support
			{
				HMENU hMenuPopup = ::GetSubMenu(hMenu, uItem);
				
				UINT nID = -1;
				TCHAR szString[100];

				// search the first non-popup menu's ID
				for (int i = 0; i < ::GetMenuItemCount(hMenuPopup); ++i) {
					// Fixed by Nisizawa@mcomp.co.jp, thanks.
					// Note. GetMenuItemInfo often change mii.dwTypeData.
					//       even if the API reference says not.
					CMenuItemInfo mii;
					mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_SUBMENU;
					mii.dwTypeData = szString;
					mii.cch = 100;
					
					if (!::GetMenuItemInfo(hMenuPopup, i, TRUE, &mii))
						continue;

					bool bSkip = _check_flag(MFT_SEPARATOR, mii.fType) || mii.hSubMenu != NULL;
					nID =  bSkip ? -1 : mii.wID;
					if (nID != -1) {
						if (nID >= ID_FILE_MRU_FIRST && nID <= ID_FILE_MRU_LAST)	// MRU items
							nID = ATL_IDS_MRU_FILE;
						else if (nID >= ATL_IDM_FIRST_MDICHILD)				// MDI child windows
							nID = ATL_IDS_MDICHILD;
						break;
					}
				}

				if (nID != -1) {
					strHelp.LoadString(nID);
					int nIndex = strHelp.Find(_T('\t'));
					if (nIndex != -1) {
						strHelp = strHelp.Left(nIndex);
					}
					else {
						strHelp.Empty();
					}
				}
			}

			::SendMessage(pT->m_hWndStatusBar, SB_SIMPLE, TRUE, 0L);
			::SendMessage(pT->m_hWndStatusBar, SB_SETTEXT, (255 | SBT_NOBORDERS), (LPARAM)(LPCTSTR)strHelp);
		}

		return pT->DefWindowProc(uMsg, wParam, lParam);
	}
};

/////////////////////////////////////////////////////////////////////////////
// CInitDialogImpl - property page that supports DropDownList initialization

#ifndef _ATL_RT_DLGINIT
	#define _ATL_RT_DLGINIT  MAKEINTRESOURCE(240)
#endif

template <class T, class TBase = CWindow>
class ATL_NO_VTABLE CInitDialogImpl : public CDialogImpl< T, TBase >
{
public:
	typedef CInitDialogImpl< T, TBase > thisClass;
	typedef CDialogImpl< T, TBase > baseClass;

// Data members
	HGLOBAL m_hInitData;

// Constructor/destructor
	CInitDialogImpl() :	m_hInitData(NULL)
	{
		T* pT = static_cast<T*>(this);
		pT;	// avoid level 4 warning

		HINSTANCE hInstance = _Module.GetResourceInstance();
		LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD);
		HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG);
		if(hDlg != NULL)
		{
			HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT);
			if(hDlgInit != NULL)
			{
				m_hInitData = ::LoadResource(hInstance, hDlgInit);
			}
		}
		else
		{
			ATLASSERT(FALSE && _T("CInitDialogImpl - Cannot find dialog template!"));
		}
	}

	~CInitDialogImpl()
	{
		if(m_hInitData != NULL)
		{
			UnlockResource(m_hInitData);
			::FreeResource(m_hInitData);
		}
	}
// Methods
	bool ExecuteDlgInit()
	{
		BYTE* pInitData = (BYTE*)::LockResource(m_hInitData);
		return _ExecuteDlgInit(pInitData);
	}

	bool _ExecuteDlgInit(LPVOID lpResource)
	{// cf.MFC
		bool bSuccess = true;
		if (lpResource != NULL)
		{
			UNALIGNED WORD* lpnRes = (WORD*)lpResource;
			while (bSuccess && *lpnRes != 0)
			{
				WORD nIDC = *lpnRes++;
				WORD nMsg = *lpnRes++;
				DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;

				// In Win32 the WM_ messages have changed.  They have
				// to be translated from the 32-bit values to 16-bit
				// values here.

				#define WIN16_LB_ADDSTRING  0x0401
				#define WIN16_CB_ADDSTRING  0x0403
				#define AFX_CB_ADDSTRING    0x1234

				// unfortunately, WIN16_CB_ADDSTRING == CBEM_INSERTITEM
				if (nMsg == AFX_CB_ADDSTRING)
					nMsg = CBEM_INSERTITEM;
				else if (nMsg == WIN16_LB_ADDSTRING)
					nMsg = LB_ADDSTRING;
				else if (nMsg == WIN16_CB_ADDSTRING)
					nMsg = CB_ADDSTRING;

			// check for invalid/unknown message types
				ATLASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
					nMsg == CBEM_INSERTITEM);

#ifdef _DEBUG
				// For AddStrings, the count must exactly delimit the
				// string, including the NULL termination.  This check
				// will not catch all mal-formed ADDSTRINGs, but will
				// catch some.
				if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM)
					ATLASSERT(*((LPBYTE)lpnRes + (UINT)dwLen - 1) == 0);
#endif

				if (nMsg == CBEM_INSERTITEM)
				{
					USES_CONVERSION;
					COMBOBOXEXITEM item;
					item.mask = CBEIF_TEXT;
					item.iItem = -1;
					item.pszText = A2T(LPSTR(lpnRes));	

					if (::SendDlgItemMessage(m_hWnd, nIDC, nMsg, 0, (LPARAM) &item) == -1)
						bSuccess = false;
				}
				else if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)
				{
					// List/Combobox returns -1 for error
					if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LPARAM) lpnRes) == -1)
						bSuccess = false;
				}


				// skip past data
				lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
			}
		}

		// send update message to all controls after all other siblings loaded
//		if (bSuccess)
//			SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, FALSE, FALSE);

		return bSuccess;
	}

// DDX methods
	void DDX_CBIndex(UINT nID, int& nValue, BOOL bSave)
	{
		HWND hWndCtrl = GetDlgItem(nID);
		ATLASSERT(::IsWindow(hWndCtrl));
		if(bSave)
		{
			nValue = (int)::SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0L);
			ATLASSERT(nValue >= 0 && nValue < (int)::SendMessage(hWndCtrl, CB_GETCOUNT, 0, 0L));
		}
		else
		{
			if(nValue < 0 || nValue >= (int)::SendMessage(hWndCtrl, CB_GETCOUNT, 0, 0L))
			{
				ATLTRACE2(atlTraceUI, 0, "ATL: Warning - dialog data combobox value (%d) out of range.\n", nValue);
				nValue = 0;  // default to off
			}
			int nRet = ::SendMessage(hWndCtrl, CB_SETCURSEL, nValue, 0L);
			ATLASSERT(nRet != CB_ERR);
		}
	}
};

/////////////////////////////////////////////////////////////////////////////
// CInitPropertyPageImpl - property page that supports DropDownList initialization
//   That is, the subset of CAxProtertyPageImpl
//   If you use combobox ex, don't miss ICC_USEREX_CLASSES.

#define DDX_CBINDEX(nID, var) \
		if(nCtlID == (UINT)-1 || nCtlID == nID) \
			DDX_CBIndex(nID, var, bSaveAndValidate);

template <class T, class TBase = CPropertyPageWindow>
class ATL_NO_VTABLE CInitPropertyPageImpl : public CPropertyPageImpl< T, TBase >
{
public:
	typedef CInitPropertyPageImpl< T, TBase > thisClass;
	typedef CPropertyPageImpl< T, TBase > baseClass;

// Data members
	HGLOBAL m_hInitData;

// Constructor/destructor
	CInitPropertyPageImpl(_U_STRINGorID title = (LPCTSTR)NULL) : 
			CPropertyPageImpl< T, TBase >(title),
			m_hInitData(NULL)
	{
		T* pT = static_cast<T*>(this);
		pT;	// avoid level 4 warning

		HINSTANCE hInstance = _Module.GetResourceInstance();
		LPCTSTR lpTemplateName = MAKEINTRESOURCE(pT->IDD);
		HRSRC hDlg = ::FindResource(hInstance, lpTemplateName, (LPTSTR)RT_DIALOG);
		if(hDlg != NULL)
		{
			HRSRC hDlgInit = ::FindResource(hInstance, lpTemplateName, (LPTSTR)_ATL_RT_DLGINIT);
			if(hDlgInit != NULL)
			{
				m_hInitData = ::LoadResource(hInstance, hDlgInit);
			}
		}
		else
		{
			ATLASSERT(FALSE && _T("CInitPropertyPageImpl - Cannot find dialog template!"));
		}
	}

	~CInitPropertyPageImpl()
	{
		if(m_hInitData != NULL)
		{
			UnlockResource(m_hInitData);
			::FreeResource(m_hInitData);
		}
	}
	
	BEGIN_MSG_MAP(thisClass)
		MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog)
		CHAIN_MSG_MAP(baseClass)
	END_MSG_MAP()

	LRESULT OnInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
	{
		bHandled = FALSE;

		BYTE* pInitData = (BYTE*)::LockResource(m_hInitData);
		ExecuteDlgInit(pInitData);

		return TRUE;
	}

// Methods
	bool ExecuteDlgInit(LPVOID lpResource)
	{// cf.MFC
		bool bSuccess = true;
		if (lpResource != NULL)
		{
			UNALIGNED WORD* lpnRes = (WORD*)lpResource;
			while (bSuccess && *lpnRes != 0)
			{
				WORD nIDC = *lpnRes++;
				WORD nMsg = *lpnRes++;
				DWORD dwLen = *((UNALIGNED DWORD*&)lpnRes)++;

				// In Win32 the WM_ messages have changed.  They have
				// to be translated from the 32-bit values to 16-bit
				// values here.

				#define WIN16_LB_ADDSTRING  0x0401
				#define WIN16_CB_ADDSTRING  0x0403
				#define AFX_CB_ADDSTRING    0x1234

				// unfortunately, WIN16_CB_ADDSTRING == CBEM_INSERTITEM
				if (nMsg == AFX_CB_ADDSTRING)
					nMsg = CBEM_INSERTITEM;
				else if (nMsg == WIN16_LB_ADDSTRING)
					nMsg = LB_ADDSTRING;
				else if (nMsg == WIN16_CB_ADDSTRING)
					nMsg = CB_ADDSTRING;

			// check for invalid/unknown message types
				ATLASSERT(nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING ||
					nMsg == CBEM_INSERTITEM);

#ifdef _DEBUG
				// For AddStrings, the count must exactly delimit the
				// string, including the NULL termination.  This check
				// will not catch all mal-formed ADDSTRINGs, but will
				// catch some.
				if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING || nMsg == CBEM_INSERTITEM)
					ATLASSERT(*((LPBYTE)lpnRes + (UINT)dwLen - 1) == 0);
#endif

				if (nMsg == CBEM_INSERTITEM)
				{
					USES_CONVERSION;
					COMBOBOXEXITEM item;
					item.mask = CBEIF_TEXT;
					item.iItem = -1;
					item.pszText = A2T(LPSTR(lpnRes));	

					if (::SendDlgItemMessage(m_hWnd, nIDC, nMsg, 0, (LPARAM) &item) == -1)
						bSuccess = false;
				}
				else if (nMsg == LB_ADDSTRING || nMsg == CB_ADDSTRING)
				{
					// List/Combobox returns -1 for error
					if (::SendDlgItemMessageA(m_hWnd, nIDC, nMsg, 0, (LPARAM) lpnRes) == -1)
						bSuccess = false;
				}


				// skip past data
				lpnRes = (WORD*)((LPBYTE)lpnRes + (UINT)dwLen);
			}
		}

		// send update message to all controls after all other siblings loaded
//		if (bSuccess)
//			SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, FALSE, FALSE);

		return bSuccess;
	}

// DDX methods
	void DDX_CBIndex(UINT nID, int& nValue, BOOL bSave)
	{
		HWND hWndCtrl = GetDlgItem(nID);
		if(bSave)
		{
			nValue = (int)::SendMessage(hWndCtrl, CB_GETCURSEL, 0, 0L);
			ATLASSERT(nValue >= 0 && nValue < (int)::SendMessage(hWndCtrl, CB_GETCOUNT, 0, 0L));
		}
		else
		{
			if(nValue < 0 || nValue >= (int)::SendMessage(hWndCtrl, CB_GETCOUNT, 0, 0L))
			{
				ATLTRACE2(atlTraceUI, 0, "ATL: Warning - dialog data combobox value (%d) out of range.\n", nValue);
				nValue = 0;  // default to off
			}
			::SendMessage(hWndCtrl, CB_SETCURSEL, nValue, 0L);
		}
	}
};

/////////////////////////////////////////////////////////////////////////////
// WTL forgot to center a sheet...
class CCenterPropertySheet : public CPropertySheetImpl<CCenterPropertySheet>
{
public:
	bool m_bCentered;

	CCenterPropertySheet(_U_STRINGorID title = (LPCTSTR)NULL, UINT uStartPage = 0, HWND hWndParent = NULL)
		: CPropertySheetImpl<CCenterPropertySheet>(title, uStartPage, hWndParent), m_bCentered(false)
	{ }

	BEGIN_MSG_MAP(CCenterPropertySheet)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_COMMAND, CPropertySheetImpl<CCenterPropertySheet>::OnCommand)
	END_MSG_MAP()

	LRESULT OnSize(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
	{
		if (!m_bCentered) {
			// now center the property sheet
			CenterWindow(GetParent());
			m_bCentered = true;
		}

		return 0;
	}
};

/////////////////////////////////////////////////////////////////////////////
// menu helper
inline int MtlGetCmdIDFromAccessKey(CMenuHandle menu, const CString& strAccess, bool bFromBottom = true)
{
	int nID = -1;
	CString strItem;

	if (bFromBottom)
	{
		for (int i = menu.GetMenuItemCount() - 1; i >= 0 ; --i)
		{
			if (menu.GetMenuString(i, strItem, MF_BYPOSITION) == 0)
				continue;

			if (strItem.Find(strAccess) != -1) {
				nID = menu.GetMenuItemID(i);
				break;
			}
		}
	}
	else
	{
		for (int i = 0; i < menu.GetMenuItemCount(); ++i)
		{
			if (menu.GetMenuString(i, strItem, MF_BYPOSITION) == 0)
				continue;

			if (strItem.Find(strAccess) != -1) {
				nID = menu.GetMenuItemID(i);
				break;
			}
		}
	}

	return nID;
}


/////////////////////////////////////////////////////////////////////////////
}  //namespace MTL

#endif // __MTLUSER_H__

⌨️ 快捷键说明

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