| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 701 人关注过本帖
标题:WndProc如何刷新动态字符
只看楼主 加入收藏
angelhot
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2015-1-9
结帖率:50%
收藏
已结贴  问题点数:10 回复次数:4 
WndProc如何刷新动态字符
程序代码:
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_PAINT:
           {
        PAINTSTRUCT ps;
        HDC hdc = BeginPaint(hWnd, &ps);

         .........
        SYSTEMTIME st;
        GetLocalTime(&st);
        TCHAR cha[9] = {};
        swprintf_s(cha, _T("%hu%hs%hu%hs%hu"), st.wHour, ":", st.wMinute, ":", st.wSecond);
        //InvalidateRect(hWnd, NULL, true);
        DrawText(hdc, cha, -1, &rect, DT_WORDBREAK);
        //Sleep(1000);
                .........
        }
    }
}

为什么DrawText放在 switch (message)循环里不会重复打印时间st.wSecond变化啊?
加上InvalidateRect后,清除太快,直接都看不到显示了。
Sleep(1000)虽然能显示变化,但整个循环每1秒都会卡定。
要用什么方法刷新动态字符呢?


[此贴子已经被作者于2023-4-4 08:48编辑过]

搜索更多相关主题的帖子: 字符 message 动态 HWND 刷新 
2023-04-04 08:32
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:4 
程序代码:
#include <SDKDDKVer.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "resource.h"
#include <cwchar>

RECT g_SysTimeRect = { 0, 0, 100, 50 };
UINT g_SysTimeElapse = 100;
SYSTEMTIME g_SysTime;

LRESULT CALLBACK WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
    case WM_COMMAND:
        {
            switch( LOWORD(wParam) )
            {
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_CREATE:
        SetTimer( hWnd, 1, g_SysTimeElapse, nullptr );
        break;
    case WM_TIMER:
        {
            WORD wHour   = g_SysTime.wHour;
            WORD wMinute = g_SysTime.wMinute;
            WORD wSecond = g_SysTime.wSecond;
            GetLocalTime( &g_SysTime );
            if( wHour!=g_SysTime.wHour || wMinute!=g_SysTime.wMinute || wSecond!=g_SysTime.wSecond )
                InvalidateRect( hWnd, &g_SysTimeRect, FALSE );
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            {
                wchar_t temp[9] = {};
                swprintf( temp, 9, L"%02hu:%02hu:%02hu", g_SysTime.wHour, g_SysTime.wMinute, g_SysTime.wSecond );
                DrawText( hdc, temp, -1, &g_SysTimeRect, DT_WORDBREAK );
            }
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        KillTimer( hWnd, 1 );
        PostQuitMessage( 0 );
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

int __stdcall wWinMain( HINSTANCE hInstance, HINSTANCE, LPWSTR, int nCmdShow )
{
    WNDCLASSEXW wcex = { 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_VCWIN32));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_VCWIN32);
    wcex.lpszClassName  = L"YourWindowClass";
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    RegisterClassExW( &wcex );

    HWND hWnd = CreateWindowW( L"YourWindowClass", L"YourTitle", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr );
    if( !hWnd )
        return FALSE;
    ShowWindow( hWnd, nCmdShow );
    UpdateWindow( hWnd );

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_VCWIN32));

    MSG msg;
    while( GetMessage(&msg,nullptr,0,0) )
    {
        if( !TranslateAccelerator(msg.hwnd,hAccelTable,&msg) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    return (int)msg.wParam;
}
2023-04-04 09:47
angelhot
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2015-1-9
收藏
得分:0 
回复 2楼 rjsp
SetTimer以时间间隔发送WM_TIMER消息InvalidateRect刷新,不需要调用KillTimer销毁时钟。
又学到新姿势,感谢rjsp版主亲授
2023-04-04 11:50
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9025
专家分:54030
注 册:2011-1-18
收藏
得分:6 
像时间这种频繁刷新的文字,其实不应该经过 WM_PAINT
即:定时,发现文字需要改变,创建兼容位图,在兼容位图上画好文字,位图覆盖
2023-04-04 11:53
angelhot
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2015-1-9
收藏
得分:0 
回复 4楼 rjsp
rjsp版主:先用CreateCompatibleDC创建内存兼容DC,用CreateCompatibleBitmap创建位图,
然后在WM_TIMER计时器消息里用Rectangle和TextOutW绘制文字图形到内存兼容DC?
最后在WM_PAINT用StretchBlt将兼容DC绘制到窗口上吗?

只学了C++基础,一直都是以黑底白字的控制台作练习,对WindowsAPI函数不了解
2023-04-05 15:40
快速回复:WndProc如何刷新动态字符
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.022782 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved