问题:基本上总是一个窗口固定为蓝色,而另一个窗口固定为红色,没有出现“明显变换”现象(变换是有的,但都是眨眼即过,按理说均有三秒的停留时间,不明白这是为什么)
// 定时器#2(使用定时器回调函数)
#include <windows.h>
UINT_PTR ID1,ID2;
HWND hwnd1,hwnd2 ;
// 定时器回调函数
VOID CALLBACK TimerProc1 (HWND, UINT, UINT, DWORD ) ;
VOID CALLBACK TimerProc2 (HWND, UINT, UINT, DWORD ) ;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Beeper2") ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("程序需要 Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd1 = CreateWindow (szAppName, TEXT ("定时器演示#2-1"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd1, iCmdShow) ;
UpdateWindow (hwnd1) ;
hwnd2 = CreateWindow (szAppName, TEXT ("定时器演示#2-2"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd2, iCmdShow) ;
UpdateWindow (hwnd2) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE: // 设置定时器
ID1 = SetTimer (NULL, 0, 3000, TimerProc1) ;
ID2 = SetTimer (NULL, 0, 3000, TimerProc2);
return 0 ;
case WM_DESTROY : // 停止定时器
KillTimer (hwnd1, ID1) ;
KillTimer (hwnd2, ID2) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
// 定时器回调函数
VOID CALLBACK TimerProc1 (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
static BOOL fFlipFlop = FALSE ;
HBRUSH hBrush ;
HDC hdc ;
RECT rc ;
MessageBeep (-1) ;
fFlipFlop = !fFlipFlop ;
GetClientRect (hwnd1, &rc) ;
hdc = GetDC (hwnd1) ;
hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) : RGB(0,0,255)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd1, hdc) ;
DeleteObject (hBrush) ;
}
VOID CALLBACK TimerProc2 (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
static BOOL TWO = TRUE ;
HBRUSH hBrush ;
HDC hdc ;
RECT rc ;
MessageBeep (-1) ;
TWO = !TWO ;
GetClientRect (hwnd2, &rc) ;
hdc = GetDC (hwnd2) ;
hBrush = CreateSolidBrush (TWO ? RGB(255,0,0) : RGB(0,0,255)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd2, hdc) ;
DeleteObject (hBrush) ;
}
运行截图:
应该是每过三秒上面的窗口和下面的窗口颜色就对换一次,可是现在上面的窗口始终是红色,下面的窗口始终是蓝色,(有变换,但都是眨一下即过,程序原意是每个状态要保持三秒,三秒一次切换,不应该这么快呀)
8 个解决方案
#1
你的程序每个窗口都创建了两个定时器!
#2
两个窗口同时用了一个注册类和同一个窗口函数,
#3
多谢二位。
#4
请问,为什么我这么改写了函数,情况还是和原来一样?
// 定时器#2(使用定时器回调函数)
#include <windows.h>
UINT_PTR ID;
HWND hwnd1,hwnd2 ;
// 定时器回调函数
VOID CALLBACK TimerProc (HWND, UINT, UINT, DWORD ) ;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Beeper2") ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("程序需要 Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd1 = CreateWindow (szAppName, TEXT ("定时器演示#2-1"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd1, iCmdShow) ;
UpdateWindow (hwnd1) ;
hwnd2 = CreateWindow (szAppName, TEXT ("定时器演示#2-2"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd2, iCmdShow) ;
UpdateWindow (hwnd2) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE: // 设置定时器
ID = SetTimer (NULL, 0, 3000, TimerProc) ;
return 0 ;
case WM_DESTROY : // 停止定时器
KillTimer (hwnd1, ID) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
// 定时器回调函数
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
static BOOL fFlipFlop = FALSE ;
HBRUSH hBrush ;
HDC hdc ;
RECT rc ;
MessageBeep (-1) ;
fFlipFlop = !fFlipFlop ;
GetClientRect (hwnd1, &rc) ;
hdc = GetDC (hwnd1) ;
hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) : RGB(0,0,255)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd1, hdc) ;
GetClientRect (hwnd2, &rc);
hdc = GetDC (hwnd2) ;
hBrush = CreateSolidBrush ( fFlipFlop ? RGB(0,0,255) : RGB(255,0,0)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd2, hdc) ;
DeleteObject (hBrush) ;
}
#5
不明白还有什么一样,如果你说过渡效果你本来就没有设计,如果说变色应该是没有问题的。但是,你这种绘制方式有问题,应该是在定时器中修改变量,刷新窗口,窗口WM_PAINT消息中根据控制变量重绘。
话说已经好几年没搞Win32了,但是你的代码还有几处问题,是不是关闭一个窗口另外一个也关了?回调函数中你创建了两次画刷却只销毁一次,存在GDI资源泄漏。
话说已经好几年没搞Win32了,但是你的代码还有几处问题,是不是关闭一个窗口另外一个也关了?回调函数中你创建了两次画刷却只销毁一次,存在GDI资源泄漏。
#6
我知道原因了,你只需要一个定时器就行了,现在两个窗口各自创建一个定时器,还是在互相修改。
#7
正好吃完饭没事干:
// 全局变量:
BOOL bFlip = FALSE;
int nTimerId = 1;
HWND hWnd1 = NULL;
HWND hWnd2 = NULL;
HBRUSH brush[2];
void CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
bFlip = !bFlip;
if (hWnd1){
InvalidateRect(hWnd1, NULL, TRUE);
}
if (hWnd2){
InvalidateRect(hWnd2, NULL, TRUE);
}
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
if (hWnd == hWnd1){
FillRect(ps.hdc, &ps.rcPaint, brush[bFlip]);
}
else
{
FillRect(ps.hdc, &ps.rcPaint, brush[!bFlip]);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
TCHAR szWindowClass[] = _T("MyWindowClass"); // 主窗口类名
// 目的: 注册窗口类。
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&wcex);
hWnd1 = CreateWindow(szWindowClass, _T("窗口一"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
hWnd2 = CreateWindow(szWindowClass, _T("窗口二"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
brush[0] = CreateSolidBrush(RGB(255, 0, 0));
brush[1] = CreateSolidBrush(RGB(0, 0, 255));
if (!hWnd1 || !hWnd2 || !brush[0] || !brush[1])
{
return FALSE;
}
ShowWindow(hWnd1, nCmdShow);
UpdateWindow(hWnd1);
ShowWindow(hWnd2, nCmdShow);
UpdateWindow(hWnd2);
SetTimer(NULL, nTimerId, 3000, TimerProc);
// 主消息循环:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
hWnd1 = NULL;
hWnd2 = NULL;
DeleteObject(brush[0]);
brush[0] = NULL;
DeleteObject(brush[1]);
brush[1] = NULL;
return (int) msg.wParam;
}
#8
学习了,版主......
#1
你的程序每个窗口都创建了两个定时器!
#2
两个窗口同时用了一个注册类和同一个窗口函数,
#3
多谢二位。
#4
请问,为什么我这么改写了函数,情况还是和原来一样?
// 定时器#2(使用定时器回调函数)
#include <windows.h>
UINT_PTR ID;
HWND hwnd1,hwnd2 ;
// 定时器回调函数
VOID CALLBACK TimerProc (HWND, UINT, UINT, DWORD ) ;
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[] = TEXT ("Beeper2") ;
MSG msg ;
WNDCLASS wndclass ;
wndclass.style = CS_HREDRAW | CS_VREDRAW ;
wndclass.lpfnWndProc = WndProc ;
wndclass.cbClsExtra = 0 ;
wndclass.cbWndExtra = 0 ;
wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
wndclass.lpszMenuName = NULL ;
wndclass.lpszClassName = szAppName ;
if (!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("程序需要 Windows NT!"),
szAppName, MB_ICONERROR) ;
return 0 ;
}
hwnd1 = CreateWindow (szAppName, TEXT ("定时器演示#2-1"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd1, iCmdShow) ;
UpdateWindow (hwnd1) ;
hwnd2 = CreateWindow (szAppName, TEXT ("定时器演示#2-2"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInstance, NULL) ;
ShowWindow (hwnd2, iCmdShow) ;
UpdateWindow (hwnd2) ;
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
return msg.wParam ;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE: // 设置定时器
ID = SetTimer (NULL, 0, 3000, TimerProc) ;
return 0 ;
case WM_DESTROY : // 停止定时器
KillTimer (hwnd1, ID) ;
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
// 定时器回调函数
VOID CALLBACK TimerProc (HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
static BOOL fFlipFlop = FALSE ;
HBRUSH hBrush ;
HDC hdc ;
RECT rc ;
MessageBeep (-1) ;
fFlipFlop = !fFlipFlop ;
GetClientRect (hwnd1, &rc) ;
hdc = GetDC (hwnd1) ;
hBrush = CreateSolidBrush (fFlipFlop ? RGB(255,0,0) : RGB(0,0,255)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd1, hdc) ;
GetClientRect (hwnd2, &rc);
hdc = GetDC (hwnd2) ;
hBrush = CreateSolidBrush ( fFlipFlop ? RGB(0,0,255) : RGB(255,0,0)) ;
FillRect (hdc, &rc, hBrush) ;
ReleaseDC (hwnd2, hdc) ;
DeleteObject (hBrush) ;
}
#5
不明白还有什么一样,如果你说过渡效果你本来就没有设计,如果说变色应该是没有问题的。但是,你这种绘制方式有问题,应该是在定时器中修改变量,刷新窗口,窗口WM_PAINT消息中根据控制变量重绘。
话说已经好几年没搞Win32了,但是你的代码还有几处问题,是不是关闭一个窗口另外一个也关了?回调函数中你创建了两次画刷却只销毁一次,存在GDI资源泄漏。
话说已经好几年没搞Win32了,但是你的代码还有几处问题,是不是关闭一个窗口另外一个也关了?回调函数中你创建了两次画刷却只销毁一次,存在GDI资源泄漏。
#6
我知道原因了,你只需要一个定时器就行了,现在两个窗口各自创建一个定时器,还是在互相修改。
#7
正好吃完饭没事干:
// 全局变量:
BOOL bFlip = FALSE;
int nTimerId = 1;
HWND hWnd1 = NULL;
HWND hWnd2 = NULL;
HBRUSH brush[2];
void CALLBACK TimerProc(HWND hwnd, UINT message, UINT iTimerID, DWORD dwTime)
{
bFlip = !bFlip;
if (hWnd1){
InvalidateRect(hWnd1, NULL, TRUE);
}
if (hWnd2){
InvalidateRect(hWnd2, NULL, TRUE);
}
}
//
// 函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// 目的: 处理主窗口的消息。
//
// WM_COMMAND - 处理应用程序菜单
// WM_PAINT - 绘制主窗口
// WM_DESTROY - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// TODO: 在此添加任意绘图代码...
if (hWnd == hWnd1){
FillRect(ps.hdc, &ps.rcPaint, brush[bFlip]);
}
else
{
FillRect(ps.hdc, &ps.rcPaint, brush[!bFlip]);
}
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
TCHAR szWindowClass[] = _T("MyWindowClass"); // 主窗口类名
// 目的: 注册窗口类。
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WIN32PROJECT1));
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
RegisterClassEx(&wcex);
hWnd1 = CreateWindow(szWindowClass, _T("窗口一"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
hWnd2 = CreateWindow(szWindowClass, _T("窗口二"), WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
brush[0] = CreateSolidBrush(RGB(255, 0, 0));
brush[1] = CreateSolidBrush(RGB(0, 0, 255));
if (!hWnd1 || !hWnd2 || !brush[0] || !brush[1])
{
return FALSE;
}
ShowWindow(hWnd1, nCmdShow);
UpdateWindow(hWnd1);
ShowWindow(hWnd2, nCmdShow);
UpdateWindow(hWnd2);
SetTimer(NULL, nTimerId, 3000, TimerProc);
// 主消息循环:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
hWnd1 = NULL;
hWnd2 = NULL;
DeleteObject(brush[0]);
brush[0] = NULL;
DeleteObject(brush[1]);
brush[1] = NULL;
return (int) msg.wParam;
}
#8
学习了,版主......