Forum: Mikrocontroller und Digitale Elektronik Vektor als Switchkriterium


von Bruno (Gast)


Lesenswert?

Hallo zusammen.

Ich bin gerade dabei ein Display mit Menüführung zu programmieren. Das 
läuft auch solange, bis ich am Ende des Menüs ankomme und es darum geht 
mir Werte anzeigen zu lassen. Die Menüsprünge realisiere ich mittels 
Vektoren, die auf ein Struct aus Strings zeigen. Diese werden dann 
ausgegeben. Läuft 1a solange ich nur Strings anzeigen muß. Jetzt möchte 
ich aber auf Werte zurück greifen und diese Anzeigen. Dafür benötige ich 
viele verschiedene Funktionen und nicht die Standardroutine.

Lange Rede kurzer Sinn. Kann ich mit einer Switch-Anweisung irgendwie 
auch auf einen Vektor verweisen?

Gruß Bruno

von Karl H. (kbuchegg)


Lesenswert?

Hä?


Klingt aber danach, also ob die Antwort auf deine Frage "Nein"
lautet.

Da ich aber nicht wirklich kapiert habe, was du da machst, kann
ich dir auch keine Alternative vorschlagen.

von Bruno (Gast)


Lesenswert?

Vllcht kannst dui dich an den Thread erinnern

Beitrag "strlen bei mehrdimensionalen Strings"

Ich möchte jetzt nicht auf ein Subdisplay verweisen, sondern auf eine 
Funktion.
1
MenuEntry MainMenu[] =
2
  {
3
    { { "Hilfe", "Help" },      NULL },
4
    { { "Bearbeiten", "Edit" }, &EditScreen },
5
    { { "Beenden", "Exit" },    NULL }
6
  };

von Stefan (Gast)


Lesenswert?

Etwa sowas?
1
typedef struct
2
{
3
  unsigned int  bla;          // Parameter 1
4
  unsigned int  blub;         // Parameter 2
5
  void (*p_func)(void);       // Funktions-Pointer
6
} Cmd_Tab;
7
8
9
void test_func (void)
10
{
11
  ...
12
  return;
13
} 
14
15
const Cmd_Tab Test_Tab =
16
        {0x0000,            // Param 1
17
         0x0001,            // Param 1
18
         test_func          // Funktions-Pointer
19
        };

von Karl H. (kbuchegg)


Lesenswert?

Bruno wrote:
> Vllcht kannst dui dich an den Thread erinnern
>
> Beitrag "strlen bei mehrdimensionalen Strings"
>
> Ich möchte jetzt nicht auf ein Subdisplay verweisen, sondern auf eine
> Funktion.
>
>
1
> MenuEntry MainMenu[] =
2
>   {
3
>     { { "Hilfe", "Help" },      NULL },
4
>     { { "Bearbeiten", "Edit" }, &EditScreen },
5
>     { { "Beenden", "Exit" },    NULL }
6
>   };
7
>

OK.

Dann musst du deine Struktur erweitern.
Die besteht jetzt nicht mehr aus den 2 Einträgen, sondern aus 3
1
typedef void (*FuncPtr) ( void );
2
3
4
// Ein Eintrag (Menuepunkt) im Scrollbereich
5
typedef struct MenueEntry_ {
6
  Text                   m_Text;
7
  struct DisplayScreen_* m_pSubDisplay;
8
  FuncPtr                m_pFunction;
9
} MenuEntry;

wobei der dritte Eintrag der Funktionspointer ist. Die Auswerte-
funktion checkt jetzt einfach ab, welcher der beiden Pointer
nicht NULL ist. Ist es der SupDisplay Pointer, dann wird ein
Untermenü angezeigt. Ist es der Funktionspointer, dann wird die
Funktion aufgerufen.
1
void doCopy()
2
{
3
}
4
5
void doCut()
6
{
7
}
8
9
void doPaste()
10
{
11
}
12
13
// "Bearbeiten" Display
14
MenuEntry EditMenu[] =
15
  {
16
    { { "Kopieren",     "Copy" },  NULL, doCopy },
17
    { { "Ausschneiden", "Cut" },   NULL, doCut },
18
    { { "Einsetzen",    "Paste" }, NULL, doPaste }
19
  };
20
21
...
22
23
void HandleDisplay( DisplayScreen * pDisplay )
24
{
25
   ...  // konstante Teile des Screens aufbauen
26
27
   HandleMenu( pDisplay->ScrollArea.Entries,
28
               pDisplay->ScrollArea.m_Size );
29
}
30
31
void HandleMenu( MenuEntry* Entries, size_t NrEntries )
32
{
33
  size_t i;
34
  
35
  for( i = 0; i < NrEntries; ++i ) {
36
    // GetCurrentText( &Entries[i].m_Text ) )  ausgeben und so
37
    // das Menü aufbauen
38
  }
39
40
  // du hast eine Rückmeldung vom Benutzer und musst sie
41
  // jetzt auswerten
42
43
  // an dieser Stelle enthält i den Index des ausgewählten
44
  // Eintrags
45
  //
46
  // Checken ob es eine Funktion dafür gibt, wenn ja aufrufen
47
  if( Entries[i].pFunction != NULL )
48
    (*Entries[i].pFunction)();
49
50
  // Wenn es ein Submenü gibt, dann dieses auswählen
51
  if( Entries[i].m_pSubDisplay != NULL )
52
    HandleDisplay( Entries[i].m_pSubDisplay );
53
}


Beachten musst du nur, dass alle Funktionen immer die gleichen
Argumente haben, falls du welche brauchst. Das kann auch mal
bedeuten, dass eine Funktion Argumente bekommt, die sie nicht
benötigt.
Die tatsächlichen Argumente nimmst du ebenfalls mit in die
Struktur auf, damit sie beim Funktionsaufruf zur Verfügung
stehen.

zb.
1
typedef void (*FuncPtr) ( int * );
2
3
4
// Ein Eintrag (Menuepunkt) im Scrollbereich
5
typedef struct MenueEntry_ {
6
  Text                   m_Text;
7
  struct DisplayScreen_* m_pSubDisplay;
8
  FuncPtr                m_pFunction;
9
  int*                   m_pArg1;
10
} MenuEntry;
11
12
13
void doIncrement( int * pArg )
14
{
15
  (*pArg)++;
16
}
17
18
void doDecrement( int * pArg )
19
{
20
  (*pArg)--;
21
}
22
23
int Counter;
24
int Anzahl;
25
26
// "Bearbeiten" Display
27
MenuEntry EditMenu[] =
28
  {
29
    { { "Counter erhöhen", "inc Counter" },    NULL, doIncrement, &Counter },
30
    { { "Coutner verringern", "dec Counter" }, NULL, doDecrement, &Counter },
31
    { { "Anzahl erhöhen", "inc Anzahl" },    NULL, doIncrement, &Anzahl },
32
    { { "Anzahl verringern", "dec Anzahl" }, NULL, doDecrement, &Anzahl },
33
    { { "Beenden",    "Exit" }, NULL, NULL, NULL }
34
  };
35
36
...
37
38
void HandleDisplay( DisplayScreen * pDisplay )
39
{
40
  do {
41
    ...  // konstante Teile des Screens aufbauen
42
43
  } while(  HandleMenu( pDisplay->ScrollArea.Entries,
44
                        pDisplay->ScrollArea.m_Size );
45
}
46
47
uint8_t HandleMenu( MenuEntry* Entries, size_t NrEntries )
48
{
49
  size_t i;
50
  
51
  for( i = 0; i < NrEntries; ++i ) {
52
    // GetCurrentText( &Entries[i].m_Text ) )  ausgeben und so
53
    // das Menü aufbauen
54
  }
55
56
  // du hast eine Rückmeldung vom Benutzer und musst sie
57
  // jetzt auswerten
58
59
  // an dieser Stelle enthält i den Index des ausgewählten
60
  // Eintrags
61
  //
62
  // Checken ob es eine Funktion dafür gibt, wenn ja aufrufen
63
  if( Entries[i].pFunction != NULL )
64
    (*Entries[i].pFunction)( m_pArg1 );
65
66
  // Wenn es ein Submenü gibt, dann dieses auswählen
67
  if( Entries[i].m_pSubDisplay != NULL )
68
    HandleDisplay( Entries[i].m_pSubDisplay );
69
70
  return Entries[i].pFunction != NULL || Entries[i].m_pSubDisplay != NULL;
71
}

von Bruno (Gast)


Lesenswert?

Jetzt brauche ich erst mal Verarbeitungszeit.
Aber danke für den/die Ansatz/Lösung.

von Karl H. (kbuchegg)


Lesenswert?

Bruno wrote:
> Jetzt brauche ich erst mal Verarbeitungszeit.
> Aber danke für den/die Ansatz/Lösung.

Ist sehr simpel.
Im Grunde wurde einfach nur in die Struktur ein zusätzlicher
Member mit aufgenommen. Alles andere ergibt sich daraus.

von Bruno (Gast)


Lesenswert?

Na ja so simpel war das nicht. Wenn man an einem bestehenden Programm an 
der Basis fummelt kommt oft nur quatsch raus. Auf dem ganzen Jedöns 
basieren ca 20k Code. Aber der Ansatz war super. So in der Art hatte ich 
das auch geplant. Nur die Codestelle
1
(*Entries[i].pFunction)( m_pArg1 )

war mir nicht geläufig.
Danke nochmal² für die Hilfe.

Gruß Bruno

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.