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

6 篇文章 0 订阅
5 篇文章 0 订阅

        (源代码下载地址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
{
// Construction
public:
	CEScreen();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CEScreen)
	public:
	virtual BOOL PreTranslateMessage(MSG* pMsg);
	//}}AFX_VIRTUAL

// Implementation
public:

	// Generated message map functions
protected:
	//{{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,包括了消息路由和其他

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值