Wert nach dem Ändern eines Kombinationsfeldes nach einer Nachricht auslesen

Dieses Thema im Forum "Programmieren" wurde erstellt von christian_3, 28. April 2005.

Status des Themas:
Es sind keine weiteren Antworten möglich.
  1. christian_3

    christian_3 Byte

    Registriert seit:
    20. Oktober 2004
    Beiträge:
    13
    Hallo,

    Ich habe hier ein MFC-Projekt unter MS Visual C++ V6.0 (dialogfeldbasierend).
    Ich möchte, dass wenn ein Wert eines Kombinationsfeldes ausgesucht wird, eine Nachricht versandt wird. Dies macht man mittels der Nachrichtenzuordnungstabelle. Als Nachricht habe ich ausgesucht 'CBN_SELCHANGE' (ist das richtig?).

    So, wenn ich nun den entsprechenden Quelltext debugge, dann springt er mir auch in die Routine, sobalb ein Wert aus dem Kombinationsfeld ausgesucht wurde. Soweit so gut. Wenn ich nun aber mittels 'UpdateData (true);' den ausgesuchten Wert ermitteln möchte, dann erhalte ich nur den alten Wert; nicht den ausgesuchten :-((( Das soll logisch sein??????

    In der Hilfe habe ich nun unter CBN_SELCHANGE folgendes gefunden:

    ...

    Remarks
    To get the index of the current selection, send the CB_GETCURSEL message to the control.

    Hier liegt wohl der Grund, warum ich die Eingabe nicht erhalte. Aber ehrlich gesagt, verstehe ich nur Bahnhof. Hier wäre m.M. ein Beispiel angebracht gewesen.
    Kann mir einer erklären, was ich tun muss? Wie sende ich ein "CB_GETCURSEL" an "control"? Wer oder was ist "control"?

    Vielen Dank schon mal im Voraus für jede Antwort!
     
  2. Michi0815

    Michi0815 Guest

    Registriert seit:
    7. Januar 2004
    Beiträge:
    3.429
    control ist (offenbar) das kombinationsfeld. genauer gesagt: das handle des feldes.

    nachrichten versendet man mit
    Ergebnis = SendMessage(Fenster, Nachricht, Parameter1, Parameter2);

    einfach mal in der MSDN Biobliothek nach CBN_SELCHANGE und/oder SendMessage suchen...
     
  3. christian_3

    christian_3 Byte

    Registriert seit:
    20. Oktober 2004
    Beiträge:
    13
    Hallo!

    Erstmal herzlichen Dank für Deine Antwort!

    Hab' mal gesucht und folgendes im Internet gefunden:



    SendMessage
    The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread's message queue and returns immediately.

    LRESULT SendMessage(
    HWND hWnd, // handle of destination window
    UINT Msg, // message to send
    WPARAM wParam, // first message parameter
    LPARAM lParam // second message parameter
    );

    Parameters

    hWnd
    Handle to the window whose window procedure will receive the message. If this parameter is HWND_BROADCAST, the message is sent to all top-level windows in the system, including dis

    Msg
    Specifies the message to be sent.

    wParam
    Specifies additional message-specific information.

    lParam
    Specifies additional message-specific information.

    Return Values
    The return value specifies the result of the message processing and depends on the message sent.

    Remarks
    Applications that need to communicate using HWND_BROADCAST should use the RegisterWindowMessage function to obtain a unique message for inter-application communication.

    If the specified window was created by the calling thread, the window procedure is called immediately as a subroutine. If the specified window was created by a different thread, the system switches to that thread and calls the appropriate window procedure. Messages sent between threads are processed only when the receiving thread executes message retrieval code. The sending thread is blocked until the receiving thread processes the message.

    Windows CE: Windows CE does not support all the messages the desktop Windows platforms support. Before using SendMessage, check to make sure the message you are sending is supported.

    QuickInfo
    Windows NT: Requires version 3.1 or later.
    Windows: Requires Windows 95 or later.
    Windows CE: Requires version 1.0 or later.
    Header: Declared in winuser.h.
    Import Library: Use user32.lib.
    Unicode: Implemented as Unicode and ANSI versions on Windows NT.




    Geht schon mal los, dass ich das meiste nicht begreife und auch keine Erklärung dafür gefunden habe... warum nur können die keine Beispiele mit anführen??? Bin was C++ angeht Anfänger; mein Gebiet ist eher ANSI C...

    Also, ich erklär' Dir noch kurz, was ich alles ausprobiert habe:





    Ich habe folgendes Probiert:


    LRESULT lResult;
    HWND hWndControl;
    UINT CB_GETCURSEL;
    WPARAM wParam = 0;
    LPARAM lParam = 0;

    lResult = SendMessage ( // returns LRESULT in lResult
    hWndControl, // handle to destination control
    CB_GETCURSEL, // message ID
    wParam, // = 0; not used, must be zero
    lParam); // = 0; not used, must be zero );


    Ich bekam beim Compilieren:

    Compiling...
    NasperKonvertDlg.cpp
    C:\Visual C++\Projekte\NasperKonvert\NasperKonvertDlg.cpp(870) : warning C4091: '' : Ignoriert auf der linken Seite von 'unsigned int', wenn keine Variable deklariert wurde
    C:\Visual C++\Projekte\NasperKonvert\NasperKonvertDlg.cpp(870) : error C2143: Syntaxfehler : Fehlendes ';' vor 'constant'
    C:\Visual C++\Projekte\NasperKonvert\NasperKonvertDlg.cpp(878) : error C2660: 'SendMessageA' : Funktion akzeptiert keine 4 Parameter
    Error executing cl.exe.

    NasperKonvertDlg.obj - 2 error(s), 1 warning(s)


    Ich dachte mir, CB_GETCURSEL müsste ja eigentlich schon definiert sein, so probierte ich folgendes:

    LRESULT lResult;
    HWND hWndControl;
    // UINT CB_GETCURSEL;
    WPARAM wParam = 0;
    LPARAM lParam = 0;

    lResult = SendMessage ( // returns LRESULT in lResult
    hWndControl, // handle to destination control
    CB_GETCURSEL, // message ID
    wParam, // = 0; not used, must be zero
    lParam); // = 0; not used, must be zero );



    ich bekam:

    Compiling...
    NasperKonvertDlg.cpp
    C:\Visual C++\Projekte\NasperKonvert\NasperKonvertDlg.cpp(878) : error C2660: 'SendMessageA' : Funktion akzeptiert keine 4 Parameter
    Error executing cl.exe.

    NasperKonvertDlg.obj - 1 error(s), 0 warning(s)


    Was soll das jetzt? In der MSN steht, dass vier Parameter übergeben werden müssen und plötzlich will er keine 4 haben? Muss man jetzt aber nicht verstehen...

    Noch eine Frage zum Verständnis für mich: was heißt hWndControl? Ist das irgendein Name, den ich irgendwo raussuchen muss oder ist das ein Wert, den ich von der Routine bekomme? Er muss doch wissen, von welchem Kombinationsfeld ich das Ergebnis haben will, oder? Oder weiß er das dadurch, dass ja nur eines geändert wurde?



    Jedenfalls habe ich dann nochmal bei der MSDN nachgeguckt. Da habe ich folgendes gefunden, was für mich ebenfalls passend klang:

    Control.sendMessage

    Sends the specified Win32 message to this control.

    Syntax

    public final int sendMessage( int msg, int wParam, int lParam )

    protected final int sendMessage( int msg, int wParam, Object lParam )

    protected final int sendMessage( int msg, Object wParam, Object lParam )

    Parameters

    msg

    The Win32 message to send.

    wParam

    The wParam to send with the message.

    lParam

    The lParam to send with the message.

    Return Value

    Returns an integer that represents the result of the message processing.


    Hier sind's jetzt plötzlich drei Parameter... Kein Kommentar. Ist das das, was ich suche?

    Hab' dann folgendes ausprobiert:

    int ergebnis;
    WPARAM wParam = 0;
    LPARAM lParam = 0;

    ergebnis = SendMessage (CB_GETCURSEL, wParam, lParam );


    Als Ergebnis bekomme ich aber immer nur 0 zurückgegeben...

    Kann mir bitte jemand nochmal weiterhelfen? Oder kann mir jemand eine Quelle nennen, wo dieses Thema _verständlich_ beschrieben wird, so dass es auch ein Anfänger versteht? Am besten MIT Beispiel?

    Vielen Dank schon mal im Voraus für jede Antwort!!
     
  4. Michi0815

    Michi0815 Guest

    Registriert seit:
    7. Januar 2004
    Beiträge:
    3.429
    ich kenne mfc nicht; mache meine fenster lieber zu fuss auf ;)
    also nur ganz allgemein:

    SendMessage mit 4 pararametern ist eine windows-standard-api-funktion die mit allen fenstern funktioniert - also auch mit edit- und dropdownfeldern und deren kombination, den kombifeldern.
    alles was du brauchst damit das funktioniert ist das handle (=so eine art seriennnummer bzw eindeutiger identifier) des fensters. das erhält man normalerweise bei der erzeugung als ergebnis der CreateWindow-funktion. zur not kann man windows auch dazu bringen es herauszusuchen, wenn man ein paar daten des fensters kennt (name oder zumindest die klasse).

    die SendMessage mit 3 parametern ist keine eigenständige funktion sondern nur eine methode eines objekts (bei dir wahrscheinlich CWindow oder ein nachfolger davon). wenn dieses CWindow-objekt zufällig das verwaltende objekt deines kombisfeldes ist, dann kommt die nachricht auch genau richtig an und du kriegst eine sinnvolle antwort. auf dieses objekt solltest du eigentlich zugriff haben, auch wenn die eigentliche instanzierung vom visual-aufsatz der programmiersprache vorgenommen wird.

    nach dem du das kombifeld offenbar nicht selber erzeugt hast (sonst wüsstest du was ein handle ist), sondern visual-<irgendwas> verwendest, dass das für dich regelt, musst du variante 2 (das mit den 3 parametern) genauer ansehen.
    du musst doch irgendwas von dem kombifeld haben. einen index, ein objekt, etc.

    beispiele finden sich massenhaft in diversen programmier-boards und -howtos. man muss sie nur suchen.

    EDIT: kann es sein, dass du irgendwelche hooks oder actionlistener setzen/verwenden kannst? darüber würde es auch gehen.
     
  5. specialist7

    specialist7 Kbyte

    Registriert seit:
    29. Juli 2002
    Beiträge:
    490
    Mit den MFC kannst du aber auch jedem Feld in deiner Ressourcen-datei eine Membervariable zuweisen, mit der du dann auf die entsprechenden Funktionen zugreifen kannst.

    Dafür klickst du im Dialogeditor mit der rechten Maustaste auf den Dialog und rufst "Memberviariablen" auf. Im folgenden Dialog erstellst du eine neue Membervariable mit dem Typ "CComboBox" bzw. "Steuerelementvariable" zu deinem Combofeld. Habe schon lange nicht mehr mit den MFC gearbeitet, müsste aber noch so stimmen... :rolleyes:

    Zu deinem Problem mit dem Auslesen:

    Code:
    int index = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
    
    // bzw. mit den MFC heißt es:
    
    int index = ControlCombo.GetCurSel():
    
    //nun hast du den Index des im Kontextmenü ausgewählten Eintrages
    
    //Auselen des Strings aus der Combobox:
    
    CString cString; // Variable für den Text
    ControlCombo.GetDlgItemText(index, cString);
    
    So, ich hoffe, das reicht erstmal für den Anfang. :) Ich muss ja zugeben, dass ich die vorherigen Posts nicht durchgelesen habe. Also verzeiht mir, falls das jetzt schon gepostet wurde... :p
     
  6. christian_3

    christian_3 Byte

    Registriert seit:
    20. Oktober 2004
    Beiträge:
    13
    Hallo!!!

    Herzlichen Dank für Deine Antwort! Das war das, was ich gesucht habe; zumindest zum Teil ;-))

    Auf die Idee mit der Variablenzuordnung hätte ich eigentlich auch selbst kommen können - aber nachdem ich bei Eingabefeldern darauf fixiert war mit UpdateData die Werte auszulesen, war ich da etwas 'vernebelt'.
    Jedenfalls hat die Sache so funktioniert. Was nicht funktioniert hat, war die Geschichte mit dem Auslesen des Wertes selbst. Der String, in dem das Ergebnis stehen sollte ist bei mir leer. Aber nachdem in meinen Konbinationsfeldern eh nur Zahlen von 1 bis 10 stehen und ich das Ergebnis auch als int benötige, benutze ich gleich den index.
    Trotzdem: vielleicht benötige ich ja auch mal die Einträge aus dem Kombinationsfeld. Kannst Du Dir die Zeilen nochmal angucken? Die Hilfe gibt mal wieder überhaupt nichts her. Da hab' ich nur gefunden:

    UINT GetDlgItemText( int nID, LPTSTR lpStr, int nMaxCount ) const;

    BOOL GetDlgItemText( int nID, BSTR& bstrText ) const;

    SeeGetDlgItemText in the Win32 SDK.

    Remarks

    Retrieves a control’s text. The second version of this method allows you to copy the control’s text to a BSTR. This version returns TRUE if the text is successfully copied; otherwise, FALSE.

    Was BSTR bedeutet - keine Ahnung. Da findet man:

    A length-prefixed string used by Automation data manipulation functions.

    typedef OLECHAR *BSTR;

    BSTRs are wide, double-byte (Unicode) strings on 32-bit Windows platforms and narrow, single-byte strings on the Apple® PowerMac™.

    For details on the BSTR data type, see Chapter 7, "Conversion and Manipulation Functions."

    Ich versteh's nicht. Aber wahrscheinlich ist das der Grund, warum nichts im String steht. Du hast ihn ja als CString definiert... Von BSTR hab' ich noch nie was gehört...


    @Michi0815: Auch Dir ein großes Dankeschön für Deine Mühe! Ich habe wirklich probiert zu verstehen, was Du mir geschrieben hast, bin dazu aber wohl leider zu doof gewesen ;-))
     
  7. specialist7

    specialist7 Kbyte

    Registriert seit:
    29. Juli 2002
    Beiträge:
    490
    Also die MFC handhaben alles immer ein bisschen anders als "normale" WinApi-Anwendungen.

    Deshalb dachte ich, dass

    Code:
    ControlCombo.GetDLgItemText(index, cString);
    
    funktionieren würde- index wäre der Index des Eintrages und cString eine Variable vom Typ CString (wie oben beschrieben :) ) Normalerweise musst du bei GetDlgItemText als ersten Parameter die Ressource-ID angeben und als zweiten den String. Optional als dritten Parameter die maximale Länge.

    Musst mal selber ein bisschen damit rumprobieren. Kann dir ansonsten leider nicht weiterhelfen, wenn es immer noch nicht funktioniert... :heul:
     
Status des Themas:
Es sind keine weiteren Antworten möglich.

Diese Seite empfehlen