void Dde_Item::Advise ( HWND Server, HWND Client, BOOL Hot ) { if ( Hot ) { // Search for a matching entry in the hot link list. Return if found. for ( int i=0; i<sizeof(HotLinks)/sizeof(HotLinks[0]); i++ ) { if ( ( HotLinks[i][0] == Server ) AND ( HotLinks[i][1] == Client ) ) { Log ( "WARNING: Link already established." ) ; PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_FACK, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; return ; } /* endif */ } /* endfor */ // Search for an empty entry in the hot link list. Use if not found. for ( i=0; i<sizeof(HotLinks)/sizeof(HotLinks[0]); i++ ) { if ( ( HotLinks[i][0] == 0 ) AND ( HotLinks[i][1] == 0 ) ) { HotLinks[i][0] = Server ; HotLinks[i][1] = Client ; PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_FACK, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; return ; } /* endif */ } /* endfor */ Log ( " WARNING: Hot link table full." ) ; } else { // Search for a matching entry in the warm link list. Return if found. for ( int i=0; i<sizeof(WarmLinks)/sizeof(WarmLinks[0]); i++ ) { if ( ( WarmLinks[i][0] == Server ) AND ( WarmLinks[i][1] == Client ) ) { Log ( "WARNING: Link already established." ) ; PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_FACK, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; return ; } /* endif */ } /* endfor */ // Search for an empty entry in the warm link list. Use if not found. for ( i=0; i<sizeof(WarmLinks)/sizeof(WarmLinks[0]); i++ ) { if ( ( WarmLinks[i][0] == 0 ) AND ( WarmLinks[i][1] == 0 ) ) { WarmLinks[i][0] = Server ; WarmLinks[i][1] = Client ; PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_FACK, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; return ; } /* endif */ } /* endfor */ Log ( " WARNING: Warm link table full." ) ; } /* endif */ // Reply with an error. PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_NOTPROCESSED, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; }
MRESULT EXPENTRY clientWindowProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 ) { /**********************************************************************************/ WClient *client = (WClient *)WinQueryWindowPtr( hwnd, 0 ); switch( msg ) { case WM_DDE_INITIATEACK: { // response from server after WinDdeInitiate() DDEINIT *ddei = (PDDEINIT)mp2; client->_serverWindow = (HWND)mp1; DosFreeMem( ddei ); client->_connected = true; return( (MRESULT)TRUE ); } case WM_DDE_DATA: // reply from server case WM_DDE_ACK: { // negative reply from server DDESTRUCT *ddes = (PDDESTRUCT)mp2; client->reply( (HWND)mp1, ddes ); DosFreeMem( ddes ); break; } case WM_DDE_TERMINATE: { WinDdePostMsg( (HWND)mp1, client->_clientWindow, WM_DDE_TERMINATE, NULL, 0 ); break; } default: return( client->_prevClientProc( hwnd, msg, mp1, mp2 ) ); } return( 0 ); }
void WEXPORT WClient::disconnect() { /**********************************/ if( _connected ) { WinDdePostMsg( _serverWindow, _clientWindow, WM_DDE_TERMINATE, NULL, 0 ); _connected = false; } }
static char SendData( message *msg, char send_init ) /**************************************************/ { initiate_data *idata; goto_data *gdata; DDESTRUCT *dde; gdata = MemAlloc( sizeof( goto_data ) + strlen( msg->error ) ); if( gdata == NULL ) { return( FALSE ); } if( send_init ) { idata = MemAlloc( sizeof( initiate_data ) + strlen( CurrSession->help_library ) ); if( idata == NULL ) { MemFree( gdata ); return( FALSE ); } idata->errorcount = 1; idata->errors[0].errorline = msg->row; idata->errors[0].offset = msg->col; idata->errors[0].length = msg->len; idata->errors[0].magic = 0; idata->liblength = strlen( CurrSession->help_library ); strcpy( idata->libname, CurrSession->help_library ); dde = MakeDDEObject( CurrSession->hwnd, "Initialize", 0, DDEFMT_TEXT, idata, sizeof( initiate_data ) + idata->liblength ); WinDdePostMsg( CurrSession->hwnd, hwndDDE, WM_DDE_EXECUTE, dde, DDEPM_RETRY ); } gdata->errorline = msg->row; gdata->offset = msg->col; gdata->resourceid = msg->resourceid; gdata->magic = 0; gdata->textlength = strlen( msg->error ); strcpy( gdata->errortext, msg->error ); dde = MakeDDEObject( CurrSession->hwnd, "Goto", 0, DDEFMT_TEXT, gdata, sizeof( goto_data ) + gdata->textlength ); WinDdePostMsg( CurrSession->hwnd, hwndDDE, WM_DDE_EXECUTE, dde, DDEPM_RETRY ); if( send_init ) { MemFree( idata ); } MemFree( gdata ); return( TRUE ); }
void Dde_Item::BroadcastUpdate ( ) { // Send data complete to all hot links. for ( int i=0; i<sizeof(HotLinks)/sizeof(HotLinks[0]); i++ ) { if ( HotLinks[i][0] ) { PDDESTRUCT Message = MakeDDEObject ( HotLinks[i][1], PSZ(Name), 0, Format, Data, Size ) ; WinDdePostMsg ( HotLinks[i][1], HotLinks[i][0], WM_DDE_DATA, Message, DDEPM_RETRY ) ; } /* endif */ } /* endfor */ // Send advisory to all warm links. for ( i=0; i<sizeof(WarmLinks)/sizeof(WarmLinks[0]); i++ ) { if ( WarmLinks[i][0] ) { PDDESTRUCT Message = MakeDDEObject ( WarmLinks[i][1], PSZ(Name), DDE_FNODATA, Format, 0, 0 ) ; WinDdePostMsg ( WarmLinks[i][1], WarmLinks[i][0], WM_DDE_DATA, Message, DDEPM_RETRY ) ; } /* endif */ } /* endfor */ }
void Dde_Item::Unadvise ( HWND Server, HWND Client ) { // Cancel any links on this item for this Server/Client pair. Terminate ( Server, Client ) ; // Reply with an ACK. PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_FACK, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; }
WString * WEXPORT WClient::sendMsg( const char *msg, WClientFlags ) { /*******************************************************************/ DDESTRUCT *dde; if( !_connected ) return( NULL ); dde = WDDEObject::makeDDEObject( _serverWindow, msg, 0, DDEFMT_TEXT, NULL, 0 ); WinDdePostMsg( _serverWindow, _clientWindow, WM_DDE_REQUEST, dde, DDEPM_RETRY ); return( NULL ); }
MRESULT EXPENTRY clientProc( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 ) /**************************************************************************/ { switch( msg ) { case WM_DDE_INITIATE: { // editor has started DDEINIT *ddei = (PDDEINIT)mp2; if( (strcmp( "WB Editor", (char *)ddei->pszAppName ) == 0) && (stricmp( CurrSession->file_name, (char *)ddei->pszTopic ) == 0) ) { // make sure that we are expecting a session to be started - more // than one application may be using the DLL (i.e. the IDE and // browser) if( StartingSessionInProgress ) { CurrSession->hwnd = (HWND)mp1; StartingSessionInProgress = FALSE; Connect(); } } DosFreeMem( ddei ); return( (MRESULT)TRUE ); } case WM_DDE_INITIATEACK: { // response from EPM after WinDdeInitiate() DDEINIT *ddei = (PDDEINIT)mp2; session *sess = FindSessionByHWND( (HWND)mp1 ); if (sess != NULL) { sess->connected = TRUE; if( sess->msg != NULL ) { SendData( sess->msg, TRUE ); } } DosFreeMem( ddei ); return( (MRESULT)TRUE ); } case WM_DDE_ACK: { // acknowledgement from EPM DDESTRUCT *ddes = (PDDESTRUCT)mp2; DosFreeMem( ddes ); break; } case WM_DDE_DATA: { // request to send "Goto" message to EPM session *sess = FindSessionByHWND( (HWND)mp1 ); if (sess != NULL) SendData( sess->msg, FALSE ); break; } case WM_DDE_TERMINATE: { WinDdePostMsg( (HWND)mp1, hwndDDE, WM_DDE_TERMINATE, NULL, 0 ); DeleteSession( (HWND)mp1 ); break; } default: return( prevClientProc( hwnd, msg, mp1, mp2 ) ); } return( 0 ); }
int EDITAPI EDITDisconnect( void ) /*****************************************/ { session *sess; for( sess = SessionList; sess != NULL; sess = sess->link ) { WinDdePostMsg( sess->hwnd, hwndDDE, WM_DDE_TERMINATE, NULL, 0 ); } if( hwndDDE != NULLHANDLE ) { WinDestroyWindow( hwndDDE ); hwndDDE = NULLHANDLE; } return( TRUE ); }
void Dde_Topic::Execute ( HWND Server, HWND Client, char *ItemName, int Format, PVOID Data, int Size ) { // Search for the item and ask it to reply. Dde_Item *Item = First ; while ( Item ) { if ( !strcmpi ( ItemName, Item->QueryName() ) ) { Item->Execute ( Server, Client, Format, Data, Size ) ; return ; } /* endif */ Item = Item->QueryNext() ; } /* endwhile */ // Reply with an error if the topic was not found. PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_NOTPROCESSED, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; }
void Dde_Topic::Terminate ( HWND Server, HWND Client, BOOL DestroyServer ) { // Echo the termination command to the client. WinDdePostMsg ( Client, Server, WM_DDE_TERMINATE, 0, TRUE ) ; // Remove the server from the list. for ( int i=0; i<sizeof(Servers)/sizeof(Servers[0]); i++ ) if ( Servers[i] == Server ) Servers[i] = 0 ; // Cancel any links. Dde_Item *Item = First ; while ( Item ) { Item->Terminate ( Server, Client ) ; Item = Item->QueryNext() ; } /* endwhile */ // If server window not already being destroyed, destroy it now. if ( DestroyServer ) WinDestroyWindow ( Server ) ; }
MRESULT EXPENTRY fnwpMain(HWND hwndFrame, ULONG msg, MPARAM mp1, MPARAM mp2) { PSZ szData; PDDESTRUCT pddeStruct; ULONG mem; CHAR szBuffer[200]; switch (msg) { // all answers to the WinDDEInitate call arrive here case WM_DDE_INITIATEACK: { PDDEINIT pddeInit; PSZ szInApp, szInTopic; static BOOL bNetscapeAnswered = FALSE; pddeInit = (PDDEINIT)mp2; szInApp = pddeInit->pszAppName; szInTopic = pddeInit->pszTopic; G_hServerWnd = (HWND)mp1; ShowMessage("WM_DDE_INITIATEACK (resp to WinDDEInitiate)"); ShowMessage(" application: \"%s\"", pddeInit->pszAppName); ShowMessage(" topic: \"%s\"", pddeInit->pszTopic); // RDP 2000-07-07 07:24:18 // There was no check on which application responded. // This made NETSCDDE fail when another DDE-aware application, // like EPM, was running. // Now the handle from mp1 is only assigned if the application // responding is Netscape. // If the app is not Netscape then the handle is nullified. // I don't know if assigning 0 to the handle is correct but // is seems to solve the problem. // V0.9.19 (2002-03-28) [umoeller] // Opera fix: use stricmp instead of strcmp if (!stricmp(pddeInit->pszAppName, G_szDDENetscape)) // V0.9.16 (2001-10-02) [umoeller] { // ShowMessage("!! Netscape answered."); G_hServerWnd = (HWND)mp1; bNetscapeAnswered = TRUE; } else { // ShowMessage("!! Other application aswered."); G_hServerWnd = (HWND)0; } } break; // all answers to DDE requests arrive here case WM_DDE_DATA: { ShowMessage("!! Received data from Netscape: "); pddeStruct = (PDDESTRUCT) mp2; DosGetSharedMem(pddeStruct, PAG_READ | PAG_WRITE); szData = (BYTE *) (pddeStruct + (pddeStruct->offabData)); ShowMessage(szData); } break; // menu item processing (in debug mode, otherwise these // WM_COMMAND msgs have been posted automatically) case WM_COMMAND: switch (SHORT1FROMMP(mp1)) { // start DDE conversation: this was posted // by "main" before the PM loop was entered // (even if we're in debug mode) case IDM_INITIATE: // WinPostMsg(G_hwndListbox, LM_DELETEALL, 0, 0); ShowMessage("IDM_INITIATE:"); ShowMessage("Topic: \"%s\"", G_szOpenURLTopic); G_context.cb = sizeof(CONVCONTEXT); G_context.fsContext = 0; WinDdeInitiate(hwndFrame, G_szDDENetscape, G_szOpenURLTopic, &G_context); if (!G_optDebug) // if we're not in debug mode, post subsequent // menu commands automatically WinPostMsg(hwndFrame, WM_COMMAND, MPFROM2SHORT(IDM_CHAIN2, 0), 0); break; // "Open URL": request data from server case IDM_OPENURL: { ShowMessage("IDM_OPENURL"); ShowMessage(" URL: \"%s\"", G_szURL); strlcpy(szBuffer, G_szURL, sizeof(szBuffer)); strlcat(szBuffer, ",,0xFFFFFFFF,0x0", sizeof(szBuffer)); DDERequest(hwndFrame, szBuffer); } break; // "Open URL in new window": request data from server, // but with different parameters case IDM_OPENURLNEW: { ShowMessage("IDM_OPENURLNEW"); ShowMessage(" URL: \"%s\"", G_szURL); strlcpy(szBuffer, G_szURL, sizeof(szBuffer)); strlcat(szBuffer, ",,0x0,0x0", sizeof(szBuffer)); DDERequest(hwndFrame, szBuffer); } break; /* * IDM_CHAIN2: * this is posted after DDE_INITIATE was * successful */ case IDM_CHAIN2: { if (G_optNewWindow) WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_OPENURLNEW, 0), 0); else WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_OPENURL, 0), 0); WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_CHAIN3, 0), 0); } break; /* * IDM_CHAIN3: * this is posted to close the whole thing; we just need * another msg before going for IDM_CLOSE, or some DDE * msgs might get lost */ case IDM_CHAIN3: WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_CLOSE, 0), 0); break; case IDM_FULLSEQUENCE: WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_INITIATE, 0), 0); WinPostMsg(G_hwndDebug, WM_COMMAND, MPFROM2SHORT(IDM_CHAIN2, 0), 0); break; /* * IDM_CLOSE: * this is posted to close the whole thing */ case IDM_CLOSE: WinDdePostMsg(G_hServerWnd, hwndFrame, WM_DDE_TERMINATE, NULL, DDEPM_RETRY); ShowMessage("DDE connection closed."); if (!G_optDebug) WinPostMsg(hwndFrame, WM_COMMAND, MPFROM2SHORT(IDM_DELAYEXIT, 0), 0); break; /* * IDM_DELAYEXIT: * this is posted after IDM_CLOSE; we will now * check for whether the DDE conversation with * Netscape was successful and, if not, start * a new instance of Netscape according to the * command line parameters */ case IDM_DELAYEXIT: { if ( (!G_NetscapeFound) && (G_optExecute) ) { CHAR szStart[256]; GetNLSString(szStart, sizeof(szStart), ID_NDSI_STARTNETSCAPE); // confirm start netscape if ( (!G_optConfirmStart) // get rid of this hideously ugly dialog || (WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szStart, (PSZ)NETSCDDE_TITLE, 0, MB_YESNO | MB_MOVEABLE) == MBID_YES) /* WinCenteredDlgBox(HWND_DESKTOP, G_hwndDebug, WinDefDlgProc, G_hmodNLS, ID_NDD_QUERYSTART, NULL) == DID_OK) */ ) { UCHAR achObjBuf[256] = ""; CHAR szArgs[CCHMAXPATH]; HWND hwndNotify = HWND_DESKTOP; PROGDETAILS pd; HAPP happ; // destroy "Contacting", create "Starting Netscape" // window WinDestroyWindow(G_hwndContacting); G_hwndContacting = NULLHANDLE; if (!G_optQuiet) { G_hwndContacting = WinLoadDlg(HWND_DESKTOP, G_hwndDebug, WinDefDlgProc, G_hmodNLS, ID_NDD_STARTING, 0); WinShowWindow(G_hwndContacting, TRUE); } strlcpy(szArgs, G_szNetscapeParams, sizeof(szArgs)); strlcat(szArgs, " ", sizeof(szArgs)); strlcat(szArgs, G_szURL, sizeof(szArgs)); // now start app memset(&pd, 0, sizeof(pd)); pd.Length = sizeof(pd); pd.progt.progc = PROG_DEFAULT; pd.progt.fbVisible = SHE_VISIBLE; pd.pszExecutable = G_szNetscapeApp; pd.pszParameters = szArgs; pd.pszStartupDir = G_szStartupDir; if (!(happ = WinStartApp(NULLHANDLE, &pd, szArgs, NULL, SAF_INSTALLEDCMDLINE))) { DisplayError("WinStartApp failed for app \"%s\", params \"%s\", startup dir \"%s\"", G_szNetscapeApp, szArgs, G_szStartupDir); } } } // keep "Contacting" / "Starting" window visible for two seconds G_idTimer = WinStartTimer(G_hab, hwndFrame, 1, 2000); break; } // User closes the window case IDM_EXIT: WinPostMsg(hwndFrame, WM_CLOSE, 0, 0); break; } break; case WM_TIMER: // after two seconds, close status window WinStopTimer(G_hab, hwndFrame, G_idTimer); WinPostMsg(hwndFrame, WM_CLOSE, 0, 0); break; // Send the message to the usual WC_FRAME WndProc default: return G_SysWndProc(hwndFrame, msg, mp1, mp2); } return FALSE; }
BOOL DDERequest(HWND hwndClient, PSZ pszItemString) { ULONG mem; PID pid; TID tid; PDDESTRUCT pddeStruct; PSZ pszDDEItemName; // get some sharable memory DosAllocSharedMem((PVOID)&mem, NULL, sizeof(DDESTRUCT) + 1000, PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE); // get the server's ID and give it access // to the shared memory WinQueryWindowProcess(G_hServerWnd, &pid, &tid); DosGiveSharedMem(&mem, pid, PAG_READ | PAG_WRITE); /* here is definition for DDESTRUCT, for further reference: * typedef struct _DDESTRUCT { * ULONG cbData; * This is the length of data that occurs after the offabData parameter. If no * data exists, this field should contain a zero (0). * USHORT fsStatus; / Status of the data exchange. * DDE_FACK * Positive acknowledgement * DDE_FBUSY * Application is busy * DDE_FNODATA * No data transfer for advise * DDE_FACKREQ * Acknowledgements are requested * DDE_FRESPONSE * Response to WM_DDE_REQUEST * DDE_NOTPROCESSED * DDE message not understood * DDE_FAPPSTATUS * A 1-byte field of bits that are reserved for application-specific returns. * USHORT usFormat; / Data format. * USHORT offszItemName; / Offset to item name. * This is the offset to the item name from the start of this structure. Item * name is a null (0x00) terminated string. If no item name exists, there must * be a single null (0x00) character in this position. (That is, ItemName is * ALWAYS a null terminated string.) * * USHORT offabData; / Offset to beginning of data. * This is the offset to the data, from the start of this structure. This field * should be calculated regardless of the presence of data. If no data exists, * cbData must be zero (0). * * For compatibility reasons, this data should not contain embedded pointers. * Offsets should be used instead. * * -- CHAR szItemName[] / offset: offszItemName * -- BYTE abData[] / offset: offabData * } DDESTRUCT; */ // setup DDE data structures pddeStruct = (PDDESTRUCT) mem; pddeStruct->fsStatus = 0; // DDE_FACKREQ; // Status pddeStruct->usFormat = DDEFMT_TEXT; // Text format // go past end of data structure for the item name pddeStruct->offszItemName = sizeof(DDESTRUCT); pszDDEItemName = ((BYTE*)pddeStruct) + pddeStruct->offszItemName; strcpy(pszDDEItemName, pszItemString); // go past end of data structure // (plus past the name) for the data pddeStruct->offabData = strlen(pszDDEItemName) + 1; // offset to BEGINNING of data pddeStruct->cbData = 500; // length of the data ShowMessage(__FUNCTION__ ": sending request \"%s\"", pszItemString); // post our request to the server program if (G_NetscapeFound = WinDdePostMsg(G_hServerWnd, hwndClient, WM_DDE_REQUEST, pddeStruct, 0)) // WinDdePostMsg frees the shared mem! ShowMessage(" --> success"); else ShowMessage(" --> failed"); return G_NetscapeFound; }
void Dde_Item::Execute ( HWND Server, HWND Client, int, PVOID, int ) { // Reply with an error, as we don't support this function. PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), DDE_NOTPROCESSED, DDEFMT_TEXT, 0, 0 ) ; WinDdePostMsg ( Client, Server, WM_DDE_ACK, Response, DDEPM_RETRY ) ; }
void Dde_Item::Request ( HWND Server, HWND Client ) { // Reply with the item data. PDDESTRUCT Response = MakeDDEObject ( Client, PSZ(Name), 0, Format, Data, Size ) ; WinDdePostMsg ( Client, Server, WM_DDE_DATA, Response, DDEPM_RETRY ) ; }