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