home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
epm603b.zip
/
EPMDDE.ZIP
/
DDESAMP.C
< prev
next >
Wrap
Text File
|
1992-12-09
|
20KB
|
421 lines
/*────────────────────────────────────────────────────────────────────┐
│ │
│ Sample DDE Client Application which connects with EPM v6.00 │
│ (32-bit version) │
│ │
│ John Ponzo 11/92 │
└────────────────────────────────────────────────────────────────────*/
#include "ddesamp.h"
HAB hab;
main(void)
{
HMQ hmq; /* Message queue handle */
HWND hwndClient; /* Client area window handle */
HWND hwndFrame; /* Frame window handle */
QMSG qmsg; /* Message from message queue */
ULONG flCreate; /* Window creation control flags*/
hab = WinInitialize(0); /* Initialize PM */
hmq = WinCreateMsgQueue( hab, 0 ); /* Create a message queue */
WinRegisterClass( /* Register window class */
hab, /* Anchor block handle */
"DDESAMP", /* Window class name */
DdeSampleWndProc, /* Address of window procedure */
CS_SIZEREDRAW, /* Class style */
0); /* No extra window words */
flCreate = FCF_SYSMENU | FCF_MENU | FCF_TITLEBAR | FCF_SIZEBORDER |
FCF_MINMAX | FCF_ICON | FCF_TASKLIST;
hwndFrame = WinCreateStdWindow(
HWND_DESKTOP, /* Desktop window is parent */
0L, /* No frame styles */
&flCreate, /* Frame control flag */
"DDESAMP", /* Client window class name */
"", /* No window text */
0L, /* No special class style */
0, /* Resource is in .EXE file */
ID_WINDOW, /* Frame window identifier */
&hwndClient /* Client window handle */
);
WinSetWindowPos( hwndFrame, /* Shows and activates frame */
HWND_TOP, /* window at position 100, 100, */
100, 100, 200, 200, /* and size 200, 200. */
SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW
);
while( WinGetMsg( hab, &qmsg, 0, 0, 0 ) )
WinDispatchMsg( hab, &qmsg );
WinDestroyWindow( hwndFrame ); /* Tidy up... */
WinDestroyMsgQueue( hmq ); /* and */
WinTerminate( hab ); /* terminate the application */
}
MRESULT EXPENTRY DdeSampleWndProc( HWND hwnd, MSG msg, MPARAM mp1, MPARAM mp2 )
{
HPS hps; /* Presentation Space handle */
RECTL rc; /* Rectangle coordinates */
POINTL pt; /* String screen coordinates */
PDDECLIENTINFO pDDEClientInfo; /* Client Info Structure */
//Get pointer to DDEClientInfo Struct stored in window ULong
pDDEClientInfo = (PDDECLIENTINFO) WinQueryWindowULong(
WinQueryWindow(hwnd, QW_PARENT),
QWL_USER);
switch( msg )
{
/*──────────────────────────────────────────────────────────────────┐
│Allocate memory for DDEClientInfo Structure. If memory allocation │
│fails terminate application. If successful set bConnected field to │
│FALSE, and set the window ulong to pDDEClientInfo. │
└──────────────────────────────────────────────────────────────────*/
case WM_CREATE:
{
LONG rc;
rc = DosAllocMem((PPVOID)&pDDEClientInfo,
sizeof(DDECLIENTINFO),
PAG_READ | PAG_WRITE | PAG_COMMIT);
if(rc){
WinPostMsg(hwnd, WM_QUIT, 0, 0);
return ((MRESULT)1);
} else {
pDDEClientInfo->bConnected = FALSE;
WinSetWindowULong(WinQueryWindow(hwnd,QW_PARENT), QWL_USER, (ULONG)pDDEClientInfo);
}
}
break;
/*─────────────────────────────────────────────────────────────────────┐
│This message is sent if a DDE Server has responded to our request to │
│initiate a DDE conversation. Check the pszAppName and pszTopic fields │
│of pDdeInit to make sure that the Server that responded has the │
│correct name and topic. │
└─────────────────────────────────────────────────────────────────────*/
case WM_DDE_INITIATEACK:
{
PDDEINIT pDdeInit = (PDDEINIT)mp2;
if(((HWND)mp1 != hwnd) &&
(!pDDEClientInfo->bConnected) &&
!strcmp(pDdeInit->pszAppName, EPMDDEAPPNAME) &&
!strcmp(pDdeInit->pszTopic, EPM_DDE_TOPIC) )
{
pDDEClientInfo->hwndDDEServer = (HWND)mp1;
pDDEClientInfo->bConnected = TRUE;
DosFreeMem(mp2);
DosBeep(200, 200);
return((MPARAM)1);
}
}
break;
/*────────────────────────────────────────────────────────────────────┐
│WM_DDE_ACK is sent whenever the DDE Server responds to a previously │
│sent WM_DDE_* message. Check mp2(hwnd of the Responding server), to │
│see if it matches the hwnd of the DDE Server we are currently │
│connected to. If it is the correct server store the status, and │
│Free the giveable mem that was allocated. │
└────────────────────────────────────────────────────────────────────*/
case WM_DDE_ACK:
{
PDDESTRUCT pDdeStruct = (PDDESTRUCT)mp2;
if(pDDEClientInfo->hwndDDEServer != (HWND)mp1) {
return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}
pDDEClientInfo->usAck = pDdeStruct->fsStatus;
DosFreeMem(pDdeStruct);
return((MRESULT)1);
}
break;
/*───────────────────────┐
│ Process the menu items │
└───────────────────────*/
case WM_COMMAND:
{
switch(SHORT1FROMMP(mp1)) {
/*───────────────────────────────────────────────────┐
│Broadcast a message to all top level windows in the │
│system, requesting a DDE server named EPMDDEAPPNAME,│
│who will handle the topic named EPM_DDE_TOPIC. │
│Return if we are already connected to a DDE Server. │
└───────────────────────────────────────────────────*/
case ID_INIT_DDE:
{
CONVCONTEXT ConvContext;
memset(&ConvContext, 0, sizeof(CONVCONTEXT));
ConvContext.cb = sizeof(CONVCONTEXT);
if(!pDDEClientInfo->bConnected) {
WinDdeInitiate(hwnd, EPMDDEAPPNAME, EPM_DDE_TOPIC, &ConvContext);
}
return((MRESULT)1);
}
break;
/*────────────────────────────────────────────────────────┐
│Send a Command to the connected DDE Server. Put the │
│EPM edit command string in EditCommand, and │
│call MakeDDEMsg() to set up the pDdeStruct we need to │
│send. Post the message WM_DDE_EXECUTE to the server with │
│pDdeStruct. │
└────────────────────────────────────────────────────────*/
case ID_SEND_COMMAND:
{
COMMANDDLGSTRUCT CommandDlgStruct;
UCHAR EditCommand[200];
PDDESTRUCT pDdeStruct;
//Don't send any commands unless we are connected to the EPM Server
if(!pDDEClientInfo->bConnected) {
return((MPARAM)1);
}
CommandDlgStruct.Size = sizeof(COMMANDDLGSTRUCT);
WinDlgBox(HWND_DESKTOP, WinQueryWindow(hwnd, QW_PARENT), CommandDlgBox, (HMODULE)NULL, IDD_COMMAND, &CommandDlgStruct);
strcpy(EditCommand, CommandDlgStruct.Buffer);
pDdeStruct = MakeDDEMsg(DDEFMT_TEXT, DDE_ITEM_EDIT_COMMAND,
&EditCommand, sizeof(EditCommand));
WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_EXECUTE, pDdeStruct, TRUE);
}
break;
/*───────────────────────────────────────────────────────┐
│Terminate the current DDE conversation if one currently │
│exists. │
└───────────────────────────────────────────────────────*/
case ID_TERMINATE_DDE:
{
if(pDDEClientInfo->bConnected) {
WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
pDDEClientInfo->bConnected = 0;
}
return((MRESULT)1);
}
break;
/*───────────────────────┐
│ Close the application. │
└───────────────────────*/
case ID_EXITPROG:
WinPostMsg(hwnd, WM_CLOSE, (MPARAM)0, (MPARAM)0);
break;
}
}
break;
/*────────────────────────────────────────────────────────────────────┐
│WM_DDE_TERMINATE is sent to us in reponse to a WM_DDE_TERMINATE that │
│we sent to the server, or as a server request to terminate the │
│DDE connection. If pDDEClientInfo->bConnected is TRUE the server is │
│requesting to terminate the conversation. In this case respond to │
│the terminate request by sending WM_DDE_TERMINATE and setting │
│pDDEClientInfo->bConnect to FALSE. If we are not connected then │
│this a response from our request to terminate the connection. │
│In this case do nothing. │
└────────────────────────────────────────────────────────────────────*/
case WM_DDE_TERMINATE:
{
if(pDDEClientInfo->bConnected) {
WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, FALSE);
pDDEClientInfo->bConnected = FALSE;
}
}
break;
/*────────────────────────────────────────────────────────────┐
│Data is sent back from the EPM window. Display the item name │
│and the data in a message box. │
└────────────────────────────────────────────────────────────*/
case WM_DDE_DATA:
{
if( pDDEClientInfo->bConnected &&
((HWND)mp1==pDDEClientInfo->hwndDDEServer)) {
PDDESTRUCT pDdeStruct = (PDDESTRUCT)mp2;
PSZ ItemName;
PSZ Data;
UCHAR MessageString[300];
if(pDdeStruct->usFormat == DDEFMT_TEXT) {
ItemName = ((PSZ)pDdeStruct+pDdeStruct->offszItemName);
Data = ((PSZ)pDdeStruct+pDdeStruct->offabData);
}
sprintf(MessageString,"The Item String is '%s', The Data String is '%s'",
ItemName, Data);
WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, MessageString, "WM_DDE_DATA Message Received",
100, MB_OK);
if(pDdeStruct->fsStatus == DDE_FACKREQ) {
WinDdePostMsg(pDDEClientInfo->hwndDDEServer,
hwnd,
WM_DDE_ACK,pDdeStruct,TRUE);
}
}
}
/*───────────────────────────────────────────────────────┐
│Return TRUE to request PM to paint the window background│
│in SYSCLR_WINDOW. │
└───────────────────────────────────────────────────────*/
case WM_ERASEBACKGROUND:
return (MRESULT)( TRUE );
case WM_PAINT:
hps = WinBeginPaint( hwnd, 0, &rc ); // Create a presentation space
pt.x = 50; pt.y = 50; // Set the text coordinates,
GpiSetColor( hps, CLR_NEUTRAL ); // colour of the text,
GpiSetBackColor( hps, CLR_BACKGROUND ); // its background and
GpiSetBackMix( hps, BM_OVERPAINT ); // how it mixes,
// and draw the string...
WinEndPaint( hps ); // Drawing is complete
break;
/*────────────────────────────────────────────────────────────┐
│If the application is closing make sure that we terminate an │
│existing DDE connection. │
└────────────────────────────────────────────────────────────*/
case WM_CLOSE:
if(pDDEClientInfo->bConnected) {
WinDdePostMsg(pDDEClientInfo->hwndDDEServer, hwnd, WM_DDE_TERMINATE, NULL, TRUE);
pDDEClientInfo->bConnected = 0;
}
WinPostMsg( hwnd, WM_QUIT, 0L, 0L ); //Cause termination
break;
default:
return WinDefWindowProc( hwnd, msg, mp1, mp2 );
}
return FALSE;
}
/*─────────────────────────────────────────────────────────────────────────────────────┐
│ MAKEDDEReqSeg() │
│ │
│ This procedure is used to allocate and fill in a PDDESTRUCT variable │
│ with information that we want to send in our next message that │
│ we send to the DDE server we are connected to. │
│ │
│ Parameters: │
│ usFormat: Format of the Data being sent. │
│ When communicating with EPM this field is always │
│ DDEFMT_TEXT. │
│ pszItemName: Name of the data item being sent. We issuing an │
│ Edit Command to EPM. This will always be DDE_ITEM_EDIT. │
│ │
│ Data: This is a pointer to the Data that you want to send │
│ in you DDE message. When sending a DDE_ITEM_EDIT item │
│ this will always be an edit command string. │
│ │
│ usDataSize: The size of the Data item being sent. │
│ │
└─────────────────────────────────────────────────────────────────────────────────────*/
PDDESTRUCT MakeDDEMsg(USHORT usFormat,PSZ pszItemName,PVOID Data, USHORT usDataSize)
{
PDDESTRUCT pdde = (PDDESTRUCT)0;
ULONG rc = 0;
ULONG usSegSize;
ULONG totalsize;
/**************************************************************************/
/* 1) Allocate givable shared memory */
/**************************************************************************/
usSegSize = (USHORT)strlen(pszItemName)+1;
totalsize = sizeof(DDESTRUCT)+usDataSize+usSegSize;
rc = DosAllocSharedMem((PPVOID)&pdde,
(PSZ)0,
totalsize,
PAG_READ | PAG_WRITE | PAG_COMMIT | OBJ_TILE
| OBJ_GIVEABLE | OBJ_GETTABLE);
if (rc) {
return ((PDDESTRUCT)0);
}
/**************************************************************************/
/* 2) Fill in the new DDE structure */
/**************************************************************************/
memset((PVOID)pdde, 0, (size_t)usSegSize); // zero out memory
pdde->usFormat = usFormat;
pdde->offszItemName = (USHORT)sizeof(DDESTRUCT);
memcpy(DDES_PSZITEMNAME(pdde), pszItemName,usSegSize);
pdde->offabData = (USHORT)sizeof(DDESTRUCT)+usSegSize;
memcpy(DDES_PABDATA(pdde), Data,usDataSize);
pdde->fsStatus = 0; // set status flags
pdde->cbData = (ULONG)totalsize;
return pdde;
}
/*───────────────────────────────────────────────────────────────────────────┐
│ CommandDlgBox │
│ │
│ Simple Command Dialog Box used to retrieve Edit commands that the │
│ user want to send to the connected EPM DDE server. │
└───────────────────────────────────────────────────────────────────────────*/
MRESULT EXPENTRY CommandDlgBox(HWND hwndDlg, MSG msg, MPARAM mp1, MPARAM mp2)
{
PCOMMANDDLGSTRUCT CommandDlgStruct;
switch(msg) {
case WM_INITDLG:
WinSetWindowULong(hwndDlg, QWL_USER, (ULONG)mp2);
return((MPARAM)0);
case WM_COMMAND:
{
switch(LOUSHORT(mp1)) {
case IDD_OK:
CommandDlgStruct = (PCOMMANDDLGSTRUCT)WinQueryWindowULong(hwndDlg, QWL_USER);
WinQueryDlgItemText(hwndDlg, IDD_ENTRYFIELD, MAXLEN, CommandDlgStruct->Buffer);
WinDismissDlg(hwndDlg, (USHORT)0);
break;
case IDD_CANCEL:
CommandDlgStruct = (PCOMMANDDLGSTRUCT)WinQueryWindowULong(hwndDlg, QWL_USER);
CommandDlgStruct->Buffer[0] = 0;
WinDismissDlg(hwndDlg, 0);
break;
}
}
break;
default:
return((MRESULT)WinDefDlgProc(hwndDlg, msg, mp1, mp2));
}
return((MPARAM)0);
}