2010-01-10 6 views
5

J'ai un programme d'interface graphique Win32 avec un contrôle de tabulation, chaque onglet ayant un contrôle de liste. Il y a un scintillement massif chaque fois que la fenêtre est redimensionnée. J'ai essayé les choses suivantes:Win32 GUI scintillant sur le redimensionnement

  • Manipuler WM_ERASEBKGND dans le wndproc principal et renvoyer TRUE. Aucun effet.
  • Filtrage de tous les messages WM_ERASEBKGND dans la boucle d'événements. Aucun effet.
  • Définition du style WM_CLIPCHILDREN dans la fenêtre principale. Maintenant, lorsque la fenêtre est redimensionnée, le contrôle de vue liste est simplement effacé sur un fond blanc et ne se redessine pas.
  • L'utilisation de DefWindowPos au lieu de MoveWindow. Aucun effet.
  • Passage de FAUX à bRepaint dans MoveWindow. Même effet que la définition de WS_CLIPCHILDREN (voir ci-dessus).

Voici le code RegisterClassEx:

memset(&wcex, 0, sizeof(WNDCLASSEX)); 
wcex.cbSize = sizeof(WNDCLASSEX); 
wcex.style = 0; 
wcex.lpfnWndProc = PhMainWndProc; 
wcex.cbClsExtra = 0; 
wcex.cbWndExtra = 0; 
wcex.hInstance = PhInstanceHandle; 
wcex.hIcon = LoadIcon(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER)); 
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 
//wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); 
wcex.lpszMenuName = MAKEINTRESOURCE(IDR_MAINWND); 
wcex.lpszClassName = PhWindowClassName; 
wcex.hIconSm = (HICON)LoadImage(PhInstanceHandle, MAKEINTRESOURCE(IDI_PROCESSHACKER), IMAGE_ICON, 16, 16, 0); 

Le gestionnaire WM_SIZE:

RECT rect; 

// Resize the tab control. 

GetClientRect(PhMainWndHandle, &rect); 
MoveWindow(TabControlHandle, rect.left, rect.top, 
    rect.right - rect.left, rect.bottom - rect.top, TRUE); 

// Resize the list view. 

TabCtrl_AdjustRect(TabControlHandle, FALSE, &rect); 

MoveWindow(ListViewHandle, rect.left, rect.top, 
    rect.right - rect.left, rect.bottom - rect.top, TRUE); 

Les styles sont les suivants:

  • fenêtre principale: WS_OVERLAPPEDWINDOW
  • Contrôle Tab: WS_CHILD (et WS_VISIBLE)
  • liste Voir contrôle: WS_CHILD | WS_BORDER | LVS_REPORT (et WS_VISIBLE)
+4

Ah oui, la fenêtre win32 scintille. Cela ramène des souvenirs ... –

+0

Je me demande si le double tampon aiderait en quelque sorte ... –

Répondre

4

Il s'est avéré qu'il y avait un problème avec l'ordre Z - appeler BringWindowToTop sur la liste a résolu le problème.

+0

J'ai eu le même problème en appelant 'BringWindowToTop' pour la fenêtre montrée comme le contenu d'un onglet l'a résolu Je l'ai fait dans InitDialog après avoir montré l'onglet initial –

+2

J'ai également eu des problèmes similaires avec le contrôle des tabulations scintillantes (sur le redimensionnement), ce qui a été résolu en ajoutant le style 'WS_CLIPCHILDREN' à la boîte de dialogue parente: –

+0

@Adam: merci beaucoup, en ajoutant que –

2

Windows prend en charge une opération de mise en lots re-taille qui vise à éviter le scintillement causé lorsque beaucoup de fenêtres enfants sont indepently redimensionnées . Voir BeginDeferWindowPos pour plus d'informations à ce sujet. Si cela ne fonctionne pas, essayez le message WM_SETREDRAW. Il semble possible d'arrêter le dessin de la fenêtre parente - ce qui inhibera tous les contrôles enfants, puis, lorsque la mise en page est terminée, réactiver le dessin et appeler RedrawWindow pour repeindre la fenêtre entière en une passe. J'ai plutôt pensé que c'est ce que le positionnement de fenêtre Différé utiliserait intérieurement.

+0

J'ai déjà essayé cela, comme je l'ai dit dans la question ... – wj32

+0

désolé, raté cela. Arrêt suivant, WM_SETREDRAW –

0

Lorsqu'un ListView est Amarré, comme dans Explorateur Windows (et vous avez une bonne quantité d'articles), le redimensionnement de la principale forme va marquer tous les éléments à scintillement. http://www.codeproject.com/KB/list/listviewxp.aspx

+0

Je n'utilise pas .NET, il n'est donc pas "ancré". – wj32

+0

Même si l'article parle de .net, le problème est un problème générique win32 et tous ceux qui ont fait quelque chose en utilisant win32api gui-controls ont plus ou moins frappé le problème de scintillement listview quand ils font quelque chose qui n'est pas du code jouet. – Jonke

+0

Pourriez-vous suggérer comment l'article s'appliquerait à ma situation? J'ai déjà essayé de filtrer tous les messages d'arrière-plan d'effacement, ce qui ne peut pas être le problème :( – wj32

1

je peux être une lapalissade, mais je pensais que double buffering est la solution à Win32 scintille. Je suis un Développeur Java et il a été une condition sine while je l'ai écrit win32 alors s'il vous plaît laissez-moi savoir si je déraisonne

Voici le comment: http://www.gamedev.net/community/forums/topic.asp?topic_id=411559

Voici un code de sampe: http://www.codeproject.com/KB/cpp/DoubleBuffering.aspx

Voici la question équivalente .NET (?): How to prevent a Windows Forms TextBox from flickering on resize?

+0

Je définis déjà le style étendu LVS_EX_DOUBLEBUFFER dans la vue de liste. Ou parlez-vous d'un autre type de double tampon? FYI J'ai essayé d'utiliser WS_EX_COMPOSITED mais comme avec WS_CLIPCHILDREN la vue de liste ne se redessine plus :( – wj32