editwnd.c

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

C
939
字号
static void leftButtonDoubleClick( HWND id, int x, int y, BOOL dclick )
{
    cancelDrag();
    regionSelected( id, x, y, dclick, FALSE );
} /* leftButtonDoubleClick */

typedef void (*func)( HWND, int, int, BOOL );

/*
 * mouseEvent - handle all mouse events in an edit window
 */
static void mouseEvent( HWND hwnd, LONG l, BOOL flag, func f )
{
    if( EditFlags.HoldEverything ) {
        return;
    }
    if( EditFlags.InsertModeActive ) {
        PushMode();
        f( hwnd, (signed_16) LOWORD( l ), (signed_16) HIWORD( l ), flag );
        PopMode();
    } else {
        f( hwnd, (signed_16) LOWORD( l ), (signed_16) HIWORD( l ), flag );
    }
    DCUpdate();
    SetWindowCursorForReal();

} /* mouseEvent */

/*
 * sendDragMessage - when we get a timer event, pretend we got a mouse move
 */
static void sendDragMessage( HWND hwnd )
{
    if( timerID ) {
        if( isMouseButtonDown() ) {
            SendMessage( hwnd, WM_MOUSEMOVE, 0, MAKELONG( MouseX, MouseY ) );
        } else {
            /* it's possible that someone ate our WM_BUTTONUP
             * or something stupid (WVIDEO perhaps...) */
            stopDragTimer();
        }
    }

} /* sendDragMessage */

/*
 * PositionVerticalScrollThumb - place the vertical thumb
 */
void PositionVerticalScrollThumb( window_id id, linenum top, linenum last )
{
    /*
     * NOTE: This will not work well yet - linenum's are 32-bit while
     * windows takes a stupid 16-bit int.
     */
    int wlines;
    int min,max,pos;
    int newtop,newlast;

    if( BAD_ID( id ) ) {
        return;
    }

    /* if last > 32000+ and ints are short, then set scaling factor to 2
     *   otherwise scale is 1
     */
    VScrollBarScale = 1 + last / INT_MAX;

    wlines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );

    /* Reduce number of redraws by checking current range and position
    */
    GetScrollRange( id, SB_VERT, (LPINT)&min, (LPINT)&max );

    newlast = last/VScrollBarScale;
    newtop = top/VScrollBarScale;

    if( newlast > 1 ) {
        /* have enough lines to set position normally
        */
        if( max != newlast ){
            // always set position with range to avoid screen draws
            SetScrollRange( id, SB_VERT, 1, newlast, FALSE );
            SetScrollPos( id, SB_VERT, newtop, TRUE );
        } else {
            pos = GetScrollPos( id, SB_VERT );
            if( newtop != pos ){
                SetScrollPos( id, SB_VERT, newtop, TRUE );
            }
        }
    } else {
        /* set dummy range & leave at bottom
        */
        SetScrollRange( id, SB_VERT, 1, 2, FALSE );
        SetScrollPos( id, SB_VERT, 2, TRUE );
    }
} /* PositionVerticalScrollThumb */


/*
 * PositionHorizontalScrollThumb - place the horizontal thumb
 */
void PositionHorizontalScrollThumb( window_id id, int left )
{
    if( BAD_ID( id ) ) {
        return;
    }

    // must reset range every time (size changes -> mdisim trashes it)
    SetScrollRange( id, SB_HORZ, 1, HScrollBarScale, FALSE );
    SetScrollPos( id, SB_HORZ, left, TRUE );
} /* PositionHorizontalScrollThumb */

/*
 * EditDrawScrollBars
 */
void EditDrawScrollBars( HWND hwnd )
{
    window_data *wd;

    wd = DATA_FROM_ID( hwnd );
    if( wd->info != NULL ) {
        PositionVerticalScrollThumb( hwnd, wd->info->TopOfPage,
                    wd->info->CurrentFile->fcb_tail->end_line );
        PositionHorizontalScrollThumb( hwnd, wd->info->LeftColumn );
    }

} /* EditDrawScrollBars */

