eatom.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 674 行 · 第 1/2 页

C
674
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Routines to handle the operations on an EATOM.
*
****************************************************************************/

#include <windows.h>

#include "fmedit.def"
#include "memory.def"
#include "paint.def"
#include "object.def"
#include "state.def"
#include "currobj.def"
#include "scroll.def"
#include "global.h"
#include "grid.def"

#include "eatom.h"

/* This boolean DEFINE controls where eatom's get each their own window */
/* use the app window. */
#define USE_OWN_WINDOW 1

/* forward references */

static BOOL PASCAL EAtomDispatch( ACTION, EATOM *, void *, void * );
static BOOL EAtomLocation( OBJPTR, void *, void * );
static BOOL EAtomMove( OBJPTR, void *, void * );
static BOOL EAtomResize( OBJPTR, void *, void * );
static BOOL EAtomRegister( OBJPTR, void *, void * );
static BOOL EAtomRecreate( OBJPTR, void *, void * );
static BOOL EAtomDestroy( OBJPTR, void *, void * );
static BOOL EAtomValidateAction( OBJPTR, void *, void * );
static BOOL EAtomDraw( OBJPTR, void *, void * );
static BOOL EAtomGetObjptr( OBJPTR, void *, void * );
static BOOL EAtomUndoMove( OBJPTR, void *, void * );
static BOOL EAtomRemoveFromParent( OBJPTR, void *, void * );
static BOOL EAtomGetAnchor( OBJPTR, void *, void * );
static BOOL EAtomNotify( OBJPTR, void *, void * );
static BOOL EAtomIsMarkValid( OBJPTR, void *, void * );

static void ShowEAtomRect( EATOM * obj );

static DISPATCH_ITEM EAtomActions[] = {
    { LOCATE,               EAtomLocation           }
,   { MOVE,                 EAtomMove               }
,   { RESIZE,               EAtomResize             }
,   { REGISTER,             EAtomRegister           }
,   { RECREATE,             EAtomRecreate           }
,   { DESTROY,              EAtomDestroy            }
,   { VALIDATE_ACTION,      EAtomValidateAction     }
,   { DRAW,                 EAtomDraw               }
,   { GET_OBJPTR,           EAtomGetObjptr          }
,   { UNDO_MOVE,            EAtomUndoMove           }
,   { REMOVE_FROM_PARENT,   EAtomRemoveFromParent   }
,   { GET_ANCHOR,           EAtomGetAnchor          }
,   { NOTIFY,               EAtomNotify             }
,   { IS_MARK_VALID,        EAtomIsMarkValid        }
};

#define MAX_ACTIONS (sizeof(EAtomActions)/sizeof(DISPATCH_ITEM))

extern BOOL PASCAL EAtomDispatch( ACTION id, EATOM * obj,
                                      void * p1, void * p2 )
/**********************************************************/

/* dispatch the desired operation to the correct place */

  {
    int i;

    if( id >= APP_ACTIONS  ) {
        return( Forward( obj->obj, id, p1, p2 ));
    }

    for(i=0; i<MAX_ACTIONS; i++ ) {
        if( EAtomActions[i].id == id ) {
            return((EAtomActions[i].rtn)( obj, p1, p2));
        }
    }
    return( FALSE );
  }

static BOOL EAtomValidateAction( OBJPTR _obj, void * _idptr, void * p2 )
/*********************************************************************/

/* check if the desired action is valid for and EATOM */

  {
    EATOM   *obj = _obj;
    ACTION  *idptr = _idptr;
    int i;

    obj = obj;        /* ref'd to avoid warning */
    p2 = p2;          /* ref'd to avoid warning */

    if( *idptr >= APP_ACTIONS  ) {
        return( Forward( obj->obj, VALIDATE_ACTION, idptr, p2 ));
    }
    for(i=0; i<MAX_ACTIONS; i++ ) {
        if( EAtomActions[i].id == *idptr ) {
            return( TRUE );
        }
    }
    return( FALSE );
  }


extern OBJPTR EAtomCreate( OBJPTR parent, RECT * loc, OBJPTR handle )
/*******************************************************************/

/* create an EATOM object */

  {
    EATOM   *new;
    POINT   offset;
    STATE_ID st;

    new = EdAlloc( sizeof( EATOM ) );
    new->invoke = (FARPROC)&EAtomDispatch;
    new->obj = parent;
    new->parent = NULL;
    if( handle == NULL ) {
        new->handle = new;
    } else {
        new->handle = handle;
    }
    new->rect = *loc;
    new->anchor.x = new->rect.left;
    new->anchor.y = new->rect.top;
    new->show = GetShowEatoms();
    GetOffset( &offset );
    if( new->show ) {
        #if USE_OWN_WINDOW
            new->hwnd = CreateWindow( "EAtomClass",
                                      NULL,
                                      WS_VISIBLE | WS_CHILD | WS_DISABLED,
                                      new->rect.left - offset.x,
                                      new->rect.top - offset.y,
                                      new->rect.right - new->rect.left,
                                      new->rect.bottom - new->rect.top,
                                      GetAppWnd(),
                                      NULL,
                                      GetInst(),
                                      NULL );
        #else
            new->hwnd = GetAppWnd();
        #endif
    } else {
        new->hwnd = NULL;
    }
    new->displayed = FALSE;
    st = GetState();
    if( st != SELECTING ) {
        MouseAction( &new->rect );
    }
    ShowEAtomRect( new );
    return( new );
  }


