Wince中为元件注册鼠标事件以实现Canvas中的拖拽效果

来源:互联网 发布:python lambda 编辑:程序博客网 时间:2024/06/04 15:16

摘自:http://blog.csdn.net/xingjunli/archive/2010/07/30/5777226.aspx
作者:

    伴随这苹果在设计和用户体验方面取得的成功,现在越来越多的UI交互都向Touch flow方向发展,而Silverlight For Windows Embedded方案,可帮助我们快速建立和实现内涵丰富用户体验友好的软件界面UI,下面通过鼠标事件的方式实现元件的移动和拖拽的效果,我在同一个页面放了很多控件拖拉效率还可以。本示例通过动态加载图片资源,动态为图片资源设置SetRenderTransform属性实现缩放变暗及拖放效果,有关动态资源加载请参考 在Wince 中使用IXRResourceDictionary加载全局资源App.xaml !部分代码也请参考前面这篇Blog。

   1、用到的头文件:

view plaincopy to clipboardprint?
01.#include "stdafx.h"  
02.#include <xamlRuntime.h>  
03.#include <XRDelegate.h>  
04.#include <pwinuser.h>  
05.#include <xrptr.h>  
06.#include <comutil.h> 
#include "stdafx.h"
#include <xamlRuntime.h>
#include <XRDelegate.h>
#include <pwinuser.h>
#include <xrptr.h>
#include <comutil.h>

   2、设置几个全局变量来记录当前移动的元件对象,移动开始时的坐标,移动完成后的坐标,当前是处于移动状态

view plaincopy to clipboardprint?
01.IXRDependencyObject* curMoveElement; //當前選中的元件  
02.XRPoint beforePoint;     //開始鼠標點擊坐標  
03.XRPoint endPoint;     //鼠标结束坐标  
04.bool isMove =false;     //鼠标事件当前是否在拖拽图标 
IXRDependencyObject* curMoveElement; //當前選中的元件
XRPoint beforePoint;     //開始鼠標點擊坐標
XRPoint endPoint;     //鼠标结束坐标
bool isMove =false;     //鼠标事件当前是否在拖拽图标

   3、实现为元件注册RenderTransform属性的方法

view plaincopy to clipboardprint?
01./******** 為元件动态注册Transform屬性已支持移動和動態動畫功能************ 
02. element : 动态设置变换属性的元件 
03. app:当前应用程序 
04.*****************************************************************************/ 
05.bool SetElementRenderTransform(IXRFrameworkElement* element,IXRApplication* app)  
06.{  
07. if(element == NULL) return false;  
08. IXRTransformGroup* transGroup;  
09. IXRTransformCollection* transColl;  
10. 
11. IXRTranslateTransform* translate;  
12. IXRRotateTransform* rotateTrans;  
13. IXRSkewTransform* skewTrans;  
14. IXRScaleTransform* scaleTrans;  
15. 
16. if(FAILED(app->CreateObject(IID_IXRTransformGroup,&transGroup))) return false;  
17. if(FAILED(app->CreateObject(IID_IXRTransformCollection,&transColl))) return false;  
18. if(FAILED(app->CreateObject(IID_IXRTranslateTransform,&translate))) return false;  
19. if(FAILED(app->CreateObject(IID_IXRRotateTransform,&rotateTrans))) return false;  
20. if(FAILED(app->CreateObject(IID_IXRSkewTransform,&skewTrans))) return false;  
21. if(FAILED(app->CreateObject(IID_IXRScaleTransform,&scaleTrans))) return false;  
22. 
23. 
24. int *scIndex=0;  
25. transColl->Add(scaleTrans,scIndex);   
26. transColl->Add(skewTrans,scIndex);  
27. transColl->Add(rotateTrans,scIndex);  
28. transColl->Add(translate,scIndex);  
29. 
30. transGroup->SetChildren(transColl);  
31. element->SetRenderTransform(transGroup);  
32. return true;  
33.} 
/******** 為元件动态注册Transform屬性已支持移動和動態動畫功能************
 element : 动态设置变换属性的元件
 app:当前应用程序
*****************************************************************************/
bool SetElementRenderTransform(IXRFrameworkElement* element,IXRApplication* app)
{
 if(element == NULL) return false;
 IXRTransformGroup* transGroup;
 IXRTransformCollection* transColl;

 IXRTranslateTransform* translate;
 IXRRotateTransform* rotateTrans;
 IXRSkewTransform* skewTrans;
 IXRScaleTransform* scaleTrans;

 if(FAILED(app->CreateObject(IID_IXRTransformGroup,&transGroup))) return false;
 if(FAILED(app->CreateObject(IID_IXRTransformCollection,&transColl))) return false;
 if(FAILED(app->CreateObject(IID_IXRTranslateTransform,&translate))) return false;
 if(FAILED(app->CreateObject(IID_IXRRotateTransform,&rotateTrans))) return false;
 if(FAILED(app->CreateObject(IID_IXRSkewTransform,&skewTrans))) return false;
 if(FAILED(app->CreateObject(IID_IXRScaleTransform,&scaleTrans))) return false;


 int *scIndex=0;
 transColl->Add(scaleTrans,scIndex);
 transColl->Add(skewTrans,scIndex);
 transColl->Add(rotateTrans,scIndex);
 transColl->Add(translate,scIndex);

 transGroup->SetChildren(transColl);
 element->SetRenderTransform(transGroup);
 return true;
}

   4、实现为元件透明度设置、移动、缩放等功能的方法(调用些方法需要保证 步骤3已调用)这里有一个重载方法只实现移动这样做的目的为了提升效率

 
