| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423 |
- /*
- * Program type: API
- *
- * EVENTS.C -- Example events program
- *
- * Description: This program does an asynchronous event wait
- * on a trigger set up in the sales table of
- * employee.fdb.
- * Somebody must add a new sales order to alert
- * this program. That role can be accomplished
- * by running the api16t example program
- * after starting this program.
- *
- * Note: The system administrator needs to create the account
- * "guest" with password "guest" on the server before this
- * example can be run.
- * The contents of this file are subject to the Interbase Public
- * License Version 1.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy
- * of the License at http://www.Inprise.com/IPL.html
- *
- * Software distributed under the License is distributed on an
- * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
- * or implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code was created by Inprise Corporation
- * and its predecessors. Portions created by Inprise Corporation are
- * Copyright (C) Inprise Corporation.
- *
- * All Rights Reserved.
- * Contributor(s): ______________________________________.
- */
- #include <windows.h>
- #include <windowsx.h>
- #include <ibase.h>
- #include <stdio.h>
- #include <string.h>
- /*
- ** Local Defines
- */
- #define USER "guest"
- #define PASSWORD "guest"
- #define DATABASE "employee.fdb"
- #define IDM_EXIT 1
- #define WM_DB_EVENT WM_USER + 1
- /*
- ** This is an event block defined to keep track of all the parameters
- ** used to queue and proecess events. A pointer to this structure
- ** will be passed as the user argument to gds_que_events.
- */
- typedef struct _EventBlk {
- char *EventBuf;
- char *ResultBuf;
- short length;
- long EventId;
- char *EventName;
- isc_callback lpAstProc;
- isc_db_handle DB;
- HWND hWnd;
- struct _EventBlk *NextBlk;
- } EVENTBLK;
- /*
- ** GLOBAL VARIABLES
- */
- char szAppName [] = "Events";
- HINSTANCE hInstance;
- ISC_STATUS_ARRAY status;
- /*
- ** FUNCTION PROTOTYPES
- */
- LRESULT CALLBACK _export WndProc (HWND, UINT, WPARAM, LPARAM) ;
- HWND InitApplication(int nCmdShow, HINSTANCE hPrevInstance);
- int InitEvent(EVENTBLK *lpEvent, long *DB,
- HWND hWnd, char *event);
- void ReleaseEvents(EVENTBLK *lpEvent);
- #ifdef __cplusplus
- extern "C" { /* Assume C declarations for C++ */
- #endif /* __cplusplus */
- void AstRoutine(EVENTBLK *result, short length,
- char *updated);
- #ifdef __cplusplus
- }
- #endif /* __cplusplus */
- void WinPrint(char*);
- int CHK_ERR(long *gds__status);
- /*****************************************************************
- *
- * WinMain
- *
- *****************************************************************
- *
- * Functional description
- * Description: Setup the dpb with the username and password
- * and attach to the database, employee.fdb.
- * If the attach was successful, allocate an event
- * control block and register interest in the
- * event "new_order".
- *
- *
- ****************************************************************/
- int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrevInstance,
- LPSTR lpszCmdLine, int nCmdShow)
- {
- MSG msg;
- isc_db_handle DB = NULL;
- HWND hWnd;
- EVENTBLK *lpEventNewOrder = NULL;
- char dpb[48];
- int i = 0, len;
- hInstance = hInst;
- hWnd = InitApplication(nCmdShow, hPrevInstance);
- if (!hWnd)
- {
- WinPrint("Unable to initialize main window");
- /* Get rid of warning for both Borland and Microsoft */
- lpszCmdLine = lpszCmdLine;
- return FALSE;
- }
- /* Format the dpb with the user name a password */
- dpb[i++] = isc_dpb_version1;
-
- dpb[i++] = isc_dpb_user_name;
- len = strlen (USER);
- dpb[i++] = (char) len;
- strncpy(&(dpb[i]), USER, len);
- i += len;
-
- dpb[i++] = isc_dpb_password;
- len = strlen (PASSWORD);
- dpb[i++] = len;
- strncpy(&(dpb[i]), PASSWORD, len);
- i += len;
- isc_attach_database(status, 0, DATABASE, &(DB), i, dpb);
-
- /* If the attach was successful, initialize the event handlers */
- if (!CHK_ERR(status))
- {
- /* Allocate our event control block to hold all the event parameters */
- lpEventNewOrder = (EVENTBLK *) GlobalAllocPtr(
- GMEM_MOVEABLE | GMEM_ZEROINIT,
- sizeof(EVENTBLK));
- /* Register interest in the "new_order" event */
- InitEvent(lpEventNewOrder, (long *)DB, hWnd, "new_order");
- }
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- isc_detach_database(status, &DB);
- /* Release the allocated event blocks */
- ReleaseEvents(lpEventNewOrder);
- return msg.wParam;
- }
- /*****************************************************************
- *
- * InitApplication
- *
- *****************************************************************
- *
- * Functional description:
- * Registers the window class and displays the main window.
- * Returns:
- * window handle on success, FALSE otherwise
- *
- *****************************************************************/
- HWND InitApplication (int nCmdShow, HINSTANCE hPrevInstance)
- {
- WNDCLASS wndclass;
- HWND hWnd;
- if (!hPrevInstance)
- {
- wndclass.style = CS_HREDRAW | CS_VREDRAW;
- wndclass.lpfnWndProc = WndProc;
- wndclass.cbClsExtra = 0;
- wndclass.cbWndExtra = 0;
- wndclass.hInstance = hInstance;
- wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
- wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
- wndclass.hbrBackground = (HBRUSH)GetStockObject (WHITE_BRUSH);
- wndclass.lpszMenuName = szAppName;
- wndclass.lpszClassName = szAppName;
- if (!RegisterClass(&wndclass))
- return NULL;
- }
- if ((hWnd = CreateWindow(szAppName, "Event Test",
- WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, CW_USEDEFAULT,
- CW_USEDEFAULT, CW_USEDEFAULT,
- NULL, NULL, hInstance, NULL)) == NULL )
- return NULL;
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return hWnd;
- }
- /*****************************************************************
- *
- * InitEvents
- *
- *****************************************************************
- *
- * Functional description:
- * Initialize the event_block, and queue interest in a particular
- * event.
- * Returns:
- * TRUE if success, FALSE if que_events failed.
- *
- *****************************************************************/
- int InitEvent (EVENTBLK *lpEvent, long *DB, HWND hWnd, char *event)
- {
- /* Allocate the event buffers and initialize the events of interest */
- lpEvent->length = (short)isc_event_block(&(lpEvent->EventBuf),
- &(lpEvent->ResultBuf),
- 1, event);
- /* Store any necessary parameters in the event block */
- lpEvent->lpAstProc = (isc_callback) MakeProcInstance((FARPROC) AstRoutine,
- hInstance);
- lpEvent->DB = DB;
- lpEvent->hWnd = hWnd;
- lpEvent->EventName = event;
- /* Request the server to notify when any of our events occur */
- isc_que_events(status, &(lpEvent->DB),
- &(lpEvent->EventId), lpEvent->length, lpEvent->EventBuf,
- lpEvent->lpAstProc, lpEvent);
- if (CHK_ERR(status))
- return FALSE;
- return TRUE;
- }
- /*****************************************************************
- *
- * ReleaseEvents
- *
- *****************************************************************
- *
- * Functional description:
- * Releases the event buffers allocated by isc_event_block
- * and releases the main event block.
- * Returns:
- * none
- *
- *****************************************************************/
- void ReleaseEvents (EVENTBLK *lpEvent)
- {
- if (lpEvent == NULL)
- return;
- isc_free(lpEvent->EventBuf);
- isc_free(lpEvent->ResultBuf);
- (VOID)GlobalFreePtr(lpEvent);
- }
- /*****************************************************************
- *
- * WndProc
- *
- *****************************************************************
- *
- * Functional description:
- * Main window processing function.
- * Returns:
- * 0 if the message was handled,
- * results from DefWindowProc otherwise
- *
- *****************************************************************/
- LRESULT CALLBACK _export WndProc (HWND hWnd, UINT message, WPARAM wParam,
- LPARAM lParam)
- {
- EVENTBLK *lpEvent;
- ISC_STATUS_ARRAY Vector;
- char msgbuf[200];
- switch (message)
- {
- case WM_COMMAND:
- switch (wParam)
- {
- case IDM_EXIT:
- SendMessage(hWnd, WM_CLOSE, 0, 0L);
- return 0;
- }
- break;
- case WM_DB_EVENT:
- /* The event block is passed in lParam by the ast */
- lpEvent = (EVENTBLK *)lParam;
- /*
- ** isc_event_counts will update Vector with the number
- ** of times each event occurred. It will then copy
- ** ResultBuf into EventBuf to prepare for the next que_events.
- */
- isc_event_counts(Vector, lpEvent->length, lpEvent->EventBuf,
- lpEvent->ResultBuf);
- sprintf(msgbuf, "Event %s triggered with count %ld\n...Resetting"
- " count and calling gds_que_events again",
- lpEvent->EventName, Vector[0]);
- WinPrint(msgbuf);
- /* Re-queue the event, so we can do this all over again */
- isc_que_events(status, &(lpEvent->DB), &(lpEvent->EventId),
- lpEvent->length, lpEvent->EventBuf,
- lpEvent->lpAstProc, lpEvent);
- CHK_ERR(status);
- return 0;
- case WM_DESTROY:
- PostQuitMessage(0);
- return 0;
- }
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
-
- /*****************************************************************
- *
- * AstRoutine
- *
- *****************************************************************
- *
- * Functional description:
- * This is the callback routine which is called by the
- * gds library when an event occurs in the database.
- * The event block which was passed as an argument to
- * gds_que_events is received as the first argument,
- * along with the updated event buffer and its length.
- * Returns:
- * none
- *
- *****************************************************************/
- void AstRoutine (EVENTBLK *lpEvent, short length, char *updated)
- {
- char *ResultBuf = lpEvent->ResultBuf;
- /* Update the result buffer with the new values */
- while (length--)
- *ResultBuf++ = *updated++;
- /* Let the parent window know the event triggered */
- PostMessage(lpEvent->hWnd, WM_DB_EVENT, 0, (LPARAM) lpEvent);
- }
- /*****************************************************************
- *
- * WinPrint
- *
- *****************************************************************
- *
- * Functional description:
- * Print a message in a message box.
- * Returns:
- * none
- *
- *****************************************************************/
- void WinPrint (char *line)
- {
- MessageBox(NULL, line, szAppName, MB_ICONINFORMATION | MB_OK);
- }
- /*****************************************************************
- *
- * CHK_ERR
- *
- *****************************************************************
- *
- * Functional description:
- * If an error was returned in the status vector, print it
- * and the post a quit message to terminate the app.
- * Returns:
- * TRUE if there was error, FALSE otherwise
- *
- *****************************************************************/
- int CHK_ERR (long *status)
- {
- if (status[1])
- {
- isc_print_status(status);
- PostQuitMessage(1);
- return TRUE;
- }
- return FALSE;
- }
|