返回首页


{S0}简介
这篇文章的目的是显示自定义列表视图控件(报表视图,单行模式),使用自定义的滚动控制的机会。我希望这篇文章能帮助别人不仅仅是上网的他/她的时间花费很高兴。
控制定制的主要思想是不是作为一个创新。通常情况下,我们需要改变外观离开其内部的行为控制。
的行动计划很简单:创建动态控制(或子类的现有),并覆盖所需的消息处理程序,例如,油漆消息(所有者绘制,自定义绘制,或WM_PAINT消息)??。这取决于控制(如果它支持所需的油漆计划,使其定制更容易),我们想如何从根本上改变它。
让我们开始与滚动控制。像往常一样,我们创建标准控制(CScrollBar)遗留下来的,在我们自己的方式处理一些需要的消息。 CScrollBar控制支持既不是所有者绘制(WM_DRAWITEM),也没有自定义绘制(NM_CUSTOMDRAW)规格,所以我们不得不自己来绘制它完全(见WM_PAINT处理函数)。显然,我们需要处理的标准鼠标消息(WM_LBUTTONDOWN,WM_LBUTTONUP,WM_MOUSEMOVE),必要时更新扑通位置。要模仿标准的滚动条的行为,我们添加WM_VSCROLL请求全家人的支持(详情请参阅MSDN上)。你可以看到,标准的滚动条到它的元素重复处理它们能够处理一按。为了实现同样的功能,我们只需要设置一个定时器,当鼠标按下事件进展情况。我们也不要忘记对捕获到鼠标消息,即使鼠标光标外滚动条控制鼠标。
和一个诀窍是连接与处理的SBM_SETSCROLLINFO消息。我发现,控制接收消息时,它看起来像标准的控制,直到被称为重绘操作。所以,我被迫处理与我们自己的绘画过程的调用此通知,有需要时(取决于fRedraw标志):LRESULT CMyScrollbar::OnSetScrollInfo(UINT uMsg, WPARAM的wParam,LPARAM lParam的,BOOLamp; / * bHandled * /){ 常量布尔fRedraw =(BOOL)wParam参数; LRESULT RES = DefWindowProc(uMsg,(WPARAM)FALSE时,LPARAM); 如果(fRedraw) {  0; 无效(); } 返回水库;}
为了使自定义的滚动条控制更方便,有SetBuddy方法,允许设置一哥们窗口发送WM_VSCROLL的通知(而不是父窗口,默认情况下)。
最后认为相关的滚动条控制的资源。如果你研究的资源,你会发现,控制使用4位图显示:上部箭头(IDB_SCROLL_UP),回矩形可以移动滚动滑块(IDB_SCROLL_BACK)滚动滑块(IDB_SCROLL_THUMB)向下箭头(IDB_SCROLL_DOWN)。所以,你可以看到,有什么困难的事。
A位问题,我们得到的列表视图控件。由于我们要使用外部滚动,我们使用LVS_NOSCROLL样式。但作为一个结果,控制停止处理滚动。我们应该做些什么呢?看来,唯一的办法就是仿效处理WM_VSCROLL消息滚动。为了实现它,我决定记住当前的第一个可见行的位置和滚动时需要进行更改(见CMyListCtrl m_IndexOffset成员)。听起来很困难吗?但它最大的问题,其他的可以迎刃而解。
若要更改控件的外观,我们处理自定义绘制通知。为了支持通过键盘滚动,我们还处理来自键盘的消息。
一对夫妇的话,为什么我处理绘画中的OnPrePaint方法。如你所知,我们可以返回CDRF_NOTIFYITEMDRAW价值,获得每个项目要绘制更多的消息。问题是我们使用原来的列表视图控件的方式。正如我们拒绝LVS_NOSCROLL风格的滚动,我们工作的第一GetCountPerPage项。而每次我们得到了一个WM_PAINT消息的整个客户区,这意味着这些项目应当制定。出现问题,与选定的项目,因为它们是绝对指数重绘。这意味着,每次我们得到一个OnItemPrePaint消息,我们将无法识别哪些项目必须制定与相对指标(见dwItemSpec领域的LPNMLVCUSTOMDRAW结构)或绝对的。所以,我决定杀一杆都野兔:不关心项指数,我们需要制定,并尽可能简单(我们涂料通过一个周期的计数从的每一个项目,它是非常简单的画第一个可见的)。为了使其更加有效,我排除项目没有一个十字路口,与当前的剪贴区域(GetClipBox)。
不要忘记使用WM_MEASUREITEM消息,如果有必要改变排在列表控件的默认高度。
最后,WM_CTLCOLORXXX消息用于检索控制画笔(滚动条,列表和单选按钮)。每个控制使用它自己的的画笔,因为他们自己的特定的矩形(CreatePatternBrush系统调用的手段)创建。
你会发现有两个不同类型的项目??应用程序的桌面版和掌上电脑。您可以使用您需要更多的版本。 WTL的使用,为他们两个的代码是相同的。
我想感谢Hyungchul善,文章的作者,创建自定义的背景技术是从那篇文章完全通过。
这是今天!很好!典型的问题:我没有得到WM_MEASUREITEM消息,因此我不能改变列表的行的高度?
它可能发生,当你控制的现有实例,做子类。 WM_MEASUREITEM消息只发送一次创建时的控制。所以,当你手动创建列表视图控件时,你会得到这个消息时,它会自动创建,你会不会。事实上,我有一个导致系统重新发送一个WM_MEASUREITEM消息发送WM_WINDOWPOSCHANGED消息,但我没有足够的勇气来测试它。你可以试试,.=我的列表控件没有得到自定义绘制消息呢?
也许你已经忘记了添加REFLECT_NOTIFICATIONS对话框的消息映射宏,不是吗?我没有在WinCE WM_CTLCOLORSCROLLBAR消息?
是的,这是真的。只是,该系统不发送此消息,自定义滚动条控件(可能它是一个错误)。所以,唯一的选择就是效仿其发送WM_PAINT消息或WM_ERASEBKGND处理程序通过调用此消息.=如何显示的掌上电脑上全屏对话框?
参见MSDN中的SHInitDialog功能,并在我的代码的例子.=你为什么不使用GetCursorPos函数?
是用于Pocket PC和桌面版本一样的代码。如果您尝试在WinCE GetCursorPos,你肯定会说"的功能是不支持"的错误。因此,我们必须用我们自己的方法,知道在哪里的鼠标光标。如果你看一下代码,你会看到我的想法记住在WM_LBUTTONDOWN处理程序的光标位置,并在WM_MOUSEMOVE消息的更新.=一不留神,你不知道如何重写的编辑控制的背景WinCE平台?
一不留神,我知道:)。有一次,我发现,有没有办法迫使编辑控制,以改变它的背景(基于WinCE)??它总是白色。我尝试改变自己的行为是不成功的,直到两天无用的诅咒,我看了论坛上一个消息。有人说,编辑控件,我们必须采取行动以不同的方式"阅读MSDN和反之亦然":??)。示例代码如下:LRESULT AppDlg:OnCtlColor(UINT uMsg,WPARAM wParam参数, LPARAM lParam的,BOOLamp; bHandled){&# 160; ... ... / /确保您与编辑控制工作 & #160; 如果(... ...) { HBRUSH HBRUSH = getBkBrush(editCtrl); ::SetWindowLong函数(m_hWnd,DWL_MSGRESULT,(长)HBRUSH);  0; = TRUE; } ... ...}

回答

评论会员:Manjunathcv 时间:2011/12/07
我发现了一个更好的方式做
评论会员:Tejasp 时间:2011/12/07
我WM_MEASUREITEM消息,但是当涉及到​​wm_draw项目rectangle.botton 17默认情况下,无论身高我把。
评论会员:lroels 时间:2011/12/07
您好,

如何绘制一个ComboBox的滚动条的任何想法?
评论会员:poney 时间:2011/12/07
LRESULT CMyScrollbar::OnPaint中

UINT / * uMsg * /
WPARAM / * wParam参数* /
LPARAM / * lParam参数* /
布尔/ * bHandled * /

{
...

HBRUSH HBRUSH =(HBRUSH)::SendMessage函数

GetParent()
WM_CTLCOLORSCROLLBAR,
(WPARAM)((HDC)的DC),
(LPARAM)m_hWnd

_ASSERT(HBRUSH = NULL!)

...
}
HBRUSH总是NULL。为什么呢?

你好,我Poney | Shunix:
评论会员:游客 时间:2011/12/07
您好,您是否尝试过在自己的应用程序?要确保一切都很正确,使用调试器来检查,如果你的主对话框接收和处理WM_CTLCOLORSCROLLBAR消息(见CMainDlg::OnCtlColor消息处理程序)。当滚动条发送WM_CTLCOLORSCROLLBAR父对话框,对话框必须意识到,背景图像的一部分需要重新调整刷。检查设立CMyScrollbar在SendMessage调用之前和之后的断点::的OnPaint消息处理程序,以及在CMainDlg::OnCtlColor父对话框的消息处理程序。如果您尝试测试应用程序连接到的文章,一切都应该正常工作Win32平台和PocketPC一个。
Vincent_RICHOMME
评论会员:游客 时间:2011/12/07
不,它不需要!!!!{BR}WM5的测试上与VS2008。MyScrollbar.cppL72有一个断言:HBRUSHHBRUSH=(HBRUSH)::SendMessage函数(GetParent()WM_CTLCOLORSCROLLBAR,(WPARAM)((HDC)的DC),(LPARAM)m_hWnd)_ASSERT(HBRUSH=NULL)
zuog
评论会员:游客 时间:2011/12/07
其实我满足在Wince.Can同一troule有谁知道why.thanks很多的author.You酷
尼古拉Avrionov
评论会员:游客 时间:2011/12/07
尝试添加codepreSetWindowLong(DWL_MSGRESULT,(LONG)hBrush);/pre/codeCMainDlg::OnCtlColor处理程序返回之前的WM_CTLCOLORSCROLLBAR消息。它应有助于问题是SetWindowLong函数设置DWL_MSGRESULT值将被忽略,""在MSDN中写的是没有更多的真实。并简单地返回HBRUSH不帮助任何作者十分感谢!一个真正奇妙的样本!Voland
迪特尔锤
评论会员:游客 时间:2011/12/07
没有在所有的设计技能。
Shunix
评论会员:游客 时间:2011/12/07
我觉得认为是一个关于编程的文章,而不是关于设计。
Shunix
评论会员:游客 时间:2011/12/07
迪特,非常感谢,其实你是对的。如果有人发表了评论,例如,油漆的自定义列表控制的过程是不是最优的,因为它可能会像这样,我也不会感到惊讶......但是,如果我们对设计的发言...我不是一个设计师,我是一个程序员(至少,我尝试imgsrc=http://www.orcode.com/upimg/2011_12_07_06_29_29_1.gif)
thready
评论会员:游客 时间:2011/12/07
本文的主要目的是展示如何解决定制#8211标准控制的问题;更精确的列表视图控件和滚动控制,但不表明它可能是相当绘制。使用这种方法的人可以创造的东西,看起来更好,如果他/她的意愿(顺便说一下,你是欢迎imgsrc=http://www.orcode.com/upimg/2011_12_07_06_29_29_1.gif)。我没有对这类目标,