请教关于MFC下使用aero毛玻璃效果的问题

supercllc 2014-12-10 05:10:43
最近在使用aero毛玻璃效果,遇到不能理解的问题,希望能够得到解答

重现步骤
1、新建一MFC对话框程序,使用多字节字符集
2、在主窗口CPP中添加

#include <dwmapi.h>
#pragma comment (lib , "dwmapi.lib" )

在OnInitDialog中添加

MARGINS margins = {-1};
DwmExtendFrameIntoClientArea(m_hWnd, &margins);

将OnPaint函数修改为画黑色背景

void Ctestaero4Dlg::OnPaint()
{
CPaintDC dc(this);
CRect rc;
GetClientRect(&rc);
dc.FillSolidRect(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, RGB(0,0,0));
CDialogEx::OnPaint();
}

这时编译运行,窗口中的确定和取消按钮显示是不正常的
为了解决这个问题,再进行如下步骤

3、从CButton派生CMyButton类,添加link库

#pragma comment (lib , "UxTheme.lib" )

4、给确定按钮添加变量,类型为CMyButton
5、CMyButton中,响应WM_PAINT,重写OnPaint函数,重画按钮

void CMyButton::OnPaint()
{
PAINTSTRUCT ps;
HDC hdc = ::BeginPaint(m_hWnd, &ps);
if(hdc)
{
LONG_PTR dwStyle = GetWindowLongPtr(m_hWnd, GWL_STYLE);
LONG_PTR dwButtonStyle = LOWORD(dwStyle);
LONG_PTR dwButtonType = dwButtonStyle&0xF;
CRect rcClient;
VERIFY(::GetClientRect(m_hWnd, &rcClient));

if(BS_PUSHBUTTON==dwButtonType || BS_DEFPUSHBUTTON==dwButtonType)
{
HTHEME hTheme = OpenThemeData(m_hWnd, L"Button");
if(hTheme)
{
HDC hdcPaint = NULL;
BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) };
params.dwFlags = BPPF_ERASE;
HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint);
if (hdcPaint)
{
VERIFY(PatBlt(hdcPaint, 0, 0, rcClient.Width(), rcClient.Height(), BLACKNESS));

VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00));

LRESULT dwCheckState = ::SendMessage(m_hWnd, BM_GETCHECK, 0, NULL);
POINT pt;
RECT rc;
::GetWindowRect(m_hWnd, &rc);
GetCursorPos(&pt);
BOOL bHot = PtInRect(&rc, pt);
BOOL bFocus = ::GetFocus()==m_hWnd;
int iPartId = BP_PUSHBUTTON;

if(dwButtonStyle==BS_RADIOBUTTON || dwButtonStyle==BS_AUTORADIOBUTTON)
iPartId = BP_RADIOBUTTON;


int iState;

iState = PBS_NORMAL;
if (dwStyle&WS_DISABLED)
iState = PBS_DISABLED;
else
{
if(dwStyle&BS_DEFPUSHBUTTON)
iState = PBS_DEFAULTED;

if(::GetCapture()==m_hWnd && bHot)
iState = PBS_PRESSED;
else if (::GetCapture()==m_hWnd || bHot)
iState = PBS_HOT;
}

RECT rcPaint = rcClient;
VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL));


VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc));


DTTOPTS DttOpts = {sizeof(DTTOPTS)};
DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE;
DttOpts.crText = RGB(255, 255, 255);
DttOpts.iGlowSize = 12; // Default value

HFONT hFontOld = (HFONT)::SendMessage(m_hWnd, WM_GETFONT, 0L, NULL);
if(hFontOld)
hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld);
int iLen = ::GetWindowTextLength(m_hWnd);

if(iLen)
{
iLen+=5;
LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen);
if(szText)
{
iLen = ::GetWindowTextW(m_hWnd, szText, iLen);
if(iLen)
{
DWORD dwFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER;
VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint,
iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts));
}

VERIFY(!LocalFree(szText));
}
}

if (hFontOld)
{
SelectObject(hdcPaint, hFontOld);
hFontOld = NULL;
}

VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE));
}
VERIFY(S_OK==CloseThemeData(hTheme));
}
}
}

::EndPaint(m_hWnd, &ps);
}

这时问题来了,工程字符集选为多字节,按下确定按钮时,样式就不对了
但是如果是unicode字符集,按下确定时,样式正常


不知道这是什么原因,谁能给个解释吗

附:百度网盘中示例工程代码(win7,vs2010)
http://pan.baidu.com/s/1sjFL1b3

代码主要参考:
[1] http://blog.csdn.net/cometnet/article/details/6547504
[2] tortoiseSVN源码
...全文
320 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
向立天 2015-01-17
  • 打赏
  • 举报
回复
您好 我是本版版主 此帖已多日无人关注 请您及时结帖 如您认为问题没有解决可按无满意结帖处理 另外本版设置了疑难问题汇总帖 并已在版面置顶 相关规定其帖子中有说明 您可以根据规定提交您帖子的链接 如您目前不想结帖只需回帖说明 我们会删除此结帖通知 见此回复三日内无回应 我们将强制结帖 相关规定详见界面界面版关于版主结帖工作的具体办法
supercllc 2014-12-15
  • 打赏
  • 举报
回复
和设为多字节一样,有问题
引用 2 楼 Evankaka 的回复:
工程字符集改为未设置的看看
supercllc 2014-12-12
  • 打赏
  • 举报
回复
自己顶一下,防止沉了
Evankaka 2014-12-12
  • 打赏
  • 举报
回复
工程字符集改为未设置的看看

15,979

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