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