2009-10-01 7 views
2

Je suis nouveau à MFC (venant de C# et de Java) et de comprendre les choses.Comment gérer CEdit clic de souris sous forme parent?

Considérez une boîte de dialogue avec trois zones de texte. J'ai sous-classé CEdit à CMyEdit, et les trois zones de texte sont attachées aux variables de CMyEdit dans la classe de dialogue.

Je souhaite autoriser la classe de dialogue à "savoir" lorsque l'une des trois zones de texte a été cliquée avec le bouton gauche de la souris. J'ai trouvé des exemples de comment ajouter un gestionnaire ON_WM_LBUTTONDOWN à ma classe CMyEdit. Fonctionne bien, mais le gestionnaire est uniquement dans la classe CMyEdit. Supposons que chaque fois que l'on clique sur l'une des zones de texte, je veux que la boîte de dialogue désactive les deux autres. Comment puis-je obtenir la boîte de dialogue notifiée du clic gauche?

Ceci est un exemple complètement artificiel et simplifié. Je n'ai pas d'application avec des clics gauches dans les zones de texte. Mais je pense que le fait que je ne peux pas comprendre comment le faire indique une incompréhension fondamentale de la façon de traiter les événements de l'interface utilisateur dans MFC. Venant du monde de C#, où tout est fait pour moi et j'ai un accès direct à l'un des événements que je veux (mise au point, double clic de souris, peu importe) Je suis très confus sur pourquoi certains événements sont spéciaux et fournir un accès facile. Dans le cas de CEdit, je ne comprends pas pourquoi j'ai eu le focus, le focus, le changement, et plusieurs autres sont "directement" disponibles pour moi sans problème, mais d'autres événements, comme le clic de souris, ne le sont pas.

Mais revenons à ma vraie question: dans le scénario décrit ci-dessus, comment puis-je obtenir la boîte de dialogue notifiée des clics gauche de la souris sur les zones de texte? Est-ce que les boîtes de texte doivent lever des événements ou envoyer des messages (ou quelque chose d'autre) à la boîte de dialogue?

Répondre

2

Ajouter un gestionnaire WM_LBUTTONUP à votre carte de message

-à-dire

BEGIN_MESSAGE_MAP(CYourDialog, CDialog) 
    ON_WM_LBUTTONUP() 
END_MESSAGE_MAP() 

Il est plus facile de le faire en ajoutant un gestionnaire d'événements à la fenêtre. Ceci est le plus facilement fait à travers l'éditeur de ressources. Accédez à la page des propriétés, puis accédez à la section des messages. Ajoutez ensuite une fonction pour WM_LBUTTONUP.

Enfin, vous pouvez remplir la fonction comme suit.

void CYourDialog::OnLButtonUp(UINT nFlags, CPoint point) 
{ 
    // Grab the 3 (or more) edit control 
    CEdit* pEdit1 = (CEdit*)GetDlgItem(ID_YOUR_EDIT_CONTROL1); 
    CEdit* pEdit2 = (CEdit*)GetDlgItem(ID_YOUR_EDIT_CONTROL2); 
    CEdit* pEdit3 = (CEdit*)GetDlgItem(ID_YOUR_EDIT_CONTROL3); 

    // Grab the edit control window rects in screen coords. 
    CRect edit1Rect; 
    CRect edit2Rect; 
    CRect edit3Rect; 
    pEdit1->GetWindowRect(&edit1Rect); 
    pEdit2->GetWindowRect(&edit2Rect); 
    pEdit3->GetWindowRect(&edit3Rect); 

    // Convert to client coordinates relative to their parent (ie this) window. 
    ScreenToClient(edit1Rect); 
    ScreenToClient(edit2Rect); 
    ScreenToClient(edit3Rect); 

    // Test if the point passed in to this function is in the control's rectangle. 
    const BOOL bEnable1 = edit1Rect.PtInRect(point); 
    const BOOL bEnable2 = edit2Rect.PtInRect(point); 
    const BOOL bEnable3 = edit3Rect.PtInRect(point); 

    // Enable the window that was clicked on and disable the others. 
    pEdit1->EnableWindow(bEnable1); 
    pEdit2->EnableWindow(bEnable2); 
    pEdit3->EnableWindow(bEnable3); 

    // Set keyboard focus to the relevant control 
    if  (bEnable1) 
    { 
     pEdit1->SetFocus(); 
    } 
    else if (bEnable1) 
    { 
     pEdit2->SetFocus(); 
    } 
    else if (bEnable1) 
    { 
     pEdit3->SetFocus(); 
    } 

    CDialog::OnLButtonUp(nFlags, point); 
} 

Cette volonté, essentiellement, frappé de test et si le test de recherche dans une fenêtre d'édition, il permettra, désactivez les autres et de donner le focus du clavier.

+0

Merci Goz pour le code, je vois que va effectivement accomplir ce que j'ai demandé. Ce n'est pas vraiment ce que j'espérais, cependant. Ce qui m'embête, c'est ceci: comme je l'ai mentionné, j'ai sous-classé CEdit dans CMyEdit, et j'ai traité le message ON_WM_LBUTTONDOWN ici. Les objets CMyEdit "savent" quand ils ont été cliqués. N'y a-t-il pas un moyen pour eux de notifier la boîte de dialogue qu'ils ont été cliqués, plutôt que de faire tous les tests de réussite? Cela a plus de sens pour moi, mais ce n'est peut-être pas la façon de le faire. – Rob3C

+0

Eh bien, vous savez ce que la classe parent est ... vous pouvez toujours appeler une fonction sur elle. Il vous lierait cependant quelque peu la boîte d'édition à votre boîte de dialogue. Je suppose que vous pourriez dériver un "CMyDialog" de CDialog et ad la fonctionnalité là ... – Goz

Questions connexes