/*
 * doVScroll - handle various scroll events (vertical)
 */
static void doVScroll( HWND hwnd, UINT wparam, LONG lparam )
{
    window_data *wd;
    int         scrollAmount;
    linenum     newTopOfPage, oldTopOfPage;
    int         text_lines;
    int         diff;

    lparam = lparam;            // Shut up the compiler for the NT version
    wd = DATA_FROM_ID( hwnd );

    oldTopOfPage = TopOfPage;
    EditFlags.ScrollCommand = TRUE;
    switch( GET_WM_VSCROLL_CODE( wparam, lparam ) ) {
    case SB_LINEUP:
        newTopOfPage = TopOfPage - 1;
        if( EditFlags.JumpyScroll ) {
            newTopOfPage = TopOfPage - SCROLL_VLINE;
        }
        MoveScreenML( newTopOfPage );
        break;
    case SB_LINEDOWN:
        newTopOfPage = TopOfPage + 1;
        if( EditFlags.JumpyScroll ) {
            newTopOfPage = TopOfPage + SCROLL_VLINE;
        }
        scrollAmount = newTopOfPage - TopOfPage;
        MoveScreenML( newTopOfPage );
        break;
    case SB_PAGEUP:
        MoveScreenUpPageML();
        break;
    case SB_PAGEDOWN:
        MoveScreenDownPageML();
        break;
    case SB_THUMBTRACK:
        MoveScreenML( GET_WM_VSCROLL_POS( wparam, lparam )
                        * VScrollBarScale );
        break;
    }
    EditFlags.ScrollCommand = FALSE;

    text_lines = WindowAuxInfo( CurrentWindow, WIND_INFO_TEXT_LINES );
    diff = TopOfPage - oldTopOfPage;
    if( diff != 0 ){
        if( abs( diff ) > text_lines / 2 ) {
            //  faster to redraw whole screen
            DCInvalidateAllLines();
            GoToLineNoRelCurs( TopOfPage );
            DCDisplayAllLines();
            DCUpdate();
        } else {
            //  faster to shift screen up and redraw rest
            // but its difficult to figure out how!
            DCInvalidateAllLines();
            GoToLineNoRelCurs( TopOfPage );
            DCDisplayAllLines();
            DCUpdate();
        }

        SetWindowCursor();
        SetWindowCursorForReal();
    }

} /* doVScroll */

/*
 * doHScroll - handle various scroll events (horizontal)
 */
static void doHScroll( HWND hwnd, UINT wparam, LONG lparam )
{
    int newLeftColumn;

    lparam = lparam;
    EditFlags.ScrollCommand = TRUE;
    switch( GET_WM_HSCROLL_CODE( wparam, lparam ) ) {
    case SB_LINEUP:
        newLeftColumn = LeftColumn - 1;
        if( EditFlags.JumpyScroll ) {
            newLeftColumn = LeftColumn - SCROLL_HLINE;
        }
        MoveScreenLeftRightML( newLeftColumn );
        break;
    case SB_LINEDOWN:
        newLeftColumn = LeftColumn + 1;
        if( EditFlags.JumpyScroll ) {
            newLeftColumn = LeftColumn + SCROLL_HLINE;
        }
        MoveScreenLeftRightML( newLeftColumn );
        break;
    case SB_PAGEUP:
        MoveScreenLeftPageML();
        break;
    case SB_PAGEDOWN:
        MoveScreenRightPageML();
        break;
    case SB_THUMBTRACK:
        MoveScreenLeftRightML( GET_WM_HSCROLL_POS( lparam, wparam ) - 1 );
        break;
    }
    EditFlags.ScrollCommand = FALSE;

    DCInvalidateAllLines();
    DCDisplayAllLines();
    DCUpdate();
    SetWindowCursor();
    SetWindowCursorForReal();

    PositionHorizontalScrollThumb( hwnd, LeftColumn );
} /* doHScroll */

