3.50 DM_PictureHandler

Mit einem benutzerdefinierten Grafik-Handler (GFX-Handler) können Bilder in Grafikformaten, die der IDM nicht unterstützt, geladen und angezeigt werden. Dafür ruft der IDM jedes Mal, wenn ein Bild geladen werden muss (weil es z.B. über eine Tile-Ressource in der Anwendung angebunden wurde), als erstes die angemeldeten Grafik-Handler auf. Kann einer dieser Handler das Bild laden, übergibt er die Bilddaten an den IDM und es werden keine weiteren Grafik-Handler aufgerufen. Wenn kein Grafik-Handler das Bild laden konnte, versucht der IDM selbst das Bild zu parsen. Das Verhalten ist dann so, als ob keine Grafik-Handler benutzt wurden.

Grafik-Handler werden mit der Funktion DM_PictureReaderHandler beim IDM an- und abgemeldet.

Ein Grafik-Handler muss wie folgt definiert sein:

DM_Boolean DML_default DM_CALLBACK <ProcName>
(
  DM_PicInfo * pic
)
{
  /* benutzerdefinierter Code */
}

Beim Aufruf wird dem Grafik-Handler ein Zeiger auf die Struktur DM_PicInfo übergeben. Diese Struktur enthält alle Informationen über ein Bild, das geladen oder dessen Speicherplatz freigegeben werden soll.

typedef struct {
  DM_Integer  struct_size;  // Groesse der Struktur zur Verifikation der Version
  DM_UInt1    task;         // Task fuer den Grafik-Handler
  DM_String   fname;        // Dateiname des Bildes
  DM_String   name;         // Name des Bildes wie an tile oder image angegeben
#if defined(WSIWIN)
  DM_UInt2    width;        // Breite des Bildes
  DM_UInt2    height;       // Hoehe des Bildes
  DM_UInt2    type;         // Bildtyp
  HANDLE      palette;      // Handle fuer die Farbpalette
  HANDLE      image;        // Handle fuer das Bild
  HANDLE      trans_mask;   // Handle fuer die Transparenzmaske
#endif
#if defined(MOTIF) || defined(QT)
  DM_UInt2    type;         // Bildtyp
  DM_Pointer  image;        // Zeiger auf die Bilddaten
  DM_Pointer  trans_mask;   // Zeiger auf die Transparenzmaske
#endif
  DM_Integer  trans_color;  // Index der transparenten Farbe
} DM_PicInfo;

Bedeutung der Elemente

DM_Integer struct_size

Hier wird die Größe der Struktur übergeben. Damit kann im Grafik-Handler mit sizeof() überprüft werden, ob die Größe der übergebenen Struktur mit der verwendeten Strukturdefinition übereinstimmt.

DM_UInt1 task

Definiert, was der Grafik-Handler tun soll. Es sind zwei Aufgaben möglich:

  • DM_GFX_TASK_LOAD

    Laden eines Bildes.

    Der Grafik-Handler muss eine Bilddatei mit dem Dateinamen fname laden und folgende Elemente der DM_PicInfo-Struktur setzen.

    • width (erforderlich unter Microsoft Windows; sonst in den Bilddaten enthalten)
    • height (erforderlich unter Microsoft Windows; sonst in den Bilddaten enthalten)
    • type (erforderlich)
    • palette (optional; nur Microsoft Windows)
    • image (erforderlich)
    • trans_mask (optional; unterstützt ab IDM-Version A.05.02.e)
    • trans_color (optional; zurzeit nicht ausgewertet)
  • DM_GFX_TASK_UNLOAD

    Speicher für die Bilddaten freigeben.

    In diesem Fall sind folgende Strukturelemente gesetzt, damit der Grafik-Handler den Speicherplatz dieser Objekte freigeben kann:

    • palette (falls vorhanden; nur Microsoft Windows)
    • image
    • trans_mask (falls vorhanden; unterstützt ab IDM-Version A.05.02.e)

DM_String fname

Nur bei task == DM_GFX_TASK_LOAD gültig.

In diesem Element werden Pfad und Dateiname des Bildes angegeben, das geladen werden soll.

Der IDM überprüft, ob das Bild geladen werden kann. Wenn das der Fall ist, enthält fname den aufgelösten Dateinamen des Bildes.

Wenn das Bild nicht geladen, d.h. der Dateiname nicht aufgelöst werden kann, dann ist name == fname.

DM_String name

Nur bei task == DM_GFX_TASK_LOAD gültig.

Das Element enthält den unaufgelösten Dateinamen des Bildes, wie er an der Tile-Ressource bzw. am Image-Objekt angegeben wurde.

