An String von Menu Item kommen?



  • @Mike85Dev sagte in An String von Menu Item kommen?:

    der rückgabewert ist immer 0.

    Der sicherste Weg hier ignoriert zu werden ist auf Anfragen keine Antwort zu geben. Th69 hat dich um Quelltext gebeten, nicht um das Ergebnis eines Funktionsaufrufs.



  • Doch, um beides. 😉

    Paßt denn auch der erste Parameter? Ist dies wirklich das Handle zu dem Menü? Denn der Name hwndItem und der Cast deuten nicht daraufhin...
    Was ist Item denn für eine Struktur?



  • Das Popup Menu (alles kurz zusammengefasst)...

    HMENU hMenu = CreatePopupMenu();
    InsertMenu (hMenu, 1, MF_STRING | MF_BYPOSITION | MF_OWNERDRAW, 888, L"Test Eintrag");
    TrackPopupMenu(hMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, pt.x, pt.y, 0, hwnd, NULL);

    und dann die abfrage...
    case WM_DRAWITEM:
    LPDRAWITEMSTRUCT Item = (LPDRAWITEMSTRUCT)lParam;
    GetMenuString((HMENU)Item->hwndItem, Item->itemID, lpBuff, 50, MF_BYCOMMAND);
    MessageBox(hwnd,lpBuff,NULL,0);



  • OK, scheint wohl das richtige Handle laut DRAWITEMSTRUCT zu sein.

    Und wie ist lpBuff deklariert und initialisiert?

    Üblicherweise würde man es so programmieren:

    TCHAR buff[50] = { 0 };
    GetMenuString((HMENU)Item->hwndItem, Item->itemID, buff, sizeof(buff)/sizeof(buff[0]), MF_BYCOMMAND);
    MessageBox(hwnd, buff, NULL, MB_OK);
    


  • Genau so habe ich es auch initialisiert.



  • Mich hat nur der Prefix lp (long pointer) verwundert.

    Aber so langsam bin ich jetzt auch überfragt.

    Klappt denn überhaupt das Auslesen, z.B.

    GetMenuString((HMENU)Item->hwndItem, 0, buff, sizeof(buff)/sizeof(buff[0]), MF_BYPOSITION); // 1. Menüeintrag
    

    ?



  • Nein, klappt nicht.



  • Hast du denn mal den Wert von hwndItem jetzt überprüft, ob der dem Rückgabewert von CreatePopupMenu entspricht?

    Das sollte doch alles mittels Debuggen innerhalb von ein paar Minuten erledigt sein...

    Edit: Und hast du beim Zeichnen denn auch den Typ abgefragt (item->CtlType == ODT_MENU)?



  • Ich würde als erstes mal probieren das direkt nach InsertMenu zum Laufen zu bekommen. Mit dem korrekten Handle. Und mich dann von dort aus weiterhanteln.



  • @Th69 ja hab geprüfte auf ODT_MENU und der Handle ist auch der selbe.



  • @Mike85Dev sagte in An String von Menu Item kommen?:

    InsertMenu (hMenu, 1, MF_STRING | MF_BYPOSITION | MF_OWNERDRAW, 888, L"Test Eintrag");

    Das Ding gibt nen BOOL zurück. Könnte leicht sein dass da 0 zurückkommt.

    Versuch's mal mit 0 bzw. -1 für uPosition.
    Ansonsten: GetLastError nach dem Aufruf prüfen.



  • Sieh Dir einmal die Parameterbeschreibung für lpNewItem aus der Funktion InsertMenu an und was MF_OWNERDRAW dort bewirkt.
    Das OWNERDRAW-Flag erst nach dem Aufruf von InsertMenu setzen, dann klappt es auch. ;o)
    Oder besser gleich InsertMenuItem benutzen.



  • Beim Aufruf von InsertMenu macht es keinen Sinn, sowohl `MF_STRING' als auch 'MF_OWNERDRAW' anzugeben.

    InsertMenu (hMenu, 1, MF_BYPOSITION | MF_OWNERDRAW, 888, L"Test Eintrag");
    

    Und dann braucht auch bei WM_DRAWITEM nicht extra GetMenuString aufgerufen werden, denn in Item->itemData steht dann der Zeiger auf den übergebenen Text drin.

    s.a. Creating Owner-Drawn Menu Items

    Ergo: Wichtig, wenn etwas nicht funktioniert: Doku lesen und vernünftig debuggen. 😉

    PS: Erzeugst du denn (laut deinem Code) einfach ein neues Popup-Menu mit diesem einem Eintrag?! Warum verwendest du dann nicht AppendMenu?



  • @Th69 sagte in An String von Menu Item kommen?:

    Beim Aufruf von InsertMenu macht es keinen Sinn, sowohl `MF_STRING' als auch 'MF_OWNERDRAW' anzugeben.

    MF_STRINGist eh nur symbolische Kosmetik, weil Wert gleich 0.

    Und dann braucht auch bei WM_DRAWITEM nicht extra GetMenuString aufgerufen werden (auch wenn immer noch nicht geklärt ist, warum es nicht funktioniert?!), denn in Item->itemData steht dann der Zeiger auf den übergebenen Text drin).

    Weil GetMenuString keinen Zeiger auf eine Zeichenkette findet, denn (wie Du richtig erkannt hast) der OP hat den Zeiger mit seinem Aufruf von InsertMenu plus ´MF_OWNERDRAW´ in dwItemData abgelegt und nicht in dwTypeData.
    MENUITEMINFOW structure

    Die alten Menüfunktionen sind nur noch Wrapper der neuen Menüfunktionen wie InsertMenuItem oder Get-/SetMenuItemInfo.
    (Edit: Dies ist nur eine Annahme meinerseits)

    Daher mein Rat besser gleich InserMenuItem zu benutzen.

    LG
    Greenhorn



  • Ja, ist ja (jetzt) auch logisch, daß dann kein String-Text ausgelesen werden kann, da ja nicht zwangsläufig ein String bei MF_OWNERDRAW übergeben werden muß, sondern es kann ja auch eine beliebige Datenstruktur o.ä. sein.



  • Doch das geht. Hab gemerkt das der String sich in Item->itemData versteckt hat. Ich musste nicht mal was beim Menü erstellen ändern. Danke für eure Hilfe ☺



  • @Mike85Dev sagte in An String von Menu Item kommen?:

    Doch das geht. Hab gemerkt das der String sich in Item->itemData versteckt hat. Ich musste nicht mal was beim Menü erstellen ändern. Danke für eure Hilfe ☺

    Das geht nur, so lange garantiert ist dass der Speicherbereich in dem der String steht nicht freigegeben wird so lange das Menu existiert.
    Probier das selbe mal mit

    std::wstring text = L"Test Eintrag";
    InsertMenu (hMenu, 0, MF_STRING | MF_BYPOSITION | MF_OWNERDRAW, 888, text.c_str());
    

    dann siehst du was ich meine.



  • Und ich meinte bei
    @Th69 sagte in An String von Menu Item kommen?:

    Ja, ist ja (jetzt) auch logisch, daß dann kein String-Text ausgelesen werden kann, da ja nicht zwangsläufig ein String bei MF_OWNERDRAW übergeben werden muß, sondern es kann ja auch eine beliebige Datenstruktur o.ä. sein.

    explizit das Auslesen mittels der GetMenuString-Funktion.


Anmelden zum Antworten