Zum Inhalt springen

Empfohlene Beiträge

Geschrieben

Hallo Community,

Ich bin gerade drüber einen Wecker in Windows zu programmieren.

Man kann entweder bestimmte Tage angeben die die dann für jede Woche gelten

oder man kan ein bestimmtes Datum eingeben.

Dazu noch eine Uhrzeit und einen Text der dann Ausgegeben werden soll.

Das ganze Übertrage ich in ein StringGrid und dann speicher ich es per StringList in eine txt.

Beim nächsten Start werden die Vorhandenen Wecktermine wieder in das StringGrid geladen.

Außerdem ist dem Programm noch in einem Label die aktuelle Uhrzeit und das Datum mitgegeben.

Die Uhrzeit hole ich über TDateTime = Now() über Multithreading;

So meine Frage ist nun ,

Der Benutzer hat seine Daten eingetippt und abgespeichert.

Wie frage ich das ab?

Ich denke das ich noch einen weiteren Thread erstellen muss und dort die Abfrage routine definieren muss.

Die Abfrage ist dann eine for schleife die jede Sekunde oder eventuell Minute

die Now() mit den einzelnen Werten aus der Liste vergleicht.

wenn einer Identisch ist gibts ne Meldung

oder nen Alarm.

Sind meine Überlegungen bezüglich des alamierens meines Weckers richtig?

Oder gibt es einen einfacheren Weg dann den Alarm auszulösen zu dem vorgegebenen Zeitpunkt?

Mfg

Alex

Geschrieben

Alle X Sec ist ja eher nicht so gut.

Ich speichere ja Datum , bzw. Tag, und Zeit ab.

Also muss ich ja erst den Tag abgleichen bzw. Datum (Sind 2 verschiedene Sachen in meinem Programm)

und dann die Zeit.

Da nützt mir die Funktion die du von Timer beschrieben hast denke ich mal nichts.

Muss ich es wohl doch über meinen Ansatz machen?!

Geschrieben
Alle X Sec ist ja eher nicht so gut.
Wieso nicht? X kann ja auch 1 sein.

Muss ich es wohl doch über meinen Ansatz machen?!
Nein. Ein Timer reicht völlig aus. Du kannst den Timer ggf. auch flexibel halten, d.h. wenn der nächste Alarmzeitpunkt weit entfernt ist, das Timerintervall raufsetzen.
Geschrieben

Intervall heißt doch er prüft in diesem Intervall , also dieser Zeiteinheit die man ihm da mitgibt

richtig?!

Wie ist das dann, wenn ich heute sage er soll am 2.2.08 um 12 Uhr eine Erinnerung ausgeben.

Wie läuft das dann ab?!

Steig irgendwie nicht in die Funktionsweiße der Komponente ein.

Habs bis jetzt so umgesetzt wie ich meinte, mit noch nem Thread

und einer Schleife die dauernd die abgespeicherten Daten durchgeht und mit Datum und Uhrzeit abgleicht.

Geht auch , brauch nur noch eine Idee wie ich mit dem Datum den Tag

rausfinde.

Praktisch ob der 19.12.07 ein Donnerstag is oder ein Mittwoch.

Das schöne ist ja das immer mehr Wege zum Ziel führen :)

Geschrieben

Also den Wochentag kannst du ganz einfach berechnen lassen in dem du die anzahl Tage vom z.B. 03.12.2007 bis zum 19.12.2007 berechnest und dann das ergebniss durch 7 teilst.

Wegen dem Timer naja ganz einfach der Timer löst nach ablauf eines Interfalls einen Event aus. in diesem prüfts du dann einfach ob ein eventausgelöst werden muss oder nicht.

Das macht das ganze einfacher und ist vermutlich nicht so belastent wie ein Thread der in einer endlosschleife läuft.

Achja und zudem kannst du z.B. wie klotzkop schon geschrieben hat das Intervall so wählen das der TImer erst beim nächsten event auslöst.

Geschrieben

Das mit dem Wochentag ging einfacher

gab von der TDateTime Komponente den Befehl DayOfWeek();

=)

So nun hab ich meinen Wecker in die Trayleiste versteckt

und Prophisorisch, ihm ein Windows Standard Icon verpasst und zwar weil ich es nicht auf die Reihe Bringe ihm das in dem verzeichnis liegende .ico zu nehmen.


LRESULT IconDrawItem(LPDRAWITEMSTRUCT lpdi)

