2012-03-09 26 views
2

スクロールバーの現在のnPos値に従って、WM_PAINT内のすべてのコンテンツを無効にして再描画して、親ウィンドウをスクロールします。私は背景を再描画しないようにWM_ERASEBKGNDを処理するので、ちらつきなくスクロールしたい。私はまた、私のTextOut呼び出しと表示されるいくつかのビットマップのための単純なダブルバッファリングを行います。それは私の子供のコントロールを除いて良い作品です。特にnPos == 0でアプリがSB_LINEUPまたはnPos == nMaxを処理し、アプリがSB_LINEDOWNを処理したり、スクロールバーをドラッグアンドドロップしたりすると、それらはひどくちらつきます。 MoveWindow()でそれらを移動します。私もDeferWindowPos()を試しました。私はちらつきの解決のためにそれをgoogledしましたが、それは動作しません、または私は正しく使用していません。どのように子供のコントロールのちらつきを排除するには?Win32 API:基本的なウィンドウコントロールのちらつきを避けるには?

P.S.メインウィンドウにWS_CLIPCHILDRENスタイルを使用すると、コントロールは点滅しませんが、ウィンドウの一部をスクロールすると、特にWM_DRAWITEMを処理していくつかのものを描画している静的コントロールが乱れてしまいます。

EDIT:(簡略化コード)私は、このようWM_PAINT内のバッファ倍 :

case WM_PAINT: { 
    hDC = BeginPaint(hwnd, &PS); 
    hDCMem = CreateCompatibleDC(hDC); 
    hBMMem = CreateCompatibleBitmap(hDC, wnd_x, wnd_y); 
    SelectObject(hDCMem, hBMMem); 

    Font = CreateFont(130, 50, 0, 0, FW_SEMIBOLD, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, "Arial"); 
    SelectObject(hDCMem, Font); 
    SetTextColor(hDCMem, RGB(30, 144, 255)); 
    SetBkColor(hDCMem, RGB(192, 192, 192)); 
    TextOut(hDCMem, 650, 69 - scr_pos, "ABC", 3); 

    MoveWindow(GetDlgItem(hwnd, ID_BUTT_START), 720, 500 - scr_pos, 160, 150, TRUE); 

    BitBlt(hDC, 0, 0, wnd_x, wnd_y, hDCMem, 0, 0, SRCCOPY); 
    DeleteObject(hBMMem); 
    DeleteDC(hDCMem); 
    EndPaint(hwnd, &PS); 
} 

scr_posスクロールバーから採取した現在のNPO値です。

case WM_ERASEBKGND: 
    return 1; 
break; 

case WM_VSCROLL: { 
    SCROLLINFO sinfo; 
    ZeroMemory(&sinfo, sizeof(SCROLLINFO)); 
    sinfo.cbSize = sizeof(SCROLLINFO); 
    sinfo.fMask = SIF_POS | SIF_PAGE | SIF_TRACKPOS; 
    GetScrollInfo(hwnd, SB_VERT, &sinfo); 
    scr_pos = sinfo.nPos; 
    switch(LOWORD(wParam)) { 
     case SB_TOP: 
      scr_pos = 0; 
     break; 
     case SB_BOTTOM: 
      scr_pos = 4000; 
     break; 
     case SB_LINEUP: { 
      scr_pos -= 200; 
      if (scr_pos < 0) { 
       scr_pos = 0; 
      } 
     } 
     break; 
     case SB_LINEDOWN: { 
      scr_pos += 200; 
      if (scr_pos > 4000) { 
       scr_pos = 4000; 
      } 
     } 
     break; 
     case SB_PAGEUP: { 
      scr_pos -= si.nPage; 
      if(scr_pos < 0) { 
       scr_pos = 0; 
      } 
     } 
     break; 
     case SB_PAGEDOWN: { 
      scr_pos += si.nPage; 
      if(scr_pos > 4000) { 
       scr_pos = 4000; 
      } 
     } 
     break; 
     case SB_THUMBPOSITION: 
      scr_pos = HIWORD(wParam); 
     break; 
     case SB_THUMBTRACK: 
      scr_pos = HIWORD(wParam); 
     break; 
    }  
    RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_INTERNALPAINT); 
// InvalidateRect (hwnd, NULL, true); 
// UpdateWindow(hwnd); 
    ZeroMemory(& sinfo, sizeof(SCROLLINFO)); 
    sinfo.cbSize = sizeof(SCROLLINFO); 
    sinfo.fMask = SIF_POS; 
    snfo.nPos = scr_pos; 
    SetScrollInfo(hwnd, SB_VERT, & sinfo, TRUE); 
    } 
} 
break; 

何も子コントロールを除いて点滅しない...

+0

ダブルバッファリングしている場合、これがどのようにちらつくか想像できません。あなたのコードの*説明*を解決するのではなく、実際のコード**を投稿すると診断する方がはるかに簡単です。 –

+0

あなたはどこかで不要な無効化をしないのですか?コーディーグレイは正しいです、コードを投稿してください。 – Flot2011

+0

コードが追加されました。私がいくつかの重要な部分を見逃しているかどうか教えてください。 – okt

答えて

4

WS_CLIPCHILDRENは確かなソリューションです。先に進んで、それを有効にすると、あなたは "私の窓の部分が台無しになる"の原因を追跡しなければならないでしょうが、あなたはそれについて十分な詳細を提供していません。

また、ScrollWindowExをご覧になることもできます。このドキュメントでは、スクロール中に子ウィンドウを正しく再配置する方法について具体的に説明しています。

関連する問題