2015-09-17 1 views
1

J'ai créé une zone d'édition et cela fonctionnait correctement, mais après avoir ajouté un WndProc personnalisé, le texte "mon édition" n'est pas visible et ne prend pas en compte cliqué.Le contrôle d'édition ne peut pas obtenir le focus ou le texte après le sous-classement

HWND handle=CreateWindowExW(0,L"Edit",L"my edit",WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_CENTER | ES_MULTILINE | ES_AUTOVSCROLL, 
         0,0,200,200,window.handle,0,GetModuleHandle(NULL),0); 

Jusqu'à là, il travaillait très bien
Après avoir mis cette procédure de fenêtre, le contrôle d'édition ne fonctionne plus comme prévu

SetWindowLongPtr(handle,GWLP_WNDPROC,(LRESULT)staticWndProc); 
LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam){ 
    switch (uMsg){ 
     case WM_LBUTTONDOWN: 
      std::wcout << handle << L" click\n"; //click event works 
      break; 
     default: 
      return DefWindowProcW(handle,uMsg,wParam,lParam); 
    } 
    return 0; 
} 

Dois-je gérer manuellement un événement ou modifier ma drapeaux de style de construction?

Répondre

4

Le sous-classement consiste à intercepter des messages pour une fenêtre, en manipulant éventuellement certains d'entre eux et en transmettant ceux que vous ne gérez pas à la procédure originale .

Vous ne faites pas cela - vous passez tout ce que vous ne parvenez pas à DefWindowProc. DefWindowProc n'a aucun des comportements spécialisés pour un contrôle d'édition (ou en effet pour tout type de contrôle). Vous avez donc effectivement transformé un contrôle d'édition en une fenêtre générique.

En utilisant SetWindowLongPtr à sous-classe d'une fenêtre est déconseillée ces jours-ci, mais si vous utilisez cette méthode, la valeur de retour de l'appel à SetWindowLongPtr vous donne l'ancienne procédure de fenêtre, et vous êtes censé utiliser la fonction CallWndProc au lieu de DefWindowProc pour l'appeler.

Cependant, la façon moderne de sous-classe d'une fenêtre utilise la fonction SetWindowSubclass, qui gère l'appel de la proc original pour vous - tout ce que vous devez faire est d'appeler la fonction DefSubclassProc, comme indiqué ici:

LRESULT CALLBACK staticWndProc(HWND handle, UINT uMsg, WPARAM wParam, LPARAM lParam, UINT_PTR, DWORD_PTR){ 
    switch (uMsg){ 
     case WM_LBUTTONDOWN: 
      std::wcout << handle << L" click\n"; //click event works 
      break; 
     case WM_NCDESTROY: 
      RemoveWindowSubclass(handle, staticWndProc, 0); 
      // fall through 
     default: 
      return DefSubclassProc(handle,uMsg,wParam,lParam); 
    } 
    return 0; 
} 

SetWindowSubclass(handle, staticWndProc, 0, 0); 

Notez que la fonction de sous-classe ci-dessus est supprimée lorsque WM_NCDESTROY est reçu.

+0

Cela fonctionne bien, merci! Je pensais que c'était correct de laisser une procédure de fenêtre unique avec DefWindowProcW mais apparemment j'avais encore besoin de cette CallWndProc. – shuji