| 控件间文本拖拽功能--上位机VC   控件间文本拖拽功能--上位机VC
 功能展示
 控件之间文本的拖拽可以很方便在一些时候,进行参数选项的设置,当前例程实现按钮Cbutton列表框CListBox,复选框CCheckBox,组合框CComboBox之间的文本拖拽功能,效果如图,拖拽按钮到列表控件,可将按钮文本复制到列表控件中,其他控件也一样可实现这一效果,还可将控件文本拖拽到其他程序中显示
 要点提示
 
 例程主要通过从微软类IDropTarget派生一自定义类实现interface ECOleMemDropTarget : public IDropTarget; 集成类中有四个虚函数供我们实现完成拖拽功能GotDrop() GotDrag() GotLeave() GotEnter() 
 所以这个类的使用会销麻烦些, GotDrop()用于实现拖拽放开后,控件文本的处理;GotDrag()用于拖拽过程信息的回馈 实现功能 1.新建基于对话框的应用程序 2.将集成类ECOleMemDropTarget对应两文件ECOleMemDropTarget.h, ECOleMemDropTarget.cpp复制到自己工程根目录并加载到工程,再派生一新类class ECMaterialDropText : publicECOleMemDropTarget用于实现前面四个虚函数;记得头文件中包含#include "ECOleMemDropTarget.h“ 3.实现想要有拖拽功能控件,当前例程实现3种控件的拖拽,按钮控件的拖拽实现: 从Cbutton派生新类class CButtonDragDrop : public Cbutton,包含头文件#include “ECMaterialDropText.h”,添加自定义变量及函数private: ECMaterialDropText   *m_TargetDrop;  CPoint  m_StartPoint; UINT  m_TimerID; void  InitDrag();及运行时识别宏DECLARE_DYNAMIC(CButtonDragDrop)声明 
 4.添加虚函数PreSubclassWindow()调用InitDrag();构造函数中初始化变量,析构函数中释放变量 复制代码void CButtonDragDrop::PreSubclassWindow() 
{
        InitDrag();
        CButton::PreSubclassWindow();
}
CButtonDragDrop::CButtonDragDrop()
{
        m_TargetDrop =NULL;
        m_TimerID    =0;
        m_StartPoint = CPoint(-1, -1);
        m_TargetDrop = new ECMaterialDropText();
}
CButtonDragDrop::~CButtonDragDrop()
{
        if(m_TargetDrop)
        {        
                m_TargetDrop->Revoke();//        stop drag and drop
                delete m_TargetDrop;
        }
        m_TargetDrop = NULL;
}
5.添加运行时识别宏实现IMPLEMENT_DYNAMIC(CButtonDragDrop,CButton),再分别添加鼠标点击,放开,移动,定时器处理函数 复制代码void CButtonDragDrop::OnLButtonDown(UINT nFlags, CPoint point) 
{
        m_StartPoint =         point;
        m_TimerID    = SetTimer(1, 100, NULL);
        CButton::OnLButtonDown(nFlags, point);
}
void CButtonDragDrop::OnLButtonUp(UINT nFlags, CPoint point) 
{
        m_StartPoint.x = -100;
        m_StartPoint.y = -100;
        if(m_TimerID)
        {
                KillTimer(m_TimerID);
                m_TimerID = 0;
        }
        CButton::OnLButtonUp(nFlags, point);
}
void CButtonDragDrop::OnMouseMove(UINT nFlags, CPoint point) 
{
        if(m_TimerID > 0)
        {
                if(00==(GetKeyState(VK_LBUTTON)&0XFF00) )
                {
                        OnLButtonUp(0,CPoint(0,0));
                        return;
                }
                int iX = m_StartPoint.x - point.x;
                int iY = m_StartPoint.y - point.y;
                if((iX*iX + iY*iY) > 100)//        check if we really moved enough
                {
                        COleDataSource*        pSource = new COleDataSource();
                        if(pSource)
                        {
复制代码CSharedFile        sf(GMEM_MOVEABLE|GMEM_DDESHARE|GMEM_ZEROINIT);
                                CString iText;
                                GetWindowText(iText);        
                                sf.Write(iText, iText.GetLength());//        write name to clipboard
                                HGLOBAL hMem = sf.Detach();
                                if (!hMem)   return;
                                pSource->CacheGlobalData(CF_TEXT, hMem);                
                                pSource->DoDragDrop();//        Do drag and drop!                        
                                delete pSource;
                        }
                }
        }
        CButton::OnMouseMove(nFlags, point);
}
void CButtonDragDrop::OnTimer(UINT nIDEvent) 
{        
        if(nIDEvent == 1)//        check if mouse is still in rect
        {
                POINT pt;
                ::GetCursorPos(&pt);
                CRect iRect;
                GetWindowRect(iRect);
                if(!(iRect.PtInRect(pt)))
                {
                        KillTimer(nIDEvent);
                        m_TimerID = 0;
                }
        }
        CButton::OnTimer(nIDEvent);
}
6.一样的方法实现其他想要有拖拽功能的控件,当前例程还实现有class CComboxDragDrop, CListBoxDragDrop,一样的实现过程,下面就是类ECMaterialDropText的四个虚函数的实现。 
 在类的源文件顶部包含头文件#include “gkbc8Dlg.h”#include “ButtonDragDrop.h”#include“ListBoxDragDrop.h”#include “ComboxDragDrop.h“ 分别实现四个函数体部分 复制代码DWORD ECMaterialDropText::GotDrag(void)
{
        if(m_DropTargetWnd)
        {
                CPoint iPoint      = m_DropPoint;
                CWnd *iPossibleWnd = CWnd::WindowFromPoint(iPoint);
                if(NULL == iPossibleWnd)
                        return DROPEFFECT_NONE;         
                if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CButtonDragDrop)))
                {
                        if(AfxGetMainWnd())
                        {
                                CString iRSString("Dropping on button");
                                ((CGkbc8Dlg *)AfxGetMainWnd())->UpdateNotation(iRSString);
                        }
                        return DROPEFFECT_COPY;   
                }
                else if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CListBoxDragDrop)))
                {
                        if(AfxGetMainWnd())
                        {
                                CString iRSString("Dropping on ListBox");
                                ((CGkbc8Dlg *)AfxGetMainWnd())->UpdateNotation(iRSString);
                        }
                        return DROPEFFECT_LINK;                //        something else again
                }
                else if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CComboxDragDrop)))
                {
                        if(AfxGetMainWnd())
                        {
                                CString iRSString("Dropping on Combox");
                                ((CGkbc8Dlg *)AfxGetMainWnd())->UpdateNotation(iRSString);
                        }
                        return DROPEFFECT_LINK;        
                }
        }
        return DROPEFFECT_NONE;   
}
复制代码void ECMaterialDropText::GotDrop(void)
{
        if(m_Data)
        {        
                char *iText = (char *)m_Data;//        get the text
                if((iText) && (m_DropTargetWnd))
                {
                        TRACE("Found text %s.\n", iText);
                        CPoint iPoint = m_DropPoint;
                        //        lets check if this one wants use
                        CWnd *iPossibleWnd = CWnd::WindowFromPoint(iPoint);
                        if(NULL == iPossibleWnd)
                                return;        
                        //        check if this is one of us...
                        if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CButtonDragDrop)))
                        {
                                ((CButtonDragDrop *)iPossibleWnd)->SetWindowText(iText);
                        }
                        else if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CListBoxDragDrop)))
                        {
                                ((CListBoxDragDrop *)iPossibleWnd)->AddString(iText);
                        }
                        else if(iPossibleWnd->IsKindOf(RUNTIME_CLASS(CComboxDragDrop)))
                        {
                                ((CComboxDragDrop *)iPossibleWnd)->AddString(iText);
                                ((CComboxDragDrop *)iPossibleWnd)->SetCurSel(0);
                        }
                }
        }
}
void ECMaterialDropText::GotLeave(void)
{
}
DWORD ECMaterialDropText::GotEnter(void)
{
        return DROPEFFECT_LINK;   
}
7.在主对话框中分别添加按钮,组合框,复选框,列表框分别关联前面创建的控件类,再添加一静态控件ID改为IDC_NOTATION用于显示拖拽过程的信息,添加函数UpdateNotation()实现信息显示 
 
 
 我们来演示功能实现过程 
   如果您认可,可联系功能定制! 如果您着急,充值会员可直接联系发您资料!    
 
 |