2016-04-22 13 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つの関数を使用しているにもかかわらず:ShowWindowUpdateWindowRedrawWindow、私が望むように再描画は機能しません。私が挿入されているアプリケーションで作業していて、作成したウィンドウに表示したい値を生成しても、ウィンドウのタイトルバーもメインエリアも更新されません。しかし、希望の値が変更され、私のウィンドウ上にマウスを移動すると、タイトルバーが更新されます。メインエリアは、画面の端にウィンドウをドラッグすると更新されるので、テキストが表示される場所をカバーして、それを表示したり(部分的に再描画することもできます)、最小化して復元するだけです窓。

答えて

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を使用してタイマーメッセージを生成したり、GetMessageの代わりにPeekMessageを使用して(PM_REMOVEフラグを使用して)おそらくSetTimerを使用して処理するメッセージがあることを確認する必要があります。

+0

ありがとう、PeekMessageは私が欲しかったものです! – tomwyn

1

UpdateWindowの前に呼び出します。

+0

ありがとう、タイトルバーのように、ウィンドウが非アクティブであっても、マウスのマウスの動きをリフレッシュします。しかし、私はそれが何の相互作用もなくリフレッシュしたい。 – tomwyn

+0

'SetTimer' APIを参照してください。指定された時刻に 'WM_TIMER'メッセージを送ります。そこで' InvalidateRect'を呼び出します( 'UpdateWindow'は必要ありません)。 – i486

+0

私はInvalidateRectをいつも呼んでいるので、私はそれが私を助けてくれるのか分かりません。これは私を気にしません。私はちょうど回避策の一種を見つけました - SetForegroundWindowを更新機能と一緒に呼び出します。しかしそれほどエレガントで便利ではありません。 – tomwyn