static BOOL EAtomLocation( OBJPTR _obj, void * _rect, void * p2 )
/**************************************************************/

/* return the location of the atom */

  {
    EATOM   *obj = _obj;
    RECT    *rect = _rect;
    p2 = p2;          /* ref'd to avoid warning */
    *rect = obj->rect;
    return( TRUE );
  }

static void CalcDrawRect( RECT * rect, RECT * drawrect )
/****************************************************/
/* Calculate the rectangle for this eatom's client area */
{
#if USE_OWN_WINDOW
    drawrect->left = 0;
    drawrect->top = 0;
    drawrect->right = rect->right - rect->left;
    if( drawrect->right < 0 ) {
        drawrect->right = 0;
    }
    drawrect->bottom = rect->bottom - rect->top;
    if( drawrect->bottom < 0 ) {
        drawrect->bottom = 0;
    }
#else
    POINT   offset;

    GetOffset( &offset );
    drawrect->left = rect->left - offset.x;
    drawrect->right = rect->right - offset.x;
    drawrect->top = rect->top - offset.y;
    drawrect->bottom = rect->bottom - offset.y;
#endif
}

static void DrawEAtomRect( EATOM * obj )
/**************************************/
{
    RECT  drawrect;
    HDC   hdc;

    if( obj->show ) {
        CalcDrawRect( &obj->rect, &drawrect );
        hdc = GetDC( obj->hwnd );
        DrawFocusRect( hdc, &drawrect );
        ReleaseDC( obj->hwnd, hdc );
    }
} /* DrawEAtomRect */

static void ShowEAtomRect( EATOM * obj )
/**************************************/
{
    if( !obj->displayed ) {
        DrawEAtomRect( obj );
        obj->displayed = TRUE;
    }
} /* ShowEAtomRect */

static void HideEAtomRect( EATOM * obj )
/**************************************/
{
    if( obj->displayed ) {
        DrawEAtomRect( obj );
        obj->displayed = FALSE;
    }
} /* HideEAtomRect */

static BOOL EAtomMove( OBJPTR _obj, void * _offset, void * p2 )
/*************************************************************/

/*  do the move operation.  The amount to move is stored in the left and
 *  top values of the passed rect.
 */

  {
    EATOM   *obj = _obj;
    POINT   *offset = _offset;
    POINT   scrolloffset;

    p2 = p2;          /* ref'd to avoid warning */
    HideEAtomRect( obj );
    AutoScroll( obj->rect, *offset );
    GetOffset( &scrolloffset );
    OffsetRect( &obj->rect, offset->x, offset->y );
    #if USE_OWN_WINDOW
        if( obj->show ) {
            InvalidateRect( obj->hwnd, NULL, TRUE );
            MoveWindow( obj->hwnd, obj->rect.left - scrolloffset.x,
                                   obj->rect.top - scrolloffset.y,
                                   obj->rect.right - obj->rect.left,
                                   obj->rect.bottom - obj->rect.top,
                                   FALSE );
        }
    #endif
    MouseAction( &obj->rect );
    ShowEAtomRect( obj );
    return( TRUE );
  }


static BOOL EAtomResize( OBJPTR _obj, void * _info, void * p2 )
/************************************************************/

/*  do the resize operation.  The amount to resize is stored in the left and
 *  top values of the passed rect.
 */

  {
    EATOM   *obj = _obj;
    RECT    *info = _info;
    POINT   point;
    POINT   scrolloffset;
    RECT    drawrect;
    RECT    newrect;

    point.x = 0;
    point.y = 0;
    p2 = p2;          /* ref'd to avoid warning */
    CalcDrawRect( &obj->rect, &drawrect );
    CopyRect( &newrect, &obj->rect );
    if( Sizing( R_TOP ) ) {
        newrect.top = obj->rect.top + info->top;
        point.y =  info->top;
    }
    if( Sizing( R_BOTTOM ) ) {
        newrect.bottom = obj->rect.bottom + info->bottom;
        point.y = info->bottom;
    }
    if( Sizing( R_LEFT ) ) {
        newrect.left = obj->rect.left + info->left;
        point.x = info->left;
    }
    if( Sizing( R_RIGHT ) ) {
        newrect.right = obj->rect.right + info->right;
        point.x = info->right;
    }
    if( point.x || point.y  ) {
        HideEAtomRect( obj );
        AutoScroll( obj->rect, point );
        GetOffset( &scrolloffset );
        CopyRect( &obj->rect, &newrect );
        #if USE_OWN_WINDOW
            if( obj->show ) {
                InvalidateRect( obj->hwnd, NULL, TRUE );
            }
        #endif
        point.x = obj->rect.right - obj->rect.left;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?