Freitag, 21. Dezember 2007

Erstellen einer Desktopverknüpfung unter VFP / Creating a desktop shortcut with VFP

Immer wieder besteht der Bedarf, bei einer Installation eine Desktopverknüpfung zu einer oder mehreren Dateien oder Applikationen zu erzeugen.

Professionelle Installer führen dies natürlich vollautomatisch für uns durch, aber hin und wieder müssen auch wir Entwickler solch eine Verknüpfung erzeugen.

Den einfachsten Weg stellt wie so oft der Windows Scripting Host bereit. Über 'CreateShortcut' können wir ein Verknüpfungsobjekt erzeugen, das diverse Eigenschaften bereitstellt, um eine Verknüpfung mit allen notwendigen Features zu erzeugen. Damit dies auch sauber funktioniert sind einige Schritte vorab durchzuführen.
  1. Auswählen der Datei oder Applikation zu der eine Verknüpfung erzeugt werden soll
  2. Einen sprechenden Namen für die Verknüpfung definieren. Hierdurch erscheint bspw. nicht 'notepade.exe' sondern 'Texteditor' als Verknüpfungsname auf dem Desktop.
  3. Der nun definierte Dateiname muss mit der Endung '.lnk' versehen werden.
Im Anschluß erzeugen wir ein ShortCut-Objekt und füllen es mit den gewünschten Eigenschaften.

* Beliebige Datei auf dem Deskop verknüpfen

* Arbeitsvariablen definieren
LOCAL cFileName as String, cLinkName as String, oShell as Object, ;
      cDesktop as String, oLink as Object

* Datei auswählen
cFileName        = GETFILE()
* ggf. alternative Bezeichnung für die Verknüpfung definieren
cLinkName        = INPUTBOX([Name: ],[Name der Verknüpfung],JUSTSTEM(cFileName))
* Dateinamenserweiterung 'lnk' erzwingen
cLinkName        = FORCEEXT(JUSTSTEM(cLinkName),[.lnk])
* Scriptinghost Object erzeugen
oShell           = CREATEOBJECT([WScript.Shell])
* Pfad für das lokale Desktop-Verzeichnis abfragen
cDesktop         = oShell.SpecialFolders([Desktop])
* Shortcutobject erzeugen
oLink            = oShell.CreateShortcut(ADDBS(cDesktop) + cLinkName)

WITH oLink
    * Darstellung - 3=Maximized  1=Normal  7=Minimized
    .WindowStyle        = 3
    * Zielverzeichnis
    .TargetPath         = cFileName
    * Ausführen in
    .WorkingDirectory   = ADDBS(JUSTPATH(cFileName))
    * Tastaturshortcut
    .Hotkey             = [Ctrl+Alt+m]
    * Tooltipp
    .Description        = [Demonstration eine Verknüpfung]
    *Objektverknüpfung erzeugen
    .Save()
ENDWITH

* Arbeitsvariablen freigeben
RELEASE cFileName, cLinkName, oShell, cDesktop, oLink

Dienstag, 18. Dezember 2007

Wieso verhält sich die Modulo-Funktion so wie sie sich verhält?!? / The reason why modulo behaves as it behaves

Die vielleicht etwas eigenwillige Frage im Post-Titel beruht auf dem Ergebnis der beiden folgenden Berechnungen:

?MOD(9/10)  && liefert 9 -> 0 Rest 9
?MOD(-9/10) && liefert 1 -> x Rest 1 ??????

Woher kommt bei der zweiten Zeile das Ergebnis 1?

Grundsätzlich gilt, das bei der Modulo-Berechnung alle Zahlen in 'Blöcke' von 0 bis 9 eingeordnet werden:

...
  0 => Block 0
  1 => Block 1
  2 => Block 2
  3 => Block 3
  4 => Block 4
  5 => Block 5
  6 => Block 6
  7 => Block 7
  8 => Block 8
  9 => Block 9
 10 => Block 0
 11 => Block 1
...

Wird diese Vorgehensweise ins negative geführt, so ist zu erkennen, dass die -1 im Block 9 steht, da dieser immer vor Block 0 kommt:

...
 -9 => Block 1
 -8 => Block 2
 -7 => Block 3
 -6 => Block 4
 -5 => Block 5
 -4 => Block 6
 -3 => Block 7
 -2 => Block 8
 -1 => Block 9
  0 => Block 0
  1 => Block 1
  2 => Block 2
  3 => Block 3
  4 => Block 4
  5 => Block 5
  6 => Block 6
...

Etwas anders erklärt:

Die MOD()-Funktion gibt den Rest an, der bei einer ganzzahligen Division entsteht. Dass bei 18 MOD 10 als Ergebnis 8 herauskommt, ist sofort einsichtig. Bei negativen Zahlen verhält es sich ebenso, wie an der oben angezeigten Blocklogik zu erkennen ist. Wird -8 durch 10 geteilt, so geht die 10 eben null Mal in die -8. Von der nächstkleineren (!) Zahl, die durch 10 teilbar ist (das wäre die -10), sind wir 2 Stellen entfernt. Somit ist -8 MOD 10 = 2.