utils.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 807 行 · 第 1/2 页
C
807 行
/****************************************************************************
*
* 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 <dos.h>
#include <assert.h>
#include <ctype.h>
#include "winvi.h"
#include "color.h"
#include "font.h"
#include "utils.h"
#include "banner.h"
#include "aboutdlg.h"
#include "win.h"
/*
* WriteText - write a length specified string to a window
*/
void WriteText( HWND hwnd, int x, int y, type_style *style, char * text, int len )
{
HDC hdc;
#ifdef __WINDOWS_386__
short tab;
#else
int tab;
#endif
if( len > 0 ){
hdc = TextGetDC( hwnd, style );
tab = FontTabWidth( style->font );
TabbedTextOut( hdc, x, y, text, len, 1, &tab, 0 );
TextReleaseDC( hwnd, hdc );
}
} /* WriteText */
/*
* WriteString - write a null delimited string to a window
*/
void WriteString( HWND hwnd, int x, int y, type_style *style, char *text )
{
WriteText( hwnd, x, y, style, text, strlen( text ) );
} /* WriteString */
/*
* TextGetDC - get the DC for a window, and set its properties
*/
HDC TextGetDC( HWND hwnd, type_style *style )
{
HDC hdc;
hdc = GetDC( hwnd );
SaveDC( hdc );
SelectObject( hdc, FontHandle( style->font ) );
// SelectObject( hdc, ColorPen( style->foreground ) );
// SelectObject( hdc, ColorBrush( style->background ) );
SetTextColor( hdc, ColorRGB( style->foreground ) );
SetBkColor( hdc, ColorRGB( style->background ) );
return( hdc );
} /* GetTextDC */
/*
* TextReleaseDC - release the dc for a window
*/
void TextReleaseDC( HWND hwnd, HDC hdc )
{
RestoreDC( hdc, -1 );
ReleaseDC( hwnd, hdc );
} /* TextReleaseDC */
/*
* BlankRectIndirect - blank out a rectangle given a pointer to the rectangle
*/
void BlankRectIndirect( HWND hwnd, UINT color, RECT *rect )
{
HDC hdc;
hdc = GetDC( hwnd );
FillRect( hdc, rect, ColorBrush( color ) );
ReleaseDC( hwnd, hdc );
} /* BlankRectIndirect */
/*
* BlankRect - blank out a rectangle given its coordinates
*/
void BlankRect( HWND hwnd, UINT color, int x1, int x2, int y1, int y2 )
{
RECT rect;
rect.left = x1;
rect.right = x2;
rect.top = y1;
rect.bottom = y2;
BlankRectIndirect( hwnd, color, &rect );
} /* BlankRect */
/*
* MyTextExtent - get the text extend of a string in a specified style
*/
int MyTextExtent( HWND hwnd, type_style *style, char *text, unsigned length )
{
HDC hdc;
int extent;
unsigned text_len, extra;
int font_width;
#ifdef __WINDOWS_386__
short tab;
#else
int tab;
#endif
hdc = TextGetDC( hwnd, style );
font_width = FontAverageWidth( style->font );
tab = FontTabWidth( style->font );
text_len = strlen( text );
extra = 0;
if( length > text_len ) {
extra = length - text_len - 1;
length = text_len;
}
extent = LOWORD( GetTabbedTextExtent( hdc, text, length, 1, &tab ) );
extent += extra * font_width;
TextReleaseDC( hwnd, hdc );
return( extent );
} /* MyTextExtent */
int MyStringExtent( HWND hwnd, type_style *style, char *text )
{
return( MyTextExtent( hwnd, style, text, strlen( text ) ) );
}
/*
* ClientToRowCol - Given an (x,y) in client coords inside an *EDIT* window,
* fill in the row and col with the correct values (base 1).
*/
void ClientToRowCol( HWND hwnd, int x, int y, int *row, int *col, int divide )
{
window *w;
dc dc_line;
ss_block *ss, *ss_start, *ss_prev;
int startCols, intoCols;
int startPixel, lenBlock;
int intoExtent, difExtent;
int toleftExtent;
int avg_width;
char *str;
w = WINDOW_FROM_ID( hwnd );
*row = y / FontHeight( WIN_FONT( w ) ) + 1;
if( x < 0 ) {
*col = 1;
return;
}
if( *row < 1 || *row > CurrentInfo->dc_size ) {
*col = 0;
return;
}
// get line data
dc_line = DCFindLine( ( *row ) - 1, hwnd );
if( dc_line->display != 0 ){
// line needs to be displayed
// therefore ss information has not been set!
// therefore we cant use it to calculate anything of value!
// best we can do is a good solid guess.
avg_width = FontAverageWidth( WIN_FONT( w ) );
*col = x/avg_width + 1;
return;
}
assert( dc_line->valid );
if( dc_line->start_col < LeftColumn ) {
// entire line has been scrolled off to left - go to end of that line
*col = 10000;
return;
}
assert( dc_line->start_col == LeftColumn );
ss_start = ss = dc_line->ss;
// find which block x lies on
while( ss->offset < x ) {
// this could be the problem ?
// will ss->offset always be valid
// if not, this goes right off the end of the valid blocks
ss++;
}
// Not needed anymore now we have slayed the dragon
#if 0
if( (ss->type < 0) ||
(ss ->type >= SE_NUMTYPES) ||
(ss->end > BEYOND_TEXT ) ||
(ss->len > BEYOND_TEXT )
){
assert( 0 );
}
#endif
// grab info about this block
if( ss != ss_start ) {
ss_prev = ss - 1;
startPixel = ss_prev->offset;
startCols = ss_prev->end + 1;
lenBlock = ss->end - ss_prev->end;
str = dc_line->text + startCols;
} else {
startPixel = 0;
startCols = 0;
str = dc_line->text;
lenBlock = ss->end + 1;
}
// lenBlock must be less than the length of the text
// and greater than zero
if( ss->end >= BEYOND_TEXT ) {
lenBlock = strlen( str );
}
lenBlock = max( lenBlock, 0 );
// avg_width must be greater than 0 (this probablly isn't needed but ...)
avg_width = max( FontAverageWidth( SEType[ ss->type ].font ), 1 );
if( EditFlags.RealTabs ){
char *start_str, *end_str;
int cur_pixel;
linenum line_num = (linenum)(TopOfPage + *row - 1);
line *line;
fcb *fcb;
int i,v_pos;
i = CGimmeLinePtr( line_num, &fcb, &line );
if( i == ERR_NO_ERR ) {
char *text = line->data;
// get the tab boundries in this block
#if 0
v_pos = WinVirtualCursorPosition( text, startCols );
if( v_pos < LeftColumn ){
// block begins off left edge, advance forward to leftColumn
int rp = WinRealCursorPosition( text, LeftColumn );
start_str = text + rp;
v_pos = LeftColumn;
startPixel = 0;
lenBlock -=( rp - startCols );
}
#else
if( LeftColumn > 1 ){
// this only works for fixed fonts but its better than
// being wrong in every case; It's also correct
// immediately after every tab stop. And it should be
// at least close everywhere else :(
*col = x/avg_width + 1;
return;
}
#endif
end_str = start_str = text + startCols;
while( end_str != start_str + lenBlock ){
if( *end_str == '\t' ){
cur_pixel = ( WinVirtualCursorPosition( text, end_str+1-text )
-LeftColumn )*avg_width;
if( cur_pixel > x ) {
// we've found the new boundries for the block.
// that do not contain any tabs!
break;
}
start_str = end_str + 1;
startPixel = cur_pixel;
}
end_str++;
}
// startCols are virtual# columns before the block
v_pos = WinVirtualCursorPosition( text, start_str - text + 1 ) - 1;
if(start_str == text+startCols ) {
if( startCols != v_pos ){
startCols = v_pos - LeftColumn;
}
} else {
startCols = v_pos - LeftColumn;
}
lenBlock = end_str - start_str;
str = start_str;
} /* else use the previous values */
}
// guess how far we are into block
x -= startPixel;
intoCols = x / avg_width;
if( intoCols > lenBlock ) {
intoCols = lenBlock;
}
// refine guess
intoExtent = MyTextExtent( hwnd, &SEType[ss->type], str, intoCols );
if( intoExtent > x ) {
while( intoExtent > x ) {
intoCols--;
difExtent = intoExtent - MyTextExtent( hwnd, &SEType[ss->type], str, intoCols );
intoExtent -= difExtent;
}
intoCols++;
toleftExtent = intoExtent;
} else {
while( intoExtent <= x ) {
intoCols++;
toleftExtent = intoExtent;
difExtent = MyTextExtent( hwnd, &SEType[ss->type], str, intoCols ) - intoExtent;
intoExtent += difExtent;
}
}
// fine-tune if have | cursor
if( divide == DIVIDE_MIDDLE ) {
if( ( x - toleftExtent ) > ( difExtent / 2 ) ) {
intoCols++;
}
}
*col = startCols + intoCols;
} /* ClientToRowCol */
/*
* ToggleHourglass - turn the hourglass cursor on/off
*/
void ToggleHourglass( bool on )
{
static int isOn;
static HCURSOR lastCursor;
static HCURSOR waitCursor;
if( !on ) {
isOn--;
if( isOn == 0 ) {
SetCursor( lastCursor );
}
} else {
if( waitCursor == NULL ) {
waitCursor = LoadCursor( (HANDLE) NULL, IDC_WAIT );
}
lastCursor = SetCursor( waitCursor );
isOn++;
}
} /* ToggleHourglass */
long MemSize( void )
{
#ifndef __NT__
return( GlobalCompact( 0 ) );
#else
return( 0 );
#endif
}
char *GadgetString;
void SetGadgetString( char *str )
{
AddString2( &GadgetString, str );
}
#ifdef __AXP__
extern void delay(unsigned int __milliseconds);
#endif
void MyDelay( int ms )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?