• 发现:在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

     

    小结

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

  • 相关阅读:
    hdu1546+spfa
    hdu1245+dij,堆优化
    hdu1669+二分多重匹配+二分
    hdu2389+二分匹配(Hopcroft-Karp算法)
    hdu3360+二分匹配(匈牙利算法)
    hdu4253 二分+MST (经典模型)
    本次项目开发的体会
    test

    结构图
  • 原文地址:https://www.cnblogs.com/pengxinglove/p/1848550.html
Copyright © 2020-2023  润新知