364 lines
8.4 KiB
C++
364 lines
8.4 KiB
C++
/*++
|
|
|
|
copyright (c) 1992 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ddewnd.cpp
|
|
|
|
Abstract:
|
|
|
|
This module contains the code for the dde window procs
|
|
|
|
Author:
|
|
|
|
Srini Koppolu (srinik) 20-June-1992
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
#include "ddeproxy.h"
|
|
|
|
|
|
|
|
#define SYS_MSG 0
|
|
#define DOC_MSG 1
|
|
|
|
// SysWndProc: Window Procedure for System Topic DDE conversations
|
|
// wndproc for system topic
|
|
|
|
|
|
STDAPI_(LRESULT) SysWndProc (
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
StackAssert(SSOnSmallStack());
|
|
CDdeObject FAR* pDdeObj = NULL;
|
|
LPDDE_CHANNEL pChannel = NULL;
|
|
|
|
if (message>=WM_DDE_FIRST && message <= WM_DDE_LAST)
|
|
{
|
|
if (pDdeObj = (CDdeObject FAR*) GetWindowLong (hwnd, 0))
|
|
{
|
|
pChannel = pDdeObj->GetSysChannel();
|
|
}
|
|
|
|
if (pChannel == NULL)
|
|
{
|
|
intrAssert(pChannel != NULL);
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|
|
}
|
|
if ( pChannel
|
|
&& ( pChannel->iAwaitAck == AA_EXECUTE
|
|
|| pChannel->iAwaitAck == AA_INITIATE) )
|
|
{
|
|
MSG msg;
|
|
BOOL fDisp = FALSE;
|
|
while (SSPeekMessage(&msg, hwnd, WM_DDE_ACK, WM_DDE_ACK, PM_REMOVE | PM_NOYIELD) )
|
|
{
|
|
intrDebugOut((DEB_WARN, "DDE SysWndProc: dispatching WM_DDE_ACK message (%x)\n",pChannel));
|
|
SSDispatchMessage(&msg);
|
|
fDisp = TRUE;
|
|
}
|
|
if (fDisp && (pDdeObj = (CDdeObject FAR*) GetWindowLong (hwnd, 0)))
|
|
{
|
|
pChannel = pDdeObj->GetSysChannel();
|
|
}
|
|
|
|
if (pChannel == NULL)
|
|
{
|
|
intrAssert(pChannel != NULL);
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
switch (message){
|
|
case WM_DDE_ACK:
|
|
intrDebugOut((DEB_ITRACE,
|
|
"SWP: WM_DDE_ACK pChannel(%x)\n",pChannel));
|
|
if (pChannel->bTerminating)
|
|
{
|
|
intrDebugOut((DEB_ITRACE,
|
|
"SWP: pChannel->bTerminating: no action\n"));
|
|
|
|
break;
|
|
}
|
|
|
|
switch (pChannel->iAwaitAck) {
|
|
case AA_INITIATE:
|
|
pDdeObj->OnInitAck (pChannel, (HWND)wParam);
|
|
if (LOWORD(lParam))
|
|
GlobalDeleteAtom (LOWORD(lParam));
|
|
if (HIWORD(lParam))
|
|
GlobalDeleteAtom (HIWORD(lParam));
|
|
break;
|
|
|
|
case AA_EXECUTE:
|
|
pDdeObj->OnAck (pChannel, lParam);
|
|
break;
|
|
|
|
default:
|
|
intrDebugOut((DEB_ITRACE,
|
|
"SWP: WM_DDE_ACK UnhandledpChannel(%x)\n",pChannel));
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case WM_TIMER:
|
|
pDdeObj->OnTimer (pChannel);
|
|
break;
|
|
|
|
case WM_DDE_TERMINATE:
|
|
intrDebugOut((DEB_ITRACE,
|
|
"SWP: WM_DDE_TERMINATE pChannel(%x)\n",pChannel));
|
|
pDdeObj->OnTerminate (pChannel, (HWND)wParam);
|
|
break;
|
|
|
|
default:
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|
|
|
|
return 0L;
|
|
}
|
|
|
|
|
|
// ClientDocWndProc: Window procedure used to document DDE conversations
|
|
STDAPI_(LRESULT) ClientDocWndProc (
|
|
HWND hwnd,
|
|
UINT message,
|
|
WPARAM wParam,
|
|
LPARAM lParam
|
|
)
|
|
{
|
|
StackAssert(SSOnSmallStack());
|
|
CDdeObject FAR* pDdeObj = NULL;
|
|
LPDDE_CHANNEL pChannel = NULL;
|
|
HANDLE hData;
|
|
ATOM aItem;
|
|
|
|
if (message>=WM_DDE_FIRST && message <= WM_DDE_LAST)
|
|
{
|
|
|
|
if (pDdeObj = (CDdeObject FAR*) GetWindowLong (hwnd, 0))
|
|
pChannel = pDdeObj->GetDocChannel();
|
|
|
|
if (pChannel == NULL)
|
|
{
|
|
//
|
|
// pChannel == NULL. Something is very wrong! But, lets
|
|
// not fault on it.
|
|
//
|
|
//intrAssert(pChannel != NULL);
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|
|
|
|
}
|
|
if ( pChannel
|
|
&& ( pChannel->iAwaitAck == AA_EXECUTE
|
|
|| pChannel->iAwaitAck == AA_INITIATE
|
|
|| pChannel->iAwaitAck == AA_REQUESTAVAILABLE
|
|
|| pChannel->iAwaitAck == AA_REQUEST
|
|
|| pChannel->iAwaitAck == AA_UNADVISE
|
|
|| pChannel->iAwaitAck == AA_EXECUTE
|
|
|| pChannel->iAwaitAck == AA_ADVISE
|
|
|| pChannel->iAwaitAck == AA_POKE) )
|
|
{
|
|
MSG msg;
|
|
BOOL fDisp = FALSE;
|
|
while (SSPeekMessage(&msg, hwnd, WM_DDE_ACK, WM_DDE_ACK, PM_REMOVE | PM_NOYIELD) )
|
|
{
|
|
intrDebugOut((DEB_WARN, "DDE DocWndProc: dispatching WM_DDE_ACK message (%x)\n",pChannel));
|
|
SSDispatchMessage(&msg);
|
|
fDisp = TRUE;
|
|
}
|
|
|
|
if (fDisp && (pDdeObj = (CDdeObject FAR*) GetWindowLong (hwnd, 0)))
|
|
{
|
|
pChannel = pDdeObj->GetDocChannel();
|
|
}
|
|
|
|
if (pChannel == NULL)
|
|
{
|
|
intrAssert(pChannel != NULL);
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
}
|
|
}
|
|
|
|
switch (message)
|
|
{
|
|
case WM_DDE_ACK:
|
|
|
|
intrDebugOut((DEB_ITRACE,
|
|
"ClientWndProc: WM_DDE_ACK pChannel(%x)\n",
|
|
pChannel));
|
|
if (pChannel->bTerminating){
|
|
// ### this error recovery may not be correct.
|
|
DEBUG_OUT ("No action due to termination process",0)
|
|
break;
|
|
}
|
|
|
|
switch(pChannel->iAwaitAck){
|
|
case AA_INITIATE:
|
|
pDdeObj->OnInitAck (pChannel, (HWND)wParam);
|
|
if (LOWORD(lParam))
|
|
GlobalDeleteAtom (LOWORD(lParam));
|
|
if (HIWORD(lParam))
|
|
GlobalDeleteAtom (HIWORD(lParam));
|
|
break;
|
|
|
|
case AA_REQUESTAVAILABLE:
|
|
case AA_REQUEST:
|
|
case AA_UNADVISE:
|
|
case AA_EXECUTE:
|
|
case AA_ADVISE:
|
|
pDdeObj->OnAck (pChannel, lParam);
|
|
break;
|
|
|
|
case AA_POKE:
|
|
// freeing pokedata is done in handleack
|
|
pDdeObj->OnAck (pChannel, lParam);
|
|
break;
|
|
|
|
default:
|
|
intrDebugOut((DEB_IERROR,
|
|
"ClientWndProc: WM_DDE_ACK unhandled\n"));
|
|
break;
|
|
|
|
} // end of switch
|
|
break;
|
|
|
|
case WM_DDE_DATA:
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
pDdeObj->Guard();
|
|
#endif // _CHICAGO_
|
|
hData = GET_WM_DDE_DATA_HDATA(wParam,lParam);
|
|
aItem = GET_WM_DDE_DATA_ITEM(wParam,lParam);
|
|
intrDebugOut((DEB_ITRACE,
|
|
"CWP: WM_DDE_DATA pChannel(%x) hData(%x) aItem(%x)\n",
|
|
pChannel,hData,aItem));
|
|
pDdeObj->OnData (pChannel, hData, aItem);
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
if (pDdeObj->UnGuard())
|
|
{
|
|
SetWindowLong(hwnd, 0, (LONG)0);
|
|
intrDebugOut((DEB_IWARN, "DDE ClientDocWndProc Release on pUnkOuter == 0 (this:%x, hwnd:%x\n",pDdeObj, hwnd ));
|
|
}
|
|
#endif // _CHICAGO_
|
|
|
|
break;
|
|
|
|
case WM_DDE_TERMINATE:
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
pDdeObj->Guard();
|
|
#endif // _CHICAGO_
|
|
intrDebugOut((DEB_ITRACE,
|
|
"CWP: WM_DDE_TERMINATE pChannel(%x)\n",pChannel));
|
|
|
|
|
|
if (pDdeObj->m_fDoingSendOnDataChange)
|
|
{
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
BOOL fPostMsg = TRUE;
|
|
#endif
|
|
//
|
|
// Cheese alert! This protocol is very bad. The original
|
|
// 16 bit code something even more worse, so we are stuck
|
|
// to do something roughly compatible.
|
|
//
|
|
// If fDoingSendOnDataChange, the client may be asking for
|
|
// additional information from the server. The way the code
|
|
// is structured, it doesn't handle OnTerminate gracefully
|
|
// in this case.
|
|
//
|
|
// To fix this, we first tell the call control that
|
|
// the server has died. Then we repost the terminate
|
|
// message so we can handle it later.
|
|
//
|
|
// The old code did a
|
|
// pDdeObj->QueueMsg (hwnd, message, wParam, lParam);
|
|
//
|
|
// and the old SendOnDataChange removed the message.
|
|
// This probably didn't work either, but was never
|
|
// actually encountered.
|
|
//
|
|
|
|
intrDebugOut((DEB_ITRACE,
|
|
"CWP: term doing SendOnDataChange \n"));
|
|
//
|
|
// If we got here, there should be a CallData assigned
|
|
// to the channel.
|
|
//
|
|
if ((pChannel->pCD) && (pChannel->pCallCont))
|
|
{
|
|
intrDebugOut((DEB_ITRACE,"CWP: Setting call state\n"));
|
|
|
|
pChannel->pCallCont->SetCallState(pChannel->pCD,
|
|
SERVERCALLEX_ISHANDLED,
|
|
RPC_E_SERVER_DIED);
|
|
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// If there is no call data, then we aren't waiting in
|
|
// the channel. Terminate the conversation.
|
|
//
|
|
|
|
intrDebugOut((DEB_ERROR,"CWP: No call state exists\n"));
|
|
pDdeObj->OnTerminate (pChannel, (HWND)wParam);
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
fPostMsg = FALSE;
|
|
#else
|
|
break;
|
|
#endif //
|
|
}
|
|
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
if (fPostMsg)
|
|
{
|
|
#endif
|
|
//
|
|
// Repost the message and try again.
|
|
//
|
|
intrDebugOut((DEB_ITRACE,"CWP: Reposting WM_DDE_TERMINATE\n"));
|
|
PostMessage(hwnd,message,wParam,lParam);
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
}
|
|
#else
|
|
break;
|
|
#endif
|
|
|
|
}
|
|
else
|
|
{
|
|
pDdeObj->OnTerminate (pChannel, (HWND)wParam);
|
|
}
|
|
#ifdef _CHICAGO_
|
|
//Note:POSTPPC
|
|
if (pDdeObj->UnGuard())
|
|
{
|
|
SetWindowLong(hwnd, 0, (LONG)0);
|
|
intrDebugOut((DEB_IWARN, "DDE ClientDocWndProc Release on pUnkOuter == 0 (this:%x, hwnd:%x\n",pDdeObj, hwnd ));
|
|
}
|
|
#endif // _CHICAGO_
|
|
break;
|
|
|
|
default:
|
|
return SSDefWindowProc (hwnd, message, wParam, lParam);
|
|
|
|
}
|
|
|
|
return 0L;
|
|
}
|