当前位置: 首页 > 工具软件 > SoUI > 使用案例 >

SOUI中心事件的使用实例

吴品
2023-12-01

首先使用SOUI的向导建立一个工程

需要注意以下几点:

首先要包含 notifycenter.h这个头文件,这个头文件工程默认是不会添加的,验证方法使用SNotifyCenter在程序的任何一个地方会出现红色的下划线表示没有包含

常规普通模式下的中心事件 作用在目标窗口上的,注意目标窗口需要继承public TAutoEventMapReg<类名> 这样就可以自动注册这个事件中心

两种常规的处理方式(消息映射方式)

1.EVENT_HANDLER(cd,func) //cd:表示事件的ID func:处理事件的函数

2.EVENT_NAME_HANDLER(id,cd,func) //id:表示该条中心消息事件的ID(定义在调用方那边的头文件中) cd:表示事件的ID func:处理事件的函数

 

下面开始实际的例子 使用中心事件中的 异步通讯方式 和 同步通讯方式

需求:在子窗口中点击按钮,使主窗口的控件得到一个变化

实现步骤:

Step 1: 首先包含notifycenter.h头文件 包含在 stdafx.h中这样就可以整个工程使用 SNotifycenter了,然后在工程的入口函数中 添加 

SNotifyCenter *pNotifycenter = new SNotifyCenter;        //添加的部分
		// BLOCK: Run application
		{
			CMainDlg dlgMain;
			dlgMain.Create(GetActiveWindow());
			dlgMain.SendMessage(WM_INITDIALOG);
			dlgMain.CenterWindow(dlgMain.m_hWnd);
			dlgMain.ShowWindow(SW_SHOWNORMAL);
			nRet = theApp->Run(dlgMain.m_hWnd);
		}

		delete pNotifycenter;      //添加的部分
		// BLOCK: Run application
		{
			CMainDlg dlgMain;
			dlgMain.Create(GetActiveWindow());
			dlgMain.SendMessage(WM_INITDIALOG);
			dlgMain.CenterWindow(dlgMain.m_hWnd);
			dlgMain.ShowWindow(SW_SHOWNORMAL);
			nRet = theApp->Run(dlgMain.m_hWnd);
		}

		delete pNotifycenter;

黄色的部分,进行添加

Step 2: 创建一个模态对话框需要注意以下问题

    -》创建的窗口继承的类是 SHostDialog这个类,并且在构造函数中进行XML文件的初始化

    -》在需要创建窗口的地方 使用类的对象来调用DoModal就可以实现一个模态窗口的创建了,具体的属性设置,可以参照主窗口的XML文件配置

Step 3: 来编写需要创建事件的一个类 来测试使用同步或异步事件

//创建一个类 来包含自定义的事件
namespace SOUI
{
#define EVT_TESTEVENT EVT_EXTERNAL_BEGIN + 1
	class TestEvent :public TplEventArgs<TestEvent>
	{
		SOUI_CLASS_NAME(TestEvent, L"on_event_test")
	public:
		TestEvent(SObject *pSender) :TplEventArgs<TestEvent>(pSender) {}
		enum {EventID = EVT_TESTEVENT};
	};
}

//使用自定义的事件来进行同步或异步操作
void TestDlg::OnClickSynchronizationEvent_btn()
{
	//SMessageBox(NULL, L"同步JamesWu9527", L"", MB_OK);
	TestEvent pEvt(this);
	SNotifyCenter::getSingleton().addEvent(EVENTID(TestEvent));	//注册
	SNotifyCenter::getSingleton().FireEventSync(&pEvt);	//同步通讯
}

void TestDlg::OnClickAsynchronousEvent_btn()
{
	//SMessageBox(NULL, L"异步JamesWu9527", L"", MB_OK);
	//使用异步通讯 必须在堆栈上进行内存的分配,用完记得释放
	TestEvent *pEvt = new TestEvent(this);
	SNotifyCenter::getSingleton().addEvent(EVENTID(TestEvent));	//注册
	SNotifyCenter::getSingleton().FireEventSync(pEvt);	//异步通讯
	pEvt->Release();
}

Step 4:在主窗口中定义消息映射事件 两种方式,一种是带ID的 一种是不带ID的,这里例子使用带ID的来进行操作,所以还需要在子窗口的类中进行GetID的重写 virtual int GetID() const {return 9527;} 这样就表示这个子窗口的ID就是9527了 有一个固定的窗口ID和其他的窗口消息事件进行区分

在主窗口定义消息映射 在EVENT_MAP_BEGIN() 和  EVENT_MAP_END() 中间进行定义

EVENT_ID_HANDLER(TestDlg::TEST_DLG_ID, EVT_TESTEVENT,OnNotifyCenterFun)

也需要注意OnNotifyCenterFun的定义 void OnNotifyCenterFun(EventArgs *pEvt);

实现:

SEdit *pEdit = FindChildByName2<SEdit>(L"showresult");
	SASSERT(pEdit);
	pEdit->SetWindowTextW(L"响应事件成功");

实现效果,在子窗口点击按钮 在主窗口的编辑框内 就出现了 “响应事件成功”

 

小结:

需要注意两点即可

1.需要添加头文件Notifycenter.h文件 这个文件在SOUI的目录下可以找到,并且在程序入口函数中需要进行新建一个SNotifycenter的对象 并且在程序结束后 释放之~

2.注意需要接受中心事件的目标窗口需要继承public TAutoEventMapReg<类名> 这里我的类名是CMainDlg

3.同步和异步事件的处理顺序一定都是 创建一个对象堆或者栈(同步都可以,异步只能在堆上分配内存)-》注册事件-》触发事件

拓展:

使用不带ID的就使用下面的消息映射

EVENT_HANDLER(cd,func) //cd:表示事件的ID func:处理事件的函数

参考:http://www.cnblogs.com/setoutsoft/p/5642056.html

参考:https://blog.csdn.net/ceffans/article/details/78403910

 

 

 

 类似资料: