Button reagiert nicht auf klick (Sprache: c)

Willkommen!

Wenn du im Nexave-Forum mitmachen möchtest, schreib an community@nexave.de. Wir haben die Registrierungsfunktion in unserem Diskussionsforum nämlich deaktiviert, weil sich praktisch nur noch Spammer und Werbebots registriert haben. Per E-Mail sind wir dir gern behilflich, einen Account anzulegen.
  • Wenn ich den dynamisch erzeugten Button anklicke, so
    löst dieser scheinbar keinen Event aus. Der Button ändert
    auch nicht (wie sonst üblich) seine Farbe.


    Ich wäre sehr dankbar, wenn mir jemand weiter helfen
    könnte.


    Die (meines erachtens) relevanten Stellen habe ich
    farbig markiert.


    Sorry, dass der Code so lang ist. Ich bin allerdings Anfänger im
    Bereich der Palm-Programmierung und nur so bin ich mir sicher,
    dass keine wesentlichen Informationen fehlen.


    Zur Entwicklung verwende ich den Palm Emulator.


    Vielen Dank im Voraus! :)




    #include <Pilot.h>
    #include <SysEvtMgr.h>
    #include "StarterRsc.h"



    struct StarterPreferenceType
    {
    Byte replaceme;
    } ;


    struct StarterAppInfoType
    {
    Byte replaceme;
    } ;



    const unsigned long appFileCreator = 'STRT';
    const unsigned short appVersionNum = 0x01;
    const unsigned short appPrefID = 0x00;
    const unsigned short appPrefVersionNum = 0x01;
    const unsigned long version20 = 0x02000000;


    static Err RomVersionCompatible(DWord requiredVersion, Word launchFlags)
    {
    DWord romVersion;


    // See if we're on in minimum required version of the ROM or later.
    FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion);
    if (romVersion < requiredVersion)
    {
    if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) ==
    (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp))
    {
    FrmAlert (RomIncompatibleAlert);

    // Pilot 1.0 will continuously relaunch this app unless we switch to
    // another safe one.
    if (romVersion < version20)
    {
    //Err err;

    AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL);
    }
    }

    return (sysErrRomIncompatible);
    }


    return (0);
    }



    static VoidPtr GetObjectPtr(Word objectID)
    {
    FormPtr frmP;


    frmP = FrmGetActiveForm();


    return (FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID)));
    }



    static void MainFormInit(FormPtr frmP)
    {
    }



    static Boolean MainFormDoCommand(Word command)
    {
    Boolean handled = false;



    switch (command)
    {
    case MainOptionsAboutStarterApp:
    handled = true;
    break;


    }
    return handled;
    }




    static Boolean MainFormHandleEvent(EventPtr eventP)
    {
    Boolean handled = false;
    FormPtr frmP;



    switch (eventP->eType)
    {
    case menuEvent:
    ErrNonFatalDisplay("Text-Menue----");
    return MainFormDoCommand(eventP->data.menu.itemID);
    break;


    case frmOpenEvent:
    frmP = FrmGetActiveForm();
    MainFormInit( frmP);
    FrmDrawForm ( frmP);
    handled = true;
    break;

    case ctlSelectEvent:
    ErrNonFatalDisplay("Debug-Meldung1");


    switch (eventP->data.ctlSelect.controlID) {
    case 1001:
    ErrNonFatalDisplay("Debug-Meldung2");
    handled = true;
    break;
    }
    break;


    default:
    break;

    }

    return handled;
    }



    static Boolean AppHandleEvent( EventPtr eventP)
    {
    Word formId;
    FormPtr frmP;



    if (eventP->eType == frmLoadEvent)
    {
    // Load the form resource.
    formId = eventP->data.frmLoad.formID;
    frmP = FrmInitForm(formId);
    FrmSetActiveForm(frmP);


    switch (formId)
    {


    case MainForm:
    {
    FrmSetEventHandler(frmP, MainFormHandleEvent);
    }
    break;


    default:
    ErrFatalDisplay("Invalid Form Load Event");
    break;


    }
    return true;
    }

    return false;
    }



    static void AppEventLoop(void)
    {
    Word error;
    EventType event;



    do {
    EvtGetEvent(&event, evtWaitForever);

    if (! SysHandleEvent(&event))
    if (! MenuHandleEvent(0, &event, &error))
    if (! AppHandleEvent(&event))
    FrmDispatchEvent(&event);


    } while (event.eType != appStopEvent);
    }



    static Err AppStart(void)
    {
    StarterPreferenceType prefs;
    Word prefsSize;



    // Read the saved preferences / saved-state information.
    prefsSize = sizeof(StarterPreferenceType);
    if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) !=
    noPreferenceFound)
    {
    }

    return 0;
    }




    static void AppStop(void)
    {
    StarterPreferenceType prefs;


    // Write the saved preferences / saved-state information. This data
    // will be backed up during a HotSync.
    PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum,
    &prefs, sizeof (prefs), true);
    }




    static DWord StarterPilotMain(Word cmd, Ptr cmdPBP, Word launchFlags)
    {
    Err error;
    FormPtr form1;
    ControlType *testButton1;



    error = RomVersionCompatible (version20, launchFlags);
    if (error) return (error);



    switch (cmd)
    {
    case sysAppLaunchCmdNormalLaunch:

    // ErrNonFatalDisplay("Text");

    error = AppStart();
    if (error)
    return error;


    FrmGotoForm(MainForm);


    form1= FrmInitForm(MainForm);
    FrmSetActiveForm(form1);
    form1= FrmGetActiveForm();
    FrmSetEventHandler(form1, MainFormHandleEvent); // !!! Event-Handler !!!
    testButton1= CtlNewControl(&form1, 1001, buttonCtl, "Button1f", 40, 20, 80, 13, stdFont, 0, false);


    CtlSetEnabled ( testButton1, true ); // macht nicht so richtig was
    CtlSetUsable ( testButton1, true ); // macht nicht so richtig was

    CtlShowControl(testButton1); // macht nix ?!?!

    FrmDrawForm(form1);



    CtlHitControl (testButton1); // --> funktioniert! Debug-Meldung erscheint!
    AppEventLoop();
    AppStop();
    break;


    default:
    break;


    }

    return 0;
    }



    DWord PilotMain( Word cmd, Ptr cmdPBP, Word launchFlags)
    {
    return StarterPilotMain(cmd, cmdPBP, launchFlags);
    }

  • OK... dann noch etwas präziser, für diejenigen die alles 100%
    wörtlich nehmen:


    Zur Entwicklung benutze ich Metroworks CodeWarrier
    Development Studio mit integriertem C / C++ Compiler.
    Für das debugging verwende ich den Palm OS Emulator.


    Für Hinweise zur Lösung des Problems wäre ich sehr dankbar.


    Gibt es hier jemanden, der das GUI ( PalmJo: das GUI ist
    korrekt!) dynamisch (zur Laufzeit) erzeugt?

  • Hallo,


    Schon einmal das Programm in Rsrcedit oder BIRD angeschaut? Wie sind die Eigenschaften des Buttons?


    Eventuell die ID des Buttons (1001?) verwenden? Jedenfalls ist das bei PalmPascal so.


    Gruß,
    Hardy.

  • Hardy: Danke für deinen Tip. Leider hat das jedoch nicht
    weitergeholfen.


    Das Problem ist folgendes: Die Button sind NICHT in einer
    Resourcen-Datei hinterlegt, sollen sie auch gar nicht. Sie
    werden dynamisch zur Laufzeit erstellt.


    Wir wollen die Oberfläche nicht in einer Entwicklungs-
    umgebung "zusammenklicken" und dann die Elemente
    per Programmiersprache mit Leben füllen, sondern alle
    Bildschirmkomponenten sollen zur Laufzeit erzeugt werden.

    • Official Post

    Machst Du ein FrmInitForm in der PilotMain und dann später nochmal eins wenn das FrmLoadEvent eintrifft? Das sieht zumindest auf den ersten Blick so aus und erscheint mir etwas komisch.
    Du solltest MainFormInit( frmP); benutzen um Deine Sachen zur Laufzeit hinzubasteln. Aber ich würde mal vorschlagen, mach das alles lieber mit einer Resource zur Compilezeit, zum Beispiel mit pilrc, wenn Du keine Lust auf klicken hast. Das dynamische Erzeugen von Controls geht zwar aber ich hatte bisher immer den Eindruck, das es nciht wirklich üblich ist und hier und da auch mit Fallstricken versehen. (z.B. Bugs in PalmOS 3.5 und früher beim Entfernen)


    Gruß
    Henk

  • MetaView:


    Du hast recht, das zweifach "FrmInitForm" macht nicht viel Sinn,
    scheint aber auch nicht die Ursache des Problems zu sein.


    Leider bin ich dazu gezwungen die Elemente (in diesem Code ist
    es nur ein Button) dynamisch zu erzeugen.


    Das Ziel ist es, Klassen zu schreiben, welche es ermöglichen
    Software für PalmOS zu erstellen ohne nähere PalmOS-
    Kenntnisse zu haben. Es soll also eine Art API sein. Dann
    ist angedacht, eine entsprechende API auch für Windows
    CE zu erstellen. Damit wäre der Entwicklungsaufwand
    deutlich reduziert um für beide Welten Software zu erstellen.


    Die GUI soll dann der Programmierer über die API dynamisch
    erzeugen.


    Dass die Oberfläche also nicht "zusammengeklickt" wird hat
    nichts mit einem "Lustfaktor" zu tun, sondern ist vielmehr
    Voraussetzung für die Lösung des eigentlichen Problems.
    Das dies nicht üblich ist, ist mir natürlich auch schon
    aufgefallen ;)

    • Official Post
    Quote

    Originally posted by bib
    MetaView:


    Du hast recht, das zweifach "FrmInitForm" macht nicht viel Sinn,
    scheint aber auch nicht die Ursache des Problems zu sein.


    Doch, ich bin mir sogar recht sicher, daß das das Problem ist. [das, das, das...]


    Update: Pack den Code in die MainFrmInit (also bei frmOpenEvent) und probier's damit nochmal.


    Gruß
    Henk

  • Hallo,
    ich möchte die Funktion zb.

    "static Boolean MainFormHandleEvent(EventPtr event)"


    aufgerufen von


    "FrmSetEventHandler(form, MainFormHandleEvent)"


    in eine andere Datei verfrachten.


    geht das irgendwie?
    denn dort sind meine ganzen Abfragen und Formfunktionen.
    So wird das Hauptprogramm unübersichtlich.
    danke

    • Official Post

    Das ist plain C: nimm das static raus, schreib eine Deklaration der Funktion (ungefähr so: Boolean MainFormHandleEvent(EventPtr event); ) in eine Headerdatei und die Funktionsdefinition in eine C-Datei. Nun kannst Du die Funktion in FrmSetEventHandler benutzen. Beachte, das der Compiler die Deklaration kennen muß (durch #include der Headerdatei) und der Linker die Funktionsdefinition finden muß, indem Du das Objectfile der MainForm... Funktion dazu linkst.


    Gruß
    Henk