在对编辑控件绘制文本后进行更新

编程语言 2026-07-08

我有一个EDIT控件,其文本作为消息窗口(我需要一个编辑控件来选中文本并更新文本)。

我需要在它上面绘制其他文本,比如发送时间在右下角。我把它绘制在WM_PAINT,文本确实绘制出来,但窗口中的文本被遮挡,只有用鼠标选中它时才会出现。

创建窗口并为它设置消息处理过程:

HWND* new_message_window = new HWND(CreateWindowEx(
    0,
    L"edit", text_wchar,
    // WS_VISIBLE | WS_CHILD | SS_LEFT | SS_EDITCONTROL | ES_MULTILINE | ES_READONLY,
    WS_VISIBLE |
    WS_CHILD |
    ES_MULTILINE |
    ES_READONLY |
    ES_AUTOVSCROLL,
    window_x, window_y - messages_vscroll_pos, 
    window_w, window_h,
    messages_window, NULL, NULL, this
));

// set ui manager in new message_window extra bytes
SetWindowLongPtr(*new_message_window, GWLP_USERDATA, (LONG_PTR)this);

// set new_message_window window message procedure as sub class
SetWindowSubclass(
    *new_message_window,
    current_chat_message_window_message_procedure,
    1,
    0
);

处理 WM_PAINT

case WM_PAINT:
{
    // get ui manager
    manager = (UIManager*)GetWindowLongPtr(hWnd, GWLP_USERDATA);

    // get window rect
    RECT window_rect;
    GetClientRect(hWnd, &window_rect);

    PAINTSTRUCT ps;
    HDC hdc;
    hdc = BeginPaint(hWnd, &ps);

    SelectObject(hdc, manager->message_date_sent_font);

    // draw date sent
    TextOut(
        hdc, 
        0, window_rect.bottom - manager->message_date_sent_height, 
        L"10:45", 5
    );

    // redraw widnow
    RedrawWindow(hWnd, &window_rect, NULL, RDW_ERASE | RDW_UPDATENOW ); // I tried this

    EndPaint(hWnd, &ps);

    // update window
    SetWindowPos(
        hWnd, NULL,
        0, 0, 0, 0, 
        SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED
    ); // and I tried this

    return 0;
}

如果我使用RedrawWindow(),窗口会闪烁,我看不到这个窗口文本。

解决方案

从描述来看,你显然想要按这个大致的布局显示:

在此输入图片描述

如果这是你想要的,我建议不要直接绘制“发送时间”部分。相反,我会为消息文本创建一个编辑控件,为发送时间再创建一个编辑控件(或静态控件)。值得一提的是,静态控件和只读编辑控件之间几乎没有区别。

请注意,虽然我给time sent区域画了边框,但其实并不需要。你可以按需要调整控件的窗口样式,决定是否要边框,以及你希望边框的类型是什么。

这样,消息文本和发送时间就能自动处理所有的重绘。你只需要把要显示的文本传给它们,它们就会从那里开始处理。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章