3.40 DM_InputHandler
Mit Hilfe dieser Funktion können zusätzliche Nachrichten in der Anwendung empfangen und verarbeitet werden. Die Art der Nachrichten sowie die Art des Nachrichtenempfanges ist fenstersystemabhängig. Die Funktion selber ist ebenfalls fenstersystemabhängig und wird in den nachfolgenden Kapiteln dargestellt.
3.40.1 Microsoft Windows
In diesen Fenstersystemen dient der Input-Handler dafür, dass auf beliebige Nachrichten, die an Objekte verschickt wird, reagiert werden kann. Diese Nachrichten sind vom jeweiligen Fenstersystem definiert.
HWND DML_default DM_EXPORT DM_InputHandler
(
DM_InputHandlerProc funcp,
FPTR funcarg,
DM_UInt msg,
DM_UInt iomode,
DM_UInt operation,
DM_Options options
)
Parameter
-> DM_InputHandlerProc funcp
In diesem Parameter wird ein Zeiger auf die Funktion übergeben, die beim Eintreffen der angegebenen Nachricht aufgerufen werden soll.
-> FPTR funcarg
In diesem Parameter wird eine Zeiger auf eine von der Anwendung definierten Struktur übergeben. Diese Struktur wird dann beim Aufruf der installierten Input-Handler-Funktion an die Anwendung übergeben. Der Dialog Manager merkt sich diesen Parameter nur, ohne ihn selber zu interpretieren.
-> DM_UInt msg
In diesem Parameter wird die Message angegeben, bei deren Eintreffen die angegebene Funktion aufgerufen werden soll. Hier können alle im Fenstersystem definierten Messages angegeben werden.
-> DM_UInt iomode
In diesem Parameter wird dem Dialog Manager mitgeteilt, wie der installierte Input-Handler zu interpretieren ist. Dazu sind folgende Konstanten definiert:
iomode |
Bedeutung |
---|---|
Diese Option ist nicht zulässig, wenn mit Hilfe der DM_InputHandler-Funktion ein Input-Handler installiert werden soll. |
|
Diese Option besagt, dass der installierte Input-Handler nur informiert werden möchte, wenn die angegebene Nachricht eingetroffen ist. Die eigentliche Handhabung der Nachricht wird dabei vom Dialog Manager übernommen. |
|
Diese Option bedeutet, dass der installierte Input-Handler die Abarbeitung der angegebenen Nachricht vollständig übernimmt. Der Dialog Manager reicht diese Nachricht also nur an die angegebene Funktion weiter und verarbeitet sie nicht. |
-> DM_UInt operation
In diesem Parameter wird der Funktion die eigentlich auszuführende Operation mitgeteilt. Dazu sind folgende Konstanten definiert:
operation |
Bedeutung |
---|---|
Mit Hilfe dieses Wertes wird ein Input-Handler im Dialog Manager installiert. |
|
Mit Hilfe dieses Wertes wird ein vorher installierter Input-Handler deinstalliert. |
|
Mit Hilfe dieses Wertes wird ein Input-Handler vorübergehend deaktiviert. |
|
Mit Hilfe dieses Wertes wird ein deaktivierter Input-Handler wieder aktiviert. |
-> DM_Options options
Normalerweise wird für diesen Parameter 0 angegeben. Wenn exakt ein Handler deinstalliert werden soll, kann über eine zusätzliche Option gesteuert werden, dass alle Funktionsargumente verglichen werden und der dieser Handler deinstalliert wird.
Option |
Bedeutung |
---|---|
Diese Option bedeutet, dass alle Funktionsargumente zum Suchen des Handler benützt werden sollen und nur genau der gleiche deinstalliert werden soll. Das kann dann nützlich sein, wenn mehrere Handler installiert worden sind und einer von diesen deinstalliert werden soll. |
Rückgabewert
Ist der Rückgabewert ungleich HWND 0, so wird in diesem Parameter die HWND des Objektes zurückgegeben, an das der Input-Handler gebunden worden ist. Eine HWND 0 bedeutet, dass das Installieren des Input-Handler nicht möglich war.
Beispiel
Das nachfolgende Beispiel für die PC-Plattformen zeigt, wie man mit Hilfe dieser Funktion eine asynchrone Funktion
gethostbyname
implementieren kann.
/* Definition von statischen Variablen */
static HWND TcpWinHwnd = (HWND) 0;
/* Definition der gewünschten Message-Nummer */
static UINT TcpWinMsgGetXByY = 0x6FE1;
/*
** Die nachfolgende Funktion lässt eine freie Message-Nummer
** berechnen. Diese übernimmt DM_ProposeInputHandlerArgs
** Das Ergebnis wird zurückgeliefert
*/
static boolean TcpWin_CheckAvail __1(
(TranspDescr *, tpdesc))
{
DM_InputHandlerArgs InpArgs;
/* liefert WinHandle des unsichtbaren Fensters, an dem
** Input-Handler haengt und gibt freie Message zurueck.
*/
InpArgs.hwnd = (HWND) 0;
InpArgs.message = TcpWinMsgGetXByY;
InpArgs.wParam = (WPARAM) 0;
InpArgs.lParam = (LPARAM) 0;
InpArgs.mresult = (LRESULT) 0;
InpArgs.userdata = (FPTR) 0;
DM_ProposeInputHandlerArgs (&InpArgs, DMF_DontTrace);
TcpWinHwnd = InpArgs.hwnd;
TcpWinMsgGetXByY = InpArgs.message;
}
/*
** Die nachfolgende Funktion ist die eigentliche Handler-
** Funktion. Sie entnimmt die gewünschten Daten den entspre-
** chenden Strukturen
*/
static DM_Boolean DML_default DM_CALLBACK TcpWinGetXByYHandler __3(DM_InputHandlerArgs far *, pInpArgs),
(DM_UInt, msg),
(DM_UInt, iomode))
{
if (msg == TcpWinMsgGetXByY)
{
if ( (WSAGETASYNCERROR (pInpArgs->lParam) == 0)
|| (WSAGETASYNCERROR (pInpArgs->lParam) == WSABASEERR))
{
TcpWinHostent = (struct hostent FAR *) (FPTR)
TcpWinBuffer;
}
return (FALSE);
}
return (TRUE);
}
/*
** Diese Funktion hat die Steuerung. Sie lässt die freie
** Message berechnen, installiert den Input-Handler und ruft
** dann die asynchrone Funktion gethostbyname auf.
*/
static struct hostent FAR * TcpWin_gethostbyname __1(
(const char FAR *, name))
{
HANDLE h = WSAAsyncGetHostByName (TcpWinHwnd,
TcpWinMsgGetXByY,name,TcpWinBuffer,MAXGETHOSTSTRUCT);
TcpWinHostent = (struct hostent FAR *) 0;
if ((h != (HANDLE) 0)
&& (DM_InputHandler (TcpWinGetXByYHandler, (FPTR) 0,
TcpWinMsgGetXByY, DMF_ModeMsgNotify,
DMF_RegisterHandler, DMF_DontTrace)
!= (HWND) 0)
&& DM_WaitForInput (TcpWinMsgGetXByY, 0,
DMF_IgnoreExtEvent | DMF_DontTrace))
{
DM_InputHandler (TcpWinGetXByYHandler, (FPTR) 0,
TcpWinMsgGetXByY, DMF_ModeMsgNotify,
DMF_DontTrace | DMF_CheckFuncarg);
}
return (TcpWinHostent);
}
3.40.2 Motif
In diesem Fenstersystem dient der Input-Handler dafür, dass auf beliebigen File-Deskriptoren auf Ereignisse gewartet werden kann.
So können z.B. Nachrichten, die aus anderen Prozessen kommen, verarbeitet werden.
DM_Boolean DML_default DM_EXPORT DM_InputHandler
(
DM_InputHandlerProc funcp,
FPTR funcarg,
int FileDescriptor,
DM_UInt iomode,
DM_UInt operation,
DM_Options options
)
Parameter
-> DM_InputHandlerProc funcp
In diesem Parameter wird ein Zeiger auf die Funktion übergeben, die beim Eintreffen von Nachrichten aufgerufen werden soll.
-> FPTR funcarg
In diesem Parameter wird ein Zeiger auf eine von der Anwendung definierten Struktur übergeben. Diese Struktur wird dann beim Aufruf der installierten Input-handler-Funktion an die Anwendung übergeben. Der Dialog Manager merkt sich diesen Parameter nur, ohne ihn selber zu interpretieren.
-> int FileDescriptor
In diesem Parameter wird ein FileDescriptor angegeben, auf dem auf eintreffende Nachrichten gewartet werden soll. Diese Nachrichten werden dann dem installierten Input-Handler übergeben.
-> DM_UInt iomode
In diesem Parameter wird dem Dialog Manager mitgeteilt, wie der installierte Input-Handler zu interpretieren ist. Dazu sind folgende Konstanten definiert:
iomode |
Bedeutung |
---|---|
Diese Option ist nicht zulässig, wenn mit Hilfe der DM_InputHandler-Funktion ein Input-Handler installiert werden soll. |
|
Diese Option teilt dem Dialog Manager mit, dass der angegebene Input-Handler aufgerufen werden soll, wenn von dem angegebenen File-Deskriptor gelesen worden ist. |
|
Diese Option teilt dem Dialog Manager mit, dass der angegebene Input-Handler aufgerufen werden soll, wenn auf dem angegebenen File-Deskriptor geschrieben worden ist. |
-> DM_UInt operation
In diesem Parameter wird der Funktion die eigentlich auszuführende Operation mitgeteilt. Dazu sind folgende Konstanten definiert:
operation |
Bedeutung |
---|---|
Mit Hilfe dieses Wertes wird ein Input-Handler im Dialog Manager installiert. |
|
Mit Hilfe dieses Wertes wird ein vorher installierter Input-Handler deinstalliert. |
|
Mit Hilfe dieses Wertes wird ein Input-Handler vorübergehend deaktiviert. |
|
Mit Hilfe dieses Wertes wird ein deaktivierter Input-Handler wieder aktiviert. |
-> DM_Options options
Dieser Parameter ist für zukünftige Versionen reserviert. Bitte geben Sie hier deshalb eine 0 an.
Rückgabe
TRUE |
Der Input-Handler wurde erfolgreich installiert |
FALSE |
Der Input-Handler konnte nicht installiert werden. |
Beispiel
static int FileDescr[2];
DM_ID dialogID;
static void DM_ENTRY GenExtEvent __0()
/* ------------------------------------------------------- */
/* This function generates an external event by writing to the output channel.*/
/* ------------------------------------------------------- */
{
static int len, i = 0;
static char *string[]= { "Hello, Europe",
"Hello, America",
"Hello, Africa",
"Hello, Asia",
"Hello, Australia" };
len = strlen(string[i]);
if ( write(FileDescr[1],string[i],len+1) < len+1 )
{
printf("Cannot write to pipe !\n");
exit(1);
}
if ( (++i) > 4 )
i = 0;
if ( i>3) close(FileDescr[0]);
}
static DM_Boolean InputHandler
__3(
(FPTR, udata),
(int, fdescr),
(DM_UInt, iomode)
)
/* ------------------------------------------------------ */
/* This handler function is called when the input channel */
/* is ready to be read from. */
/* ------------------------------------------------------ */
{
char buffer[256];
if (iomode == DMF_ModeBroken)
{
DM_ID obj_id;
DM_InputHandler (InputHandler, (FPTR) 0,
FileDescr[0], DMF_ModeRead,
DMF_WithdrawHandler, 0) ;
obj_id = dialogID;
{
DM_Value argv;
argv.type = DT_string;
argv.value.string = "Test";
/* ------------------------------------------------ */
/* It is not allowed to set attribute values here */
/* . So send an external event to the target object.*/
/* */
/* NOTE: It is recommended to set option
/* `DMF_Synchronous' here because this handler is
/* called synchronously */
/* ---------------------------------------------- */
DM_QueueExtEvent (obj_id, 4712, 1,
&argv,DMF_Synchronous);
}
return(TRUE);
}
if ( read(fdescr,buffer,256) > 0 )
{
DM_ID obj_id;
if ( obj_id = dialogID)
{
DM_Value argv;
argv.type = DT_string;
argv.value.string = buffer;
/* ---------------------------------- */
/* It is not allowed to set attribute values here */
/* . So send an external event to the target object.*/
/* */
/* NOTE: It is recommended to set option */
/* `DMF_Synchronous' here because this handler is */
/* called synchronously */
/* ------------------------------------------------ */
if ( DM_QueueExtEvent (obj_id, 4711, 1,
&argv,DMF_Synchronous) )
{
return TRUE;
}
else
{
printf ("Cannot send event to Dummy_Button !\n");
exit(1);
}
}
else
{
printf("Cannot get ID of DummyText !\n");
exit(1);
}
}
else
{
printf("Cannot read from pipe !\n");
exit(1);
}
return FALSE;
}
static DM_FuncMap FuncMap[] =
{
{ "GenExtEvent", (DM_EntryFunc) GenExtEvent }
};
#define ApplFuncCount (sizeof (FuncMap)/sizeof(FuncMap[0]))
int AppInit __4
(
(DM_ID, appl),
(DM_ID, dialog),
(int, argc),
(char, **argv)
)
{
DM_BindCallBacks (FuncMap, ApplFuncCount, appl, 0);
dialogID = dialog;
/* --------------------------------------------------- */
/* Create pipe and install handler on the input channel. */
/* --------------------------------------------------- */
if (-1 == pipe (FileDescr))
{
printf("Could not create pipe !\n");
return(1);
}
if ( !DM_InputHandler(InputHandler, (FPTR) 0,
FileDescr[0], DMF_ModeRead,
DMF_RegisterHandler, 0) )
{
printf("Cannot register input handler !\n");
return(1);
}
return(0);
}