Winapi C++;win32 API窗口赢得';在WindowUpdate上更新
我有一个程序,应该显示每秒递增的计数。计数器位于单独的线程中。当发生更改时,我调用WindowUpdate,但除非将鼠标指针悬停在窗口上或调整窗口大小,否则窗口中的计数不会更新。我试过竖立和重画窗口,但它们也不起作用 为什么不显示计数器更新Winapi C++;win32 API窗口赢得';在WindowUpdate上更新,winapi,visual-c++,Winapi,Visual C++,我有一个程序,应该显示每秒递增的计数。计数器位于单独的线程中。当发生更改时,我调用WindowUpdate,但除非将鼠标指针悬停在窗口上或调整窗口大小,否则窗口中的计数不会更新。我试过竖立和重画窗口,但它们也不起作用 为什么不显示计数器更新 #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #include <sdkddkver.h> #include <Wind
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <sdkddkver.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <strsafe.h>
typedef struct DataTransfer {
BOOL Updated;
int Counter;
} TRANSFER, *PTRANSFER;
TRANSFER Payload;
PTRANSFER pPayload;
DWORD dwThreadId;
HANDLE hThread;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DisplayData(HDC hDC);
void ErrorHandler(LPTSTR lpszFunction);
DWORD WINAPI Counter(LPVOID lpParam);
int
APIENTRY
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd)
{
MSG msg;
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpszClassName = TEXT("MYFIRSTWINDOWCLASS");
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(hInstance, IDC_ARROW);
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
if (!RegisterClassEx(&wcex))
return 1;
CREATESTRUCT cs;
ZeroMemory(&cs, sizeof(cs));
cs.x = 0;
cs.y = 0;
cs.cx = 200;
cs.cy = 300;
cs.hInstance = hInstance;
cs.lpszClass = wcex.lpszClassName;
cs.lpszName = TEXT("Test");
cs.style = WS_OVERLAPPEDWINDOW;
HWND hWnd = ::CreateWindowEx(
cs.dwExStyle,
cs.lpszClass,
cs.lpszName,
cs.style,
cs.x,
cs.y,
cs.cx,
cs.cy,
cs.hwndParent,
cs.hMenu,
cs.hInstance,
cs.lpCreateParams);
if (!hWnd)
return 1;
DWORD dwThreadId;
HANDLE hThread;
pPayload = (PTRANSFER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TRANSFER));
if (pPayload == NULL)
ExitProcess(2);
pPayload->Updated = FALSE;
pPayload->Counter = 0;
// Display the window.
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
hThread = CreateThread(
NULL,
0,
Counter,
pPayload,
0,
&dwThreadId);
if (hThread == NULL)
ExitProcess(2);
while (1)
{
if (pPayload->Updated == TRUE)
{
// InvalidateRect(hWnd, NULL, FALSE);
// RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
UpdateWindow(hWnd);
}
if (GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
::UnregisterClass(wcex.lpszClassName, hInstance);
return (int)msg.wParam;
}
LRESULT
CALLBACK
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDC;
switch (uMsg)
{
case WM_DESTROY:
::PostQuitMessage(0);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &paintStruct);
DisplayData(hDC);
EndPaint(hWnd, &paintStruct);
return 0;
break;
default:
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void DisplayData(HDC hDC)
{
char OutputStr[32];
sprintf_s(OutputStr, sizeof(OutputStr) - 1, "%d", pPayload->Counter);
TextOut(hDC, 100, 100, OutputStr, strlen(OutputStr));
}
DWORD WINAPI Counter(LPVOID lpParam)
{
PTRANSFER pTransfer;
pTransfer = (PTRANSFER)lpParam;
while (1)
{
pTransfer->Counter++;
pTransfer->Updated = TRUE;
Sleep(1000);
}
}
void ErrorHandler(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
\ifndef WIN32\u LEAN\u和\u MEAN
#定义WIN32_精益_和_平均值
#恩迪夫
#包括
#包括
#包括
#包括
#包括
#包括
typedef结构数据传输{
布尔更新;
整数计数器;
}转让,*转让;
转移有效载荷;
p转移pPayload;
德沃德·德维德;
处理hThread;
LRESULT回调WndProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM);
无效显示数据(HDC HDC);
void ErrorHandler(LPTSTR lpsz函数);
DWORD WINAPI计数器(LPVOID lpParam);
int
蜂房
温曼(
HINSTANCE HINSTANCE,
HINSTANCE HPPrevenstance,
LPWSTR lpCmdLine,
int nShowCmd)
{
味精;
WNDCLASSEX wcex;
零内存(&wcex,sizeof(wcex));
wcex.cbSize=sizeof(wcex);
wcex.style=CS_HREDRAW | CS_VREDRAW;
wcex.lpszClassName=文本(“MYFIRSTWINDOWCLASS”);
wcex.hbrBackground=(HBRUSH)(彩色窗口+1);
wcex.hCursor=LoadCursor(hInstance,IDC_箭头);
wcex.lpfnWndProc=WndProc;
wcex.hInstance=hInstance;
如果(!RegisterClassEx(&wcex))
返回1;
CREATESTRUCT-cs;
零内存(&cs,sizeof(cs));
cs.x=0;
cs.y=0;
cs.cx=200;
cs.cy=300;
cs.hInstance=hInstance;
cs.lpszClass=wcex.lpszClassName;
cs.lpszName=文本(“测试”);
cs.style=WS_重叠窗口;
HWND HWND=::CreateWindowEx(
cs.dwExStyle,
cs.lpszClass,
cs.lpszName,
cs风格,
cs.x,
政务司司长,,
政务司司长,
政务司司长,
政务司司长,
政务司司长,,
政务司司长,
cs.lps);
如果(!hWnd)
返回1;
德沃德·德维德;
处理hThread;
pPayload=(ptTransfer)HeapAlloc(GetProcessHeap(),HEAP_ZERO_内存,sizeof(TRANSFER));
if(pPayload==NULL)
出境过程(2);
pPayload->Updated=FALSE;
pPayload->计数器=0;
//显示窗口。
显示窗口(hWnd、SW_显示默认值);
更新窗口(hWnd);
hThread=CreateThread(
无效的
0,
柜台
帕洛德,
0,
&dwid);
if(hThread==NULL)
出境过程(2);
而(1)
{
如果(pPayload->Updated==TRUE)
{
//无效(hWnd、NULL、FALSE);
//重画窗口(hWnd,NULL,NULL,RDW_INVALIDATE | RDW_UPDATENOW);
更新窗口(hWnd);
}
if(GetMessage(&msg,NULL,0,0)>0)
{
翻译信息(&msg);
发送消息(&msg);
}
}
::取消注册类(wcex.lpszClassName,hInstance);
返回(int)msg.wParam;
}
勒索
回拨
WndProc(HWND HWND、UINT uMsg、WPARAM WPARAM、LPARAM LPARAM)
{
PAINTSTRUCT PAINTSTRUCT;
HDC-HDC;
开关(uMsg)
{
案例WM_销毁:
::PostQuitMessage(0);
打破
案例WM_油漆:
hDC=开始修复(hWnd和paintStruct);
显示数据(hDC);
EndPaint(hWnd和paintStruct);
返回0;
打破
违约:
return::DefWindowProc(hWnd、uMsg、wParam、lParam);
}
返回0;
}
无效显示数据(HDC HDC)
{
charoutputstr[32];
sprintf_s(OutputStr,sizeof(OutputStr)-1,“%d”,pPayload->Counter);
TextOut(hDC,100100,OutputStr,strlen(OutputStr));
}
DWORD WINAPI计数器(LPVOID lpParam)
{
转移转移;
pTransfer=(pTransfer)lpParam;
而(1)
{
p传输->计数器++;
p传输->更新=真;
睡眠(1000);
}
}
无效错误处理程序(LPTSTR LPSZ函数)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw=GetLastError();
格式化消息(
格式化\u消息\u分配\u缓冲区|
格式化来自\u系统的\u消息\u|
格式化\u消息\u忽略\u插入,
无效的
dw,
MAKELANGID(LANG_中立,SUBLANG_默认),
(LPTSTR)和lpMsgBuf,
0,空);
lpDisplayBuf=(LPVOID)LocalAlloc(LMEM_zeronit,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf)/sizeof(TCHAR),
文本(“%s失败,错误为%d:%s”),
lpsz函数、dw、lpMsgBuf);
消息框(空,(LPCTSTR)lpDisplayBuf,文本(“错误”),MB_OK);
本地免费(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
我用注释计数器++标记了我的更改;
无效设置(pttransfer->hWnd,NULL,1);
睡眠(1000);
}
}
无效错误处理程序(LPTSTR LPSZ函数)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw=GetLastError();
格式化消息(
格式化\u消息\u分配\u缓冲区|
格式化来自\u系统的\u消息\u|
格式化\u消息\u忽略\u插入,
无效的
dw,
MAKELANGID(LANG_中立,SUBLANG_默认),
(LPTSTR)和lpMsgBuf,
0,空);
lpDisplayBuf=(LPVOID)LocalAlloc(LMEM_zeronit,
(lstrlen((LPCTSTR)lpMsgBuf)+lstrlen((LPCTSTR)lpszFunction)+40)*sizeo
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <sdkddkver.h>
#include <Windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <tchar.h>
#include <strsafe.h>
typedef struct DataTransfer {
//BOOL Updated; // << updated
int Counter;
HWND hWnd; // << updated
} TRANSFER, *PTRANSFER;
TRANSFER Payload;
PTRANSFER pPayload;
DWORD dwThreadId;
HANDLE hThread;
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
void DisplayData(HDC hDC);
void ErrorHandler(LPTSTR lpszFunction);
DWORD WINAPI Counter(LPVOID lpParam);
int
APIENTRY
wWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int nShowCmd)
{
MSG msg;
WNDCLASSEX wcex;
ZeroMemory(&wcex, sizeof(wcex));
wcex.cbSize = sizeof(wcex);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpszClassName = TEXT("MYFIRSTWINDOWCLASS");
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); //<< updated
wcex.lpfnWndProc = WndProc;
wcex.hInstance = hInstance;
if (!RegisterClassEx(&wcex))
return 1;
CREATESTRUCT cs;
ZeroMemory(&cs, sizeof(cs));
cs.x = 0;
cs.y = 0;
cs.cx = 200;
cs.cy = 300;
cs.hInstance = hInstance;
cs.lpszClass = wcex.lpszClassName;
cs.lpszName = TEXT("Test");
cs.style = WS_OVERLAPPEDWINDOW;
HWND hWnd = CreateWindowEx(
cs.dwExStyle,
cs.lpszClass,
cs.lpszName,
cs.style,
cs.x,
cs.y,
cs.cx,
cs.cy,
cs.hwndParent,
cs.hMenu,
cs.hInstance,
cs.lpCreateParams);
if (!hWnd)
return 1;
DWORD dwThreadId;
HANDLE hThread;
pPayload = (PTRANSFER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(TRANSFER));
if (pPayload == NULL)
ExitProcess(2);
//pPayload->Updated = FALSE; //<< updated
pPayload->hWnd=hWnd;
pPayload->Counter = 0;
// Display the window.
ShowWindow(hWnd, SW_SHOWDEFAULT);
UpdateWindow(hWnd);
hThread = CreateThread( NULL, 0, Counter, pPayload, 0, &dwThreadId);
if (hThread == NULL)
ExitProcess(2);
while (1)
{
// ____[ updated ]_____
/*
if (pPayload->Updated == TRUE)
{
UpdateWindow(hWnd);
pPayload->Updated=FALSE;
}
*/
int ret=GetMessage(&msg, NULL, 0, 0);//<< updated
if(ret==0 || ret==-1)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnregisterClass(wcex.lpszClassName, hInstance);
return (int)msg.wParam;
}
LRESULT
CALLBACK
WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
HDC hDC;
switch (uMsg)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_PAINT:
hDC = BeginPaint(hWnd, &paintStruct);
DisplayData(hDC);
EndPaint(hWnd, &paintStruct);
break;
default:
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}
void DisplayData(HDC hDC)
{
char OutputStr[32];
sprintf_s(OutputStr, sizeof(OutputStr) - 1, "%d", pPayload->Counter);
TextOut(hDC, 100, 100, OutputStr, strlen(OutputStr));
}
DWORD WINAPI Counter(LPVOID lpParam)
{
PTRANSFER pTransfer;
pTransfer = (PTRANSFER)lpParam;
while (1)
{
pTransfer->Counter++;
InvalidateRect(pTransfer->hWnd,NULL,1);
Sleep(1000);
}
}
void ErrorHandler(LPTSTR lpszFunction)
{
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpMsgBuf,
0, NULL);
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
while (1)
{
if (pPayload->Updated == TRUE) {
UpdateWindow(hWnd);
}
if (GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
static unsigned __int64 startTime = ::GetTickCount64();
const UINT_PTR timerId = 1;
switch (uMsg)
{
case WM_CREATE:
// Start timer when window is created
::SetTimer(hWnd, timerId, 1000, nullptr);
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
case WM_TIMER: {
unsigned __int64 currTime = ::GetTickCount64();
Counter = (currTime - startTime) / 1000;
// Value changed -> initiate window update
::InvalidateRect(hWnd, nullptr, FALSE);
// Re-start timer
::SetTimer(hWnd, timerId, 1000, nullptr);
}
break;
case WM_DESTROY:
::KillTimer(hWnd, timerId);
::PostQuitMessage(0);
break;
case WM_PAINT: {
PAINTSTRUCT paintStruct = {0};
HDC hDC = BeginPaint(hWnd, &paintStruct);
DisplayData(hDC);
EndPaint(hWnd, &paintStruct);
}
return 0;
default:
return ::DefWindowProc(hWnd, uMsg, wParam, lParam);
}
return 0;
}