前几天看到论坛里有个关于“如何动态改变按钮的颜色”的求助帖。这个问题我以前一直使用画刷Brush来把按钮刷成想要的颜色予以解决的。但是,看到帖子里的恢复中,有人建议使用MFC的“SendMessage(WM_CTLCOLOR)消息,然后用OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)来响应此消息并进行处理”。个人觉得可行,于是就想测试一下,可是出现问题了:当我用“SendMessage(WM_CTLCOLOR,0,0)”发送消息的时候,编译通过,但是运行时报错,提示“出现访问冲突”,如图所示。
请问:1.出错的原因究竟在哪?2.如何解决?谢谢

解决方案 »

  1.   

    问题补充:也就是说"SendMessage(WM_CTLCOLOR,0,0)"诱发运行时错误。原因?
      

  2.   

    wParam 是HDC
    lParam 是HWND你传个0给它,不出错才怪
      

  3.   


    楼上大哥,你说的方法我也试过,见下:
              CButton* pbtn = (CButton*)GetDlgItem(IDC_BUTTON1);
    CDC* pdc = pbtn->GetDC();
    HDC hdc = pdc->GetSafeHdc();//得到HDC
    HWND hwnd = GetSafeHwnd();//得到HWND
    SendMessage(WM_CTLCOLOR,(WPARAM)hdc,(LPARAM)hwnd);
    但是,问题仍然存在呀,还是提示“出现访问冲突”!
      

  4.   

    改成PostMessage试试。这个可能也有问题,主要这个DC可能是无效的。
      

  5.   

    你调用一下invalidate,看看是否ctlcolor会响应。
      

  6.   

    ::SendMessage(pbtn->getsafeHwnd(), WM_CTLCOLOR,(WPARAM)hdc,(LPARAM)hwnd);
    另外,我记得pbtn->Invalidate()也能刷新的呀
      

  7.   

    谢谢zhanshen2891的回复,问题仍然存在:
    1.sendmessage改成postmessage,效果是一样的;
    2.invalidate后,ctlcolor有响应;
    3.如果把消息发给对话框的话,代码如下:
    CWnd* pwnd = AfxGetMainWnd();
    HWND hwnd = pwnd->GetSafeHwnd();//MFC对话框程序的窗口句柄
    CDC* pdc = pwnd->GetDC();
    HDC hdc = pdc->GetSafeHdc();

    SendMessage(WM_CTLCOLOR,(WPARAM)hdc,(LPARAM)hwnd);
    呜呜呜,我就奇了怪了,以前屡试不爽的做法今天咋就行不通呢???
      

  8.   

    你用的事SDK?
    MFC中直接重载OnCtlColor即可啊
      

  9.   


    我用的是MFC对话框程序,不是SDK。
    我已经重载OnCtlColor函数了,但是我现在不去管OnCtlColor这个函数了。我现在关注的是“使用SendMessage发送WM_CTLCOLOR导致的错误,一句话:这个该死的WM_CTLCOLOR消息该如何发送呀?”
      

  10.   

    补充:这个该死的WM_CTLCOLOR消息该如何发送并保证被OnCtlColor函数截获进而予以响应?
      

  11.   

    在按钮的OnPaint里发WM_CTLCOLOR*消息给父窗口
    PAINTSTRUCT ps;
    CDC* dc = BeginPaint(&ps);HBRUSH hBrush = (HBRUSH)::SendMessage(GetParent(), WM_CTLCOLORBTN, (WPARAM)dc->GetSafeHdc(), (LPARAM)GetSafeHwnd());//再用hBrush刷出背景EndPaint(&ps);
      

  12.   

    改变按钮的颜色.需要重载CButton类,重载DrawItem虚函数吧。