Windows-Programme (XbpDialog): Unterschied zwischen den Versionen

Aus Wiki des Deutschsprachige Xbaseentwickler e. V.
Zur Navigation springen Zur Suche springen
KKeine Bearbeitungszusammenfassung
Zeile 2: Zeile 2:
== Voraussetzungen eines Windows-Programms ==
== Voraussetzungen eines Windows-Programms ==


Voraussetzung ist, dass das Programm ein [[XbpDialog()]] Fenster verwendet und - in der Folge - mit dem Link-Switch /PM:PM gelinkt wird.
Voraussetzung ist, dass das Programm ein [[XbpDialog()]] Fenster verwendet und - in der Folge - mit dem Link-Switch [[/PM:PM]] gelinkt wird.


Dadurch sind die "klassischen" @ SAY/GET/PROMPT Befehle nicht mehr verwendbar, und "neues" tritt an ihre Stelle, nämlich ein neues Koordinaten-System, das standardmässig unten links seinen Bezugspunkt ({0, 0}) hat.
Dadurch sind die "klassischen" @ SAY/GET/PROMPT Befehle nicht mehr verwendbar, und "neues" tritt an ihre Stelle, nämlich ein neues Koordinaten-System, das standardmässig unten links seinen Bezugspunkt ({0, 0}) hat.
Zeile 80: Zeile 80:
  Dimension des Paren: {1008, 781}, Dimension des Over-Parent {1024, 819}.
  Dimension des Paren: {1008, 781}, Dimension des Over-Parent {1024, 819}.


