<Je me permets d'éditer mon message pour y apporter des corrections et de nouvelles informations>
Bonjour,
Je suis en train de construire une dll de composants hérités de la vcl dans le but de faciliter la construction d'une interface graphique sans utiliser l'éditeur de forme de builder. J'utilise C++ Builder 6.
Je n'arrive pas à m'en sortir avec la TActionMainMenuBar, voici ce que j'ai fait:
Dans TestMenuBar.h :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 #ifndef TestMenuBarH #define TestMenuBarH #include <ActnCtrls.hpp> #include <ActnMan.hpp> #include <ActnMenus.hpp> #include <vcl.h> class TestMenuBar: public TActionMainMenuBar { public: TActionBarItem *BarItem; __fastcall TestMenuBar(TComponent *Owner, TActionManager *ActionManager); public: TActionClientItem *AddMenuItem(AnsiString Category); TActionClientItem *AddSubItem(AnsiString Category); }; #endif
Dans TestMenuBar.cpp:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 #include "TestMenuBar.h" __fastcall TestMenuBar::TestMenuBar(TComponent *Owner, TActionManager *ActionManager):TActionMainMenuBar(Owner){ this->Parent = dynamic_cast<TWinControl *>(Owner); this->ActionManager = ActionManager; BarItem = this->ActionManager->ActionBars->Add(); BarItem->ActionBar = this; } TActionClientItem *TestMenuBar::AddMenuItem(AnsiString Category){ TActionClientItem *tempItem = BarItem->Items->Add(); tempItem->Caption = Category; return tempItem; } TActionClientItem *TestMenuBar::AddSubItem(AnsiString Category){ TActionClientItem *tempItem = NULL; for (int i = 0; i<this->BarItem->Items->Count; i++){ if (this->BarItem->Items->operator [](i)->Caption == Category){ tempItem = BarItem->Items->operator [](i); break; } } if (tempItem == NULL) return NULL; for (int i = 0; i<ActionManager->ActionCount; i++) { if(((TAction*) ActionManager->Actions[i])->Category == Category){ TActionClientItem *tempActionClientItem = tempItem->Items->Add(); tempActionClientItem->Action = ActionManager->Actions[i]; tempActionClientItem->Visible; } } this->CreateControl(tempItem); return tempItem; }
et pour tester le tout:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #include <vcl.h> #include "TestMenuBar.h" WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { TForm *MainForm = new TForm(Application,0); TActionManager *MainActionManager = new TActionManager(MainForm); TAction *MainAction1 = new TAction(MainForm); MainAction1->Category = "File"; MainAction1->Caption = "Test1"; MainAction1->ActionList = MainActionManager; TAction *MainAction2 = new TAction(MainForm); MainAction2->Category = "File"; MainAction2->Caption = "Test2"; MainAction2->ActionList = MainActionManager; TestMenuBar *MainMenuBar = new TestMenuBar(MainForm,MainActionManager); MainMenuBar->AddMenuItem("File"); MainMenuBar->AddSubItem("File"); MainForm->ShowModal(); return 0; }
Mon menu item "File" est bien affiché, mais lorque je clique dessus, l'application se freeze et je n'arrive pas à comprendre pourquoi!
Quelqu'un aurait-il la solution?
Merci d'avance!
Et voici mes nouvelles découvertes :
Visiblement le problème se passe au moment du dispach des actions et sans doute dans la procedure ProcessMenuLoop.
J'ai intercepté et traité certains messages comme ceci:
L'application ne freeze plus, le popup des items s'affiche mais ne s'éfface pas. Il réside encore pas mal de problème...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 void __fastcall WndProc(TMessage &Message){ switch(Message.Msg){ case(CM_ITEMCLICKED): if (this->InMenuLoop) return; PostMessage(Handle, Message.Msg, 0,(long)(this->ActionControls[0])); this->TrackMenu(); return; case(CM_ENTERMENULOOP): this->TrackMenu(); this-> return; case(CM_ITEMKEYED): if (this->InMenuLoop) return; PostMessage(Handle, Message.Msg, 0,(long)(this->ActionControls[0])); this->TrackMenu(); return; } TActionMainMenuBar::WndProc(Message); }
Donc si quelqu'un a une meilleure idée, elle serait la bienvenue!
Merci!
Partager