/*
 * EditWindowProc - window procedure for all edit windows
 */
LONG WINEXP EditWindowProc( HWND hwnd, unsigned msg, UINT wparam, LONG lparam )
{
    window      *w;
    PAINTSTRUCT ps;
    HDC         hdc;
    RECT        rect;
    window_data *data;
    HWND        win;
    HWND        tbwin;
    bool        killsel;
    info        *cinfo;
    info        *sinfo;

    w = WINDOW_FROM_ID( hwnd );
    switch( msg ) {
    case WM_CREATE:
        data = MemAlloc( sizeof( window_data ) );
        SetWindowLong( hwnd, WIN_WINDOW * MAGIC_SIZE, (LONG)(LPVOID)(&EditWindow) );
        SetWindowLong( hwnd, WIN_DATA * MAGIC_SIZE, (LONG)(LPVOID)data );
        break;
    case WM_PAINT:
        if( GetUpdateRect( hwnd, &rect, FALSE ) ) {
            data = DATA_FROM_ID( hwnd );
            hdc = BeginPaint( hwnd, &ps );
            doPaint( w, &rect, data );
            EndPaint( hwnd, &ps );
            if( IntersectRect( &rect, &rect, &data->extra ) ) {
                BlankRectIndirect( hwnd, SEType[ SE_WHITESPACE ].background, &rect );
            }
        }
        break;
    case WM_MOUSEACTIVATE:
        if( hwnd != CurrentWindow ) {
            UnselectRegion();
            activateWindow( hwnd );
        }
        return( MA_ACTIVATE );

    case WM_MDIACTIVATE:
        if( wparam == FALSE ){
            // losing focus
            cancelDrag();
            killsel = TRUE;
            win = (HWND) wparam;
            if( win != NULL ) {
                tbwin = GetToolbarWindow();
                if( win == Root || win == tbwin || win == CommandId ||
                    (hColorbar && IsChild( hColorbar, win )) ||
                    (hFontbar && IsChild( hFontbar, win )) ||
                    (hSSbar && IsChild( hSSbar, win )) ) {
                    killsel = FALSE;
                }
            }
            if( killsel ) {
                UnselectRegion();
            }
            GoodbyeCursor( hwnd );
        } else {
            // Gaining focus
            MyShowCaret( hwnd );
            ResetEditWindowCursor( hwnd );
            if( hwnd != CurrentWindow ) {
                activateWindow( hwnd );
                MyShowCaret( hwnd );
                ResetEditWindowCursor( hwnd );
                SetWindowCursor();
                SetWindowCursorForReal();
            }
        }
        break;
    case WM_LBUTTONDBLCLK:
        doubleClickPending = TRUE;
        break;
    case WM_RBUTTONUP:
        mouseEvent( hwnd, lparam, FALSE, rightButtonUp );
        break;
    case WM_RBUTTONDOWN:
        mouseEvent( hwnd, lparam, wparam & MK_SHIFT, rightButtonDown );
        break;
    case WM_LBUTTONDOWN:
        mouseEvent( hwnd, lparam, wparam & MK_SHIFT, leftButtonDown );
        break;
    case WM_LBUTTONUP:
        if( doubleClickPending ) {
            mouseEvent( hwnd, lparam, wparam & MK_SHIFT, leftButtonUp );
            mouseEvent( hwnd, lparam, TRUE, leftButtonDoubleClick );
            doubleClickPending = FALSE;
        } else {
            mouseEvent( hwnd, lparam, wparam & MK_SHIFT, leftButtonUp );
        }
        break;
    case WM_MOUSEMOVE:
        mouseMove( hwnd, (int)(signed_16) LOWORD( lparam ),
                        (int)(signed_16) HIWORD( lparam ), FALSE );
        break;
    case WM_ERASEBKGND:
        return( TRUE );
    case WM_SYSCHAR:
    case WM_SYSKEYUP:
        return( SendMessage( Root, msg, wparam, lparam ) );
    case WM_SYSKEYDOWN:
    case WM_KEYDOWN:
        if( WindowsKeyPush( wparam, HIWORD( lparam ) ) ) {
            return( FALSE );
        }
        if( msg == WM_KEYDOWN ) {
            return( DefMDIChildProc( hwnd, msg, wparam, lparam ) );
        } else {
            return( SendMessage( Root, msg, wparam, lparam ) );
        }
    case WM_VSCROLL:
        doVScroll( hwnd, wparam, lparam );
        break;
    case WM_HSCROLL:
        doHScroll( hwnd, wparam, lparam );
        break;
    case WM_CLOSE:
        if( EditFlags.HoldEverything ) {
            break;
        }
        PushMode();
        data = DATA_FROM_ID( hwnd );
        SendMessage( EditContainer, WM_MDIRESTORE, (UINT)hwnd, 0L );
        BringUpFile( data->info, TRUE );
        if( NextFile() > 0 ) {
            FileExitOptionSaveChanges( CurrentFile );
        }
        PopMode();
        break;
    case WM_TIMER:
        sendDragMessage( hwnd );
        break;
    case WM_DESTROY:
        data = DATA_FROM_ID( hwnd );
        MemFree( data );
        break;
    case WM_KILLFOCUS:
        DoneCurrentInsert( TRUE );
        return( DefMDIChildProc( hwnd, msg, wparam, lparam ) );
    case WM_SIZE:
        data = DATA_FROM_ID( hwnd );
        DCResize( data->info );
        if( wparam == SIZE_MINIMIZED ) {
            sinfo = CurrentInfo;
            cinfo = CurrentInfo->next;
            while( 1 ) {
                if( cinfo == NULL ) {
                    cinfo = InfoHead;
                }
                if( cinfo == sinfo ) {
                    SetFocus( Root );
                    break;
                }
                if( IsIconic( cinfo->CurrentWindow ) ) {
                    cinfo = cinfo->next;
                } else {
                    SaveInfo( sinfo );
                    BringUpFile( cinfo, FALSE );
                    break;
                }
            }
        }
        /* either way we remember to reset extra */
        GetClientRect( hwnd, &data->extra );
        data->extra.top = WindowAuxInfo( hwnd, WIND_INFO_TEXT_LINES ) *
                            FontHeight( WIN_FONT( &EditWindow ) );
    // explicit fall through
    default:
        return( DefMDIChildProc( hwnd, msg, wparam, lparam ) );
    }
    return( 0 );

} /* EditWindowProc */

