VC创建客户区窗口、列表框之间项的拖拽操作
2007-11-01 20:24:24 来源:WEB开发网我正在做一个商业棒球游戏程序。在我的用户界面中,我想让用户能在两个列表框之间实现拖拽操作。 MFC 有没有简单的方法来做到这一点?
针对这种情况,MFC 没有内建的处理方法,但用两种方法可以实现你的要求。COM 有其自己的接口来处理应用程序之间常规的拖拽操作。它需要实现几个接口:IDropTarget,IDropSource 和 IDataObject,此外还有一个函数,DoDragDrop 实现具体的拖拽操作。使用 COM 来实现拖拽操作需要编写大量的代码,这样有可能超出了能力所及。再说使用 COM 来实现这个功能也有些夸张,因为 COM 本身是专门设计用来以更一般的方式实现应用程序之间的交互。如果你仅仅是想在应用程序中将一个项目从一个控件拖拽到另一个控件,那么自己编写代码来的更简单和容易。
我写了一个小类库,其中包含一个类,CDragDropMgr,用这个类可以在自己的应用程序窗口间添加拖拽行为。我还写了一个测试程序,DDTest,示范了如何使用 CDragDropMgr 类(参见 Figure 2)。Figure 3 是程序运行的画面。DDTest 有两个列表框和一个编辑框。你可以将第一个列表框中的项目拖拽到第二个列表框,或者编辑框。此外,你还能在第二个列表框里通过拖拽重排项目。DDTest 就是使用 CDragDropMgr 来实现上述这些功能的。下面我首先示范如何使用 CDragDropMgr,然后在探讨它的工作原理。
Figure 3 运行中的 DDTest
为了使用拖拽管理器,首先要在主窗口或对话框中实例化 CDragDropMgr,然后用一个表对之进行初始化,就像下面的代码这样:
static DRAGDROPWND MyDragDropWindows[] = {
{ IDC_LIST1, DDW_SOURCE },
{ IDC_LIST2, DDW_SOURCE|DDW_TARGET },
{ IDC_EDIT1, DDW_TARGET },
{ 0, 0 },
};
m_ddm.Install(this, MyDragDropWindows);
我的专栏的爱好者们知道我编程的五大秘诀之一便是 一张表胜过一千行代码。表的形式比长长的一串过程代码更加简练、优雅、可靠和可维护。在本文的例子中,表告诉拖拽管理器哪个子窗口是拖拽操作的源和/或目标。每一个表入口都有一个子窗口ID以及一个 DDW_SOURCE 和 DDW_TARGET 的组合标志。在 DDTest 中,第一个列表框是源,第二个列表框既可以是源,也可以是目标,编辑框只能是目标。但是不管怎么样,不要忘了在表的末尾加上 NULL!
一旦你用窗口表对拖拽管理器进行了初始化,下一步便是改写主窗口的 PreTranslateMessage 函数以便将消息传递给拖拽管理器:
BOOL CMyDlg::PreTranslateMessage(MSG* pMsg)
{
return m_ddm.PreTranslateMessage(pMsg) ? TRUE :
CDialog::PreTranslateMessage(pMsg);
}
一切准备就绪,当用户试图从一个窗口到另一个窗口实施拖拽操作时,拖拽管理器便会察觉到并通知应用程序要做相应的处理。CDragDropMgr 可以发送四个消息/通知:WM_DD_DRAGENTER、WM_DD_DRAGOVER、WM_DD_ DRAGDROP 和 WM_DD_DRAGABORT。收到这些消息/通知后,做什么样的处理由你来决定。WM_DD_DRAGENTER 和 WM_DD_DRAGDROP 是拖拽操作必须要做的处理。其它两个可选。WM_DD_DRAGABORT 用来处理用户取消操作时的清除工作。WM_DD_ DRAGOVER 使你能够在用户实施拖拽操作而移动鼠标时进行连续不断的处理。DDTest 这样简单的程序不需要处理这些消息。
更多精彩
赞助商链接