{

 HINSTANCE hInst;

        HICON hIcon;

        hIcon = (HICON)LoadImage(hInst, "Calendar.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);

      [I]richtig? und weiter ?[/I]

      // return [I]???[/I]


}

Muss hier ja einen Wert mitgeben denn ich in dieser Funktion
bool __fastcall TForm1::BarMessage(DWORD dwMessage)

{


   NOTIFYICONDATA tnd;

   PSTR pszTip;

   pszTip = GetTip();



   tnd.cbSize = sizeof(NOTIFYICONDATA);

   tnd.hWnd = Handle;

   tnd.uID = IDC_MYICON;

   tnd.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;

   tnd.uCallbackMessage	= MYWM_NOTIFY;


   if (dwMessage == NIM_MODIFY)

    {

        tnd.hIcon =  //Anderes ICON LADEN??

        if (pszTip)

           lstrcpyn(tnd.szTip, pszTip, sizeof(tnd.szTip));

	    else

            tnd.szTip[0] = 0;

    }

    else

    {

        tnd.hIcon = LoadIcon(NULL,IDI_WINLOGO);    // Standard Windows ICON LADEN

        tnd.szTip[0] = 0;

    }


   return (Shell_NotifyIcon(dwMessage, &tnd));


}

Ich komm nicht drauf

ist im ersten ein Fehler?

Wie ruf ich das Icon denn dann auf?!

Hab im i-net ähnliches gefunden aber nichts was mit weitergeholfen hätte

Geschrieben

Das mit dem Icon habe ich immernoch nicht hinbekommen. Leider

Zudem hab ich auch noch ein neues , wie ich finde komisches, Problem.

Das Problem ist , ich gebe meinem Wecker eine Alarmzeit.

Ist die Alarmzeit erreicht und der Wecker ist gerade im Tray , erscheint einwandfrei die Message die der User eingegeben hat.

Ist der Wecker aber geöffnet , also der User sieht in gerade an oder so.

Kommt ein Fehler "Leinwand/Bild erlaubt keine Zeichen" und ich werde im Code auf diese Zeile im meinem PrüfThread hingewiesen.

PrüfThread = Er durchläuft mit der Zeit die Weckerdaten und wenn was übereinstimmt gibt er laut =)

Form1->Meldungausgeben(Form1->StringGrid1->Cells[4][i]);
in Meldungausgeben ist folgendes:


void __fastcall TForm1::Meldungausgeben(AnsiString text)

{

  Beep(37,200);

  Beep(250,200);

  ShowMessage(text);

}

Aber Warum geht es dann wenn der Wecker im Tray ist, da rufe ich ja dieselbe Routine auf?!

Aber es wird schon noch mhh komischer.

Das passiert wenn ich das Projekt mit dem BorlandBuilder kompiliere.

Wenn ich aber die fertige Exe benutze und habe dann den Wecker aktiv, dann erhalte ich ohne Fehler die Message.

???

Achjah und dann noch ein Unterschied , wenn ich mit Borland kompeliere und Beende das Programm passiert nichts.

Starte ich die Exe und beende dann das Programm

erhalte ich :

"Fehler in Anwendung"

Die Anweisung in "0x400bf197" verweist auf Speicher in "0x000002c0".

Der Vorgang "read" konnte nicht auf dem Speicher durchgeführt werden.

Klicken Sie "OK", um das Programm zu beenden.

"Abrechen", um zu debuggen.

Hab schon danach gegoogelt und viele schreiben das sie das auch bei Programmen wie Mozilla und Firebird oder irgend einer Abspielsoftware erhalten.

Hab gedacht es ist weil ich eine Schriftart mit AddFontResourceEx einbinde

und ich sie danach wieder Removen will, das er das nicht packt, aber auch als ich das auskommentiert habe , kam die Meldung.

Den WeckerCode zu posten ist wohl ein bisschen viel, sag ich mal.

Wenn mir jemand helfen kann, oder Rat weiß und dazu mal etwas vom Code sehen muss,will, je nachdem, einfach schreiben.

Mfg

Alex

Geschrieben
PrüfThread = Er durchläuft mit der Zeit die Weckerdaten und wenn was übereinstimmt gibt er laut =)

Form1->Meldungausgeben(Form1->StringGrid1->Cells[4][i]);

Greift dein "Prüfthread" etwa direkt auf die Fensterobjekte zu? Das ist nicht erlaubt. Nur der Thread, der ein Fenster erzeugt hat, darf darauf zugreifen.

Starte ich die Exe und beende dann das Programm

erhalte ich :

Die Anweisung in "0x400bf197" verweist auf Speicher in "0x000002c0".

Hab schon danach gegoogelt und viele schreiben das sie das auch bei Programmen wie Mozilla und Firebird oder irgend einer Abspielsoftware erhalten.

Das ist vermutlich ein Lesezugriff über einen Nullzeiger. Das ist ein sehr allgemeiner Programmfehler, und hat mit der Art des Programms wenig zu tun.

Das liegt wahrscheinlich auch daran, dass du in deinem Thread Sachen machst, die du nicht machen darfst. Ich hatte dir gleich zu einem Timer geraten, da hättest du solche Probleme nicht.

Geschrieben

Ja

Form1->Meldungausgeben(Form1->StringGrid1->Cells[4][i]);

steht in Unit2 und Unit1 hat das Formular.

deswegen jah Form1->Meldungsausgeben...

Wenn man das nicht darf, wie teil ich dann mit , das der Weckertermin erreicht ist?

Man kann ja auch mal andere Möglichkeiten ausprobieren, ob die gut sind sieht man erst nachdem man sie getestet hat.

Jetzt weiß ich das du Recht hast.

Pardon

Geschrieben

Ich bezweifile, dass du das Problem gelöst hast. Es tritt nur nicht mehr (oder nicht mehr so häufig) auf. Man könnte sagen, du hast es schwieriger reproduzierbar gemacht. Threadsynchonisierung mittels Warten ist keine saubere Lösung.

Geschrieben

Ist trotzdem ein bisschen viel. Ich hab mal unter c# ein kleines Countdownprogramm geschrieben, welches auch immer auf die aktuelle Zeit zurückgreift. Hab den Timerintervall auf 1 Sekunde gesetzt. Die Auslastung liegt bei 2%. Mir ist bewußt, dass der Vergleich hinkt, da wir unterschiedliche Rechner haben, trotzdem behaupte ich das dein Programm 4 mal "schneller" / performanter wird.

Ist nur eine Behauptung. Beweisen oder garantieren kann ich das nicht.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...