请问为什么下面的程序会出现一些区域 没有重绘 的现象(灰色的区域)?重现步骤:
运行下面程序, 最大化
运行另外一个程序,比如计算器, 移动计算器窗口
就会出现 灰色区域 (最好快速拖动计算器窗口,比较容易重现)
// vcwin32.cpp : Defines the entry point for the application.
//#include "stdafx.h"
#include "vcwin32.h"//---------------------------------------------------------------------------
#include <windows.h>
#include <winuser.h>
#include <commctrl.h>
#include <tchar.h>#include <assert.h>HINSTANCE ghInstance;// Global Instance// Prototyp WindowFunction
LRESULT CALLBACK WndProcedure (HWND hwnd, UINT msg,WPARAM w, LPARAM l);
//****************************************************************************************HWND mainWin;int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int nCmdShow)
{
//InitCommonControls();
static TCHAR szAppName[]= __TEXT("Test_WmPaint");
static TCHAR szTitleBar[]= __TEXT("Title Bar"); WNDCLASSEX wndclass;
MSG msg; // Register Class
ghInstance = hInstance; wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
wndclass.lpfnWndProc = WndProcedure;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;//LoadIcon (ghInstance, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //wndclass.hbrBackground = Null;
//wndclass.hbrBackground = CreateSolidBrush(RGB(200,0,0));
wndclass.hbrBackground = (HBRUSH)(COLOR_GRAYTEXT+1);//GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = NULL;//LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx (&wndclass)) {
MessageBox(NULL, __TEXT("Window Registration Failed!"), __TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
return -1;
} // Create Window and show Window
mainWin = CreateWindow (szAppName,
szTitleBar,
WS_OVERLAPPEDWINDOW, //WS_POPUP, //!WS_CAPTION ,
200, // x position for this window
200, // y position for this window
300, // window width
300, // window height
NULL, // parent
NULL, // menu
hInstance,
NULL); // user data if (mainWin == NULL) {
MessageBox(NULL, __TEXT("Window Creation Failed!"), __TEXT("Error!"),MB_ICONEXCLAMATION | MB_OK);
return 0;
} ShowWindow (mainWin, nCmdShow);
UpdateWindow (mainWin); // Dispatch Message or exit program
while (GetMessage (&msg, NULL, 0, 0)) {
//if(!IsDialogMessage(hwnd, &msg)){
TranslateMessage (&msg);
DispatchMessage (&msg);
//}
}
return (msg.wParam);
}//**************************************************************************HBRUSH brushes[] = {
CreateSolidBrush(RGB(100,0,0)),
CreateSolidBrush(RGB(0,160,0)),
CreateSolidBrush(RGB(0,0,255)),
};LRESULT CALLBACK WndProcedure (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
static int x=0;
assert(hWnd!=NULL);
int ret=0; HDC hdc=NULL;
//HPEN pen=NULL;
PAINTSTRUCT ps;
RECT rt;
SetRect(&rt,0,0,0,0); // init switch (wMsg) {
case WM_CREATE:
break;
case WM_LBUTTONDOWN:
return 0;
/*
hdc = GetDC(hWnd); GetClientRect(hWnd, &rt);
FillRect(hdc, &rt, brushes[0]);
ReleaseDC(hWnd, hdc);
break;
*/ case WM_PAINT:{
x++; hdc = BeginPaint(hWnd, &ps);
rt = ps.rcPaint; SetRect(&rt, 0,0,2000,2000);
//use this line can easy see which region is painted.
ret=FillRect(hdc, &rt/*&ps.rcPaint*/, brushes[x%2]);
//ret=FillRect(hdc, &ps.rcPaint, brushes[0]);
if(ret==0) {
MessageBox(mainWin, __TEXT("fill rect Error "), __TEXT("Error"), MB_OK);
} //RedrawWindow(hWnd, &ps.rcPaint, NULL, RDW_NOERASE);
EndPaint(hWnd, &ps); //GdiFlush ();
return 0;
} case WM_ERASEBKGND:
hdc = (HDC)wParam; rt.left = 0 ; rt.top = 0;
rt.right = 300; rt.bottom = 300;
ret=FillRect(hdc, &rt, brushes[2] );
return 1; case WM_DESTROY:
PostQuitMessage (0);
return (0);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
运行下面程序, 最大化
运行另外一个程序,比如计算器, 移动计算器窗口
就会出现 灰色区域 (最好快速拖动计算器窗口,比较容易重现)
// vcwin32.cpp : Defines the entry point for the application.
//#include "stdafx.h"
#include "vcwin32.h"//---------------------------------------------------------------------------
#include <windows.h>
#include <winuser.h>
#include <commctrl.h>
#include <tchar.h>#include <assert.h>HINSTANCE ghInstance;// Global Instance// Prototyp WindowFunction
LRESULT CALLBACK WndProcedure (HWND hwnd, UINT msg,WPARAM w, LPARAM l);
//****************************************************************************************HWND mainWin;int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /*hPrevInstance*/, LPTSTR /*lpCmdLine*/, int nCmdShow)
{
//InitCommonControls();
static TCHAR szAppName[]= __TEXT("Test_WmPaint");
static TCHAR szTitleBar[]= __TEXT("Title Bar"); WNDCLASSEX wndclass;
MSG msg; // Register Class
ghInstance = hInstance; wndclass.cbSize = sizeof(WNDCLASSEX);
wndclass.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS ;
wndclass.lpfnWndProc = WndProcedure;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = hInstance;
wndclass.hIcon = NULL;//LoadIcon (ghInstance, IDI_APPLICATION);
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); //wndclass.hbrBackground = Null;
//wndclass.hbrBackground = CreateSolidBrush(RGB(200,0,0));
wndclass.hbrBackground = (HBRUSH)(COLOR_GRAYTEXT+1);//GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szAppName;
wndclass.hIconSm = NULL;//LoadIcon(NULL, IDI_APPLICATION); if (!RegisterClassEx (&wndclass)) {
MessageBox(NULL, __TEXT("Window Registration Failed!"), __TEXT("Error!"), MB_ICONEXCLAMATION | MB_OK);
return -1;
} // Create Window and show Window
mainWin = CreateWindow (szAppName,
szTitleBar,
WS_OVERLAPPEDWINDOW, //WS_POPUP, //!WS_CAPTION ,
200, // x position for this window
200, // y position for this window
300, // window width
300, // window height
NULL, // parent
NULL, // menu
hInstance,
NULL); // user data if (mainWin == NULL) {
MessageBox(NULL, __TEXT("Window Creation Failed!"), __TEXT("Error!"),MB_ICONEXCLAMATION | MB_OK);
return 0;
} ShowWindow (mainWin, nCmdShow);
UpdateWindow (mainWin); // Dispatch Message or exit program
while (GetMessage (&msg, NULL, 0, 0)) {
//if(!IsDialogMessage(hwnd, &msg)){
TranslateMessage (&msg);
DispatchMessage (&msg);
//}
}
return (msg.wParam);
}//**************************************************************************HBRUSH brushes[] = {
CreateSolidBrush(RGB(100,0,0)),
CreateSolidBrush(RGB(0,160,0)),
CreateSolidBrush(RGB(0,0,255)),
};LRESULT CALLBACK WndProcedure (HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
static int x=0;
assert(hWnd!=NULL);
int ret=0; HDC hdc=NULL;
//HPEN pen=NULL;
PAINTSTRUCT ps;
RECT rt;
SetRect(&rt,0,0,0,0); // init switch (wMsg) {
case WM_CREATE:
break;
case WM_LBUTTONDOWN:
return 0;
/*
hdc = GetDC(hWnd); GetClientRect(hWnd, &rt);
FillRect(hdc, &rt, brushes[0]);
ReleaseDC(hWnd, hdc);
break;
*/ case WM_PAINT:{
x++; hdc = BeginPaint(hWnd, &ps);
rt = ps.rcPaint; SetRect(&rt, 0,0,2000,2000);
//use this line can easy see which region is painted.
ret=FillRect(hdc, &rt/*&ps.rcPaint*/, brushes[x%2]);
//ret=FillRect(hdc, &ps.rcPaint, brushes[0]);
if(ret==0) {
MessageBox(mainWin, __TEXT("fill rect Error "), __TEXT("Error"), MB_OK);
} //RedrawWindow(hWnd, &ps.rcPaint, NULL, RDW_NOERASE);
EndPaint(hWnd, &ps); //GdiFlush ();
return 0;
} case WM_ERASEBKGND:
hdc = (HDC)wParam; rt.left = 0 ; rt.top = 0;
rt.right = 300; rt.bottom = 300;
ret=FillRect(hdc, &rt, brushes[2] );
return 1; case WM_DESTROY:
PostQuitMessage (0);
return (0);
}
return DefWindowProc (hWnd, wMsg, wParam, lParam);
}
解决方案 »
- 求一个用VS2010的VC代码编写的资源管理器的源码
- vc++6.0与vc2005的区别
- Combo Box中输入的历史信息一般怎么保存
- 如何监听一个被绑定的端口?
- 完成端口的问题,为什么我分配内存给AcceptEx()参数调用后,用完后再释放内存有问题啊!
- 求有关应用程序框架方面的原理知识
- recordset unable update
- 一本C++书上面说引用不得在初始化后重新赋值,可是为什么在VC中可以?例程在里面,请大家指教!
- 求教!!!Win98下的VC程序到Win2000下怎么无法运行,但编译正常?
- 我用win32练习菜单,开始都没事,停了一次电以后,再点菜单什么都弹不出来
- 打印机监控求救
- 基于对话框程序的启动画面
hdc = (HDC)wParam;
GetClientRect(hWnd, &rt);
//rt.left = 0 ; rt.top = 0;
//rt.right = 300; rt.bottom = 300;
ret=FillRect(hdc, &rt, brushes[2] );
return 1;
2 WM_PAINT 中 BeginPaint 会自动裁剪刷新区域,因此导致不能刷新其它区域,
可以在BeginPaint前 InvalidateRect(hWnd, NULL, TRUE) 这样就会全部刷新
推荐使用双缓冲贴图的方法,还可以解决闪烁的问题
出现灰色的区域, 即 没有重绘俺还叫一个使用vista的朋友运行过, 但运行结果有点奇怪, 居然只会显示一种颜色,绿色
非常确定当时运行的是这一句:
ret=FillRect(hdc, &rt/*&ps.rcPaint*/, brushes[x%2]);
结果应该时 红色 和 绿色 交替 的呀
然道跟系统有关, 俺的系统是 xp, sp3
需要在 BeginPaint() 前调用 InvalidateRect(hWnd,NULL, TRUE),
那样相当于重绘整个窗口 , 理论上应该只用重绘:
PAINTSTRUCT.rcPaint 区域啊, 这还是最简化的窗口,
如果对每个窗口都 双缓冲, 重绘整个窗口 , 那样对性能会有影响啊
默认的aero主题不会像你想的那样去重绘。
win7下把界面主题改成Windows经典就可以测试你的程序了。
我在win7下测试了一下,没有出现你说的没有重绘的问题。
谢谢回复! 原来真的是跟 外观 设置有关啊,在 xp 上面,
如果使用 经典window 外观, 就会出现 没有 重绘的区域
如果使用 xp 样式 外观 , 就不会出现 没有 重绘的区域 ,显示的 是 交替的 红色 或 绿色如果代码是执行的是:ret=FillRect(hdc, &rt/*&ps.rcPaint*/, brushes[x%2]);
不太清楚为什么vista上只显示一种颜色,应该显示 交替的 红色 或 绿色 啊谢谢大家!