clipbrd.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 381 行
C
381 行
/****************************************************************************
*
* 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: Handles the interaction to the Windows clipboard.
*
****************************************************************************/
/*
Modified: By: Reason:
--------- --- -------
July 28 02 ff changed AddFcbsToClipboard():
the last \n\r is not written to the clipboard
changed GetClipboardSavebuf():
an extra \n\r is added to the buffer read from the clipboard
(this seems to be the easiest fix to a complicated crash bug,
which happens if you paste a line with exactly one \n\r at the
end copied from another application)
*/
#include "winvi.h"
#include <string.h>
#include <dos.h>
#if defined(__NT__)
#define _HUGE_
#define GET_POINTER( a, b ) (&a[b])
#define INC_POINTER( a ) (a++)
#elif defined(__WINDOWS_386__)
#define _HUGE_ __far
#define GET_POINTER( a, b ) getHugePointer( a,b )
#define INC_POINTER( a ) (a = getHugePointer( a, 1 ))
#else
#define _HUGE_ __huge
#define GET_POINTER( a, b ) (&a[b])
#define INC_POINTER( a ) (a++)
#endif
#ifdef __WINDOWS_386__
/*
* getHugePointer - given a 16-bit far pointer and an offset, return the
* far pointer
*/
void far *getHugePointer( void far *ptr, unsigned off )
{
DWORD poff;
WORD pseg;
pseg = FP_SEG( ptr );
poff = FP_OFF( ptr );
poff += off;
pseg += (poff >> 16) * 8;
poff &= 0xffff;
return( MK_FP( pseg, poff ) );
} /* getHugePointer */
#endif
/*
* openClipboardForRead - try to open the clipboard for read access
*/
static bool openClipboardForRead( void )
{
if( OpenClipboard( Root ) ) {
if( IsClipboardFormatAvailable( CF_TEXT ) ||
IsClipboardFormatAvailable( CF_OEMTEXT )) {
return( TRUE );
}
CloseClipboard();
}
return( FALSE );
} /* openClipboardForRead */
/*
* openClipboardForWrite - try to open the clipboard for read access
*/
static bool openClipboardForWrite( void )
{
if( OpenClipboard( Root ) ) {
if( EmptyClipboard() ) {
return( TRUE );
}
CloseClipboard();
}
return( FALSE );
} /* openClipboardForWrite */
/*
* AddLineToClipboard - add data on specified line to the clipboard
*/
int AddLineToClipboard( char *data, int scol, int ecol )
{
char __FAR__ *ptr;
GLOBALHANDLE hglob;
int len;
if( !openClipboardForWrite() ) {
return( ERR_CLIPBOARD );
}
/*
* get memory for line
*/
len = ecol - scol+2;
hglob = GlobalAlloc( GMEM_MOVEABLE, len );
if( hglob == NULL ) {
CloseClipboard();
return( ERR_CLIPBOARD );
}
ptr = MAKEPTR( GlobalLock( hglob ) );
if( ptr == NULL ) {
CloseClipboard();
return( ERR_CLIPBOARD );
}
/*
* copy line data and put to clipboard
*/
MEMCPY( ptr, &data[scol], len-1 );
ptr[len-1] = 0;
GlobalUnlock( hglob );
SetClipboardData( CF_TEXT, hglob );
CloseClipboard();
return( ERR_NO_ERR );
} /* AddLineToClipboard */
/*
* AddFcbsToClipboard - add all lines in a given set of fcbs to the clipboard
*/
int AddFcbsToClipboard( fcb *head, fcb *tail )
{
fcb *cfcb;
line *cline;
char _HUGE_ *ptr;
long size;
int i;
GLOBALHANDLE hglob;
BOOL crlf_left_to_write = 0;
if( !openClipboardForWrite() ) {
return( ERR_CLIPBOARD );
}
/*
* compute the number of bytes in total
*/
cfcb = head;
size = 1; // for trailing null char
while( 1 ) {
size += (long)cfcb->byte_cnt +
(long)(cfcb->end_line-cfcb->start_line + 1);
if( cfcb == tail ) {
break;
}
cfcb = cfcb->next;
}
/*
* get the memory to store this stuff
*/
hglob = GlobalAlloc( GMEM_MOVEABLE, size );
if( hglob == NULL ) {
CloseClipboard();
return( ERR_CLIPBOARD );
}
ptr = MAKEPTR( GlobalLock( hglob ) );
if( ptr == NULL ) {
CloseClipboard();
return( ERR_CLIPBOARD );
}
/*
* copy all lines into this pointer
*/
cfcb = head;
while( 1 ) {
FetchFcb( cfcb );
cline = cfcb->line_head;
while( cline != NULL ) {
// one CRLF left to write?
if (crlf_left_to_write)
{
// yes: write it
crlf_left_to_write = 0;
*ptr = CR;
INC_POINTER( ptr );
*ptr = LF;
INC_POINTER( ptr );
}
for( i=0;i<cline->len;i++ ) {
*ptr = cline->data[i];
INC_POINTER( ptr );
}
// remember to write one CRLF next time
crlf_left_to_write = 1;
cline = cline->next;
}
if( cfcb == tail ) {
break;
}
cfcb = cfcb->next;
}
// the last CRLF is omitted
*ptr = 0;
GlobalUnlock( hglob );
SetClipboardData( CF_TEXT, hglob );
CloseClipboard();
return( ERR_NO_ERR );
} /* AddFcbsToClipboard */
/*
* addAnFcb - add a new fcb and its data
*/
static int addAnFcb( fcb **head, fcb **tail, int numbytes )
{
fcb *cfcb;
int linecnt;
int used;
cfcb = FcbAlloc( NULL );
AddLLItemAtEnd( (ss**)head, (ss**)tail, (ss*)cfcb );
CreateLinesFromBuffer( numbytes, &(cfcb->line_head),
&(cfcb->line_tail), &used, &linecnt,
&(cfcb->byte_cnt) );
if( (*tail)->prev == NULL ) {
cfcb->start_line = 1;
} else {
cfcb->start_line = (*tail)->prev->end_line + 1;
}
cfcb->end_line = cfcb->start_line + linecnt-1;
return( used );
} /* addAnFcb */
/*
* GetClipboardSavebuf - gets data from the clipboard, and builds a
* temporary savebuf from it
*/
int GetClipboardSavebuf( savebuf *clip )
{
GLOBALHANDLE hglob;
char _HUGE_ *ptr;
char _HUGE_ *cpos;
fcb *head,*tail;
int i;
bool is_flushed;
bool has_lf;
bool record_done;
char ch;
int used;
if( !openClipboardForRead() ) {
return( ERR_CLIPBOARD_EMPTY );
}
hglob = GetClipboardData( CF_TEXT );
if( hglob == NULL ) {
return( ERR_CLIPBOARD );
}
ptr = MAKEPTR( GlobalLock( hglob ) );
cpos = ptr;
i = 0;
is_flushed = FALSE;
has_lf = FALSE;
head = NULL;
tail = NULL;
record_done = FALSE;
/*
* add all characters to ReadBuffer. Each time this fills,
* create a new FCB
*/
while( 1 ) {
ch = *ptr;
if( ch == 0 ) {
break;
}
INC_POINTER( ptr );
ReadBuffer[i++] = ch;
if( ch == LF ) {
has_lf = TRUE;
}
if( i >= MAX_IO_BUFFER ) {
is_flushed = TRUE;
used = addAnFcb( &head, &tail, i );
ptr = GET_POINTER( cpos, used );
cpos = ptr;
i = 0;
}
}
/*
* after we are done, see if any characters are left unprocessed
*/
if( i != 0 ) {
/*
* check if this is a partial line
*/
if( !is_flushed && !has_lf ) {
clip->type = SAVEBUF_LINE;
ReadBuffer[i] = 0;
clip->first.data = MemAlloc( i+1 );
strcpy( clip->first.data, ReadBuffer );
record_done = TRUE;
} else {
// add CRLF to end of buffer
if( i >= MAX_IO_BUFFER - 2 )
{
addAnFcb( &head, &tail, i );
i = 0;
}
ReadBuffer[i++] = CR;
ReadBuffer[i++] = LF;
addAnFcb( &head, &tail, i );
}
} else if( !is_flushed ) {
clip->type = SAVEBUF_NOP;
record_done = TRUE;
}
if( !record_done ) {
clip->type = SAVEBUF_FCBS;
clip->first.fcb_head = head;
clip->fcb_tail = tail;
}
GlobalUnlock( hglob );
CloseClipboard();
return( ERR_NO_ERR );
} /* GetClipboardSavebuf */
/*
* IsClipboardEmpty - check if the clipboard is empty or not
*/
bool IsClipboardEmpty( void )
{
if( !openClipboardForRead() ) {
return( TRUE );
}
CloseClipboard();
return( FALSE );
} /* IsClipboardEmpty */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?