Das Strukturelement ist ab IDM-Version A.05.02.e vorhanden.

DM_Integer trans_color

Hier kann die transparent darzustellende Farbe übergeben werden.

Das Element wird zurzeit nicht ausgewertet.

Belegung der Strukturelemente unter Microsoft Windows

DM_UInt2 width
DM_UInt2 height

Nur bei task == DM_GFX_TASK_LOAD gültig.

In diesen Elementen muss der Grafik-Handler als Rückgabewert die Breite und Höhe des geladenen Bildes übergeben.

DM_UInt2 type

In diesem Element muss der Grafik-Handler den Typ des Handles zurückgeben, der in image übergeben wird.

Wertebereich

  • DM_GFX_BMP Windows Bitmap
  • DM_GFX_WMF Windows Meta File
  • DM_GFX_EMF Enhanced Meta File
  • DM_GFX_ICO Windows Icon

HANDLE palette

Für task == DM_GFX_TASK_LOAD

Der Grafik-Handler kann zusammen mit dem Bild eine Farbpalette (Windows Handle Type HPALETTE) an den IDM übergeben. Ist dieses Element NULL, wird die System-Farbpalette verwendet.

Im Allgemeinen sollte darauf verzichtet werden, für jedes Bild eine eigene Farbpalette zu verwenden, da es beim Fokuswechsel auf Systemen mit geringer Farbtiefe zu Farbverfälschungen kommen kann. Stattdessen sollte der Grafik-Handler die Farben eines Bildes mit der System-Farbpalette abgleichen, und so für die Farbechtheit des Bildes sorgen.

Für task == DM_GFX_TASK_UNLOAD

Wenn eine Farbpalette verwendet wurde, wird in diesem Element deren Handle vom IDM an den Grafik-Handler übergeben, damit der Handler den Speicher für die Farbpalette freigeben kann.

HANDLE image

Für task == DM_GFX_TASK_LOAD

In diesem Element muss der Grafik-Handler den Handle des von ihm geladenen Bildes zurückgeben. Der Typ des Handles muss mit der Angabe in type übereinstimmen.

Für task == DM_GFX_TASK_UNLOAD

In diesem Element wird vom IDM der Handle des Bildes, dessen Speicher freizugeben ist, an den Grafik-Handler übergeben.

HANDLE trans_mask

Dieses Strukturelement wird erst ab IDM-Version A.05.02.e ausgewertet.

Für task == DM_GFX_TASK_LOAD

In diesem Element kann eine Transparenzmaske übergeben werden. Die Transparenzmaske muss eine monochrome Windows Bitmap (Datentyp HBITMAP) mit der gleichen Größe wie das in image übergebene Bild sein.

Eine Transparenzmaske wird nur für den Bildtyp DM_GFX_BMP unterstützt, bei anderen Bildtypen wird sie ignoriert.

Für task == DM_GFX_TASK_UNLOAD

Wenn eine Transparenzmaske verwendet wurde, wird in diesem Element deren Handle vom IDM an den Grafik-Handler übergeben, damit der Handler den Speicher für die Transparenzmaske freigeben kann.

Belegung der Strukturelemente unter Motif und Qt

DM_UInt2 type

In diesem Element muss der Grafik-Handler den Typ des Bildes zurückgeben, das in image übergeben wird

Wertebereich beim IDM für Motif

  • DM_GFX_XIMAGE XImage-Bild
  • DM_GFX_PIXMAP PixMap-Bild (unterstützt ab IDM-Version A.05.02.e)

Wertebereich beim IDM für Qt

  • DM_GFX_QPIXMAP
  • DM_GFX_QIMAGE
  • DM_GFX_QICON

DM_Pointer image

Für task == DM_GFX_TASK_LOAD

In diesem Element muss der Grafik-Handler entsprechend dem type-Element einen Zeiger auf ein PixMap-Bild oder eine XImage-Struktur mit den Bilddaten übergeben.

Die XImage-Struktur kann unter X Windows mit der Xlib-Funktion XCreateImage() generiert werden. Hierfür sind Informationen über aktuelle Bildschirmeinstellungen (z.B. Display, Visual, Screen, Depth) notwendig. Diese Daten können mit der Schnittstellenfunktion DM_GetToolkitData abgefragt werden.

Für task == DM_GFX_TASK_UNLOAD

In diesem Element wird vom IDM ein Zeiger auf die Bilddaten, deren Speicher freizugeben ist, an den Grafik-Handler übergeben.

DM_Pointer trans_mask

