epmlink.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 515 行 · 第 1/2 页
C
515 行
static DDESTRUCT *MakeDDEObject( HWND hwnd, char *item_name,
USHORT fsStatus, USHORT usFormat,
void *data, int data_len )
/****************************************************************/
{
DDESTRUCT *dde;
int item_len;
PID pid;
TID tid;
if( item_name != NULL ) {
item_len = strlen( item_name ) + 1;
} else {
item_len = 1;
}
if( !DosAllocSharedMem( (PPVOID)&dde, NULL, sizeof( DDESTRUCT ) +
item_len + data_len,
PAG_COMMIT | PAG_READ | PAG_WRITE | OBJ_GIVEABLE ) ) {
WinQueryWindowProcess( hwnd, &pid, &tid );
DosGiveSharedMem( (PVOID)&dde, pid, PAG_READ | PAG_WRITE );
dde->cbData = data_len;
dde->fsStatus = fsStatus;
dde->usFormat = usFormat;
dde->offszItemName = sizeof( DDESTRUCT );
if( (data_len != 0) && (data != NULL) ) {
dde->offabData = (USHORT)(sizeof( DDESTRUCT ) + item_len);
} else {
dde->offabData = 0;
}
if( item_name != NULL ) {
strcpy( (char *)DDES_PSZITEMNAME( dde ), item_name );
} else {
strcpy( (char *)DDES_PSZITEMNAME( dde ), "" );
}
if( data != NULL ) {
memcpy( DDES_PABDATA( dde ), data, data_len );
}
return( dde );
}
return( NULL );
}
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 );
}
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 __export _System EDITConnect( void )
/**************************************/
{
ULONG style = 0;
if( hwndDDE != NULLHANDLE ) return( TRUE );
hwndDDE = WinCreateStdWindow( HWND_DESKTOP, 0, &style, WC_FRAME,
NULL, 0, NULLHANDLE, 0, NULL );
if( hwndDDE == NULLHANDLE ) {
return( FALSE );
}
prevClientProc = WinSubclassWindow( hwndDDE, (PFNWP)clientProc );
return( TRUE );
}
int __export _System EDITFile( char *fn, char *hlib )
/***************************************************/
{
CurrSession = FindSession( fn );
if( CurrSession == NULL ) {
if( StartingSessionInProgress ) {
return( FALSE );
}
StartingSessionInProgress = TRUE;
// new session must be created before we start the editor so
// that we can process the WM_DDE_INITIATE message properly
CurrSession = NewSession( fn, hlib );
if( CurrSession == NULL ) {
return( FALSE );
}
LinkSession( CurrSession );
if( spawnlp( P_NOWAIT, _Editor, _Editor, "/W", fn, NULL ) == -1 ) {
DeleteSession( NULLHANDLE );
CurrSession = NULL;
return( FALSE );
}
}
WinSetFocus( HWND_DESKTOP, CurrSession->hwnd );
return( TRUE );
}
int __export _System EDITLocateError( long lRow, int nCol, int nLen,
int resourceid, char *error_msg )
/*********************************************************************/
{
// queue the request in case the connection to the editor has
// not fully completed
if( CurrSession->msg != NULL ) {
MemFree( CurrSession->msg );
}
CurrSession->msg = BuildMsg( lRow, nCol, nLen, resourceid, error_msg );
if( CurrSession->msg == NULL ) {
return( FALSE );
}
if( CurrSession->hwnd == NULLHANDLE ) {
// editor session hasn't started yet
return( FALSE );
}
if( !CurrSession->connected ) {
return( FALSE );
}
return( SendData( CurrSession->msg, TRUE ) );
}
int __export _System EDITLocate( long lRow, int nCol, int nLen )
/**************************************************************/
{
return( EDITLocateError( lRow, nCol, nLen, 0, NULL ) );
}
int __export _System EDITShowWindow( int nCmdShow )
/*************************************************/
{
nCmdShow = nCmdShow;
return( TRUE );
}
int __export _System 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 );
}
ULONG LibMain( ULONG hModule, ULONG ulReason )
/********************************************/
{
if( ulReason ) {
// Terminating
FreeSessions();
CurrSession = NULL;
}
else {
// Initializing
InitSessions();
CurrSession = NULL;
AllocatedBlocks = 0;
StartingSessionInProgress = FALSE;
}
return( 1 );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?