📄 wricon.c
字号:
/****************************************************************************
*
* 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: Resource editor icon/cursor manipulation.
*
****************************************************************************/
#include <windows.h>
#include <string.h>
#include <limits.h>
#include "wrdll.h"
#include "wrinfo.h"
#include "wrmem.h"
#include "wrdata.h"
#include "bitmap.h"
#include "wricon.h"
/****************************************************************************/
/* macro definitions */
/****************************************************************************/
#define DEF_MEMFLAGS ( MEMFLAG_MOVEABLE | MEMFLAG_PURE )
/****************************************************************************/
/* external function prototypes */
/****************************************************************************/
/****************************************************************************/
/* static function prototypes */
/****************************************************************************/
/****************************************************************************/
/* type definitions */
/****************************************************************************/
/****************************************************************************/
/* static variables */
/****************************************************************************/
uint_32 WR_EXPORT WRSizeOfImage( BITMAPINFOHEADER *bih )
{
uint_32 size;
size = (uint_32)(DIB_INFO_SIZE( bih->biBitCount ) + bih->biSizeImage);
return( size );
}
// This function assumes that the data represents icon data WITHOUT
// an icon directory
WORD WR_EXPORT WRCountIconImages( BYTE *data, uint_32 size )
{
BITMAPINFOHEADER *bih;
WORD count;
uint_32 pos;
pos = 0;
count = 0;
while( pos < size ) {
bih = (BITMAPINFOHEADER *)( data + pos );
count++;
pos += WRSizeOfImage( bih );
// if we overrun do not count this block
if( pos > size ) {
count--;
}
}
return( count );
}
int WR_EXPORT WRCreateIconHeader( BYTE *data, uint_32 size, WORD type,
ICONHEADER **ih, uint_32 *ihsize )
{
BITMAPINFOHEADER *bih;
WORD count;
uint_32 pos;
int i;
if( !data || !size || !ih || !ihsize ) {
return( FALSE );
}
count = WRCountIconImages( data, size );
if( count == 0 ) {
return( FALSE );
}
*ihsize = sizeof(ICONHEADER) + sizeof(ICONDIRENTRY)*(count-1);
*ih = WRMemAlloc( *ihsize );
if( *ih == NULL ) {
return( FALSE );
}
(*ih)->idReserved = 0;
(*ih)->idType = type;
(*ih)->idCount = count;
for( i=0,pos=0; i<count; i++ ) {
bih = (BITMAPINFOHEADER *)( data + pos );
(*ih)->idEntries[i].bWidth = bih->biWidth;
(*ih)->idEntries[i].bHeight = bih->biHeight/2;
if( type == 1 ) {
(*ih)->idEntries[i].bColorCount= (1<<(bih->biBitCount));
} else {
(*ih)->idEntries[i].bColorCount= 0;
}
(*ih)->idEntries[i].bReserved = 0;
(*ih)->idEntries[i].wPlanes = bih->biPlanes;
(*ih)->idEntries[i].wBitCount = bih->biBitCount;
(*ih)->idEntries[i].dwBytesInRes= WRSizeOfImage( bih );
if( i == 0 ) {
(*ih)->idEntries[i].dwImageOffset = *ihsize;
} else {
(*ih)->idEntries[i].dwImageOffset =
(*ih)->idEntries[i-1].dwImageOffset +
(*ih)->idEntries[i-1].dwBytesInRes;
}
pos += (*ih)->idEntries[i].dwBytesInRes;
}
return( TRUE );
}
int WR_EXPORT WRCreateCursorResHeader( RESCURSORHEADER **rch,
uint_32 *rchsize, BYTE *data,
uint_32 data_size )
{
CURSORHEADER *ch;
uint_32 chsize;
ICONHEADER *ih;
uint_32 ihsize;
int i;
int ok;
ih = NULL;
ok = ( rch && rchsize && data && data_size );
if( ok ) {
*rch = NULL;
*rchsize = 0;
ch = (CURSORHEADER *) data;
chsize = sizeof(CURSORHEADER);
chsize += sizeof(CURSORDIRENTRY)*(ch->cdCount-1);
ok = WRCreateIconHeader( data + chsize, data_size - chsize, 2,
&ih, &ihsize );
}
if( ok ) {
*rchsize = sizeof(RESCURSORHEADER);
*rchsize += sizeof(RESCURSORDIRENTRY)*(ih->idCount-1);
*rch = (RESCURSORHEADER *)WRMemAlloc( *rchsize );
ok = ( *rch != NULL );
}
if( ok ) {
memcpy( *rch, ch, sizeof(WORD)*3 );
for( i=0; i<ih->idCount ; i++ ) {
(*rch)->cdEntries[i].bWidth = ih->idEntries[i].bWidth;
(*rch)->cdEntries[i].bHeight = ih->idEntries[i].bHeight*2;
(*rch)->cdEntries[i].wPlanes = ih->idEntries[i].wPlanes;
(*rch)->cdEntries[i].wBitCount = ih->idEntries[i].wBitCount;
(*rch)->cdEntries[i].lBytesInRes = ih->idEntries[i].dwBytesInRes;
(*rch)->cdEntries[i].wNameOrdinal = i + 1;
}
}
if( ih != NULL ) {
WRMemFree( ih );
}
return( ok );
}
int WR_EXPORT WRCreateIconResHeader( RESICONHEADER **rih, uint_32 *rihsize,
BYTE *data, uint_32 data_size )
{
ICONHEADER *pih;
uint_32 pihsize;
ICONHEADER *ih;
uint_32 ihsize;
int i;
int ok;
ih = NULL;
ok = ( rih && rihsize && data && data_size );
if( ok ) {
pih = (ICONHEADER *) data;
pihsize = sizeof(ICONHEADER);
pihsize += sizeof(ICONDIRENTRY)*(pih->idCount-1);
ok = WRCreateIconHeader( data + pihsize, data_size - pihsize, 1,
&ih, &ihsize );
}
if( ok ) {
*rihsize = sizeof(RESICONHEADER);
*rihsize += sizeof(RESICONDIRENTRY)*(ih->idCount-1);
*rih = (RESICONHEADER *)WRMemAlloc( *rihsize );
ok = ( *rih != NULL );
}
if( ok ) {
memcpy( *rih, pih, sizeof(WORD)*3 );
for( i=0; i<ih->idCount ; i++ ) {
(*rih)->idEntries[i].bWidth = ih->idEntries[i].bWidth;
(*rih)->idEntries[i].bHeight = ih->idEntries[i].bHeight;
(*rih)->idEntries[i].bColorCount = ih->idEntries[i].bColorCount;
(*rih)->idEntries[i].bReserved = 0;
(*rih)->idEntries[i].wPlanes = ih->idEntries[i].wPlanes;
(*rih)->idEntries[i].wBitCount = ih->idEntries[i].wBitCount;
(*rih)->idEntries[i].lBytesInRes = ih->idEntries[i].dwBytesInRes;
(*rih)->idEntries[i].wNameOrdinal = i + 1;
}
}
if( ih != NULL ) {
WRMemFree( ih );
}
return( ok );
}
int WR_EXPORT WRAddCursorHotspot( BYTE **cursor, uint_32 *size,
CURSORHOTSPOT *hs )
{
int hs_size;
hs_size = sizeof(CURSORHOTSPOT);
if( !cursor || !size ) {
return( FALSE );
}
*cursor = WRMemRealloc( *cursor, *size + hs_size );
if( *cursor == NULL ) {
return( FALSE );
}
memmove( *cursor + hs_size, *cursor, *size );
memcpy( *cursor, hs, hs_size );
*size += hs_size;
return( TRUE );
}
int WR_EXPORT WRGetAndAddCursorImage( BYTE *data, WResDir dir,
CURSORDIRENTRY *cd, int ord )
{
BYTE *cursor;
int dup;
uint_32 size;
WResID *tname;
WResID *rname;
WResLangType lang;
CURSORHOTSPOT hotspot;
int ok;
dup = FALSE;
lang.lang = DEF_LANG;
lang.sublang = DEF_SUBLANG;
tname = NULL;
rname = NULL;
ok = ( data && dir && cd && cd->dwBytesInRes );
if ( ok ) {
cursor = (BYTE *)WRMemAlloc( cd->dwBytesInRes );
ok = ( cursor != NULL );
}
if( ok ) {
memcpy( cursor, data + cd->dwImageOffset, cd->dwBytesInRes );
hotspot.xHotspot = cd->wXHotspot;
hotspot.yHotspot = cd->wYHotspot;
size = cd->dwBytesInRes;
ok = WRAddCursorHotspot( &cursor, &size, &hotspot );
}
if( ok ) {
tname = WResIDFromNum( (uint_16)RT_CURSOR );
ok = ( tname != NULL );
}
if( ok ) {
rname = WResIDFromNum( ord );
ok = ( rname != NULL );
}
if( ok ) {
ok = !WResAddResource( tname, rname, DEF_MEMFLAGS, 0,
size, dir, &lang, &dup );
}
if( ok ) {
ok = WRFindAndSetData( dir, tname, rname, &lang, cursor );
}
if( !ok ) {
if( cursor != NULL ) {
WRMemFree( cursor );
}
}
if( tname != NULL ) {
WRMemFree( tname );
}
if( rname != NULL ) {
WRMemFree( rname );
}
return( ok );
}
int WR_EXPORT WRGetAndAddIconImage( BYTE *data, WResDir dir,
ICONDIRENTRY *id, int ord )
{
BYTE *icon;
int dup;
WResID *tname;
WResID *rname;
WResLangType lang;
int ok;
dup = FALSE;
lang.lang = DEF_LANG;
lang.sublang = DEF_SUBLANG;
tname = NULL;
rname = NULL;
ok = ( data && dir && id && id->dwBytesInRes );
if ( ok ) {
icon = (BYTE *)WRMemAlloc( id->dwBytesInRes );
ok = ( icon != NULL );
}
if( ok ) {
memcpy( icon, data + id->dwImageOffset, id->dwBytesInRes );
tname = WResIDFromNum( (uint_16)RT_ICON );
ok = ( tname != NULL );
}
if( ok ) {
rname = WResIDFromNum( ord );
ok = ( rname != NULL );
}
if ( ok ) {
ok = !WResAddResource( tname, rname, DEF_MEMFLAGS, 0,
id->dwBytesInRes, dir, &lang, &dup );
}
if( ok ) {
ok = WRFindAndSetData( dir, tname, rname, &lang, icon );
}
if( !ok ) {
if( icon != NULL ) {
WRMemFree( icon );
}
}
if( tname != NULL ) {
WRMemFree( tname );
}
if( rname != NULL ) {
WRMemFree( rname );
}
return( ok );
}
int WR_EXPORT WRFindImageId( WRInfo *info, WResTypeNode **otnode,
WResResNode **ornode, WResLangNode **lnode,
uint_16 type, uint_16 id,
WResLangType *ltype )
{
WResTypeNode *tnode;
WResResNode *rnode;
WResLangType lang;
int ok;
ok = ( info && lnode && ( ( type == (uint_16)RT_ICON ) ||
( type == (uint_16)RT_CURSOR ) ) );
if( ok ) {
tnode = WRFindTypeNode( info->dir, type, NULL );
ok = ( tnode != NULL );
}
if( ok ) {
if( otnode != NULL ) {
*otnode = tnode;
}
rnode = WRFindResNode( tnode, id, NULL );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -