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 + -
显示快捷键?