2016-04-22 3 views
1

У меня есть простое окно внутри потока, созданного вводом DLL. Это как мой поток выглядит следующим образом:Окно C++ WINAPI не обновляется

int Thread() 
{ 
    HWND hwnd; 
    MSG messages; 
    WNDCLASSEX wincl; 
    /* The Window structure */ 
    wincl.hInstance = hThisInstance; 
    wincl.lpszClassName = szClassName; 
    wincl.lpfnWndProc = WindowProcedure; 
    wincl.style = CS_CLASSDC; 
    wincl.cbSize = sizeof(WNDCLASSEX); 
    wincl.hIcon = LoadIcon(NULL, IDI_APPLICATION); 
    wincl.hIconSm = LoadIcon(NULL, IDI_APPLICATION); 
    wincl.hCursor = LoadCursor(NULL, IDC_ARROW); 
    wincl.lpszMenuName = NULL; 
    wincl.cbClsExtra = 0; 
    wincl.cbWndExtra = 0; 

    wincl.hbrBackground = (HBRUSH)COLOR_BACKGROUND; 
    if (!RegisterClassEx(&wincl)) 
    ; 

    hwnd = CreateWindowEx(
    0, 
    szClassName, 
    "Windows App", 
    WS_OVERLAPPEDWINDOW, 
    CW_USEDEFAULT, 
    CW_USEDEFAULT, 
    544, 
    375, 
    NULL, 
    NULL, 
    hThisInstance, 
    NULL 
    ); 
    ShowWindow(hwnd, SW_SHOW); 

    while (true) { 
    if (GetMessage(&messages, NULL, 0, 0)) { 
     TranslateMessage(&messages); 
     DispatchMessage(&messages); 
    } 
    SetWindowText(hwnd, b); 
    ShowWindow(hwnd, SW_SHOW); 

    UpdateWindow(hwnd); 
    RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW); 

    //do the stuff that computes values to show 
    } 
    return 0; 
} 

И это моя оконная процедура:

LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch (message) 
    { 
    case WM_PAINT: 
    { 

    PAINTSTRUCT ps; 
    HDC hdc = BeginPaint(hwnd, &ps); 
    TextOut(hdc, 
     10, 
     10, 
     b, 
     50); 
    EndPaint(hwnd, &ps); 
    return 0L; 
    } 
    break; 
    case WM_DESTROY: 
    PostQuitMessage(0); 
    break; 
    default: 
    return DefWindowProc(hwnd, message, wParam, lParam); 
    } 
    return 0; 
} 

окно работает, но есть большая проблема. Я хочу, чтобы значения обновлялись и отображались в реальном времени, будь то в строке заголовка или внутри окна. И несмотря на использование этих трех функций внутри цикла: ShowWindow, UpdateWindow, RedrawWindow, перерисовка не работает, как мне бы хотелось. Когда я работаю с приложением, которое вводится и генерирует значение, которое я хочу отобразить в моем созданном окне, ни строка заголовка, ни основная область моего обновления окна. Но когда желаемое значение изменяется, и я нажимаю мышку над своим окном, строка заголовка обновляется. Что касается основной области, она обновляется ТОЛЬКО, когда я перетаскиваю окно на край экрана, чтобы покрыть место, где текст должен отображаться, а затем открыть его (он может даже частично перерисоваться) или просто свернуть и восстановить окно.

ответ

1
if (GetMessage(&messages, NULL, 0, 0)) { 
    TranslateMessage(&messages); 
    DispatchMessage(&messages); 
} 
SetWindowText(hwnd, b); 
ShowWindow(hwnd, SW_SHOW); 

UpdateWindow(hwnd); 
RedrawWindow(hwnd, NULL, NULL, RDW_UPDATENOW); 

GetMessage блоки не, если нет сообщений для его обработки. Вы должны либо убедиться, что у него есть сообщения для обработки, возможно, с помощью SetTimer для передачи сообщений таймера или использования PeekMessage вместо GetMessage (с флагом PM_REMOVE)

+0

Спасибо, PeekMessage - именно то, что я хотел! – tomwyn

1

Звоните InvalidateRect до UpdateWindow.

+0

Спасибо, теперь моя ценность внутри основной области ведет себя точно как строка заголовка - она ​​обновляется при движении мыши мыши, даже если окно неактивно. Но я хочу, чтобы он обновлялся без какого-либо взаимодействия. – tomwyn

+0

См. API 'SetTimer'. Он отправит сообщение 'WM_TIMER' в указанное время - вы вызовете' InvalidateRect' там ('UpdateWindow' не требуется). – i486

+0

Я не вижу, как это может мне помочь, так как я все время звоню InvalidateRect, и это меня не беспокоит. Я только что нашел способ обхода проблемы - вызов SetForegroundWindow на основе функций обновления. Но это не очень элегантно и удобно. – tomwyn

Смежные вопросы