Programmierung

Dynamisches ermitteln von Objekten

Um Objekte gezielt ansprechen zu können, werden Deskriptoren verwendet. Damit diese nicht mühsam verwaltet werden müssen, gibt es die Möglichkeit Deskriptoren dynamisch zu ermitteln. Dafür werden die Befehle WinInfo(), WinSearch(), PrtInfo() und PrtSearch() von CONZEPT 16 zur Verfügung gestellt. Im folgenden Artikel möchte ich Ihnen aufzeigen, wie ein Deskriptor dynamisch ermittelt werden kann.

WinInfo()

Die Funktionen von WinInfo() können in vier Bereiche aufgeteilt werden:

  • Navigation durch den Objektbaum
  • Ermitteln von Objekten
  • Informationen über das Objekt
  • Informationen über die Umgebung

Die Navigation durch den Objektbaum wird mit den Parametern _WinFirst, _WinNext, _WinPrev und _WinLast ermöglicht. Hierbei ist zu beachten, dass die Objekte in der Reihenfolge zurückgegeben werden, in der sie erstellt worden sind.
Ein kleines Beispiel:
Gegeben ist eine RecList, die genaue Anzahl der Spalten ist nicht bekannt. Es sollen für jede Spalte der Name und die Breite ermittelt werden.

// Spalten in sichtbarer Reihenfolge ermitteln
tHdlRecLst->wpOrderPass # _WinOrderShow;

// Anzahl der Spalten ermitteln
tCount # tHdlRecLst->WinInfo(_WinCount);

for  tClm # tHdlRecLst->WinInfo(_WinFirst)
loop tClm # tClm->WinInfo(_WinNext)
while (tClm > 0)
{
   // Name der Spalte ermitteln
   tName # tClm->wpName;

   // Breite der Spalte
   tWidth # tClm->wpClmWidth;
   ...
}

WinInfo() liefert auch Informationen über das Objekt selbst. Es muss allerdings beachtet werden, dass bei manchen Konstanten nur bestimmte Objekttypen übergeben werden können. So kann beispielsweise, mittels _WinItem, die Spaltenposition innerhalb einer DataList ermittelt werden. Ist das Objekt keine DataList, wird die Meldung ‘Deskriptor ungültig’ zurückgeliefert.
Noch ein Beispiel:
Als nächstes sollen, ausgehend von einem MDI-Anwendungsfenster, alle Einträge des AppFrame-Menüs ermittelt werden. Das nachfolgende Beispiel zeigt, wie das funktioniert.

sub MenuRecurse
(
  aMenu : handle;
)

  local
  {
    tItem : handle;
  }

{
  for  tItem # aMenu->WinInfo(_WinFirst)
  loop tItem # tItem->WinInfo(_WinNext)
  while (tItem > 0)
  {
    // Verarbeitung des Items
    DbgTrace(tItem->wpName);

    tItem->MenuRecurse();
  }
}

main

  local
  {
    tHdlAppFrame : handle;
    tMenu        : handle;
  }

{
  // MdiFrame als Ausgangs-Objekt
  tHdlMdiFrame # ...;

  // AppFrame des MdiFrame ermitteln
  tHdlAppFrame # tHdlMdiFrame->WinInfo(_WinParent);

  if (tHdlAppFrame->WinInfo(_WinType) = _WinTypeAppFrame)
  {
    // Menü des Fensters ermitteln
    tMenu # tHdlAppFrame->WinInfo(_WinMenu);

    // Menüeinträge iterieren
    tMenu->MenuRecurse();
  }
}
WinSearch()

WinSearch() kann dazu verwendet werden, den Deskriptor eines Objekts zu ermitteln. Dabei werden auch Wildcards (‘*’ und ‘?’) berücksichtigt. Als Startobjekt wird immer das Elternobjekt des zu suchenden Objektes angegeben.

Gegeben ist ein Frame mit drei Edit-Objekten Edit1, Edit2, Edit3 und eine Variable vom Typ Integer (tInt). In der Variablen tInt steht die Nummer des Edit-Objektes.
Es soll die die Eigenschaft wpCaption des Edit-Objekts abhängig von der Integer-Variablen ermittelt werden.

