首先使用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