标签:style http io ar color os 使用 sp for
控件基本情况
控件本身+ CMainFrame + View
将所有的控件消息全部转发给CMainFrame来处理
BEGIN_MSG_MAP(CIECSChart)
	//CHAIN_MSG_MAP(CComControl<CIECSChart>)
	MESSAGE_HANDLER(MSG_SELECTION_CHANGED, MessageHandler)
	CHAIN_MSG_MAP(_Base)
		{
			MSG msg = { hWnd, uMsg, wParam, lParam };
			if(!CMainFrame::PreTranslateMessage(&msg))
			{
				CHAIN_MSG_MAP(CMainFrame)
			}
		}
	DEFAULT_REFLECTION_HANDLER()
END_MSG_MAP()<pre name="code" class="cpp">STDMETHOD(TranslateAccelerator)(LPMSG pMsg){/*HACCEL hAccel;hAccel = AtlLoadAccelerators(MAKEINTRESOURCE(IDR_IECSCHART));if(WM_KEYFIRST<=pMsg->message && pMsg->message <= WM_KEYLAST){if(hAccel && ::TranslateAccelerator(m_hWnd,hAccel,pMsg))return TRUE;}*/return CMainFrame::PreTranslateMessage(pMsg) ? S_OK : S_FALSE;}
BOOL CMainFrame::PreTranslateMessage(MSG* pMsg)
{
	
	/*if(pMsg->wParam == VK_DELETE)
	{
	if(m_hAccel != NULL && ::TranslateAccelerator(m_hWnd, m_hAccel, pMsg))
		return TRUE;
	}*/
	if (_Base::PreTranslateMessage(pMsg))
			return TRUE;
	if (mapView.PreTranslateMessage(pMsg))
		return TRUE;
	// allow typical message processing
	return FALSE;
}
再看一个函数:
综合以上分析应该是将消息转成COMMAND的时候失败了。
转换的时候需要一个转换表,其实就是在资源里面定义的加速键表,可以采用以下方式进行处理:
HACCEL hAccel;
		hAccel = AtlLoadAccelerators(MAKEINTRESOURCE(IDR_IECSCHART));
		if(WM_KEYFIRST<=pMsg->message && pMsg->message <= WM_KEYLAST)
		{
			if(hAccel && ::TranslateAccelerator(m_hWnd,hAccel,pMsg))
				return TRUE;
		}下面要看一下atlframe.h中的一个函数
	HWND CreateEx(HWND hWndParent = NULL, ATL::_U_RECT rect = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, LPVOID lpCreateParam = NULL)
	{
		const int cchName = 256;
		TCHAR szWindowName[cchName];
		szWindowName[0] = 0;
#ifndef _WIN32_WCE
		::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
		HMENU hMenu = ::LoadMenu(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
#else // CE specific
		::LoadString(ModuleHelper::GetResourceInstance(), T::GetWndClassInfo().m_uCommonResourceID, szWindowName, cchName);
		// This always needs to be NULL for Windows CE.
		// Frame Window menus have to go onto the CommandBar.
		// Use CreateSimpleCECommandBar
		HMENU hMenu = NULL;
#endif // _WIN32_WCE
		T* pT = static_cast<T*>(this);
		HWND hWnd = pT->Create(hWndParent, rect, szWindowName, dwStyle, dwExStyle, hMenu, lpCreateParam);
		if(hWnd != NULL)
			m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(T::GetWndClassInfo().m_uCommonResourceID));
		return hWnd;
	}这个其实是由应用程序负责调用的方法,然后CMainFrame的OnCreate被调用的时候,窗口已经创建完了,但与在应用程序里的方式不一样了,即在控件里CreateEx没有调用,也就是说m_hAccel其实是空的,那么TranslateAccelerator当然没法转了。
解决方案
分析清楚了之后,其实就是要调用一下AtlLoadAccelerators,把m_hAccel初始化一下就行了,当然最合适的地方就是OnCreate函数里:
LRESULT CMainFrame::OnCreate(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	
	if(m_hWnd != NULL)
	{
		//m_hAccel = ::LoadAccelerators(ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE(::GetWndClassInfo().m_uCommonResourceID));
		m_hAccel = AtlLoadAccelerators(MAKEINTRESOURCE(IDR_IECSCHART));
	}
	
	m_hWndClient = mapView.Create(*this, NULL, NULL, WS_CHILD | WS_VISIBLE, WS_EX_STATICEDGE);
	PostMessage(MSG_POSTCREATE);
	return 0;
}转换后,原消息是否被丢弃呢?
经测试,原消息并没有被丢弃,也就是说在CMainFrame::PreTranslateMessage中可以收到两个消息:一个是原始的VK_DELETE消息,另一个是转换后的COMMAND
基于ATL的控件中使用加速键(AtlLoadAccelerators)
标签:style http io ar color os 使用 sp for
原文地址:http://blog.csdn.net/wanglei9876/article/details/41709423