editwnd.c

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

C
939
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include "winvi.h"
#include "winaux.h"
#include "win.h"
#include "font.h"
#include "color.h"
#include "utils.h"
#include "keys.h"
// #include "mdisim.h"
#include "watcom.h"

char *EditWindowClassName = "Buffer Window";

extern LONG WINEXP EditWindowProc( HWND, unsigned, UINT, LONG );

extern HWND hColorbar, hFontbar, hSSbar;

static BOOL Init( window *, void * );
static BOOL Fini( window *, void * );

window EditWindow = {
    &editw_info,
    { 0, 0, 0, 0 },
    Init,
    Fini
};

long            VScrollBarScale = 1;
int             HScrollBarScale = MAX_INPUT_LINE;

/*
 * Init - initialization routine for edit windows
 */
static BOOL Init( window *w, void *parm )
{
    WNDCLASS    wc;

    w = w;
    parm = parm;

    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wc.lpfnWndProc = (WNDPROC)EditWindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = sizeof( LPVOID ) * WIN_LAST;
    wc.hInstance = InstanceHandle;
    wc.hIcon = LoadIcon( InstanceHandle, "WATCOMICON" );
    wc.hCursor = LoadCursor( (HINSTANCE)NULL, IDC_IBEAM );
    wc.hbrBackground = (HBRUSH)NULL;
    wc.lpszMenuName = NULL;
    wc.lpszClassName = EditWindowClassName;
    return( RegisterClass( &wc ) );

} /* Init */

/*
 * GetEditStyle - get the edit window style
 */
DWORD GetEditStyle( bool is_max )
{
    DWORD style = NULL;
    is_max = is_max;

    style |= WS_HSCROLL;
    style |= WS_VSCROLL;
    return( style );

} /* GetEditStyle */

/*
 * SetWindowTitle - set the current window title
 */
void SetWindowTitle( HWND hwnd )
{
    info        *cinfo;
    char        buff[MAX_STR];
    window_data *wd;

    wd = DATA_FROM_ID( hwnd );
    cinfo = wd->info;
    if( cinfo != NULL ) {
        if( cinfo->CurrentFile != NULL ) {
            if( cinfo->CurrentFile->dup_count > 0 ) {
                MySprintf( buff,"%s [%d]", cinfo->CurrentFile->name,
                                    cinfo->DuplicateID );
                 SetWindowText( cinfo->CurrentWindow, buff );
            } else {
                SetWindowText( cinfo->CurrentWindow, cinfo->CurrentFile->name );
            }
        }
    }

} /* SetWindowTitle */

/*
 * NewEditWindow - create a new window for an edit buffer
 */
window_id NewEditWindow( void )
{
    HWND        edit;
    RECT        rect;
    DWORD       style;
    window_data *wd;
    MDICREATESTRUCT mdinew;

    if( BAD_ID( EditContainer ) ) {
        return( NO_WINDOW );
    }
    style = GetEditStyle( FALSE );
    GetClientRect( EditContainer, &rect );

    mdinew.szClass = EditWindowClassName;
    mdinew.szTitle = "Edit Buffer";
    mdinew.hOwner = InstanceHandle;
    mdinew.x = rect.top ;
    mdinew.y = rect.left ;
    mdinew.cx = rect.right- rect.left ;
    mdinew.cy = rect.bottom - rect.top ;
    mdinew.style = style;
    mdinew.lParam = NULL;

    edit =(HWND)SendMessage( EditContainer, WM_MDICREATE, 0, (LONG)(&mdinew) );

    wd = DATA_FROM_ID( edit );

    ShowWindow( edit, SW_NORMAL );
    UpdateWindow( edit );
    SetFocus( Root );

    return( edit );

} /* NewEditWindow */

/*
 * doPaint - handle painting a specific edit window
 */
static void doPaint( window *w, RECT *r, window_data *wd )
{
    info        *old_info, *new_info;
    int         start, stop;
    int         height;
    int         max_lines;

    new_info = wd->info;
    if( new_info != NULL ) {
        old_info = CurrentInfo;
        if( new_info != old_info ) {
            SaveCurrentInfo();
            RestoreInfo( new_info );
        }
        height = FontHeight( WIN_FONT( w ) );
        start = r->top / height;
        stop = ( r->bottom + height - 1 ) / height;
        max_lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );
        if( stop + 1 > max_lines ) {
            stop = max_lines - 1;
        }
        DCInvalidateSomeLines( start, stop );
        DCDisplaySomeLines( start, stop );
        DCUpdate();
        if( new_info != old_info ) {
            RestoreInfo( old_info );
        }
    }

} /* doPaint */

static void cancelDrag( void );

/*
 * activateWindow - make a particular edit window active
 */
static void activateWindow( HWND hwnd )
{
    info        *cinfo;
    window_data *wd;

    cancelDrag();
    SaveCurrentInfo();
    wd = DATA_FROM_ID( hwnd );
    cinfo = wd->info;
    if( cinfo != NULL ) {
        BringUpFile( cinfo, TRUE );
    }
} /* activateWindow */

/*
 * Mouse code:
 */
static int      startDragRow, startDragCol;
static bool     buttonDown;
static bool     hasCapture;
static bool     doubleClickPending;
static bool     dragPending;
static int      timerID;
static HWND     timerHwnd;
int             MouseX, MouseY;

#define TIMER_ID        0x01

/*
 * startDragTimer - activate a timer that will tell us when to
 *                  update dragging when the mouse leaves the window
 */
static void startDragTimer( HWND hwnd )
{
    timerID = SetTimer( hwnd, TIMER_ID, 10, NULL );
    if( timerID != 0 ) {
        timerHwnd = hwnd;
    }

} /* startDragTimer */