Dieses Strukturelement wird erst ab IDM-Version A.05.02.e ausgewertet.

Für task == DM_GFX_TASK_LOAD

In diesem Element kann ein Zeiger auf eine Transparenzmaske übergeben werden. Unter Motif muss die Transparenzmaske ein PixMap-Bild sein, unter Qt muss ihr Datentyp dem in type angegebenen Bildtyp entsprechen. Die Transparenzmaske muss die gleiche Größe wie das in image übergebene Bild haben.

Für task == DM_GFX_TASK_UNLOAD

Wenn eine Transparenzmaske verwendet wurde, wird in diesem Element ein Zeiger darauf vom IDM an den Grafik-Handler übergeben, damit der Handler den Speicher für die Transparenzmaske freigeben kann.

Rückgabewert

DM_TRUE

Das Bild konnte geladen werden.

DM_FALSE

Im Fehlerfall.

Anmerkungen

Grafik-Handler sind systemabhängig. Wie die DM_PicInfo-Struktur zeigt, unterscheiden sich je nach System die Datenformate für die Rückgabe von Bilddaten.

Da ein Grafik-Handler zum Laden eines Bildes Speicher allokieren muss (z.B. für image, palette und trans_mask), muss er auch mit der Freigabe dieses Speichers beauftragt werden. Deshalb ruft der IDM die Grafik-Handler mit task == DM_GFX_TASK_LOAD auf, wenn ein Bild gebraucht wird. Wenn das Bild nicht mehr gebraucht wird, werden die Grafik-Handler mit task == DM_GFX_TASK_UNLOAD aufgerufen, damit sie den Speicherplatz freigeben können.

Der erste Grafik-Handler, der den Speicher freigibt, liefert DM_TRUE zurück, sodass danach keine weiteren Handler aufgerufen werden. Dies muss nicht unbedingt der selbe Handler sein, der das Bild geladen hat.

Vom IDM erfolgt keine Zuordnung zwischen einem Bild und dem für das Laden und somit auch für das Freigeben des Bildes zuständigen Grafik-Handler. Wenn z.B. alle Grafik-Handler den Speicher auf die gleiche Art und Weise allokieren, dann kann auch jeder Handler den Speicher eines anderen freigeben. Das heißt, der erste aufgerufene Handler gibt sofort den Speicher frei.

Beispiel

Ein typischer GFX-Handler hat in etwa folgende Struktur:

DM_Boolean DML_default DM_CALLBACK MyGfxHandler __1((DM_PicInfo *, pic))
{
  /* zuerst feststellen, was zu tun ist */
  if (pic->task == DM_GFX_TASK_LOAD) {
    /* das eigentliche Laden erfolgt in LoadPicture_... */

#if defined(WIN32)
    /* Bild laden (Microsoft Windows) */
    pic->image = LoadPicture_Win32 (pic->fname);
#endif
#if defined(MOTIF) || defined(QT)
    /* Bild laden (XWindows) */
    pic->image = LoadPicture_X (pic->fname);
#endif

    if (pic->image) {
      /* Rueckgabewerte in pic einragen */

#if defined(WIN32)
      pic->type    = DM_GFX_...;
      pic->palette = Handle auf Palette, falls gewuenscht;
      pic->width   = Breite des Bildes;
      pic->height  = Hoehe des Bildes;
#endif
#if defined(MOTIF) || defined(QT)
      pic->type = DM_GFX_...;
#endif

      return DM_TRUE;  /* Erfolg */
    } else {
      /* Bild konnte nicht geladen werden, vielleicht ist ein anderer
         GFX-Handler oder der Grafikparser des IDM erfolgreicher */
      return DM_FALSE;
    }
  } else {
    /* Speicher freigeben */

#if defined(WIN32)
    if (pic->image)       /* hier geladen */
      DeleteObject(pic->image);
    if (pic->palette)     /*  hier generiert */
      DeleteObject(pic->palette);
#endif
#if defined(MOTIF) || defined(QT)
    if (pic->image)       /* hier geladen */
      XDestroyImage((XImage *)pic->image);
    if (pic->trans_mask)  /*  hier generiert */
      free(pic->trans_mask);
#endif
 
    return DM_TRUE;
  }
}

Der GFX-Handler sollte vor dem Laden von Bilddateien und somit in der Regel vor dem Laden des Dialogs angemeldet werden:

if (!DM_PictureReaderHandler (MyGfxHandler, DMF_RegisterHandler, 0))
  DM_TraceMessage("GFX-Handler registering error", 0);
...
/* Dialog laden */

Siehe auch

Funktion DM_PictureReaderHandler