view plaincopy to clipboardprint?
01./******** 动态改变元件相关属性已实现移动,旋转等功能******************** 
02. source: 要进行变换的元件 
03. transPoint:要位移变换量 
04. angle:旋转变换量 
05. skewPoint:变形变换量 
06. scalePoint:缩放变换量 
07. alpha:元素透明度 
08.*****************************************************************************/ 
09.void SetElementTransForm(IXRDependencyObject* source,XRPoint transPoint,float angle,XRPoint skewPoint,XRPoint scalePoint,float alpha)  
10.{  
11. IXRFrameworkElement* element = (IXRFrameworkElement*)source;  
12. IXRTransform* transform;  
13. if(!FAILED(element->GetRenderTransform(&transform)))   
14. {  
15.  IXRTransformGroup* transGroup = (IXRTransformGroup*)transform;  
16.  IXRTransformCollection* transColl;  
17. 
18.  IXRTranslateTransform* translate;  
19.  IXRRotateTransform* rotateTrans;  
20.  IXRSkewTransform* skewTrans;  
21.  IXRScaleTransform* scaleTrans;  
22. 
23.  transGroup->GetChildren(&transColl);  
24.  if(!FAILED(transColl->GetItem(0,&scaleTrans)))  
25.  {  
26.   scaleTrans->SetScaleX(scalePoint.x);  
27.   scaleTrans->SetScaleY(scalePoint.x);  
28.  }  
29.  if(!FAILED(transColl->GetItem(1,&skewTrans)))  
30.  {  
31.   skewTrans->SetAngleX(skewPoint.x);  
32.   skewTrans->SetAngleY(skewPoint.y);  
33.  }  
34.  if(!FAILED(transColl->GetItem(2,&rotateTrans)))  
35.  {  
36.   rotateTrans->SetAngle(angle);  
37.  }  
38.  if(!FAILED(transColl->GetItem(3,&translate)))  
39.  {  
40.   translate->SetX(transPoint.x);  
41.   translate->SetY(transPoint.y);  
42.  }  
43.  element->SetRenderTransform(transGroup);  
44. }  
45.}  
46. 
47./******** 动态改变元件相关属性已实现移动功能***************************** 
48. source: 要进行变换的元件 
49. transPoint:要位移变换量 
50.*****************************************************************************/ 
51.void SetElementTransForm(IXRDependencyObject* source,XRPoint transPoint)  
52.{  
53. IXRFrameworkElement* element = (IXRFrameworkElement*)source;  
54. IXRTransform* transform;  
55. if(!FAILED(element->GetRenderTransform(&transform)))    
56. {  
57.  IXRTransformGroup* transGroup = (IXRTransformGroup*)transform;  
58.  IXRTransformCollection* transColl;  
59.  IXRTranslateTransform* translate;  
60.  transGroup->GetChildren(&transColl);  
61.  if(!FAILED(transColl->GetItem(3,&translate)))  
62.  {  
63.   translate->SetX(transPoint.x);  
64.   translate->SetY(transPoint.y);  
65.  }  
66.  element->SetRenderTransform(transGroup);  
67. }  
68.} 
/******** 动态改变元件相关属性已实现移动,旋转等功能********************
 source: 要进行变换的元件
 transPoint:要位移变换量
 angle:旋转变换量
 skewPoint:变形变换量
 scalePoint:缩放变换量
 alpha:元素透明度
*****************************************************************************/
void SetElementTransForm(IXRDependencyObject* source,XRPoint transPoint,float angle,XRPoint skewPoint,XRPoint scalePoint,float alpha)
{
 IXRFrameworkElement* element = (IXRFrameworkElement*)source;
 IXRTransform* transform;
 if(!FAILED(element->GetRenderTransform(&transform)))
 {
  IXRTransformGroup* transGroup = (IXRTransformGroup*)transform;
  IXRTransformCollection* transColl;

  IXRTranslateTransform* translate;
  IXRRotateTransform* rotateTrans;
  IXRSkewTransform* skewTrans;
  IXRScaleTransform* scaleTrans;

  transGroup->GetChildren(&transColl);
  if(!FAILED(transColl->GetItem(0,&scaleTrans)))
  {
   scaleTrans->SetScaleX(scalePoint.x);
   scaleTrans->SetScaleY(scalePoint.x);
  }
  if(!FAILED(transColl->GetItem(1,&skewTrans)))
  {
   skewTrans->SetAngleX(skewPoint.x);
   skewTrans->SetAngleY(skewPoint.y);
  }
  if(!FAILED(transColl->GetItem(2,&rotateTrans)))
  {
   rotateTrans->SetAngle(angle);
  }
  if(!FAILED(transColl->GetItem(3,&translate)))
  {
   translate->SetX(transPoint.x);
   translate->SetY(transPoint.y);
  }
  element->SetRenderTransform(transGroup);
 }
}