/*
 * stopDragTimer - deactivate the drag timer
 */
static void stopDragTimer( void )
{
    if( timerID ) {
        KillTimer( timerHwnd, TIMER_ID );
        timerID = 0;
    }

} /* stopDragTimer */

/*
 * cancelDrag - cancel any dragging or pending dragging
 */
static void cancelDrag( void )
{
    stopDragTimer();
    EditFlags.Dragging = FALSE;
    buttonDown = FALSE;
    dragPending = FALSE;
    if( hasCapture ) {
        hasCapture = FALSE;
        ReleaseCapture();
    }
} /* cancelDrag */

/*
 * isMouseButtonDown - check if a mouse button is down
 */
static bool isMouseButtonDown( void )
{
    if( ( GetKeyState( VK_LBUTTON ) & ~0x01 ) != 0 ) {
        return( TRUE );
    }
    if( ( GetKeyState( VK_RBUTTON ) & ~0x01 ) != 0 ) {
        return( TRUE );
    }
    return( FALSE );

} /* isMouseButtonDown */

/*
 * jumpToCoord - move to a specific coordinate in an edit window
 */
static bool jumpToCoord( int row, int col )
{
    GoToLineRelCurs( TopOfPage + row - 1 );
    col = RealCursorPosition( col + LeftColumn );
    GoToColumnOnCurrentLine( col );
    return( TRUE );

} /* jumpToCoord */

/*
 * regionSelected - handle selection with a mouse
 */
static void regionSelected( HWND id, int x, int y, BOOL dclick, bool popMenu )
{
    int         row, col;
    int         tmp;

    MyKillCaret( id );
    ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
    jumpToCoord( row, col );
    MouseX = x;
    MouseY = y;
    if( dclick ) {
        InitWordSearch( WordAltDefn );
    }
    /*
     * The hook stuff needs to know if it was invoked by a mouse press
     * or an '_' thingy.
     */
    if( popMenu ) {
        tmp = LastEvent;
        LastEvent = VI_KEY( FAKEMOUSE );
        DoSelectSelection( popMenu );
        LastEvent = tmp;
    } else {
        DoSelectSelection( popMenu );
    }
    if( dclick ) {
        InitWordSearch( WordDefn );
    }
    MouseY = 0;
    MouseX = 0;
    MyRaiseCaret( id );
    // UnselectRegion();

} /* regionSelected */

/*
 * mouseButtonDown - handle a mouse down event in an edit window
 */
static void mouseButtonDown( HWND id, int x, int y, BOOL shift )
{
    int         row, col;

    if (!EditFlags.WasOverstrike ) {
        ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
    } else {
        ClientToRowCol( id, x, y, &row, &col, DIVIDE_BETWEEN );
    }

    if( CurrentWindow != id ) {
        UnselectRegion();
        activateWindow( id );
        jumpToCoord( row, col );
        return;
    }

    MouseX = x;
    MouseY = y;
    buttonDown = TRUE;
    if( SelRgn.selected && shift ) {
        if( EditFlags.WasOverstrike ) {
            /*  if already dragging, always divide in middle of chars
            */
            ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
        }
        EditFlags.Dragging = TRUE;
        UpdateDrag( id, col, row );
    } else {
        jumpToCoord( row, col );
        UnselectRegion();
        dragPending = TRUE;
        if( !hasCapture ) {
            SetCapture( id );
            hasCapture = TRUE;
        }
        if (EditFlags.WasOverstrike ) {
            /*  dragging always based on middle of chars
            */
            ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
        }
        startDragRow = row;
        startDragCol = col;
    }

} /* mouseButtonDown */

/*
 * rightButtonDown - handle the right mouse button being pressed
 */
static void rightButtonDown( HWND id, int x, int y, BOOL shift )
{
    if( SelRgn.selected ) {
        regionSelected( id, x, y, FALSE, TRUE );
    } else {
        mouseButtonDown( id, x, y, shift );
    }

} /* rightButtonDown */

/*
 * leftButtonDown - handle the right mouse button being pressed
 */
static void leftButtonDown( HWND id, int x, int y, BOOL shift )
{
    mouseButtonDown( id, x, y, shift );

} /* leftButtonDown */

/*
 * mouseMove - handle a mouse move event in an edit window
 */
static void mouseMove( HWND id, int x, int y, BOOL not_used )
{
    int     row, col;
    not_used = not_used;

    if( dragPending ) {
        ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
        if( row == startDragRow && col == startDragCol ) {
            return;
        }
        InitSelectedRegion();
        EditFlags.Dragging = TRUE;
        dragPending = FALSE;
        startDragTimer( id );

        MyKillCaret( id );
    }

    if( !EditFlags.InsertModeActive && EditFlags.Dragging && buttonDown ) {
        MouseX = x;
        MouseY = y;
        ClientToRowCol( id, x, y, &row, &col, DIVIDE_MIDDLE );
        UpdateDrag( id, col, row );
        DCUpdate();
        SetWindowCursorForReal();
    }

} /* mouseMove */

/*
 * leftButtonUp - handle a mouse up event in an edit window
 */
static void leftButtonUp( HWND id, int x, int y, BOOL shift )
{
    id = id;
    x = x;
    y = y;
    shift = shift;

    cancelDrag();
    MouseX = MouseY = 0;

    MyRaiseCaret( id );
} /* leftButtonUp */

/*
 * rightButtonUp - handle right mouse button coming up
 */
static void rightButtonUp( HWND id, int x, int y, BOOL dclick )
{
    cancelDrag();
    regionSelected( id, x, y, dclick, TRUE );
} /* rightButtonUp */

/*
 * leftButtonDoubleClick - handle double click of left button (word selectn)
 */

⌨️ 快捷键说明

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