home *** CD-ROM | disk | FTP | other *** search
- // Borland C++ - (C) Copyright 1991 by Borland International
-
- //*******************************************************************
- //
- // program - DDESrvr.c
- // purpose - DDE server interface routines. This file is part of the
- // MSGWND project.
- //
- //*******************************************************************
-
-
- #include <windows.h>
- #include <dde.h>
- #include <stdio.h>
- #include <string.h>
-
- # include "ddesrvr.h"
-
- # define WW_CLIENT 0
- # define ACK 0x8000
- # define BUSY 0x4000
-
- static int nServerClassRegistered;
- static char szServerClass[] = "ddeserver";
- static WORD wLastDDEServerMsg;
-
- //*******************************************************************
- // DDEServerInit - called in response to WM_DDE_INITIATE
- //
- // paramaters:
- // hParentWnd - The handle of the server window trying to
- // respond to this dde conversation.
- // hClientWnd - The handle of the client window trying to start
- // this dde conversation.
- // lParam - lParam send by client window.
- // Contains atoms of application and topic client
- // wants to talk about.
- // szApp - The name of the application server represents.
- // szTopic - The name of the topic server knows about.
- //
- // returns:
- // The handle of the channel to use to continue the conversation
- // or
- // NULL if conversation could not be opened.
- //
- //*******************************************************************
- HWND DDEServerInit(HWND hParentWnd, HWND hClientWnd, LONG lParam,
- char *szApp, char *szTopic)
- {
- HANDLE hInst;
- HWND hChannel;
- ATOM aApp;
- ATOM aTopic;
- WNDCLASS wclass;
- char szClassName[sizeof(szServerClass) + 10];
-
- // Get atoms representing application and topic we will talk about.
- aApp = GlobalAddAtom(szApp);
- if (!aApp)
- return(0);
-
- aTopic = GlobalAddAtom(szTopic);
- if (!aTopic)
- {
- GlobalDeleteAtom(aApp);
- return(0);
- }
-
- // If request is not for application and topic we will talk about
- // do not open conversaton.
- if ((aApp != LOWORD(lParam)) || (aTopic != HIWORD(lParam)))
- {
- GlobalDeleteAtom(aApp);
- GlobalDeleteAtom(aTopic);
- return(0);
- }
-
- // Get parents instance to use in creating window to carry on
- // dde conversation.
- hInst = GetWindowWord(hParentWnd, GWW_HINSTANCE);
- if (!hInst)
- return(0);
-
- // Create a unique class name for this instance of the server.
- sprintf(szClassName, "%s%04X", szServerClass, hInst);
-
- // If we have not already done it, register the window class to
- // carry on this conversation.
- if (!nServerClassRegistered)
- {
- wclass.style = CS_HREDRAW | CS_VREDRAW;
- wclass.lpfnWndProc = DDEServerWndProc;
- wclass.cbClsExtra = 0;
- wclass.cbWndExtra = 2;
- wclass.hInstance = hInst;
- wclass.hIcon = 0;
- wclass.hCursor = 0;
- wclass.hbrBackground = 0;
- wclass.lpszMenuName = 0;
- wclass.lpszClassName = szClassName;
-
- // Do not fail if register fails, because another app may have
- // already registered this class.
- RegisterClass(&wclass);
-
- // So we won't try to register again.
- nServerClassRegistered = 1;
- }
-
- // Create the window that will remain hidden but will carry on the
- // conversation wih the dde client.
- hChannel = CreateWindow(szClassName, // window class name
- NULL, // window title
- WS_CHILD, // window style
- CW_USEDEFAULT, // window origin
- 0,
- CW_USEDEFAULT, // window size
- 0,
- hParentWnd, // window parent
- NULL, // window id
- hInst, // window instance
- NULL); // no parms
-
- // If create of window failed we cannot continue.
- if (!hChannel)
- return(0);
-
- // Remember the handle of our client.
- SetWindowWord(hChannel, WW_CLIENT, hClientWnd);
-
- // Send acknowledgement to client.
- wLastDDEServerMsg = WM_DDE_ACK;
- SendMessage(hClientWnd, wLastDDEServerMsg, hChannel, MAKELONG(aApp, aTopic));
-
- // Return handle of window that will carry on the conversation for
- // this server.
- return(hChannel);
- }
-
- //*******************************************************************
- // DDEServerClose - close the dde conversation with a client
- //
- // paramaters:
- // hChannel - The handle of the window conducting
- // the dde conversation.
- //
- //*******************************************************************
- int DDEServerClose(HWND hChannel)
- {
- HWND hClientWnd;
-
- // If the channel is still active.
- if (IsWindow(hChannel))
- {
- wLastDDEServerMsg = WM_DDE_TERMINATE;
-
- // Get handle of client we were conversing with.
- hClientWnd = GetWindowWord(hChannel, WW_CLIENT);
-
- // If he is still active.
- if (IsWindow(hClientWnd))
- SendMessage(hClientWnd, wLastDDEServerMsg, hChannel, 0L);
- }
-
- return(1);
- }
-
- //*******************************************************************
- // DDEServerWndProc - window proc to manage interface with client
- //
- // paramaters:
- // hWnd - The window handle for this message
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- // returns:
- // depends on message.
- //
- //*******************************************************************
- LONG FAR PASCAL DDEServerWndProc(HWND hWnd, WORD message,
- WORD wParam, LONG lParam)
- {
- WORD wStatus;
- HWND hClientWnd;
- HANDLE hCommand;
- HANDLE hData;
- LPSTR lpData;
- HANDLE hShData;
- DDEDATA FAR *lpShData;
- char szItem[30];
- ATOM aItem;
- LPSTR lpCommand;
- int nRc;
- int nSize;
-
- switch (message)
- {
- case WM_DDE_EXECUTE: // execute a command for client
- // Get handle of client.
- hClientWnd = wParam;
-
- // Init status.
- wStatus = 0;
-
- // Get handle of command client is sending us.
- hCommand = HIWORD(lParam);
-
- // Lock it down to get address.
- lpCommand = GlobalLock(hCommand);
- if (lpCommand)
- {
- // Call our function to execute the command.
- if (DDEExecuteCommand(lpCommand))
- wStatus = ACK;
-
- GlobalUnlock(hCommand);
- }
-
- // Send acknowledgement back to client.
- PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
- MAKELONG(wStatus, hCommand));
- break;
-
- case WM_DDE_REQUEST: // data request from a client
- // Get handle of client.
- hClientWnd = wParam;
-
- // Get atom representing data request item.
- aItem = HIWORD(lParam);
- if (!GlobalGetAtomName(aItem, szItem, sizeof(szItem)))
- {
- // Error if atom not found.
- PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
- MAKELONG(0, aItem));
- return(0L);
- }
-
- // Init return code.
- nRc = 0;
-
- // Don't care about case.
- strupr(szItem);
-
- // Call our function to get the data item.
- nSize = DDEData(szItem, &hData);
-
- // If any data found.
- if (nSize)
- {
- // Get shared memory to send item back in.
- hShData = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_DDESHARE,
- (DWORD) (nSize + sizeof(DDEDATA) + 1));
- if (hShData)
- {
- // Lock it down to get address.
- lpShData = (DDEDATA FAR *) GlobalLock(hShData);
- if (lpShData)
- {
- // Setup data header.
- lpShData->fResponse = 1;
- lpShData->fRelease = 1;
- lpShData->fAckReq = 0;
- lpShData->cfFormat = CF_TEXT;
-
- // Lock out local copy of data to get address.
- lpData = GlobalLock(hData);
- if (lpData)
- {
- // Copy data to shared memory.
- _fstrcpy(lpShData->Value, lpData);
- GlobalUnlock(hData);
-
- nRc = 1;
- }
-
- GlobalUnlock(hShData);
- }
- }
-
- GlobalFree(hData);
- }
-
- if (nRc)
- {
- // If ok send data back.
- PostMessage(hClientWnd, WM_DDE_DATA, hWnd,
- MAKELONG(hShData, aItem));
- }
- else
- {
- // If errors just send negative acknowlegement back.
- PostMessage(hClientWnd, WM_DDE_ACK, hWnd,
- MAKELONG(0, aItem));
- }
- break;
-
- case WM_DDE_TERMINATE: // server says terminate conversation
- // Get handle of client we are dealing with.
- hClientWnd = GetWindowWord(hWnd, WW_CLIENT);
-
- // Ignore if not from our client.
- if (wParam != hClientWnd)
- return(0L);
-
- // Forget who client is.
- SetWindowWord(hWnd, WW_CLIENT, 0);
-
- // Tell our parent conversation closed.
- SendMessage(GetParent(hWnd), WMU_DDE_CLOSED, hWnd, 0L);
-
- // Send terminate to server to acknowledge we recieved
- // terminate, if we did not initiate the termination ourselves.
- if ((wLastDDEServerMsg != WM_DDE_TERMINATE) && IsWindow(hClientWnd))
- PostMessage(hClientWnd, WM_DDE_TERMINATE, hWnd, 0L);
-
- // Terminate this child window.
- DestroyWindow(hWnd);
- break;
-
- case WM_DESTROY: // destroy this window
- // Terminate any ongoing conversation on our way out.
- DDEServerClose(hWnd);
- break;
-
- default:
- return(DefWindowProc(hWnd, message, wParam, lParam));
- }
-
- return(0L);
- }
-
- //*******************************************************************