Menü - dynamische Menüs
-
Es ist folgende Problemstellung:
Man hat ein Menu, und fügt während der Laufzeit Daten (Untermenus)hinzu.
Das daraus resultierende Problem ist, das man auf diese Dynamisch
implementierten Menus auch dynamisch während der Laufzeit reagieren muss.
Ich möchte dies an folgendem Beispiel demonstrieren:Implementation während der Laufzeit:
(Das Beispiel fügt Ordner Namen als Untermenüs hinzu)CFileFind find; BOOL bWorking = find.FindFile(MusikDirectory+"\\*.*"); CString Ordner; int i=FileWork.GetnDir(MusikDirectory);//stellt fest wieviele Ordner vorhanden sind. Musikordner = new Musikrichtung[i+1];//struct zur Datenspeicherung i=0; int n_ID=50001;//die IDs für die neuen Untermenus. CMenu Menu, *submenu, *smenu, *quellen; Menu.LoadMenu(IDR_MENU1);//das Hauptmenü submenu=Menu.GetSubMenu(0);//in Untermenüs verzweigen. smenu= submenu->GetSubMenu(0); quellen = smenu->GetSubMenu(0); while(bWorking) { bWorking = find.FindNextFile(); if(find.IsDirectory()) { Ordner=find.GetFileName(); if(Ordner != "Music" && Ordner != "." && Ordner != "..") { quellen->InsertMenu(0,MF_BYPOSITION,n_ID,Ordner); Musikordner[i].Dir=MusikDirectory + "\\"+Ordner; Musikordner[i].nID=n_ID; n_ID++; i++; } } } Musikordner[i].Dir="Music"; Musikordner[i].nID=50000; SetMenu(&Menu); Menu.Detach();//Recource wieder freigeben find.Close(); return true;
Der Code tut folgendes machen:
Er fügt im Menu Music Maker-> Musikquellen->Musikrichtungen neue Menus ein.
Unter Musikrichtungen besteht bereits ein Untermenü mit dem Titel ‘Music‘.
Die Namen der Untermenus sind Ordnernamen eines bestimmten Pfades. (z.B. “C:\\“ [img]images/smiles/icon_wink.gif[/img]
Musikordner ist ein Struct welches folgenden Aufbau hat:struct Musikrichtung { int nID;//die ID CString Dir;//der Name des Untermenus };
Dieses Struct dient zur Speicherung der IDs der neuen Untermenus.
Die Neuen Menus haben alle die ID ab 50000, so dass man nun
auf Meldungen in der OnCommand entsprechend reagieren kann:BOOL CMusicMakerDlg::OnCommand(WPARAM wParam, LPARAM lParam) { UINT Wert=(UINT) LOWORD(wParam);//wParam enthält die ID der angeklickten Recource if((UINT) LOWORD(wParam)>49999 && (UINT) LOWORD(wParam) < 50200 )//mehr als 200 Untermenüs wird er schon nicht finden ;) { for(int i =-1;Musikordner[i].nID != Wert;i++);//nach der ID suchen CurrentDir = Musikordner[i].Dir; //hier kann man dann auf die Ausgewählte ID reagieren. } return CDialog::OnCommand(wParam, lParam); }
Es funktioniert natürlich auch mit nicht Modalen Anwendungen (SDI/MDI).
Devil
-
Kommt in die FAQ images/smiles/icon_smile.gif
-
Ich bin in der FAQ images/smiles/icon_biggrin.gif
Devil
-
Hallo zusammen,
ein wenig wurde von seiten der Programmierer von MSVC++ schon auch auf diese Problematik eingegangen. Es gibt die Möglichkeit über On_Command_Range (analog On_Control_Range) einen gewissen ID- Bereich in der MessageMap festzulegen (s. MSDN).
Nur so als zusätzliche Anmerkung zum Thema, die vielleicht nicht unerwähnt bleiben sollte...
Gruß, Volle.