Mein Rechner hat einen Monitor mit einer Darstellung von 1280*1024 Pixel. 80 % davon sind 1024*819,2 - wobei wir ja die Dimensionen auf die jeweilige Ganzzahl begrenzt haben, also 1024*819. Dies ist dann auch die Dimension unseres SetAppWindow() und enthält die Titelliste (title bar), und die Rahmen um das Fenster (nochmals der Hinweis: wir haben keine abweichenden Presentation Parameter in der :new() Methode definiert, daher "erbt" unser Programm die Standard-Einstellungen, die in Windows definiert sind.
Mein Rechner hat einen Monitor mit einer Darstellung von 1280*1024 Pixel. 80 % davon sind 1024*819,2 - wobei wir ja die Dimensionen auf die jeweilige Ganzzahl begrenzt haben, also 1024*819. Dies ist dann auch die Dimension unseres [[SetAppWindow()]] und enthält die Titelliste (title bar), und die Rahmen um das Fenster (nochmals der Hinweis: wir haben keine abweichenden Presentation Parameter in der [[:new()]] Methode definiert, daher "erbt" unser Programm die Standard-Einstellungen, die in Windows definiert sind.


Würden wir versuchen, diesen Bereich zu nutzen, sind Kollisionen mit den Randbereichen fast vorprogrammiert. "Innerhalb" des [[XbpDialog()]]-Fensters gibt es einen rechteckigen Bereich, die sogenannte :drawingArea, die als Ziel (Parent und/oder Owner) für unsere Xbase-Parts verwendet werden sollte (man muss nicht, sollte aber).
Würden wir versuchen, diesen Bereich zu nutzen, sind Kollisionen mit den Randbereichen fast vorprogrammiert. "Innerhalb" des [[XbpDialog()]]-Fensters gibt es einen rechteckigen Bereich, die sogenannte [[:drawingArea]], die als Ziel ([[Parent]] und/oder [[Owner]]) für unsere [[Xbase-Parts]] verwendet werden sollte (man muss nicht, sollte aber).


Durch das Klicken auf den [[XbpPushButton()]] wird der :activate Slot ausgeführt, und der ruft die Funktion ShowInfo() auf und übergibt eine Referenz auf den [[XbpPushButton()]] (daher auch als self definiert).
Durch das Klicken auf den [[XbpPushButton()]] wird der [[:activate]] Slot ausgeführt, und der ruft die Funktion ShowInfo() auf und übergibt eine Referenz auf den [[XbpPushButton()]] (daher auch als [[self]9 definiert).


In ShowInfo() erstellen wir eine String zur Anzeige mit der Funktion [[ConfirmBox()]]. Als erstes weisen wir die Grösse des Parents des [[XbpPushButton()]] aus.
In ShowInfo() erstellen wir eine String zur Anzeige mit der Funktion [[ConfirmBox()]]. Als erstes weisen wir die Grösse des Parents des [[XbpPushButton()]] aus.


Um den Parent eines Xbase-Parts zu ermitteln, verwendet man die Methode :setParent(). Diese liefert eine Referenz auf den bisherigen Parent zurück und kann - wenn erforderlich - auch einen neuen Parent definierten. Uns reicht die Referenz auf den bisherigen Parent aus.
Um den Parent eines Xbase-Parts zu ermitteln, verwendet man die Methode [[:setParent()]]. Diese liefert eine Referenz auf den bisherigen Parent zurück und kann - wenn erforderlich - auch einen neuen Parent definierten. Uns reicht die Referenz auf den bisherigen Parent aus.


Die Methode :currentSize() liefert die aktuelle Grösse des Xbase-Parts, mit ein paar kleinen Konvertierungen wird die Nachricht erweitert und der Parent des Parent abgefragt. Die weiteren Schritte wiederholen sich.
Die Methode [[:currentSize()]] liefert die aktuelle Grösse des Xbase-Parts, mit ein paar kleinen Konvertierungen wird die Nachricht erweitert und der Parent des Parent abgefragt. Die weiteren Schritte wiederholen sich.




== Die Verwandschaftsverhältnisse ==
== Die Verwandschaftsverhältnisse ==


       AppDesktop()
       [[AppDesktop()]]
             +
             +
             |
             |
Zeile 104: Zeile 104:
             +
             +
             |
             |
     XbpPushButton()
     [[XbpPushButton()]]


Diese Struktur zeigt auf, welches Element für welches Xbase-Part als Parent dient. Die Abfrage "von unten nach oben" haben wir mit der Methode :setParent() durchgeführt, wobei es auch in die andere Richtung geht. Hierfür wird die Methode :childList() verwendet, die allerdings als Array zurückgegeben wird, denn:
Diese Struktur zeigt auf, welches Element für welches [[Xbase-Parts|Xbase-Part]] als [[Parent]] dient. Die Abfrage "von unten nach oben" haben wir mit der Methode [[:setParent()]] durchgeführt, wobei es auch in die andere Richtung geht. Hierfür wird die Methode [[:childList()]] verwendet, die allerdings als [[Array]] zurückgegeben wird, denn:


- es kann kein Child geben (würden wir diese Abfrage z.B. auf [[XbpPushButton()]] anwenden
- es kann kein Child geben (würden wir diese Abfrage z.B. auf [[XbpPushButton()]] anwenden
Zeile 115: Zeile 115:
== Etwas über die Orientierung ==
== Etwas über die Orientierung ==


Wer von Clipper kommt, für den mag die Tatsache, dass die Koordinaten "auf den Kopf gestellt sind", nicht so einfach zu verdauen sein.
Wer von [[Clipper]] kommt, für den mag die Tatsache, dass die Koordinaten "auf den Kopf gestellt sind", nicht so einfach zu verdauen sein.


Es gibt die Möglichkeit, die Koordinaten zu drehen.
Es gibt die Möglichkeit, die Koordinaten zu drehen.


Die Methode :new() kennt einen fünften Parameter, der die Darstellung des Xbase-Parts beeinflusst. aPP ist ein Array von Arrays. Das könnte dann so aussehen:
Die Methode [[:new()]] kennt einen fünften Parameter, der die Darstellung des [[Xbase-Parts]] beeinflusst. aPP ist ein [[Array]] von Arrays. Das könnte dann so aussehen:


  aPP := { {XBP_PP_ORIGIN, XBP_ORIGIN_TOPLEFT} }
  aPP := { {XBP_PP_ORIGIN, XBP_ORIGIN_TOPLEFT} }


Damit würde der Ursprung für das Koordinatensystem nach oben links verlegt und entspräche (in etwa) dem von Clipper bekannten System.
Damit würde der Ursprung für das Koordinatensystem nach oben links verlegt und entspräche (in etwa) dem von [[Clipper]] bekannten System.




(Artikelinarbeit)
(Artikelinarbeit)

Version vom 20. Juni 2013, 14:18 Uhr

Voraussetzungen eines Windows-Programms

Voraussetzung ist, dass das Programm ein XbpDialog() Fenster verwendet und - in der Folge - mit dem Link-Switch /PM:PM gelinkt wird.

Dadurch sind die "klassischen" @ SAY/GET/PROMPT Befehle nicht mehr verwendbar, und "neues" tritt an ihre Stelle, nämlich ein neues Koordinaten-System, das standardmässig unten links seinen Bezugspunkt ({0, 0}) hat.


kleines Demo-Programm

#INCLUDE "AppEvent.ch"
FUNCTION AppSys()
  Local aSize[2], aPos[2], nI, oDlg
  aSize := AppDesktop():currentSize()
  FOR nI := 1 TO 2
    aSize[nI] := Int(aSize[nI] * 0.8)
  NEXT
  aPos := {0, 0}
  oDlg := XbpDialog():new(AppDesktop(), AppDesktop(), aPos, aSize)
  oDlg:sysmenu := .T.
  oDlg:hideButton := .T.
  oDlg:taskList := .T.
  oDlg:close := {|| PostAppEvent(xbeP_Close)}
  oDlg:title := ""
  oDlg:create()
  oDlg:setTitle("kleine GUI-Demo")
  SetAppWindow(oDlg)
  CenterControl(oDlg)
RETURN (.T.)
FUNCTION Main()
  LOCAL nEvent, mp1, mp2, oXbp
  nEvent := xbe_None
  WHILE nEvent <> xbeP_Close
    nEvent := AppEvent(@mp1, @mp2, @oXbp)
    oXbp:handleEvent(nEvent, mp1, mp2)
  END
RETURN(.T.)

Dieser Programmcode erzeugt ein Fenster, dessen äussere Dimension 80 % des Windows-Desktop beträgt, und das zentriert auf dem Bildschirm angezeigt wird.

Das Programm reagiert auf die Standard-Windows-Befehle, die über das System-Menü eingegeben werden können, wir können es verschieben, die Grösse verändern, minimieren, maximieren, wiederherstellen - alles das ist quasi "im Paket" drin, da das verwendete XbpDialog() Fenster implizit mit den entsprechenden Ereignissen umgehen kann.

Mehr ist definitiv (noch) nicht drin.


Erweiterung des Demo-Programms um ein Xbase-Part

Beginnen wir mit der Erforschung des Fensters. Hierzu implementieren wir eine Control, die uns Informationen liefern soll:

FUNCTION Main()
  LOCAL nEvent, mp1, mp2, oXbp, aPos, aSize
  aPos := {10, 10}
  aSize := {100, 20}
  oXbp := XbpPushButton():new(SetAppWindow():drawingArea(),;
     SetAppWindow():drawingArea, aPos, aSize)
  oXbp:caption := "Klick mich!"
  oXbp:activate := {|| ShowInfo()}
  oXbp:create()
  nEvent := xbe_None
  WHILE nEvent <> xbeP_Close
    nEvent := AppEvent(@mp1, @mp2, @oXbp)
    oXbp:handleEvent(nEvent, mp1, mp2)
  END
RETURN(.T.)
FUNCTION ShowInfo(oPush)
  Local cMsg, oParent, aSize
  cMsg := "Dimension des Parent: {"
  oParent := oPush:setParent()
  aSize := oParent:currentSize()
  cMsg += LTrim(Str(aSize[1])) + ", " + LTrim(Str(aSize[2])) + "}, "
  cMsg += "Dimension des Over-Parent {"
  oParent := oParent:setParent()
  aSize := oParent:currentSize()
  cMsg += LTrim(Str(aSize[1])) + ", " + LTrim(Str(aSize[2])) + "}."
  ConfirmBox(, cMsg, "Information", XBPMB_OK, XBPMB_INFORMATION)
RETURN (.T.)

Bevor wir die Einzelheiten betrachten, erstellen wir das Programm, starten es und klicken auf den XbpPushButton():

Dimension des Paren: {1008, 781}, Dimension des Over-Parent {1024, 819}.

Mein Rechner hat einen Monitor mit einer Darstellung von 1280*1024 Pixel. 80 % davon sind 1024*819,2 - wobei wir ja die Dimensionen auf die jeweilige Ganzzahl begrenzt haben, also 1024*819. Dies ist dann auch die Dimension unseres SetAppWindow() und enthält die Titelliste (title bar), und die Rahmen um das Fenster (nochmals der Hinweis: wir haben keine abweichenden Presentation Parameter in der new() Methode definiert, daher "erbt" unser Programm die Standard-Einstellungen, die in Windows definiert sind.

Würden wir versuchen, diesen Bereich zu nutzen, sind Kollisionen mit den Randbereichen fast vorprogrammiert. "Innerhalb" des XbpDialog()-Fensters gibt es einen rechteckigen Bereich, die sogenannte drawingArea, die als Ziel (Parent und/oder Owner) für unsere Xbase-Parts verwendet werden sollte (man muss nicht, sollte aber).

Durch das Klicken auf den XbpPushButton() wird der activate Slot ausgeführt, und der ruft die Funktion ShowInfo() auf und übergibt eine Referenz auf den XbpPushButton() (daher auch als [[self]9 definiert).

In ShowInfo() erstellen wir eine String zur Anzeige mit der Funktion ConfirmBox(). Als erstes weisen wir die Grösse des Parents des XbpPushButton() aus.

Um den Parent eines Xbase-Parts zu ermitteln, verwendet man die Methode setParent(). Diese liefert eine Referenz auf den bisherigen Parent zurück und kann - wenn erforderlich - auch einen neuen Parent definierten. Uns reicht die Referenz auf den bisherigen Parent aus.

Die Methode currentSize() liefert die aktuelle Grösse des Xbase-Parts, mit ein paar kleinen Konvertierungen wird die Nachricht erweitert und der Parent des Parent abgefragt. Die weiteren Schritte wiederholen sich.


Die Verwandschaftsverhältnisse

     AppDesktop()
           +
           |
      XbpDialog()
           +
           |
XbpDialog():drawingArea
           +
           |
    XbpPushButton()

Diese Struktur zeigt auf, welches Element für welches Xbase-Part als Parent dient. Die Abfrage "von unten nach oben" haben wir mit der Methode setParent() durchgeführt, wobei es auch in die andere Richtung geht. Hierfür wird die Methode childList() verwendet, die allerdings als Array zurückgegeben wird, denn:

- es kann kein Child geben (würden wir diese Abfrage z.B. auf XbpPushButton() anwenden - es kann ein Element vorhanden sein (wie in unserem Beispiel) - es kann eine (theoretisch) unbegrenzte Anzahl von Elementen geben


Etwas über die Orientierung

Wer von Clipper kommt, für den mag die Tatsache, dass die Koordinaten "auf den Kopf gestellt sind", nicht so einfach zu verdauen sein.

Es gibt die Möglichkeit, die Koordinaten zu drehen.

Die Methode new() kennt einen fünften Parameter, der die Darstellung des Xbase-Parts beeinflusst. aPP ist ein Array von Arrays. Das könnte dann so aussehen:

aPP := { {XBP_PP_ORIGIN, XBP_ORIGIN_TOPLEFT} }

Damit würde der Ursprung für das Koordinatensystem nach oben links verlegt und entspräche (in etwa) dem von Clipper bekannten System.


(Artikelinarbeit)