// Deskriptor des Edit-Objekts ermitteln
tHdl # tHdlFrame->WinSearch('Edit' + CnvAI(tInt));

tStr # tHdl->wpCaption;
PrtSearch()

Analog zu dem Befehl WinSearch(), gibt es den Befehl PrtSearch() für Druck-Objekte. Dabei gilt wieder, das Startobjekt der Suche ist das Elternobjekt. Soll beispielsweise ein bestimmter Drucker ermittelt werden, so muss die Druckerliste angegeben werden.

// Suchen des Druckers
tPrinterList # _App->ppPrinterList;
tPrinter # tPrinterList->PrtSearch('PrinterName');
if (tPrinter > 0)
{
   WinDialogBox(0,'Drucker',tPrinter->ppName,_WinIcoInformation,_WinDialogOk,0);
}

Ist das Objekt in einem PrintForm-Objekt enthalten, muss der Deskriptor auf das PrintForm-Objekt übergeben werden. Es können allerdings auch Startobjekte angegeben werden, welche den genannten Objekten untergeordnet sind. Wird ein Objekt gefunden, so wird der Deskriptor als Resultat zurückgegeben. Ist kein Objekt gefunden worden, so ist das Resultat 0.

// Suchen eines Objektes in einem Textbaustein
tJob # PrtJobOpen(_PrtDocDinA4,'Print.job',_PrtJobOpenWrite);
if (tJob > 0)
{
   tForm # PrtFormOpen(_PrtTypePrintForm,'List.customer');
   tObject # PrtSearch(tForm,'Company');
   ...
}

Der Deskriptor eines Printjobs kann dann angegeben werden, wenn sich das gesuchte Objekt in einem PrintDoc– oder PrintDocRecord-Objekt befindet, da Druckjobs diese Objekte enthalten.

PrtInfo()

Mit PrtInfo() kann, vergleichbar mit dem Befehl WinInfo(), durch den Objektbaum von Druckobjekten navigiert werden.

// Ermitteln aller Objekte auf einer PrintForm
tJob # PrtJobOpen(_PrtDocDinA4,'',_PrtJobOpenWrite | _PrtJobOpenTemp);

if (tJob > 0)
{
   tForm # PrtFormOpen(_PrtTypePrintForm, 'My.PrintForm');
   if (tForm > 0)
   {
      tPage # tJob->PrtJobWrite(_PrtJobPageStart);

      for  tPrtItem # tForm->PrtInfo(_PrtFirst)
      loop tPrtItem # tPrtItem->PrtInfo(_PrtNext)
      while (tPrtItem != 0)
      {
         // Verarbeitung des Objektes
         ...
      }
      // PrintForm drucken
      tPage->PrtAdd(tForm);
   }
   // Druckform entladen
   tForm->PrtFormClose();

   // Druckjob abschließen und Druckvorschau anzeigen
   tJob->PrtJobClose(_PrtJobPreview);
}

Außerdem ist es mit Hilfe von PrtInfo() möglich Informationen über die Umgebung des Druckjobs zu erhalten. Im Folgenden sollen alle Druckauflösungen des Standarddruckers ermittelt werden.

tDevice # PrtDeviceOpen();

if (tDevice > 0)
{
   tDpiCount # tDevice->PrtInfo(_PrtInfoDpiCount);

   WinDialogBox(0,'Auflösung','Anzahl der Druckauflösungen für Drucker [' + tDevice->ppNamePrinter + '] : ' + CnvAI(tDpiCount));

   for tLoop # 1
   loop inc (tLoop)
   while (tLoop <= tDpiCount)
   {
      tDpiX # tDevice->PrtInfo(_PrtInfoDpiX, tLoop)
      tDpiY # tDevice->PrtInfo(_PrtInfoDpiY, tLoop)

      DbgTrace('[' + CnvAI(tLoop) + '] ' + CnvAI(tDpiX) + 'x' + CnvAI(tDpiY));
   }
}
Keine Kommentare

Kommentar abgeben