• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[C++] Problem bei Menü

zauberwürfel

Mitglied
Hallo zusammen,
ich versuche mich gerade im programmieren von menüleisten in win32 anwendungen. jetzt möchte ich erreichen, dass dem menü ein untermenü hizugefügt wird (wie z.B im ie unter ansicht -> zoom). google konnte mir hier nicht helfen, ich hoffe, ihr rettet mich!
zauberwürfel
 
Bitte erstmal etwas Code Zeigen.... da ich nicht weiß ob du gtk oder QT benutzt. Oder einfach nur eine Consolen Anwendung.
Für Grafische anzeigen musst du ja eine der Beiden Bibliotheken benutzen.
Schaue dir die Bibliotheken an dort sind meistens schon in den Klassen die gesuchten Methoden enthalten.

So kann man dir leider nicht helfen... da ich nicht weiß was du benutzt und wie es bei dir aussieht.
 
Hi,
ich muss mich erst noch daran gewöhnen, was man alles für schnell hilfe tun muss...
also, ich benutze eine einfache datei, mit der das fenster erzeugt wird (hier main.cpp). dann habe ich noch eine bibliothek namens resource.h erstellt. in dem rc-dokument steht das, was das menü braucht, also das müsste ich vermutlich auch ändern, aber ich weiß nicht, wie. die codes:
recource.h:
Code:
#define IDR_MYMENU 101
#define ID_FILE_EXIT 9001
#define ID_STUFF_GO 9002

main.cpp:
Code:
#include <windows.h>
#include "resource.h"
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
    switch(msg) {
        case WM_LBUTTONDOWN: {
             char szFileName[MAX_PATH];
             HINSTANCE hInstance = GetModuleHandle(NULL);
             GetModuleFileName(hInstance, szFileName, MAX_PATH);
             MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
        }
        break;
        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
    
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
    
    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "ERROR!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "TITEL", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
    
    if(hwnd == NULL) {
        MessageBox(NULL, "ERROR!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    
    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}

.rc:
Code:
#include "resource.h"
IDR_MYMENU MENU
    BEGIN
        POPUP "&File"
        BEGIN
            MENUITEM "E&xit", ID_FILE_EXIT
        END
        POPUP "&Stuff"
        BEGIN
            MENUITEM "&Go", ID_STUFF_GO
            MENUITEM "G&o somewhere else", 0, GRAYED
        END
END

Hier ein screenshot von dem programm:

image1.gif
zauberwürfel
 
Die untermenüs nennen sich oft subitems, da ich jetzt nicht weiss ob das qt oder gtk ist, würde ich nach subitems suchen.
 
Mit resource.rc kann ich dir leider nicht helfen, weil ich das selber nicht auf die Reihe bekommen habe, aber ich kann dir erklären, wie es ohne resource.rc geht.
Du definierst immer noch in der resource.h die einzelnen Menüpunkte und ergänzt dann die main.cpp.
Das ist dein code, meine Ergänzungen habe ich mit ******* markiert

Code:
#include <windows.h>
#include "resource.h"
const char g_szClassName[] = "myWindowClass";
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {

// *******

static HMENU hMenu = {0};
static HMENU hSubMenu1 = {0};
static HMENU hSubMenu2 = {0};

// *******

    switch(msg) {
        case WM_LBUTTONDOWN: {
             char szFileName[MAX_PATH];
             HINSTANCE hInstance = GetModuleHandle(NULL);
             GetModuleFileName(hInstance, szFileName, MAX_PATH);
             MessageBox(hwnd, szFileName, "This program is:", MB_OK | MB_ICONINFORMATION);
        }
        break;

// **************

case WM_CREATE:

hMenu = CreateMenu();
hSubMenu1 = CreatePopupMenu();
hSubMenu2 = CreatePopupMenu();

AppendMenu(hSubMenu1,MF_STRING,ID_FILE_EXIT,"Exit");
AppendMenu(hMenu,MF_STRING|MF_POPUP,(UINT_PTR)hSubMenu1,"File");

AppendMenu(hSubMenu2,MF_STRING,ID_STUFF_GO,"Go");
AppendMenu(hSubMenu2,MF_STRING,ID_STUFF_SOMEWHERE_ELSE,"Somewhere else");
AppendMenu(hMenu,MF_STRING|MF_POPUP,(UINT_PTR)hSubMenu2,"Stuff");

SetMenu(hwnd,hMenu);

break;

case WM_COMMAND:
{
switch(LOWORD(wParam))
      {
            case ID_FILE_EXIT:
            PostMessage(hwnd,WM_CLOSE,0,0);
            break;
            case ID_STUFF_GO:
            // geh irgendwo hin
            break;
            case ID_STUFF_SOMEWHERE_ELSE:
            // geh woanders hin
            break;
      }
}
break;

// *************

        case WM_CLOSE:
            DestroyWindow(hwnd);
        break;
        case WM_DESTROY:
            PostQuitMessage(0);
        break;
        default:
            return DefWindowProc(hwnd, msg, wParam, lParam);
    }
    return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
    WNDCLASSEX wc;
    HWND hwnd;
    MSG Msg;
    
    wc.cbSize = sizeof(WNDCLASSEX);
    wc.style = 0;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = g_szClassName;
    wc.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_MYICON), IMAGE_ICON, 16, 16, 0);
    
    if(!RegisterClassEx(&wc)) {
        MessageBox(NULL, "ERROR!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, g_szClassName, "TITEL", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, NULL, NULL, hInstance, NULL);
    
    if(hwnd == NULL) {
        MessageBox(NULL, "ERROR!", "Error", MB_ICONEXCLAMATION | MB_OK);
        return 0;
    }
    
    ShowWindow(hwnd, nCmdShow);
    UpdateWindow(hwnd);
    
    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    }
    return Msg.wParam;
}
 
Hi zusammen,
ich hab es selbst herausgefunden. Im rc fügt man statt einem MENUITM einfach ein weiteres POPUP ein und verfährt dann ganz normal.
@Mark: Ich werde deine Methode bei nächster Gelegenheit ausprobieren.
Allerdings hätte ich noch eine andere Frage zu Menüs in c++: Kann man ein Icon vor dem Menüeintrageinfügen? Oder den Eintrag mit ein
 
Zurück
Oben