/*
 * ResizeExtra - reset the left over rectange for an edit window
 */
BOOL CALLBACK ResizeExtra( HWND hwnd, LPARAM l )
{
    window_data         *data;
    char                class[MAX_STR];

    l = l;
    class[0] = 0;
    GetClassName( hwnd, class, sizeof( class ) );
    class[sizeof(class)-1] = 0;
    if( stricmp( EditWindowClassName, class ) ) {
        return( TRUE );
    }

    data = DATA_FROM_ID( hwnd );
    GetClientRect( hwnd, &data->extra );
    data->extra.top = WindowAuxInfo( hwnd, WIND_INFO_TEXT_LINES ) *
        FontHeight( WIN_FONT( &EditWindow ) );

    return( TRUE );

} /* ResizeExtra */

/*
 * ResetExtraRects - reset the leftover rectangle at the bottom of all
 *                   edit windows
 */
void ResetExtraRects( void )
{
    FARPROC     proc;

    if( EditContainer != HNULL ) {
        proc = MakeProcInstance( (FARPROC)ResizeExtra, InstanceHandle );
        EnumChildWindows( EditContainer, (WNDENUMPROC)proc, 0L );
        FreeProcInstance( proc );
    }

} /* ResetExtraRects */

static BOOL Fini( window *w, void *parm )
{
    w = w;
    parm = parm;
    return( TRUE );

} /* Fini */

⌨️ 快捷键说明

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