2016-04-22 244 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; 
} 

窗口工作,但有一個主要的問題。我希望實時更新和顯示值,無論是在標題欄還是在窗口內。儘管在循環中使用這3個函數:ShowWindowUpdateWindow,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

UpdateWindow之前致電InvalidateRect

+0

謝謝,現在我在主區域內的值表現正好就像標題欄一樣 - 即使窗口處於非活動狀態,鼠標移動時也會刷新。但我希望它在沒有任何交互的情況下刷新。 – tomwyn

+0

請參閱'SetTimer' API。它會在指定的時間發送'WM_TIMER'消息 - 你將在那裏調用'InvalidateRect'(不需要'UpdateWindow')。 – i486

+0

我不明白它是如何幫助我的,因爲我一直都在調用InvalidateRect,這並沒有打擾到我。我剛剛發現了一種解決方法 - 在現場調用SetForegroundWindow更新函數。但它不是很優雅和方便。 – tomwyn