home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1998 May
/
Pcwk5b98.iso
/
Borland
/
Cplus45
/
BC45
/
TSTAPP.PAK
/
DDESRVR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-08-29
|
12KB
|
360 lines
// Borland C++ - (C) Copyright 1991, 1992 by Borland International
//*******************************************************************
//
// program - DDESrvr.c
// purpose - DDE server interface routines. This file is part of the
// MSGWND project.
//
//*******************************************************************
#define STRICT
#include <windows.h>
#pragma hdrstop
#include <dde.h>
#include <stdio.h>
#include <string.h>
#include <windowsx.h>
#include "ddepack.h"
#include "ddesrvr.h"
# define WW_CLIENT 0
# define ACK 0x8000
# define BUSY 0x4000
#if defined(__WIN32__)
#define SetWindowClient(hWnd,hWndClient)\
SetWindowLong (hWnd, WW_CLIENT, (LONG) (hWndClient))
#define GetWindowClient(hWnd)\
((HWND) GetWindowLong (hWnd, WW_CLIENT))
#define DDEGetCommandHandle(hCommand)\
((LPARAM)(hCommand))
#else
#define SetWindowClient(hWnd,hWndClient)\
SetWindowWord (hWnd, WW_CLIENT, (WORD) (hWndClient))
#define GetWindowClient(hWnd)\
((HWND) GetWindowWord (hWnd, WW_CLIENT))
#define DDEGetCommandHandle(hCommand)\
((LPARAM)HIWORD(hCommand))
#endif
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, LPARAM lParam,
char *szApp, char *szTopic)
{
HINSTANCE 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 = (HANDLE)GetWindowInstance(hParentWnd);
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.
SetWindowClient(hChannel, hClientWnd);
// Send acknowledgement to client.
wLastDDEServerMsg = WM_DDE_ACK;
SendMessage(hClientWnd,
(UINT)wLastDDEServerMsg,
(WPARAM)hChannel,
(LPARAM)DDEPack(WM_DDE_ACK, 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 = (HWND)GetWindowClient(hChannel);
// If he is still active.
if (IsWindow(hClientWnd))
SendMessage(hClientWnd, (UINT)wLastDDEServerMsg, (WPARAM)hChannel, (LPARAM)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 WPARAM parameter for this message
// lParam - The LPARAM parameter for this message
//
// returns:
// depends on message.
//
//*******************************************************************
LRESULT CALLBACK _export DDEServerWndProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM 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 = (HWND)wParam;
// Init status.
wStatus = 0;
// Get handle of command client is sending us.
hCommand = (HANDLE)DDEGetCommandHandle(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, (WPARAM)hWnd,
DDEPack (WM_DDE_ACK, (UINT)wStatus, (UINT)hCommand));
break;
case WM_DDE_REQUEST: // data request from a client
// Get handle of client.
hClientWnd = (HWND)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, (WPARAM)hWnd,
(LPARAM)DDEPack(WM_DDE_ACK, 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.
#if defined(__WIN32__)
strcpy((LPSTR)lpShData->Value, lpData);
#else
_fstrcpy((LPSTR)lpShData->Value, lpData);
#endif
GlobalUnlock(hData);
nRc = 1;
}
GlobalUnlock(hShData);
}
}
GlobalFree(hData);
}
if (nRc)
{
// If ok send data back.
PostMessage(hClientWnd, WM_DDE_DATA, (WPARAM)hWnd,
(LPARAM)DDEPack (WM_DDE_DATA, (UINT)hShData, (UINT)aItem));
}
else
{
// If errors just send negative acknowlegement back.
PostMessage(hClientWnd, WM_DDE_ACK, (WPARAM)hWnd,
(LPARAM)DDEPack (WM_DDE_ACK, 0, aItem));
}
break;
case WM_DDE_TERMINATE: // server says terminate conversation
// Get handle of client we are dealing with.
hClientWnd = (HWND)GetWindowClient(hWnd);
// Ignore if not from our client.
if (wParam != (WPARAM)hClientWnd)
return(0L);
// Forget who client is.
SetWindowClient(hWnd, 0);
// Tell our parent conversation closed.
SendMessage(GetParent(hWnd), WMU_DDE_CLOSED, (WPARAM)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, (WPARAM)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);
}
//*******************************************************************