Hallo,
also erstmal rechtherzlichen Dank für die wirklich gute Antwort. Also ich habe das bereits ausprobiert und es funktioniert.
Leider bin ich zur Zeit wohl noch zu c++ lastig, das es mir an einigen Stellen wirklich schwer fällt, alles als Objekt anzusehen. Aber egal, dafür lernt man ja, und kann sich solchen Foren anschließen.
Jetzt habe ich allerdings noch eine Frage.
Und zwar geht es um folgendes Problem. Ich einer Klasse erledige ich alle DB Angelegenheiten. Da gibt es z.B. eine tabelle für die Sprache, Menüs, User, und Funktionen usw.
Jetzt möchte ich in meinem Hauptformular (C++ Builder - Style) einige Funktionen definieren. In meiner Klasse möchte ich nun dynamisch ein MainMenu zur Laufzeit erstellen. Die in meiner Main definierten Funktionen sollen jetzt der eigenen Klasse übergeben und mit den entsprechenden Menüeintragen gekoppelt werden. Vielleicht hilft es an dieser Stelle, mal die C++ Sourcen zu zeigen:
Hier die Struktur:
typedef struct functions {
AnsiString fMenuName;
TNotifyEvent fktPointer;
AnsiString fktName;
} tsFunctions, *tpsFunctions;
Also hier ist eine Funktion die das MainMenu erstellt und eine Struktur füllt:
fMainMenu = new TMainMenu(this);
fMainMenu->Name = "fMain";
fMainMenu->AutoHotkeys = maManual;
Session->Functions = (tpsFunctions) calloc(5, sizeof(tsFunctions));
Session->FunctionCount = 5;
memset(Session->Functions, '\0', sizeof(tsFunctions));
Session->Functions[0].fktPointer = ExitProgram;
Session->Functions[0].fktName = "ExitProgram";
Session->Functions[1].fktPointer = ShowAboutBox;
Session->Functions[1].fktName = "ShowAboutBox";
Session->Functions[2].fktPointer = IconViewstyle;
Session->Functions[2].fktName = "IconViewstyle";
Session->Functions[3].fktPointer = ReportViewstyle;
Session->Functions[3].fktName = "ReportViewstyle";
Session->Functions[4].fktPointer = ShowUserManagement;
Session->Functions[4].fktName = "ShowUserManagement";
Session->ReadMenus(fMainMenu);
Jetzt die Generierung des MenÜs in meiner Klasse:
void __fastcall TGlbFunctions::ReadMenus(TMainMenu *Menu)
{
AnsiString tmpSQL;
TNotifyEvent tmpFunction;
AnsiString ShortCutKey;
bool activ = false;
fMenuEvents = new TStringList();
fMenuEvents->Clear();
fMenuShortcuts = new TStringList();
fMenuShortcuts->Clear();
fSQL = "";
fSQL.SetLength(0);
fSQL = "SELECT * FROM menus ORDER BY menuid";
fDBEngine->Connected = false;
fDBTable->Active = false;
fDBTable->SQL->Clear();
fDBTable->SQL->Add(fSQL);
fDBEngine->Connected = true;
fDBTable->Active = true;
fDBTable->First();
while (! fDBTable->Eof ) {
AnsiString tmpData;
tmpData = "";
ShortCutKey = fDBTable->FieldByName("ShortCut")->AsString;
tmpData = fDBTable->FieldByName("Caption")->AsString;
if ( !fLanguage->Values[tmpData].IsEmpty() ) {
tmpData = fLanguage->Values[tmpData];
}
if ( fDBTable->FieldByName("MainID")->AsInteger == 0 ) {
fMainItem = new TMenuItem(Menu);
fMainItem->Name = tmpData + IntToStr(fMainItem->Count+1);
fMainItem->Caption = tmpData;
fMainItem->AutoHotkeys = maManual;
Menu->Items->Add(fMainItem);
} else {
activ = false;
if ( fDBTable->FieldByName("Enabled")->AsInteger == 1 ) {
activ = true;
} else {
activ = false;
}
bool checked = false;
if ( UpperCase(fDBTable->FieldByName("Checked")->AsString) == "X" ) {
checked = true;
}
for ( int i = 0; i < fFunctionCount; i++ ) {
AnsiString test1, test2, test3;
if ( strcmp(fFunctions[i].fktName.c_str(), fDBTable->FieldByName("OnClickEvent")->AsString.c_str()) == 0 ) {
fFunctions[i].fMenuName = fDBTable->FieldByName("Caption")->AsString;
tmpFunction = fFunctions[i].fktPointer;
break;
}
}
if ( ShortCutKey.IsEmpty() ) {
fSubItem = NewItem(tmpData, NULL, checked, activ, tmpFunction, TextToShortCut(ShortCutKey), fDBTable->FieldByName("Caption")->AsString);
} else {
fMenuShortcuts->Add(ShortCutKey + "=" + fDBTable->FieldByName("OnClickEvent")->AsString);
fSubItem = NewItem(tmpData + " [" + ShortCutKey + "]", NULL, checked, activ, tmpFunction, TextToShortCut(ShortCutKey), fDBTable->FieldByName("Caption")->AsString);
}
fMainItem->Add(fSubItem);
}
fDBTable->Next();
}
}
Ich hoffe es reicht, um zu zeigen, was ich eigentlich vor habe. Vielleicht habe ich es auch in C++ schon zu kompliziert angestellt, dass es mir jetzt um so schwerer fällt, das ganze in C# abzubilden.
Gruß
Sasch
also erstmal rechtherzlichen Dank für die wirklich gute Antwort. Also ich habe das bereits ausprobiert und es funktioniert.
Leider bin ich zur Zeit wohl noch zu c++ lastig, das es mir an einigen Stellen wirklich schwer fällt, alles als Objekt anzusehen. Aber egal, dafür lernt man ja, und kann sich solchen Foren anschließen.
Jetzt habe ich allerdings noch eine Frage.
Und zwar geht es um folgendes Problem. Ich einer Klasse erledige ich alle DB Angelegenheiten. Da gibt es z.B. eine tabelle für die Sprache, Menüs, User, und Funktionen usw.
Jetzt möchte ich in meinem Hauptformular (C++ Builder - Style) einige Funktionen definieren. In meiner Klasse möchte ich nun dynamisch ein MainMenu zur Laufzeit erstellen. Die in meiner Main definierten Funktionen sollen jetzt der eigenen Klasse übergeben und mit den entsprechenden Menüeintragen gekoppelt werden. Vielleicht hilft es an dieser Stelle, mal die C++ Sourcen zu zeigen:
Hier die Struktur:
typedef struct functions {
AnsiString fMenuName;
TNotifyEvent fktPointer;
AnsiString fktName;
} tsFunctions, *tpsFunctions;
Also hier ist eine Funktion die das MainMenu erstellt und eine Struktur füllt:
fMainMenu = new TMainMenu(this);
fMainMenu->Name = "fMain";
fMainMenu->AutoHotkeys = maManual;
Session->Functions = (tpsFunctions) calloc(5, sizeof(tsFunctions));
Session->FunctionCount = 5;
memset(Session->Functions, '\0', sizeof(tsFunctions));
Session->Functions[0].fktPointer = ExitProgram;
Session->Functions[0].fktName = "ExitProgram";
Session->Functions[1].fktPointer = ShowAboutBox;
Session->Functions[1].fktName = "ShowAboutBox";
Session->Functions[2].fktPointer = IconViewstyle;
Session->Functions[2].fktName = "IconViewstyle";
Session->Functions[3].fktPointer = ReportViewstyle;
Session->Functions[3].fktName = "ReportViewstyle";
Session->Functions[4].fktPointer = ShowUserManagement;
Session->Functions[4].fktName = "ShowUserManagement";
Session->ReadMenus(fMainMenu);
Jetzt die Generierung des MenÜs in meiner Klasse:
void __fastcall TGlbFunctions::ReadMenus(TMainMenu *Menu)
{
AnsiString tmpSQL;
TNotifyEvent tmpFunction;
AnsiString ShortCutKey;
bool activ = false;
fMenuEvents = new TStringList();
fMenuEvents->Clear();
fMenuShortcuts = new TStringList();
fMenuShortcuts->Clear();
fSQL = "";
fSQL.SetLength(0);
fSQL = "SELECT * FROM menus ORDER BY menuid";
fDBEngine->Connected = false;
fDBTable->Active = false;
fDBTable->SQL->Clear();
fDBTable->SQL->Add(fSQL);
fDBEngine->Connected = true;
fDBTable->Active = true;
fDBTable->First();
while (! fDBTable->Eof ) {
AnsiString tmpData;
tmpData = "";
ShortCutKey = fDBTable->FieldByName("ShortCut")->AsString;
tmpData = fDBTable->FieldByName("Caption")->AsString;
if ( !fLanguage->Values[tmpData].IsEmpty() ) {
tmpData = fLanguage->Values[tmpData];
}
if ( fDBTable->FieldByName("MainID")->AsInteger == 0 ) {
fMainItem = new TMenuItem(Menu);
fMainItem->Name = tmpData + IntToStr(fMainItem->Count+1);
fMainItem->Caption = tmpData;
fMainItem->AutoHotkeys = maManual;
Menu->Items->Add(fMainItem);
} else {
activ = false;
if ( fDBTable->FieldByName("Enabled")->AsInteger == 1 ) {
activ = true;
} else {
activ = false;
}
bool checked = false;
if ( UpperCase(fDBTable->FieldByName("Checked")->AsString) == "X" ) {
checked = true;
}
for ( int i = 0; i < fFunctionCount; i++ ) {
AnsiString test1, test2, test3;
if ( strcmp(fFunctions[i].fktName.c_str(), fDBTable->FieldByName("OnClickEvent")->AsString.c_str()) == 0 ) {
fFunctions[i].fMenuName = fDBTable->FieldByName("Caption")->AsString;
tmpFunction = fFunctions[i].fktPointer;
break;
}
}
if ( ShortCutKey.IsEmpty() ) {
fSubItem = NewItem(tmpData, NULL, checked, activ, tmpFunction, TextToShortCut(ShortCutKey), fDBTable->FieldByName("Caption")->AsString);
} else {
fMenuShortcuts->Add(ShortCutKey + "=" + fDBTable->FieldByName("OnClickEvent")->AsString);
fSubItem = NewItem(tmpData + " [" + ShortCutKey + "]", NULL, checked, activ, tmpFunction, TextToShortCut(ShortCutKey), fDBTable->FieldByName("Caption")->AsString);
}
fMainItem->Add(fSubItem);
}
fDBTable->Next();
}
}
Ich hoffe es reicht, um zu zeigen, was ich eigentlich vor habe. Vielleicht habe ich es auch in C++ schon zu kompliziert angestellt, dass es mir jetzt um so schwerer fällt, das ganze in C# abzubilden.
Gruß
Sasch
Comment