Winapi C++;win32 API窗口赢得';在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

我有一个程序,应该显示每秒递增的计数。计数器位于单独的线程中。当发生更改时,我调用WindowUpdate,但除非将鼠标指针悬停在窗口上或调整窗口大小,否则窗口中的计数不会更新。我试过竖立和重画窗口,但它们也不起作用

为什么不显示计数器更新

    #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;
}