/******** 动态改变元件相关属性已实现移动功能*****************************
 source: 要进行变换的元件
 transPoint:要位移变换量
*****************************************************************************/
void SetElementTransForm(IXRDependencyObject* source,XRPoint transPoint)
{
 IXRFrameworkElement* element = (IXRFrameworkElement*)source;
 IXRTransform* transform;
 if(!FAILED(element->GetRenderTransform(&transform))) 
 {
  IXRTransformGroup* transGroup = (IXRTransformGroup*)transform;
  IXRTransformCollection* transColl;
  IXRTranslateTransform* translate;
  transGroup->GetChildren(&transColl);
  if(!FAILED(transColl->GetItem(3,&translate)))
  {
   translate->SetX(transPoint.x);
   translate->SetY(transPoint.y);
  }
  element->SetRenderTransform(transGroup);
 }
}

   5、下面三个类分别实现鼠标按下,移动,松开事件,实现移动元件的设置,坐标获取,元件移动等操作

view plaincopy to clipboardprint?
01./********鼠标按下事件设置选中元素、开始坐标、及对图片进行缩放*********/ 
02.class OnMouseDownEventHandler  
03.{  
04.public :  
05. HRESULT OnMouseDown(IXRDependencyObject* source,XRMouseButtonEventArgs* args)  
06. {  
07.  if(!FAILED(curMoveElement = args->pOriginalSource) && curMoveElement != NULL)  
08.  {  
09.   beforePoint = args->Position;  
10.   isMove = true;  
11.   XRPoint movePoint={0,0};  
12.   XRPoint skewPoint={0.6f,0.6f};  
13.   XRPoint scalePoint={0.85f,0.85f};  
14.   float x,y;  
15.   curMoveElement->GetAttachedProperty(L"Canvas.Left",&x);  
16.   curMoveElement->GetAttachedProperty(L"Canvas.Top",&y);  
17.   beforeMove.x = x;  
18.   beforeMove.y = y;  
19.   SetElementTransForm(curMoveElement,movePoint,0,skewPoint,scalePoint,0.75);  
20.  }  
21.  return 0;  
22. }  
23.};  
24. 
25./********鼠标松开事件设置元件实际移动到的坐标,取消鼠标移动事件取消缩放及透明*********/ 
26.class OnMouseUpEventHandler  
27.{  
28.public:  
29. HRESULT OnMouseUp(IXRDependencyObject* source,XRMouseButtonEventArgs* args)  
30. {  
31.  if( curMoveElement != NULL)  
32.  {  
33.   endPoint = args->Position;  
34.   if(isMove)  
35.   {  
36.    XRPoint point;  
37.    IXRFrameworkElement* element = (IXRFrameworkElement*)curMoveElement;  
38.    element->GetActualX(&point.x);  
39.    element->GetActualY(&point.y);  
40.    XRPoint movePoint={endPoint.x - beforePoint.x,endPoint.y-beforePoint.y};  
41.    XRPoint skewPoint={0,0};  
42.    XRPoint scalePoint={1,1};  
43. 
44.    element->SetAttachedProperty(L"Canvas.Left",point.x+movePoint.x);  
45.    element->SetAttachedProperty(L"Canvas.Top",point.y+movePoint.y);  
46. 
47.    movePoint.x=0;  
48.    movePoint.y=0;  
49.    SetElementTransForm(curMoveElement,movePoint,0,skewPoint,scalePoint,1.0f);  
50.    isMove = false;  
51. 
52.   }  
53.   curMoveElement= NULL;  
54.   return 0;  
55.  }  
56. }  
57. 
58.};  
59. 
60. 
61./*********************鼠标移动事件设置元件移动********************/ 
62.class OnMouseMoveEventHandler  
63.{  
64.public:  
65. HRESULT OnMouseMove(IXRDependencyObject* source,XRMouseEventArgs* args)  
66. {  
67.  if( curMoveElement != NULL && isMove)  
68.  {  
69.   endPoint = args->Position;  
70.   XRPoint movePoint={endPoint.x - beforePoint.x,endPoint.y-beforePoint.y};  
71.   SetElementTransForm(curMoveElement,movePoint);  
72.  }   
73.  return 0;  
74. }  
75. 
76.}; 
/********鼠标按下事件设置选中元素、开始坐标、及对图片进行缩放*********/
class OnMouseDownEventHandler
{
public :
 HRESULT OnMouseDown(IXRDependencyObject* source,XRMouseButtonEventArgs* args)
 {
  if(!FAILED(curMoveElement = args->pOriginalSource) && curMoveElement != NULL)
  {
   beforePoint = args->Position;
   isMove = true;
   XRPoint movePoint={0,0};
   XRPoint skewPoint={0.6f,0.6f};
   XRPoint scalePoint={0.85f,0.85f};
   float x,y;
   curMoveElement->GetAttachedProperty(L"Canvas.Left",&x);
   curMoveElement->GetAttachedProperty(L"Canvas.Top",&y);
   beforeMove.x = x;
   beforeMove.y = y;
   SetElementTransForm(curMoveElement,movePoint,0,skewPoint,scalePoint,0.75);
  }
  return 0;
 }
};

