Keine CBN_SELCHANGE notification bei CCombobox::SetCurSel



  • Hallo,

    ich habe gerade festgestellt, dass wenn man die Auswahl einer Combobox mit SetCurSel ändert, keine CBN_SELCHANGE notification gesendet wird.
    Als am Sinnvollsten erachte ich es die Message einfach manuell nach ausführen von SetCurSel zu senden.

    Weiss aber nicht so genau wie das geht. Habe folgendes, aus dem MS Forum bereits probiert:

    myList->SetCurSel(900000);
    myList->SendMessage(WM_COMMAND, MAKEWPARAM(myList->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM((HWND)myLyst));
    

    Das funktioniert aber nicht...

    Weiss jemand wie ich die Notification manuell senden kann?

    Gruß & Dank,

    Sliv0r


  • Mod

    1. Ist dieses Verhalten normal.
    2. Darfst Du die Benachrichtigung nicht an das Control senden, Du musst die WM_COMMAND Nachricht an das Parent senden.



  • Hallo,

    dass das Verhalten normal ist verstehe ich zwar nich ganz, denn was spielt es denn für eine Rolle ob der User oder das Programm selbst die Combobox Auswahl ändert? Die aus der Änderung resultierenden Aktionen müssen doch unabhängig vom Urheber durchgeführt werden...

    Anyway...

    meinst du so:

    myList->SendMessage(WM_COMMAND, MAKEWPARAM(myList->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM((HWND)myLyst->GetParent()));
    

    So funzt es nämlich auch nich 😞


  • Mod

    Sliv0r schrieb:

    dass das Verhalten normal ist verstehe ich zwar nich ganz, denn was spielt es denn für eine Rolle ob der User oder das Programm selbst die Combobox Auswahl ändert? Die aus der Änderung resultierenden Aktionen müssen doch unabhängig vom Urheber durchgeführt werden...

    Müssen sie nicht, warum auch? Dein Programm weiß doch was es tut. Du müsstest nicht mal ein WM_COMMAND senden, sondern Du könntest direkt Deine Funktion OnDieSelektionHatSichVeraendert() aufrufen. Oder sagen wir, normalerweise weiß es der Entwickler... 🤡

    Aktuell (und ich wette auch in Zukunft) wird diese CBN_ Notification gesendet nur wenn es der User macht! Das ist eben so by Design (seit Win16 😉 ) und es ist klar dokumentiert:
    http://msdn.microsoft.com/en-us/library/bb775821(VS.85).aspx

    CBN_SELCHANGE Notification
    The CBN_SELCHANGE notification message is sent when the user changes the current selection in the list box of a combo box. The user can change the selection by clicking in the list box or by using the arrow keys. The parent window of the combo box receives this notification in the form of a WM_COMMAND message with CBN_SELCHANGE in the high-order word of the wParam parameter.

    Die älteren Controls aus Win32 haben niemals eine Notification gesendet, wenn das Programm die Operation durchführt (Ausnahme EN_CHANGE!).
    Dies wurde übrigends gezielt gemacht um Rekursionen zu vermeiden!
    Die neuen ComCtl's verhalten sich anders (ListView).

    Sliv0r schrieb:

    Anyway...

    meinst du so:

    myList->SendMessage(WM_COMMAND, MAKEWPARAM(myList->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM((HWND)myLyst->GetParent()));
    

    So funzt es nämlich auch nich 😞

    Nein! Du sendest doch wieder an Dich selbst (Dein Control) und nicht an Dein Parent!
    Zudem ist dein LPARAM Wert falsch.

    Wie wäre es wenn du mal die WM_COMMAND Doku liest 😉
    http://msdn.microsoft.com/en-us/library/ms647591(VS.85).aspx

    myList->GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(myList->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM((HWND)myLyst));
    


  • Müssen sie nicht, warum auch? Dein Programm weiß doch was es tut.

    Das weiss es auch wenn ich bei einer Edit Box ein ReplaceSel() mache. Da werden trotzdem munter Notifications verschickt. Total inkonsequent sowas... die spinnen die Redmonder :p

    2. Darfst Du die Benachrichtigung nicht an das Control senden, Du musst die WM_COMMAND Nachricht an das Parent senden.

    Das widerspricht nach meinem Dafürhalten deinem Lösungsvorschlag immerhin machst du GetParent()->SendMessage() und nicht GetParent()->ReceiveMessage() 😃

    Das hatte ich auch so wie du es vorgeschlagen hast, schonmal ausprobiert und das funzte nicht (kommt ein Assert in wincore...)

    Poste daher jetzt nochmal den Kontext mit:

    int iIndex; 
    CComboBox *pCComboBox;
    pCComboBox     = (CComboBox *) m_pParentWindow->GetDlgItem(m_iIdOfCWND);
    GetValue(&iIndex, bFromInBuf);
    pCComboBox->SetCurSel(iIndex);
    pCComboBox->GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(pCComboBox->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM((HWND)pCComboBox));
    

    Kann mir jemand sagen was ich falsch mache???



  • Hi,

    weiss zwar nicht ob du das noch brauchst aber ich Antworte trotzdem mal...

    myList->GetParent()->SendMessage(WM_COMMAND, MAKEWPARAM(myList->GetDlgCtrlID(), CBN_SELCHANGE), LPARAM( myLyst->GetSafeHwnd() ));

    wäre richtig 😉


Anmelden zum Antworten