MenuItem von MF_STRING in MF_POPUP ändern



  • Guten Morgen,

    ja das ginge, aber: Hintergrund ist, dass ich mir ein Framework selbst programmiere. Das heißt, es basieren alle grafischen Elemente auf Klassen und ich möchte mir möglichst keine unnötigen Daten im Speicher halten. Somit hat meine MenuItem-Klasse auch kein Member "Name".
    Wenn ich nun das MenuItem löschen und neu anlegen will, muss ich mir zunächst den Namen holen. Finde ich nicht so schön, auch wenn es eine Möglichkeit wäre. Die Funktion ModifyMenu habe ich aus diesem Grund bisher auch nicht genutzt.

    MfG Torsten


  • Mod

    @tormen_bln sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    SetMenuItemInfo

    Mal grundsätzlich: Dir ist klar was die Member fMask und fType machen?
    Du benutzt diese nicht!



  • @tormen_bln sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    Im Netz findet man dazu keine Informationen.

    Doch (MSDN). Da steht zum Beispiel, dass man im Fehlerfall GetLastError aufrufen kann/sollte.
    Ist _menuHandle denn überhaupt ein gültiges Handle? Wozu die Casts?



  • Hallo nochmal,

    @Martin-Richter : Natürlich ist mir die Funktionsweise klar (fMask / fType). Aber ich kann bei fType eben das POPUP nicht finden. Sind die Flags MFT_MENUBARBREAK und/oder MFT_MENUBREAK in dem Fall zu setzen?

    @yahendrik : GetLastError() nutze ich auch. Aber wenn ich die entsprechenden Flags nicht kenne bzw. nicht setze, werde ich auch keine Fehlermeldung bzgl. Popup Item bekommen, richtig? Die Handles sind natürlich gültig! Die Casts mache ich, weil die ObjectIds in meiner Applikation alle size_t sind.

    MfG Torsten



  • @tormen_bln sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    Sind die Flags MFT_MENUBARBREAK und/oder MFT_MENUBREAK in dem Fall zu setzen?

    Nein.

    fMask = MIIM_SUBMENU um ein neues hSubMenu zu setzten.



  • Ah,

    okay. Werde ich heute Abend ausprobieren.

    MfG Torsten



  • Ja nee, Kommando zurück!

    @Swordfish Was steht denn im Beispielquelltext drin (siehe oben)?

    Ich habe nun mal die Variante via ModifyMenu() versucht, um evtl. einen Hinweis auf meine fehlenden Flags zu erhalten, siehe folgendes Beispiel (soll nur examplarisch dienen):

    if (ModifyMenu(_parentHandle, (UINT)getObjectId(), MF_POPUP, (UINT_PTR)getHandle(), (LPCSTR)"N E U")) // zuvor mit MF_STRING erzeugtes MenuItem in MF_POPUP ändern
    {
    	if (AppendMenu((HMENU)getHandle(), MF_STRING, (UINT_PTR)_menuItem->getObjectId(), (LPCSTR)"SUBMENU")) // neues MenuItem an MF_POPUP anhängen
    	{
    		MENUITEMINFO _menuItemInformation = { sizeof(MENUITEMINFO), MIIM_FTYPE | MIIM_ID | MIIM_STATE | MIIM_SUBMENU };
    
    		if (GetMenuItemInfo(_parentHandle, (UINT)0, TRUE, &_menuItemInformation)) // Flags des MF_POPUP holen
    		{
    			int x = 0;
    		}
    	}
    }
    

    Nochmal zum Verständis. Ich erzeuge eine MenuBar und hänge ein MenuItem (MF_STRING) an. Dieses möchte ich gerne in ein MF_POPUP ändern (im Beispiel mache ich das mit ModifyMenu(), erste Zeile).
    Im Beispiel kann ich im Anschluss daran, ein SubMenuItem (MF_STRING) anhängen. So funktioniert das auch wie gewünscht. Aber eben nicht via GetMenuItemInfo() und SetMenuItemInfo().

    Wenn ich nun (zu Debugzwecken) mir die Informationen über das eben geänderte MenuItem hole, sehe ich keine weiteren Flags, die durch ModifyMenu() gesetzt wurden. Ich erhalte lediglich folgende Werte:

    cbSize = 0x50
    fMask = 0x107
    wID = 0x11D5044D (das ist das Handle des SubMenuItems)
    hSubMenu = 0x11D5044D (dito)

    Der Rest ist null. Wenn ich mir die Dokumentation anschaue, sehe ich auf Anhieb auch keine Hinweise dazu.

    MfG Torsten



  • @tormen_bln sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    @Swordfish Was steht denn im Beispielquelltext drin (siehe oben)?

    Keine Ahnung wo "oben" ist und warum du mich das fragst. Auch hab' ich keinen Schimmer, wo dein Problem liegt.

    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    LRESULT WINAPI window_proc(HWND window, UINT message, WPARAM wparam, LPARAM lparam)
    {
    	static HMENU menu{};
    	static HMENU submenu{};
    	static HWND button{};
    
    	switch (message) {
    	case WM_CREATE:
    		menu = CreateMenu();
    		AppendMenuW(menu, MF_STRING, 1, L"Foo");
    		AppendMenuW(menu, MF_STRING, 2, L"Bar");
    		AppendMenuW(menu, MF_STRING, 3, L"Baz");
    		AppendMenuW(menu, MF_STRING, 4, L"Qux");
    		SetMenu(window, menu);
    		button = CreateWindowW(L"BUTTON", L"Magic", WS_VISIBLE | WS_CHILD, 10, 10, 120, 25, window, nullptr, nullptr, 0);
    		return 0;
    
    	case WM_COMMAND:
    		if (reinterpret_cast<HWND>(lparam) == button && !submenu) {
    			submenu = CreateMenu();
    			AppendMenuW(submenu, MF_STRING, 5, L"one");
    			AppendMenuW(submenu, MF_STRING, 6, L"two");
    			AppendMenuW(submenu, MF_STRING, 7, L"three");
    
    			MENUITEMINFOW mii{ sizeof(mii) };
    			mii.fMask = MIIM_SUBMENU;
    			mii.hSubMenu = submenu;
    			SetMenuItemInfoW(menu, 3, TRUE, &mii);   // 3, TRUE ... by position
                                                         // 4, FALSE ... by id
                                                         // laeuft aufs gleiche raus
    		}
    		return 0;
    
    	case WM_DESTROY:
    		PostQuitMessage(0);
    		return 0;
    	}
    	return DefWindowProc(window, message, wparam, lparam);
    }
    
    int APIENTRY WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int show_state)
    {
    	WNDCLASSW wc{ sizeof( wc ) };
    	wc.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1);
    	wc.hCursor = LoadCursor(nullptr, IDC_ARROW);
    	wc.hInstance = instance;
    	wc.lpfnWndProc = window_proc;
    	wc.lpszClassName = L"TestClass";
    	wc.style = CS_HREDRAW | CS_VREDRAW;
    
    	if (!RegisterClassW(&wc)) {
    		MessageBox(nullptr, L"RegisterClassW() failed :(", L"Error:", MB_ICONEXCLAMATION);
    		return 0;
    	}
    
    	auto window = CreateWindowW(wc.lpszClassName, L"TestWindow", WS_OVERLAPPEDWINDOW,
    		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, instance, 0);
    
    	if (!window) {
    		MessageBox(nullptr, L"CreateWindowW() failed :(", L"Error:", MB_ICONEXCLAMATION);
    		return 0;
    	}
    
    	UpdateWindow(window);
    	ShowWindow(window, show_state);
    
    	MSG msg;
    	int result;
    	while ((result = GetMessageW(&msg, window, 0, 0)) != 0) {
    		if (result == -1)
    			break;
    		TranslateMessage(&msg);
    		DispatchMessageW(&msg);
    	}
    
    	return static_cast<int>(msg.wParam);
    }
    

    Click auf "Magic" und du findest wie von Geisterhand ein Submenü unter "Qux".



  • N' Abend,

    @Swordfish Das bezog sich darauf, dass ich die Flags wie im ersten Thread gezeigt, gesetzt habe. Aber das war nicht das Problem. Dank deines Quelltextes habe ich gesehen, was ich vergessen / falsch gemacht habe. Ist mir durch die Anwendung des ModifyMenu() nicht in den Sinn gekommen. Mir fehlte das CreateMenu() welches du in der WM_COMMAND benutzt.

    Vielen, vielen Dank dafür und einen schönen Abend noch.

    MfG Torsten


  • Mod

    Ich verstehe Dein Problem nicht.

    Bit zeige Code wie Du es machst. Oben hast Du Code gezeigt, der fType UND fMask nicht setzt.
    Wenn Du SetMenuItemInfo aufrufst musst Du aber in der Struktur angeben, was Du setzen möchtest und Du solltest natürlich auch fType setzen Stil für diesen Menupunkt sich auch ändert.
    Deshalb mein Einwurf und die Frage ob Du es verstanden hast.
    Und auch in Deinen nachfolgenden Postings ignorierst Du fType geflissentlich.

    Wie wäre es mit etwas mehr Dokus lesen und weniger posten?

    Ansonsten:

    1. kann es einfach gut sein, dass solch eine Änderung nicht möglich ist: Also Löschen und Neuanlegen.
    2. kannst Du mal ModifyMenu versuchen. Damit sollte es eigentlich auch gehen.


  • @Martin-Richter sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    und Du solltest natürlich auch fType setzen Stil für diesen Menupunkt sich auch ändert.

    Es gibt keinen "Stil" für ein Submenü. Entweder ein Menu Item hat ein gesetztes submenu oder eben nicht.

    @Martin-Richter sagte in MenuItem von MF_STRING in MF_POPUP ändern:

    kann es einfach gut sein, dass solch eine Änderung nicht möglich ist: Also Löschen und Neuanlegen.

    Ich habe doch oben in einem kompilierbarem Beispiel gezeigt, daß und wie es möglich ist 😕


Anmelden zum Antworten