关闭

Metro C++ 初体验 第一周

2607人阅读 评论(1) 收藏 举报

闲话少说,第一周几个问题:

1 Metro下创建无焦点空间:

设置属性 IsHitTestVisible=false;

2 Metro C++加载DLL

微软专门为Metro C++ 开放了一个新API : LoadPackageLiberary();

之前必须将要dll文件添加到工程中(这个不用多说废话了吧,右键点项目名——添加现有项),右键点dll文件——属性,内容选择 是

然后按照原来Win32方法LoadPackageLiberary,GetProcessAddress即可

3 Metro读写文件

Metro不是在随便位置都可以读写文件的,只开放了相应的读写位置。我只介绍在文档库读写文件的方法。

最重要的是必须在package manifest中事先声明。每个项目管理器中都有一个manifest文件,双击打开,点击功能按钮,在功能列表中列出了你的程序需要提供的功能,也隐含着你需要被提供访问权限的位置,勾选你需要的权限很重要,否则在访问你不具备权限的位置时将引发异常。如果是想要在文档库中进行文件操作,还要事先声明添加一个文件关联的声明,在该声明中添加你需要访问的文件类型

顺便多说一句,如果你申请了过多你不需要的权限,估计将来程序上传到App Store可能会出问题。

4 Metro只允许在主线程做UI操作

当多线程编程时,不要在自己创建的线程中进行Ui操作,那样将毫无用处。所以,要想办法通知主线程去做这件事。这里特别值得注意的是ThreadPoolTimer这个定时器的机制与Win32不同,它应该是采用的中断机制,因此在中断处理程序中也不能操作UI。

5 使用CoreDispatcher进行线程间通信

紧接上一条,如果想在线程间通信,直接使用事件可能会出问题,因为你无法保证该事件处理函数是在主线程还是子线程中执行。因此习惯了Windows Message机制的朋友,可以告诉你们一个非常振奋人心的消息:使用CoreDispatcher可以达到类似的效果,具体的方法还需要你们自己去学习,我简单说一句,你首先获得当前线程的CoreDispatcher:

m_CoreDispatcher=Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher,然后使用CoreDispatcher的Invoke或者InvokeAsyn方法向当前线程发送事件,保证该事件一定是主线程处理。

具体方法,还是去学MSDN吧,我只提供一个思路。

6 同步和异步调用:

凡是名字中带有Asyn字样的方法都是可以进行异步操作方法,在C++中使用这种方法需要Concurrency空间中的task类。task类是一个模板类,提供两个重要的方法异步的then()和同步的get()。将异步方法的返回值强制转换为一个以该返回值类型为模板的task类实例,然后调用then或者get方法,才会真正执行该方法。具体的使用方法见MSDN。

这里值得一提的是:

1 then比较可靠,但是注意如果使用lamda表达式作为参数传递给then必须注意,如果要传递一个临时变量进入lamda表达式内部,必须小心它很可能在lamda表达式还未执行完成时已经失效(因为是异步执行,该临时变量作用域属于表达式外部)。

2get非常不靠谱:

我至今不知道为什么在执行get时经常会无故抛出异常,主要是std::exception异常,不过好在该异常不属于不可恢复异常,通常你可以在catch中对你的程序进行补救。因为get是连续执行一系列操作,可能前面几个操作执行成功而最后得到返回值时失败,这时你可以尝试自己执行得到返回值的操作。我有一个小窍门对待get抛出的异常,但是不值得推广,因为至今我并办法证实这种方法是否会造成恶劣影响。

我会使用while不断执行get操作,并且捕获std::exception异常和Platform::Exception^异常,直到成功为止(当然必须是针对get抛出的莫名奇妙的异常,如果时由于你代码导致的异常,必须处理),至今为止我还未发生死循环的情况,不过请慎重对待。

7 Lamda表达式

这个东西在C++中比C#中复杂的多,它的一般形式是  [](Param0 param0,Param1 param1,...){}用它来取代一个事件处理函数

delegate void MyEventHandler(Param0 param0,Param1 param1);

void Func(Param0 param0,Param1 param1,...);

ref new MyEventHandler(nullptr,Func);

 

这其中还有许多变化,由于lamda表达式是非托管的,要想使用托管类实例的成员,就要在[]中将该实例的指针传入。同时还可以在[]中传入外部变量,效果等同于在函数内部使用全局变量。

 

这一周收获非常多,先说这么多吧,脑子有点乱,想起来下次再谈。

 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:9433次
    • 积分:131
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:0篇
    • 译文:0篇
    • 评论:4条
    文章分类
    文章存档
    最新评论