Problem mit Schaltflächen im nichtmodalen Dlg



  • Hallo,

    folgendes:

    Die Dialogklasse A erzeugt ein nichtmod. Dlg-Fenster Klasse B. Dieses Fenster hat Buttons. Auf Druck dieser wird an Fensterklasse A mittels SendMessage eine WMU gesendet, welche dort eine Funktion aufruft. Diese Funktion setzt den gedrückten Button in Klasse B mit EnableWindow außer Kraft (ausgedimmt). Dies soll verhindern, daß mehrfach diese Funktion ausgelöst wird, solange diese noch läuft.
    Leider passiert genau das. Obwohl der Button gedimmt ist, wird trotzdem die WMU an Klasse A gesendet und die Funktion ausgeführt wie wenn alles in eine Warteschlange gefüllt wird.
    Das Ausdimmen scheint wirklungslos zu sein.

    Was mache ich falsch?



  • Wenn du dein SendMessage im ON_BNCLICKED Handler des Buttons machst, wird diese bestimmt nicht aufgerufen, wenn der Button disabled ist. Bist du dir sicher, dass der Button deaktiviert ist? Rufst du vielleicht von anderer Stelle auch noch SendMessage auf?


  • Mod

    Schau doch in den Callstack, wenn Du es wiederholen kannst. Da Du SendMessage verwendest müsstest Du den Auslöser sehen.

    Rein technisch hört sich Dein Vorgehen korrekt an...

    Ansonsten:
    1. Welches Fenster bekommt die Nachricht?
    2. Wie ist die WMU definiert?
    3. Sollte dieses Fenster ein Dialog sein, dann ist Dir hoffentlich klar, dass Dialoge die folgenden WM_USER Nachrichten auch erhalten:
    #define DM_GETDEFID (WM_USER+0)
    #define DM_SETDEFID (WM_USER+1)
    #define DM_REPOSITION (WM_USER+2)
    🕶



  • Hallo,

    Bist du dir sicher, dass der Button deaktiviert ist?

    Ja da ich es sehe daß er ausgedimmt ist, also muß ich davon ausgehen daß die OnClicked-Funktion nicht aufgerufen wird.

    1. Welches Fenster bekommt die Nachricht?

    Das Maindialogfenster (dialogbasierte Applikation).

    void OnButtonClicked
    {
    ::SendMessage (m_hWnd, WMU_DLG_BUTTON_MACHWAS, 0, 0)
    }

    2. Wie ist die WMU definiert?

    #define WMU_DLG_BUTTON_MACHWAS WM_USER+10

    Mit dem Spy habe ich gesehen, daß die WMU abgeschickt wird auch wenn der Button ausgedimmt ist. Irgendwas ist da nicht OK.


  • Mod

    Breakpoint setzen. Callstack ansehen...



  • Martin Richter schrieb:

    Breakpoint setzen. Callstack ansehen...

    Also Breakpoint bei

    CMaindialog::Machwas (WPARAM, LPARAM lParam)
    {
    1.Befehl
    }

    und dann Rechtsklick bei Machwas->Aufrufbrowser->Aufruferdiagramm im neuen Fenster anzeigen ?

    Da steht "Es wurden keine Aufrufe(r) gefunden." Hmmm...



  • Update:

    Ich habs jetzt als modales Dialogfeld umgeschrieben (WMU Messages entfallen nun somit), und den Button sogar mit ShowWindow(false) komplett verschwinden lassen.
    Das hilft alles nichts.
    Wie zum Teufel kann eine unsichtbare Schaltfläche auf das Ereignis BN_CLICKED reagieren? 😞

    Wie kann ich das Problem nur lösen?


  • Mod

    Debuggen! Kann doch nicht so schwer sein...



  • Suche mal, ob Du die Methode "OnClicked..." noch an anderer Stelle aufrufst und nicht nur über die MessageMap



  • Tester2 schrieb:

    Suche mal, ob Du die Methode "OnClicked..." noch an anderer Stelle aufrufst und nicht nur über die MessageMap

    Ist nicht mehr relevant, da ich es wie erwähnt in ein modales Fenster umgeschrieben habe. Damit entfällt natürlich das Message System dafür.

    Mit dem Debugger komme ich dem auch nicht auf die Spur (hab ich natürlich als erstes probiert).



  • Mir scheint daß irgendwo ein Merker sein muß, der die Eigenschaften der Schaltflächen ignoriert. Der Spy hats mir angezeigt. Die Mausaktionen wurden automatisch gesendet, nachdem die Schaltfläche wieder freigegeben wurde.

    Ist das normal?



  • Wie sieht der Callstack im Debugger beim unerwünschten Aufruf aus?



  • MFK schrieb:

    Wie sieht der Callstack im Debugger beim unerwünschten Aufruf aus?

    Er findet nichts, vorausgesetzt ich mache es so richtig (Debugmodus):

    * Breakpoint beim 1. Befehl in der Funktion "OnBnClicked..."
    * Ansicht Aufrufdiagramm "CClass::OnBnClicked..."

    Ergebnis:
    Es wurden keine Aufrufe gefunden.
    Es wurden keine Aufrufer gefunden.



  • MFC-Coder schrieb:

    Er findet nichts, vorausgesetzt ich mache es so richtig

    Machst du nicht. Deutsche Lokalisierungen von Visual Studio sind furchtbar. IMHO.

    Such mal unter Debug -> Fenster -> Aufrufliste oder so ähnlich.



  • MFK schrieb:

    MFC-Coder schrieb:

    Er findet nichts, vorausgesetzt ich mache es so richtig

    Machst du nicht. Deutsche Lokalisierungen von Visual Studio sind furchtbar. IMHO.

    Such mal unter Debug -> Fenster -> Aufrufliste oder so ähnlich.

    Ok danke, jetzt siehts anders aus.

    Aber irgendwie hilft mir das auch nicht weiter.
    Wenn ich den BP in der OnBnClicked Funktion setze, habe ich ja keine Möglichkeit den ausgedimmten Button mehrfach zu drücken.

    Ich stehe da zugegebenermaßen auf dem Schlauch. Wo müßte ich den BP setzen damit das Gewünschte finde?



  • MFC-Coder schrieb:

    Wenn ich den BP in der OnBnClicked Funktion setze, habe ich ja keine Möglichkeit den ausgedimmten Button mehrfach zu drücken.

    Wieso nicht?

    Du kannst übrigens bei einem Breakpoint auch einstellen, dass der Debugger erst beim 2. Mal anhält.



  • MFK schrieb:

    Du kannst übrigens bei einem Breakpoint auch einstellen, dass der Debugger erst beim 2. Mal anhält.

    Wieder was gelernt... 🙂

    Aber ich sehe da keinen Unterschied. Das Ergebnis ist dasselbe wie wenn ich nur 1x drücke.


  • Mod

    Ich verstehe es nicht, was Du für ein Problem hast?
    Wenn Du einen Breakpoint setzt aufdie Stelle an der die WM_USER Nachricht ankommt, dann lässt Du das Programm weiter laufen (Go F5).
    Wenn dann nochmal die Nachricht reinkommt, ist was faul, aber dann kommt ja wieder der Breakpaoint. Also Breakpoint abpassen.
    Dann den Callstack ansehen. In dem wird irgendwo SendMessage aufgerufen. Schau eine Position weite drunter und Du hast den Verursacher (den Sender der Nachricht)...



  • Martin Richter schrieb:

    Ich verstehe es nicht, was Du für ein Problem hast?
    Wenn Du einen Breakpoint setzt aufdie Stelle an der die WM_USER Nachricht ankommt, dann lässt Du das Programm weiter laufen (Go F5).
    Wenn dann nochmal die Nachricht reinkommt, ist was faul, aber dann kommt ja wieder der Breakpaoint. Also Breakpoint abpassen.
    Dann den Callstack ansehen. In dem wird irgendwo SendMessage aufgerufen. Schau eine Position weite drunter und Du hast den Verursacher (den Sender der Nachricht)...

    Ich schrieb doch daß ich den nichtmodalen in ein modalen Dialog umgewandelt habe und damit das WMU System entfällt, bzw. auch nicht mehr da ist.
    Der Effekt ist derselbe, nur daß es eben keine Messages diesbezüglich mehr gibt und ich diese auch nicht mehr verfolgen kann.



  • MFC-Coder schrieb:

    Der Effekt ist derselbe, nur daß es eben keine Messages diesbezüglich mehr gibt und ich diese auch nicht mehr verfolgen kann.

    Besteht das Problem jetzt noch oder nicht?

    Fall ja, gibt es also immer noch Code, der mehrfach ausgeführt wird, obwohl er das nicht sollte?

    Dann mach da einen Breakpoint rein, der beim 2. Mal anhält, und zeig uns den Callstack.

    Falls nein, bist du überhaupt daran interessiert, herauszufinden, woran es lag?

    P.S.: 5000! 😃



  • MFK schrieb:

    Besteht das Problem jetzt noch oder nicht?

    Fall ja, gibt es also immer noch Code, der mehrfach ausgeführt wird, obwohl er das nicht sollte?

    Dann mach da einen Breakpoint rein, der beim 2. Mal anhält, und zeig uns den Callstack.

    Morgen,

    hier die obersten Zeilen. Egal ob ich 1, 2 oder 4 den Button drücke sehe ich immer dasselbe.

    > Appl.exe!CClass::OnBnClickedButton() Zeile 156 C++
    Appl.exe!_AfxDispatchCmdMsg(CCmdTarget * pTarget=0x0012eac0, unsigned int nID=1027, int nCode=0, void (void)* pfn=0x004ef4d3, void * pExtra=0x00000000, unsigned int nSig=57, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Zeile 82 C++
    Appl.exe!CCmdTarget::OnCmdMsg(unsigned int nID=1027, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Zeile 381 + 0x27 Bytes C++
    Appl.exe!CDialog::OnCmdMsg(unsigned int nID=1027, int nCode=0, void * pExtra=0x00000000, AFX_CMDHANDLERINFO * pHandlerInfo=0x00000000) Zeile 85 + 0x18 Bytes C++
    Appl.exe!CWnd::OnCommand(unsigned int wParam=1027, long lParam=526076) Zeile 2364 C++
    Appl.exe!CWnd::OnWndMsg(unsigned int message=273, unsigned int wParam=1027, long lParam=526076, long * pResult=0x0012e278) Zeile 1769 + 0x1e Bytes C++
    Appl.exe!CWnd::WindowProc(unsigned int message=273, unsigned int wParam=1027, long lParam=526076) Zeile 1755 + 0x20 Bytes C++
    Appl.exe!AfxCallWndProc(CWnd * pWnd=0x0012eac0, HWND__ * hWnd=0x00080704, unsigned int nMsg=273, unsigned int wParam=1027, long lParam=526076) Zeile 240 + 0x1c Bytes C++
    Appl.exe!AfxWndProc(HWND__ * hWnd=0x00080704, unsigned int nMsg=273, unsigned int wParam=1027, long lParam=526076) Zeile 403 C++


Anmelden zum Antworten