Einzelnen Beitrag anzeigen

Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#170

Re: Desktop Widget Engine (v0.65)

  Alt 3. Nov 2008, 13:39
Zitat von Sherlock:
Fade-in funktioniert und sieht schön aus.
SideBar nimmt die Widgets ebenfalls mit, perfekt.
Danke fürs Testen, hatte schon Angst, dass die SideBar mal wieder nicht funktioniert

Zitat von Sherlock:
Weiter so!
Mach ich

Zitat von Sherlock:
Ich hab gestern mal probiert ein Widget für den RSS-Feed von heise online zu basteln, aber leider erfolglos. Mein ambitionierteres Projekt, nämlich eine Börsenticker scheint damit in weite Ferne zu rücken
Aber ich probiers heute Abend nochmal, XML ist halt für mich noch relativ neu.
Also ich kann dir ja mal kurz Anhand des "Spiegel Online" - Widgets erklären, wie ich es mache.

Also als erstes Frage ich natürlich den RSS-Feed mit einer wgHTTP-Komponente ab:
wgHTTP1.GetURL('http://www.spiegel.de/schlagzeilen/rss/0,5291,,00.xml'); Im OnDone-Ereigniss lese ich dann den Inhalt aus und lassen ihn mit dem JvSimpleXML parsen:
Delphi-Quellcode:
procedure wgHTTP1Done(Sender: TObject; Content: string; ResponseCode: integer);
var pXML : TJclSimpleXML;
begin
  pXML := pXML.Create;
  try
    pXML.LoadFromString(Content);
    ParseContent(pXML);
  finally
    pXML.Free;
  end;
end;
So, jetzt ist die Funktion "ParseContent" nicht der XML-Parser, sondern ich füge den relevanten Inhalt in ein neues XML-Element ein. Zusätzlich berechne ich noch die Texthöhe von jedem Eintrag in der Funktion.

Dafür gehe ich in der "ParseContent" - Routine durch alle Einträge durch:
Delphi-Quellcode:
for i:=0 to Root.Items.Count-1 do
begin
  // Unterelement Nummer "i" abrufen
  Item := Root.Items.Item(i);
  // das sollte eigendlich nie passieren, aber sicher ist sicher
  if Item = nil then
     continue;
  // in dem RSS-Feed werden zuerst ein paar Zusatzinformationen
  // mitgesendet. Diese haben alle einen anderen Namen als "item"
  // Da diese für den Inhalt des Feeds erstmal nicht relevant sind
  // überspringen wir diese Einträge
  if Item.Name <> 'itemthen
     continue;
So, wenn jetzt "Item.Name = 'item'" ist, füge ich einen neuen Eintrag in das interne XML-File ein:
Delphi-Quellcode:
newItem := XML.Root.Items.Add('data'); // ein neuer Eintrag
newItem.Items.AddS('msg', Item.Items.ItemNamed('title').Value); // die Überschrift des Feed-Items
newItem.Items.AddS('url', Item.Items.ItemNamed('link').Value); // der Link des Feed-Items
Jetzt berechne ich die Höhe des zukünftigen Eintrags und füge diesen ebenfalls zu "newItem" hinzu.
Delphi-Quellcode:
Rec := Rect(0, 0, tmpBMP.Width - 11, tmpBMP.Height);
                           
tmpBMP.Font.SetName('MS Sans Serif');
tmpBMP.Font.SetSize(8);
// imgLogo, da dies eine "Graphic" - Komponente enthällt.
// für die "Graphic" - Komponente hab ich die DrawText-Methode
// verbessert
imgLogo.Graphic.DrawText(tmpBMP, newItem.Items.Value('msg', ''), Rec,
                         DT_LEFT or DT_CALCRECT or DT_WORDBREAK or DT_NOPREFIX,
                         0, 0);
// jetzt hab ich die Höhe des eintrags und speichere sie in das interne XML-File
height := Rec.Bottom + 7; // noch etwas Pufferabstand: 7 pixel
newItem.Items.AddI('height', height);
So, nun stehen im internen XML-File die Daten, die wirklich wichtig sind. Um genau zu sehen, wie die Sachen gespeichert werden, kannst du am Ende der "ParseContent"-Methode vor dem finally folgendes Einfügen:
ShowMessage(XML.SaveToString); (ACHTUNG: die MessageBox wird sehr lang, zum schließen dann einfach "Enter" drücken)

Jetzt ist noch die OnMeasureItem-Methode der ListBox interessant. Da ich ja in der ParseContent-Methode die Höhe eines Eintrags berechnet habe, kann ich diesen einfach aus dem internen XML-File auslesen:
Delphi-Quellcode:
procedure wgListBox1MeasureItem(Sender: TObject; Target: TBitmap32; Index: integer; var Height: integer);
var Item: TJclSimpleXMLElem;
begin
  // Eintrag Nummer "index" auslesen
  Item := XML.Root.Items.Item(index);
  // Falls dieser Vorhanden ist
  if Item <> nil then
     // Die Höhe aus dem Eintrag "height" zurückgeben
     // 13 ist dabei der Default-Wert, falls "height" nicht vorhanden ist
     Height := Item.Items.IntValue('height', 13);
end;
Du solltest dir noch das OnDraw-Event anschauen, jedoch ist da nicht viel neues dabei.

Ich hoffe, ich konnte dir etwas helfen.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat