客户区重绘的问题
时间:2011-12-01
来源:互联网
我写了其他的类来做绘制操作,在OnPaint中将DC传进去了
后来我发现绘制有些闪烁,因此想在OnPaint中使用双缓冲,我创建了兼容DC以及兼容位图,将兼容DC传给了绘制函数
多个区域的绘制完成后,我再将兼容DC一次性绘制到之前获得的窗口DC上。
这样的操作有问题么?我绘制的结果变成了灰色图像····很是不解
另外,当点击其他窗口,如IE,将程序覆盖,再点击最小化后,发现程序的边框等非客户区重绘了,而OnPaint()里的绘制函数却没起到作用,我也在OnSize以及WM_NCPAINT的响应里添加了Invalidate,但是都没有起到作用。
-----------------------------------------------------------
以上,两个问题,请大家帮忙!谢谢
作者: jiratao 发布时间: 2011-12-01
作者: xuddk727 发布时间: 2011-12-01
作者: onlycs 发布时间: 2011-12-01
1.不明白,2你应该在对话框自己的消息响应中去绘制。
第二个我就是在对话框的消息响应里做的
C/C++ code
LRESULT CTestFormDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) { // TODO: 在此添加专用代码和/或调用基类 LRESULT lrst = CDialog::DefWindowProc(message,wParam,lParam); //对话框类窗口过程函数 if(!IsWindow(m_hWnd)) return lrst; switch(message) { case WM_NCPAINT: case WM_NCACTIVATE: Invalidate(); //....... } //...... }
作者: jiratao 发布时间: 2011-12-01
C/C++ code
void CTestFormDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // 用于绘制的设备上下文 SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); // 使图标在工作区矩形中居中 int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // 绘制图标 dc.DrawIcon(x, y, m_hIcon); } else { ModifyStyle(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, 0); // 绘图 CDC *pWndDC = GetWindowDC(); CRect rcWnd; GetWindowRect(rcWnd); CDC MemDC; MemDC.CreateCompatibleDC(pWndDC); CBitmap MemBmp, *pOldBitmap; MemBmp.CreateCompatibleBitmap(&MemDC, rcWnd.Width(), rcWnd.Height()); pOldBitmap = MemDC.SelectObject(&MemBmp); m_border_left.OnPaintBorder(&MemDC); m_border_right.OnPaintBorder(&MemDC); m_Menubar.OnPaintMenu(&MemDC); m_MainBody.OnPaintMainBody(&MemDC); m_space.OnPaintSpace(&MemDC); m_statusbar.OnPaintFrame(&MemDC); pWndDC->BitBlt(0, m_titlebar.GetFrameRect().Height(), rcWnd.Width(), rcWnd.Height(), &MemDC, 0, 0, SRCCOPY); MemDC.SelectObject(pOldBitmap); MemDC.DeleteDC(); DeleteObject(MemBmp); //pWndDC->DeleteDC(); // 这句不注释掉程序会报错崩溃,不解 CDialog::OnPaint(); } }
作者: jiratao 发布时间: 2011-12-01
作者: onlycs 发布时间: 2011-12-01
作者: buyong 发布时间: 2011-12-01
绘制客户区应该用ClientDC,绘制非客户区才用WindowDC
我要一起绘制,边框也要覆盖的
作者: jiratao 发布时间: 2011-12-01
注释最后面的CDialog::OnPaint();
刚才试了一下,果然重绘可以了,这是什么原理呢?
但是还有个衍生问题··现在点击任务栏程序图标不能最小化了
作者: jiratao 发布时间: 2011-12-01
作者: shen_wei 发布时间: 2011-12-01
你的那个不注释掉 ,是不是每时每刻都在重绘。。。
刚好相反。。注释掉了,画面一直在刷
作者: jiratao 发布时间: 2011-12-01
作者: dream0411 发布时间: 2011-12-01
DefWindowProc其实可以不使用这个函数都可以...因为当你刷屏的时候,程序会自动发送WM_PAINT消息,当你不对这个消息进行处理的时候,程序识别到这个消息不用进行处理,于是程序就会自动去调用OnPaint这个消息响应的函数。..自然就可以实现刷屏的时候,绘制的背景还会存在,不会消失....所以呢,可以不用重载DefWindowProc这个函数去过滤/处理WM_PAINT这个消息...
作者: allen_lanyuhai 发布时间: 2011-12-01
把CDialog::OnPaint()这个放到ModifyStyle(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, 0)这个函数的前面。。就可以解决灰色屏幕..。
DefWindowProc其实可以不使用这个函数都可以...因为当你刷屏的时候,程序会自动发送WM_PAINT消息,当你不对这个消息进行处理的时候,程序识别到这个消息不用进行处理,于是程序……
改正前面的:
把CDialog::OnPaint()这个放到ModifyStyle(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, 0)这个函数的前面。。就可以解决灰色屏幕..。
DefWindowProc其实可以不使用这个函数都可以...因为当你刷屏的时候,程序就会接收到WM_PAINT消息,当你不对这个消息进行处理的时候,程序识别到这个消息不用进行处理,于是程序就会自动去调用OnPaint这个消息响应的函数。..自然就可以实现刷屏的时候,绘制的背景还会存在,不会消失....所以呢,可以不用重载DefWindowProc这个函数去过滤/处理WM_PAINT这个消息...
作者: allen_lanyuhai 发布时间: 2011-12-01
引用 12 楼 allen_lanyuhai 的回复:
把CDialog::OnPaint()这个放到ModifyStyle(WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU, 0)这个函数的前面。。就可以解决灰色屏幕..。
DefWindowProc其实可以不使用这个函数都可以...因为当你刷屏的时候,程序会自动发送WM_PAINT消息,当你不对这个消……
DefWindowProc里面的Invalidate我去掉了,然后按照你说的,放到前面,客户区的确重绘了
但是边框有点问题了··
我在绘制时本来是覆盖了边框了的,当程序窗口被其他窗口覆盖,其他窗口移出对话框后,对话框内界面按照我的代码绘制了,但是边框又重绘成系统边框了···
难道我只能在无边框属性对话框上操作了么···
作者: jiratao 发布时间: 2011-12-01
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28