Zufällig habe ich bei delphi.about.com gerade entdeckt, dass man mit der {$REGION 'Name'}...{$ENDREGION}-Direktive selbst Blöcke definieren kann, die sich im Quelltexteditor dann falten lassen. Ein nettes Feature, finde ich… ;D
Archive for the ‘Delphi’ Category
Explizites Code-Folding im Delphi-Editor
Icons für eigene Komponenten
Kurzer Spickzettel für das Ändern von Icons und Ressourcen eigener Komponenten:
- Icon für die KOMPONENTE (Designer) ändern: mit dem XN Resource Editor die Unit.dcr bearbeiten
- Cursor als RESSOURCE (Runtime) ändern: mit dem ResHacker “Ressourcen.res” ändern
Um eine *.dcr-Datei zu erzeugen wie folgt vorgehen:
- Mit dem XN Resource Editor eine neue Datei anlegen und einfach als *.dcr speichern. Ein Icon für die Komponente hinzufügen und mit dem Klassennamen (z.B. TMyCompo) benennen.
- Im Package-Source (*.dpk) die Ressource einbinden mit
{$R myResources.dcr}
Rückgabewert einer Delphi-Funktion an JavaScript
Bei Experimenten mit der Bridge für die Spidermonkey JavaScript Engine bin ich gerade auf die Frage gestoßen, wie man aus einer Delphi-Funktion, die dem Scriptscope vorgestellt wurde, einen Rückgabewert liefern kann. Die einfache Variante des publizieren einer Klasse mit AddNativeObject scheint für Functions nicht zu funktionieren, so dass eine Nullpointer-Exception beim Ausführen des Scripts entsteht.
Das mitgelieferte Beispiel für Kylix zeigt aber eine Möglichkeit, die allerdings eine händische Veröffentlichung der Objektstruktur erfordert:
Eine einfache Funktion mit Rückgabe eines Strings an den JavaScript-Aufruf:
uses jsintf, js15decl,...;
...
function jsAlert(cx: PJSContext; obj: PJSObject; argc: uintN;
argv, rval: pjsval): JSBool; cdecl;
...
function jsAlert(cx: PJSContext; obj: PJSObject; argc: uintN;
argv, rval: pjsval): JSBool; cdecl;
begin
//rval^ := JSVAL_VOID; //falls keine Rückgabe, void
rval^ := StringToJSVal(cx,Pchar('Das kommt zurück'));
ShowMessage(JSStringToString(JSValToJSString(argv^)));
Result := JS_TRUE;
end;
...
fEngine := TJSEngine.Create(40000);
fEngine.global.addMethod('alert',jsAlert,1);
In diesem Beispiel steht dem Script die globale Funktion alert(); zur Verfügung, die den übergebenen String zeigt und einen anderen String liefert. Folgender JS-Code ruft nun die Anzeige einer Messagebox auf und zeigt wiederum die Rückgabe in einer weiteren Messagebox an:
var erg;
erg = alert("Hallo Welt"); //Messagebox: Hallo Welt
alert(erg); //Messagebox: Das kommt zurück
Fremde Komponenten in eigenen Paketen verwenden
Wenn man mit Delphi eigene Komponenten-Packages entwickelt, kann es vorkommen, dass beim Installieren in der Entwicklungsumgebung eine Fehler-Meldung der folgenden Form erscheint:
P1 enthält die unit U1 die auch im package P2 enthalten ist
Das Problem ist, dass im eigenen Package P1 eine andere Komponente verwendet wird, die Delphi dann parallel zu installieren versucht und dabei mit dem gleichnamigen parallelen Package kollidiert. Bei mir trat das Problem auf, als ich eigene Komponenten entwickelte, die die Grafiksteuerelemente des GR32-Paketes nutzen.
Ich habe ziemlich viel Zeit und Mühen investieren müssen, bis ich eine Lösung fand. Delphi reagiert dabei auch nicht immer logisch und ich bin mir nicht sicher, ob dieser Ansatz nur zufällig oder tatsächlich “richtig” funktioniert:
Um andere Komponenten in einem eigenen Package zu nutzen ohne dabei auf den Duplikat-Fehler zu stoßen, wie folgt vorgehen:
- Das GR32-Laufzeitpackage (nicht das Design-Package!) in die
requires-Liste des eigenen Paketes aufnehmen. Dadurch wird die Abhängigkeit des externen GR32-Paketes als solches dokumentiert und (berücksichtigt). Ist das Design-Paket mit drinnen, muss dieses jedes mal nach dem Update des eigenen Paketes auch aktualisiert werden, was recht nervig und zudem überflüssig ist. - Das eigene Paket compilieren und installieren
- Tritt der Fehler “drf not found” auf, nochmal compilieren, irgendwann funktioniert es einfach (?!). Wenn nicht, ggf. Delphi einmal neu starten und nochmal versuchen.
- Falls ein Fehler erscheint, GR32 wäre mit einer falschen Delphi-Version compiliert worden, das gr32-Paket (gr32_design_2005.dpk) nochmal compilieren/aktualisieren.
Technical Paper: Delphi Programming for the HTML Help API
Auf dieser Seite findet sich ein sehr gutes und äußerst umfangreiches Paper zur Einbindung des HTML-Help-Formats in Delphi-Anwendungen, die an sich ja nur die klassischen Hilfe-Dateien unterstützen.
Passend dazu hier das inzwischen Vista-fähige Delphi HTML Help Kit. ![]()
Für jeden Tab ein Popup
Um jedem Tab/Register eines TPageControls ein eigenes Kontextmenü zuzuordnen kann per Iteration über die Pages der Tab ermittelt werden, in dem der Klick erfolgte. Anschließend lässt sich entsprechend verzweigen.
Folgendes Beispiel arbeitet mit einem Formular mit einem TPageControl mit zwei Pages und zwei TPopupMenus. Dem OnContextPopup-Ereignis des PageControls wird folgender Code zugewiesen. Man erhält dann für jeden Tab per Rechtsklick ein anderes Popupmenü.
procedure TForm1.PageControl1ContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
var i,pageidx:integer; r:TRect;
begin
if (MousePos.X=-1) and (MousePos.Y=-1) then
begin
//wenn nicht geklickt wurde, sondern die
//kontextmenütaste oder Shift+F10 gedrückt
//wurde, angzeigten Tab verwenden.
pageidx:=PageControl1.ActivePageIndex;
end
else //sonst: testen, welcher tab angeklickt wurde
begin
pageidx:=-1;
for i := 0 to pagecontrol1.PageCount - 1 do
begin
r:=pagecontrol1.TabRect(i);
if ((MousePos.X>=r.Left) and (MousePos.X< =r.Right) and (MousePos.Y>=r.top) and (mousePos.Y< =r.Bottom)) then
begin
pageidx:=i;
break; //gefunden, keine weitere Suche nötig
end;
end;
end;
//Entsprechende Menüs zeigen...
case pageidx of
0: pagecontrol1.PopupMenu:=PopupMenu1;
1: pagecontrol1.PopupMenu:=PopupMenu2;
else pagecontrol1.PopupMenu:=nil; //kein Menü, wenn ins Leere geklickt...
end;
end;
EaseInOut/Tween-Algorithmus
Bewegungen sehen oft schöner oder sogar natürlicher aus, wenn Sie nonlinear am Anfang und Ende beschleunigt oder abgebremst werden. In diesem PDF erklärt Robert Penner mehrere Algorithmen zur Bewegungsberechnung, die auch in andere Sprachen übernommen werden können. Das Beispiel ist an Flash orientiert, wohl einem der bekanntesten Anwendungsfälle.
GLScene aus dem CVS laden
GameCreation Wettbewerb
Die Seite pascalgamedevelopment.com veranstaltet auch dieses Jahr wieder einen Programmierwettbewerb für Spiele. Die eingereichten OpenSource-Projekte sollen die Mischung von mindestens zwei Genres bewältigen, was zu sehr interessanten Ergebnissen führen dürfte. Der Einsendeschluss ist der 03.06.2007 soweit ich das sehe…
Tablet PC SDK OnCursorDown
Erstellt man eine InkOverlay-Komponente in Delphi werden einige der zugewiesenen Ereignisse wie z.B. OnCursorDown, OnCursorButtonDown usw. nicht ausgelöst. Dafür muss zunächst nämlich erst Interesse an dem Ereignis über die Funktion SetEventInterest angemeldet werden.
Zum Testen einfach mal alles aktivieren:
ink1.SetEventInterest(ICEI_AllEvents,true);
Der Profi-Entwickler weiß natürlich, dass bei guter Programmierung nur die wirklich erforderlichen Events freigeschaltet werden. ;)
Weitere Infos bei MSDN.