当前位置: 首页 > 图文教程 > 开发语言 > VC++ > 创建客户区窗口,列表框之间项的拖拽操作

VC++
在类VC的界面实现中加入目录树
软件换肤技术在 BCB 中的实现
利用非模窗口生成MDI介面
报表输出轻松搞定
Windows 中不规则窗体的编程实现
解说Win32的窗口子类化
使用测试优先方法开发用户界面
一个简单的登录对话框的实现
一个简单的日记本程序
从资源中加载皮肤
一个在RichEdit中添加表情图象的类
ActiveSkin 4.3 软件换肤在VC中的实现
一种另类“关于(About)”对话框的动态显示方法
对话框打印预览及打印
关于如何换肤、子类化的解决方案
制作 MSN、QQ 的消息提示窗口
如何对 BCGControlBarPro 进行换肤
定制个性化的对话框窗口类
改变窗口中的光标形状
更新MFC中的视图,跟踪.NET Framework中的事件

VC++ 中的 创建客户区窗口,列表框之间项的拖拽操作


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-30   浏览: 61 ::
收藏到网摘: n/a

C++ Q&A 专栏...
创建客户区窗口,列表框之间项的拖拽操作......

原著:Paul DiLascia
翻译:Northtibet

原代码下载:CQA0410.exe (234KB)
原文出处:MSDN Magazine October 2004 (C++ Q&A)

  1. 创建客户区窗口
  2. 列表框之间项的拖拽操作

在发送绘画(paint)消息时,系统是如何识别某个窗口的客户区或非客户区?当我用 ::CreateWindow 创建窗口时,如何指定客户区矩形?

Vipul Solanki

在创建窗口时不必指定客户区,当收到 WM_NCCALCSIZE 消息时才指定客户区。不管什么时候,只要 Windows 想知道窗口客户区的大小,它便会发送这个消息。在 MFC 中实现 OnNcCalcSize 处理例程。该处理函数有两个参数,从 WPARAM 和 LPARAM 转换而来:
void OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS* lpncsp);
  该函数告诉应用程序是否“计算有效矩形”(稍后还要讲到);NCCALCSIZE_PARAMS 结构保存三个矩形数组,第一个保存窗口的客户区。以下是实现 OnNcCalcSize 的基本模式:
// got WM_NCCALCSIZEvoid CMainFrame::OnNcCalcSize(...){	// do default thing (important!)	CFrameWnd::OnNcCalcSize(...);	CRect& rc = (CRect&)lpncsp->rgrc[0];	// adjust rc; eg, rc.DeflateRect(...);}	
  我写了一个小程序,NCCalc,它将标准客户区四周收缩7个像素并将该区域绘制成 3D 外观颜色(典型的浅灰色)。Figure 1 列出了源代码的精华部分。重要的函数是 OnNcCalcSize,它调整客户区矩形大小,OnNcPaint 绘制边界。绘制代码简单直白,我就不再赘言。具体细节请下载源代码。
  如果你改写主窗口的 WM_NCCALCSIZE/OnNcCalcSize,一定要确保调用基类的默认窗口处理例程,以便实现缺省处理。这样程序一运行便会有得到默认的客户区矩形,然后你可以调整其大小。同样,还应该在OnNcPaint/WM_NCPAINT 中调用基类默认的处理过程。否则 Windows 不会绘制边界,滚动栏或其它标准非客户区元素。如果你实现自己的窗口类,像定制工具栏或调色板,其中要计算客户区矩形并进行绘制处理,你可以不必调用基类默认的窗口过程。随便哪种方法,当窗口收到 WM_NCPAINT 消息时,你都得负责绘制整个非客户区。
  有些人可能想知道 bCalcValidRects 以及 NCCALCSIZE_PARAMS 中的其它矩形是做什么用的。如果读一下文档,你会发现 WM_NCCALCSIZE 的语义相当复杂。文档中说如果 bCalcValidRects 为 TRUE:“应用程序应该指示客户区的哪一部分包含有效的信息。系统将有效信息拷贝到新客户区中指定的区域”这种情况下,“第二个[矩形]在被移走或重新调整大小之前包含该窗口客户区的坐标”尽管所有这些描述好像够清晰,我还是不能完全把握。我也从来没有见过那个应用程序使用这些额外的矩形。我见过的应用程序都忽略 bCalcValidRects 并简单地修改第一个矩形,在 NCCALCSIZE_PARAMS 中设置客户区。
  我之所以提到这个,是因为按照文档所言,如果 WPARAM/bCalcValidRects 是 FALSE,那么 LPARAM 不会指向 NCCALCSIZE_PARAMS 结构,而是单个的 RECT,客户区,然而 MFC 在所有情况中将 LPARAM 强制转换为 NCCALCSIZE_PARAMS。这似乎是个bug,虽然只要你仅修改 NCCALCSIZE_PARAMS 中的第一个矩形,你的程序是绝不会垮掉的。我运行了一些测试程序,确定当第一次创建窗口时,Windows 仅有一次用 bCalcValidRects=FALSE 来发送 WM_NCCALCSIZE。随后,不论窗口如何调整大小,Windows 都用 bCalcValidRects=TRUE 来发送 WM_NCCALCSIZE。你必须对两种情况都设置客户区,以便正常显示你的窗口。
  唉,恐怕到现在我都没有阐明 bCalcValidRects 到底是做什么用的。微软的大佬们也没有给出足够文档来说明这个神秘的参数,只是说它是从 Windows 3.1 远古时期延续下来的。如今只要你始终对两种情况都作处理,并且只修改第一个矩形,一切都会OK。

我正在做一个商业棒球游戏程序。在我的用户界面中,我想让用户能在两个列表框之间实现拖拽操作。 MFC 有没有简单的方法来做到这一点?
Tom Tippett  
针对这种情况,MFC 没有内建的处理方法,但用两种方法可以实现你的要求。COM 有其自己的接口来处理应用程序之间常规的拖拽操作。它需