wince +sl 群

发现:在Silverlight for windows embedded 当中用户控件状态的改变的问题

时间:9:21 2010-10-11

 

环境:


开发环境:VS2008 +XAML2CPP.EXE + SWE 2 + BLEND 2
运行环境:WINCE 6.0 R3
硬件加速: DirectX

动机

 

       发现:在Silverlight for windows embedded 当中控件状态的改变,同时集中于同一个线程当中,效果不满意,因为其只是显示最后一个状态的界面,没有中间过程。

 

背景:

 

     在开发当中遇到下列情况:用户删除文件过程的提示,用户复制文件过程的提示。

此过程由几个阶段所构成的,初始状态,执行状态,已完成状态。且每一个阶段其均是要求的提示图标。

用户控件

      为了方便地完成任务,我们制件了一个用户控件。且定义其三种状态:初始状态,执行状态,已完成状态。

11

                                图1 提示用户的控件

 

22

                                     图2 用户控件的三种状态

 

55

                                      图3 用户控件处于初始状态

 

33

                                    图4 用户控件处于等待状态的效果图

 

44

                                        图5 用户控件处于已完成状态

 

使用此控件

    我们将此控件作为子控件嵌入到主窗口当中(如图6 所示),且在C++源代码当中命名为:uctlDeleteTipsDlg.

 

111

                                         图6 用户控件在主窗口当中作为子控件使用

2222

                                     图7 主窗口的界面

                                 

删除文件的实现

 

666              

                                       图8 实现代码

 

事件过程与效果

用户操作流程

      用户在用户控件上单击“是”按钮,系统会显示等待图标且执行业务逻辑代码。当业务逻辑代码执行完之后,显示已经完成图标。

实际效果

     当用户单击“是”按钮之后,系统没有显示等待图标,而是处于假死机状态( 界面不响不更新也不响应用户的事件)

     直到业务逻辑完成之后,才显示已完成图标。

     对于这种效果是不满足的。

 

暂时想到的解决方案

     我在主窗口当中添加了三个按钮,分别用来执行三种状态,结果是可以的。

此结果的原因是因为不同时,且不在同一个线程当中。如果只是不在同个方法当中,其结果第一次的结果是一样的。

    我的想法:将业务逻辑作为一个线程来完成。当线程完成之后通知主程序。主程序来完成显示已完成图标。

   

线程   

     silverlight for windows embedded 其没有完成对于线程的封装。所以只能自己来完成了。

      我对于线程封装的要求:其应该类似于C#当中的异常通信,用户只要创建一个线程,且可以向这个线程注册一个线程完成事件监听器,因为当线程完成之后其能够通知主程序。且不要有WIN32 API的影子,以面向对象的方式来使用,这一点与C#也类似。

 

      首先GOOGLE,codeproject, pudn,baidu. 但没有找到让我满意的结果,没有办法,只能自己来搞了。

      444

                                       图9 线程类

55555

                                 图10  线程工厂类( 代理类还更为亲切些)

#pragma once
#include <xamlruntime.h>

typedef enum ThreadStatus
{
	RUN	= 1,
	PAUSE	= 2,
	STOP	=3
};



class thread
{
public:
	
	HANDLE  handleThread;						  // 线程的句柄
	DWORD   dwThreadId;							  // 线程的标识符					
	BOOL    bThreadExit;						 
					
	ThreadStatus status;
	bool isAlive;								  // 是否创建

	thread(LPVOID pfn, LPVOID param )
	{
		Init( pfn, param);
	}

	~thread(void)
	{
	}
	

	void Init( LPVOID &pfn, LPVOID &param){
	
		// CreateThread
	 // handleThread = CreateThread( NULL, NULL,
	//	              (LPTHREAD_START_ROUTINE)pfn, 
	//				   param,
	//				  NULL, 
	//			  &dwThreadId);

	  handleThread = CreateThread( NULL, NULL,
		              (LPTHREAD_START_ROUTINE)pfn, 
					   param,
					 CREATE_SUSPENDED, 
				  &dwThreadId);

	  if( handleThread != NULL ){
		 isAlive = true;
	  }else{
		 isAlive = false;
	  }
	  
	}

public:

	HRESULT Start(){
		
		if( !isAlive ){
			return S_FALSE;
		}

		// 运行线程
		::ResumeThread( this->handleThread);
		
		return S_OK;
	}


	
protected:
	

};



class threadFactory{

public:
	
	thread * pthread;

	IXRDelegate<XREventArgs>* pThreadCompletedDelegate;


	threadFactory( LPVOID pfn, LPVOID param ){
		
		pthread = new thread( pfn,param);
		
		this->pThreadCompletedDelegate = NULL;
	}

	~threadFactory(){
	/*	delete pthread;	*/
	}

	void Start(){
		this->pthread->Start();
		
		if( this->pThreadCompletedDelegate != NULL ){
			thread temp(WaitThread,this); // 等待业务线程结束,以通知用户的线程
			temp.Start();
		}

	}
	
	void Notify(){	
		// 
		__try{
			this->pThreadCompletedDelegate->Invoke(NULL,NULL);
		
		}__except(EXCEPTION_EXECUTE_HANDLER){
			
			RETAILMSG( TRUE, (L"Exception \n"));
		
		}
		
	
	}

	template <class T, typename ArgType>
	HRESULT AddThreadCompletedListen(T* pT, HRESULT (T::*pfn)(IXRDependencyObject*, ArgType*)){
		this->pThreadCompletedDelegate = CreateDelegate(pT,pfn);

		this->pThreadCompletedDelegate->Release();
		return S_OK;
	}


	static void WaitThread( LPVOID param){
		
		threadFactory * factory = (threadFactory*)param;
	
		::WaitForSingleObject(factory->pthread->handleThread,INFINITE);

		factory->Notify();
		
		delete factory;  // 相当于自杀
	
	}


};

怎么样使用此线程


业务逻辑的代理

线程结束通知的代码

HRESULT Tips(IXRDependencyObject* source,XREventArgs* args){
        if(FAILED(this->uctlDeleteTipsDlg->GoToVisualState(L"DoneStatus",false)))

       {
            return S_FALSE;
        }

        RETAILMSG( TRUE,(L"Message: THREAD has dead --------------------  \n"));
        return S_OK;
    }

 

使用线程的效果

3333

                                    图11 准备开始

5555

                                  图12  正在执行业务逻辑

1111

                               图13  已经完成

 

使用注意事项

1. 注意去设置XRWindowCreateParams::AllowsMultipleThreadAccess 为true, 但我发现两个现象:

    A.不管设不设置其都是可以运行的。

    B. 其运行都次之后,会产生数据访问异常。

 

2.关于线程类的使用

22222

 

小结

      此思路相当的不完善,希望大家能提出想法

posted @ 2010-10-12 10:32  pengxinglove  阅读(1075)  评论(5编辑  收藏  举报
wince +sl 群