Mfc 使用uxtheme.dll自定义绘图按钮
我已经实现了从CButton继承的自定义按钮,并使用uxtheme.dll(DrawThemeBackground with BP_button)绘制它 一切正常,但我有两种状态(正常和按下),其中热状态是相同的。这意味着当用户将光标放在按钮上时,无论按钮状态如何(按下或未按下),都会以相同方式绘制 这对用户来说有点混乱,我想改变按钮在按下和热状态下的绘制方式。有人知道路吗 我也曾考虑过对整个绘图进行自定义,但按钮使用了渐变、边框、阴影等。因此,要实现自己绘制所有内容的相同外观和感觉并不容易。有没有办法找到dll的源代码,或者知道怎么做 提前谢谢 哈维尔Mfc 使用uxtheme.dll自定义绘图按钮,mfc,cbutton,Mfc,Cbutton,我已经实现了从CButton继承的自定义按钮,并使用uxtheme.dll(DrawThemeBackground with BP_button)绘制它 一切正常,但我有两种状态(正常和按下),其中热状态是相同的。这意味着当用户将光标放在按钮上时,无论按钮状态如何(按下或未按下),都会以相同方式绘制 这对用户来说有点混乱,我想改变按钮在按下和热状态下的绘制方式。有人知道路吗 我也曾考虑过对整个绘图进行自定义,但按钮使用了渐变、边框、阴影等。因此,要实现自己绘制所有内容的相同外观和感觉并不容易。有
注意:我想我可以通过使用CMFCButton和重写OnDraw方法来实现我想要做的事情。让控件在OnDrawBorder上绘制按钮,然后自己绘制内部按钮。但我需要知道控件在按下时是如何绘制内部按钮的。这是一个梯度,我猜不出它是怎么做到的。有人有线索吗?在回答第二个问题时,如果从
CMFCButton
而不是CButton
派生,则可以重写OnDraw()
或OnDrawText()
而不是通常的DrawItem()
。这样会绘制默认按钮背景,然后执行绘图代码。在回答第二个问题时,如果从CMFCButton
而不是CButton
派生,则可以覆盖OnDraw()
或OnDrawText()
而不是通常的DrawItem()
。这样会绘制默认按钮背景,然后执行绘图代码。我所知道的唯一解决此问题的方法是使用“自定义绘图”,而不是“所有者绘图”。Custom draw随Windows 2000提供,但仅由comctrl32 6.0的按钮控件使用(因此Windows XP以后的版本),没有非常清晰的文档记录,MFC也没有特意提供支持
无论如何,自定义绘图的好处在于,它可以让您在绘图过程中的各个点上进行连接,而不像所有者绘图,它让您处理整个事情。查看MSDN中的NM_CUSTOMDRAW通知消息
对于问题的另一部分,即检测“热”状态,最简单的方法是使用WM_MOUSEMOVE消息和TrackMouseEvent()函数跟踪鼠标是否在按钮上方
不幸的是,这是一个模糊的答案:您需要演示使用自定义绘图的按钮的代码量太多,无法在这些答案框中键入!我确实有一个项目演示了这种技术,它使用了一个自定义的绘图按钮(在旧的Windows版本上返回到所有者绘图),在按钮上添加了一个小箭头。您可以通过以下方式查看源代码:
打开它,看看“DropArrowButton”类。重要的一点是OnCustomDraw()处理程序及其辅助函数DrawControl():它们在各个按钮绘制阶段被调用,并使用UxTheme适当地绘制控件。我所知道的唯一解决此问题的方法是使用“自定义绘制”,而不是“所有者绘制”。Custom draw随Windows 2000提供,但仅由comctrl32 6.0的按钮控件使用(因此Windows XP以后的版本),没有非常清晰的文档记录,MFC也没有特意提供支持 无论如何,自定义绘图的好处在于,它可以让您在绘图过程中的各个点上进行连接,而不像所有者绘图,它让您处理整个事情。查看MSDN中的NM_CUSTOMDRAW通知消息 对于问题的另一部分,即检测“热”状态,最简单的方法是使用WM_MOUSEMOVE消息和TrackMouseEvent()函数跟踪鼠标是否在按钮上方 不幸的是,这是一个模糊的答案:您需要演示使用自定义绘图的按钮的代码量太多,无法在这些答案框中键入!我确实有一个项目演示了这种技术,它使用了一个自定义的绘图按钮(在旧的Windows版本上返回到所有者绘图),在按钮上添加了一个小箭头。您可以通过以下方式查看源代码:
打开它,看看“DropArrowButton”类。重要的一点是OnCustomDraw()处理程序及其辅助函数DrawControl():它们在各个按钮绘制阶段被调用,并使用UxTheme适当地绘制控件。我终于找到了实现我想要做的事情的方法。这确实很容易 我打了两个电话来打回背景。第一个状态为PBS_按下,第二个状态为PBS_热。然后我做一个ExcludeClipRect,以避免在按钮的中心绘制 大概是这样的:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
当然,这不是全部代码,但我认为足以说明我的观点
谢谢。我终于想出了如何实现我想做的事。这确实很容易 我打了两个电话来打回背景。第一个状态为PBS_按下,第二个状态为PBS_热。然后我做一个ExcludeClipRect,以避免在按钮的中心绘制 大概是这样的:
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_PRESSED,
&pCustomDraw->rc,
NULL);
CDC *pDC = CDC::FromHandle(pCustomDraw->hdc);
CRect rectClient;
GetClientRect(rectClient);
CRect rectInternal = rectClient;
rectInternal.DeflateRect(4,4);
pDC->SelectClipRgn(NULL);
pDC->ExcludeClipRect(&rectInternal);
DrawThemeBackground( hTheme,
pCustomDraw->hdc,
BP_PUSHBUTTON,
PBS_HOT,
&pCustomDraw->rc,
NULL);
pDC->SelectClipRgn(NULL);
当然,这不是全部代码,但我认为足以说明我的观点
谢谢。请看一下原始问题中我的注释。谢谢你的帮助。请看一下我在原始问题中的注释。谢谢你的帮助。我看过你的代码,但我不知道这是如何解决我的问题的。最后用PBS_HOT state调用DrawThemeBackground,并用金色边框(HOT state)绘制正常(未按下)按钮。我需要一种方法来绘制与