/********鼠标松开事件设置元件实际移动到的坐标,取消鼠标移动事件取消缩放及透明*********/
class OnMouseUpEventHandler
{
public:
 HRESULT OnMouseUp(IXRDependencyObject* source,XRMouseButtonEventArgs* args)
 {
  if( curMoveElement != NULL)
  {
   endPoint = args->Position;
   if(isMove)
   {
    XRPoint point;
    IXRFrameworkElement* element = (IXRFrameworkElement*)curMoveElement;
    element->GetActualX(&point.x);
    element->GetActualY(&point.y);
    XRPoint movePoint={endPoint.x - beforePoint.x,endPoint.y-beforePoint.y};
    XRPoint skewPoint={0,0};
    XRPoint scalePoint={1,1};

    element->SetAttachedProperty(L"Canvas.Left",point.x+movePoint.x);
    element->SetAttachedProperty(L"Canvas.Top",point.y+movePoint.y);

    movePoint.x=0;
    movePoint.y=0;
    SetElementTransForm(curMoveElement,movePoint,0,skewPoint,scalePoint,1.0f);
    isMove = false;

   }
   curMoveElement= NULL;
   return 0;
  }
 }

};


/*********************鼠标移动事件设置元件移动********************/
class OnMouseMoveEventHandler
{
public:
 HRESULT OnMouseMove(IXRDependencyObject* source,XRMouseEventArgs* args)
 {
  if( curMoveElement != NULL && isMove)
  {
   endPoint = args->Position;
   XRPoint movePoint={endPoint.x - beforePoint.x,endPoint.y-beforePoint.y};
   SetElementTransForm(curMoveElement,movePoint);
  }
  return 0;
 }

};

   6、为元件注册鼠标事件

