当前位置: 代码迷 >> 软件架构设计 >> UI框架系统辨析系列4(系统适配层)
  详细解决方案

UI框架系统辨析系列4(系统适配层)

热度:9885   发布时间:2013-02-26 00:00:00.0
UI框架系统剖析系列4(系统适配层)

        (源代码下载地址http://t.cn/zW0J6lj该框架在设计之初的目标之一是做到可移植,由此带来两个问题:第一,如何在不修改代码的前提下,在不同的平台上运行基于该框架的应用程序。第二,如何让程序能在尽量多的平台上运行。要做到第一点,一般常用的方法是抽象一些通用接口,然后针对不同的平台分别实现,框架和应用程序不依赖具体平台代码,而只依赖这些通用接口,也就是常说的依赖倒置。要做到第二点,一般需要用C语言编写代码,因为目前为止还有很大一部分平台不支持C++(尤其是嵌入式平台),而C语言又难以表达面向对象思想,所以大家看到源码工程中有两个带"_C"后缀的工程(MobileDemo_C和Win32Adapter_C),这两个工程分别是将C++转换成C后的工程,方便做到更多平台的适配。在这里我们不详细介绍如何将C++代码转换成C(以后有机会再向大家介绍),而是着重介绍如何做到系统适配。

        打开Win32Adapter工程,和系统适配相关的文件主要包括以下几个:EMyUi、EScreen、EWndGc、Win32File、Win32Thread、Win32Os等,下面分别介绍。

        1.EScreen是对屏幕的抽象,比如我们的手机有显示屏,PC也有显示屏。由于是在PC中运行,这里EScreen可以看做是对硬件屏幕的一种抽象。

#include "EWndGc.h"class CEMyUi;class CEScreen : public CWnd{// Constructionpublic:	CEScreen();// Attributespublic:// Operationspublic:// Overrides	// ClassWizard generated virtual function overrides	//{{AFX_VIRTUAL(CEScreen)	public:	virtual BOOL PreTranslateMessage(MSG* pMsg);	//}}AFX_VIRTUAL// Implementationpublic:	// Generated message map functionsprotected:	//{{AFX_MSG(CEScreen)	afx_msg void OnPaint();	afx_msg void OnSize(UINT nType, int cx, int cy);	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);	afx_msg void OnSetFocus(CWnd* pOldWnd);	afx_msg void OnKillFocus(CWnd* pNewWnd);	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);	afx_msg void OnTimer(UINT nIDEvent);	afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);	//}}AFX_MSG	afx_msg LRESULT OnImeChar(WPARAM wParam, LPARAM lParam);	DECLARE_MESSAGE_MAP()public:	virtual BOOL Create(LPCTSTR lpszWindowName, const RECT& rect, CWnd* pParentWnd);	void Key(AWS_KeyType type, AWS_KeyCode code);	void SetUi(CEMyUi* pMyUi);protected:	static BOOL RegisterClass();protected:	static CString	m_strClassName;private:	CEMyUi* m_pMyUi;	CEWndGc m_oWndGc;	bool	m_bIsFirstKeyDown;	bool	m_bNoChar;};
看如上代码,CEScreen由CWnd继承而来,所以这里我们是用一个Windows窗口来模拟实际硬件屏幕。在该类的实现中会截获一些系统消息,比如按键、鼠标等消息,还有绘制消息,请看下面代码:

void CEScreen::Key(AWS_KeyType type, AWS_KeyCode code){	if ( NULL != m_pMyUi )		m_pMyUi->OnKey(type, code);}void CEScreen::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) {	// TODO: Add your message handler code here and/or call default	AWS_KeyCode code = AWS_KeyCode_Null;	switch ( nChar )	{	case VK_BACK:		code = AWS_KeyCode_Delete;		break;	case '0':		code = AWS_KeyCode_0;		break;	case '1':		code = AWS_KeyCode_1;		break;	case '2':		code = AWS_KeyCode_2;		break;	case '3':		code = AWS_KeyCode_3;		break;	case '4':		code = AWS_KeyCode_4;		break;	case '5':		code = AWS_KeyCode_5;		break;	case '6':		code = AWS_KeyCode_6;		break;	case '7':		code = AWS_KeyCode_7;		break;	case '8':		code = AWS_KeyCode_8;		break;	case '9':		code = AWS_KeyCode_9;		break;	case VK_NUMPAD0:		break;	case VK_NUMPAD1:		break;	case VK_NUMPAD2:		code = AWS_KeyCode_DownArrow;		break;	case VK_NUMPAD3:		break;	case VK_NUMPAD4:		code = AWS_KeyCode_LeftArrow;		break;	case VK_NUMPAD5:		code = AWS_KeyCode_OK;		break;	case VK_NUMPAD6:		code = AWS_KeyCode_RightArrow;		break;	case VK_NUMPAD7:		code = AWS_KeyCode_LeftMenu;		break;	case VK_NUMPAD8:		code = AWS_KeyCode_UpArrow;		break;	case VK_NUMPAD9:		code = AWS_KeyCode_RightMenu;		break;	case VK_DECIMAL:		code = AWS_KeyCode_Delete;		break;	}	if ( nChar >= VK_NUMPAD0 && nChar <= VK_DIVIDE )		m_bNoChar = true;	if ( AWS_KeyCode_Null != code && NULL != m_pMyUi )	{		if ( m_bIsFirstKeyDown )		{			m_pMyUi->OnKey(AWS_Key_Down, code);			m_pMyUi->OnKey(AWS_Key, code);			m_bIsFirstKeyDown = false;		}		else		{			m_pMyUi->OnKey(AWS_Key, code);		}	}	CWnd::OnKeyDown(nChar, nRepCnt, nFlags);}

void CEScreen::OnPaint(){	CPaintDC dc(this); // device context for painting	RECT rt;	GetWindowRect(&rt);	RECT rect = { 0 };	rect.right = rt.right - rt.left;	rect.bottom = rt.bottom - rt.top;	dc.FillSolidRect(&rect, RGB(255, 255, 255));	CEspRect ert;	ert.m_ptRB.m_nX = rect.right;	ert.m_ptRB.m_nY = rect.bottom;	TRACE0("screen paint\n");	m_pMyUi->OnDraw(ert);}

OnKeyDown函数截获了系统按键消息,然后通过m_pMyUi->OnKey(AWS_Key, code);将其传递给框架系统处理。OnPaint函数截获了系统绘制消息,通过m_pMyUi->OnDraw(ert);函数传递给框架系统处理。Key函数可以用于产生虚拟的按键消息。

        2.EMyUi是对UI的一种抽象,其父类是CAwsUi,包括了消息路由和其他

  相关解决方案