view plaincopy to clipboardprint?
01./*********************为元件设置鼠标事件已支持拖放********************/ 
02.void AttachMouseEvent(IXRFrameworkElement* element)  
03.{  
04. IXRDelegate<XRMouseEventArgs>* mouseEventDelegate;  
05. IXRDelegate<XRMouseButtonEventArgs>* mouseButtonEventDelegate;  
06. OnMouseDownEventHandler mouseDownHandler;  
07. OnMouseUpEventHandler mosueupHandler;  
08. OnMouseMoveEventHandler mouseMoveHandler;  
09. 
10. if(!FAILED(CreateDelegate(&mouseDownHandler,&OnMouseDownEventHandler::OnMouseDown,&mouseButtonEventDelegate)))  
11. {  
12.  element->AddMouseLeftButtonDownEventHandler(mouseButtonEventDelegate);  
13. }  
14. 
15. if(!FAILED(CreateDelegate(&mosueupHandler,&OnMouseUpEventHandler::OnMouseUp,&mouseButtonEventDelegate)))  
16. {  
17.  element->AddMouseLeftButtonUpEventHandler(mouseButtonEventDelegate);  
18. }  
19. 
20. if(!FAILED(CreateDelegate(&mouseMoveHandler,&OnMouseMoveEventHandler::OnMouseMove,&mouseEventDelegate)))  
21. {  
22.  element->AddMouseMoveEventHandler(mouseEventDelegate);  
23. }  
24.} 
/*********************为元件设置鼠标事件已支持拖放********************/
void AttachMouseEvent(IXRFrameworkElement* element)
{
 IXRDelegate<XRMouseEventArgs>* mouseEventDelegate;
 IXRDelegate<XRMouseButtonEventArgs>* mouseButtonEventDelegate;
 OnMouseDownEventHandler mouseDownHandler;
 OnMouseUpEventHandler mosueupHandler;
 OnMouseMoveEventHandler mouseMoveHandler;

 if(!FAILED(CreateDelegate(&mouseDownHandler,&OnMouseDownEventHandler::OnMouseDown,&mouseButtonEventDelegate)))
 {
  element->AddMouseLeftButtonDownEventHandler(mouseButtonEventDelegate);
 }

 if(!FAILED(CreateDelegate(&mosueupHandler,&OnMouseUpEventHandler::OnMouseUp,&mouseButtonEventDelegate)))
 {
  element->AddMouseLeftButtonUpEventHandler(mouseButtonEventDelegate);
 }

 if(!FAILED(CreateDelegate(&mouseMoveHandler,&OnMouseMoveEventHandler::OnMouseMove,&mouseEventDelegate)))
 {
  element->AddMouseMoveEventHandler(mouseEventDelegate);
 }
}

   7、剩下的就很简单了,调用我们上面写好的方法在Main函数中动态加载png图片注册鼠标事件和RenderTransform:

view plaincopy to clipboardprint?
01.//設置圖片  
02.IXRImage* curImage;  
03.if(!FAILED(pRoot->FindName(TEXT("img2"),&curImage)))  
04.{  
05. curImage->SetSource(L"\\Storage Card\\image\\menu_1.png");  
06. SetElementRenderTransform(curImage,app);  
07. AttachMouseEvent(curImage);  
08.} 
//設置圖片
IXRImage* curImage;
if(!FAILED(pRoot->FindName(TEXT("img2"),&curImage)))
{
 curImage->SetSource(L"\\Storage Card\\image\\menu_1.png");
 SetElementRenderTransform(curImage,app);
 AttachMouseEvent(curImage);
}

   结语:应用Touch flow,鼠标事件结合手势功能应该会在选择、划屏、拖拽等事件判断,坐标换算中更准确,实际应用过程中应进行结合使用!

 

本文来自CSDN博客,转载请标明出处:

原创粉丝点击