391 lines
12 KiB
C
391 lines
12 KiB
C
/*
|
|
* User Interface Functions
|
|
*
|
|
* Copyright 1997 Dimitrie O. Paun
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include "windows.h"
|
|
#include "debug.h"
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawDiagEdge
|
|
*
|
|
* Same as DrawEdge, but with BF_DIAGONAL
|
|
* I tested it extensively and as far as I can tell it is identical to the
|
|
* implementaion in Win95.
|
|
* I do not like that I create and
|
|
* use the 3 Pens to draw the diagonals. It would be better to draw them
|
|
* using the brushes returned by GetSysColorBrush func, but I did not have
|
|
* the patience to implement that yet.
|
|
*/
|
|
static BOOL32 UITOOLS_DrawDiagEdge(HDC32 hdc, RECT32 *rect, UINT32 edge,
|
|
UINT32 flags)
|
|
{
|
|
HPEN32 facePen, shadowPen, lightPen, blackPen, grayPen, nullPen;
|
|
HPEN32 iPen, oPen, oldPen;
|
|
HBRUSH32 oldBrush, faceBrush;
|
|
int cl, cr, ct, cb;
|
|
BOOL32 mainDiag;
|
|
POINT32 tp;
|
|
RECT32 r;
|
|
|
|
/* If both rasied and sunken is specified, they anihilate one another */
|
|
if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
|
|
if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
|
|
return FALSE;
|
|
if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
|
|
return FALSE;
|
|
}
|
|
|
|
/* Create/get the tools of the trade... */
|
|
facePen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNFACE));
|
|
shadowPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNSHADOW));
|
|
lightPen = CreatePen32(PS_SOLID, 0, GetSysColor32(COLOR_BTNHILIGHT));
|
|
grayPen = CreatePen32(PS_SOLID, 0, RGB(168, 152, 144));
|
|
blackPen = GetStockObject32(BLACK_PEN);
|
|
nullPen = GetStockObject32(NULL_PEN);
|
|
faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
|
|
oldPen = SelectObject32(hdc, nullPen);
|
|
oldBrush = SelectObject32(hdc, faceBrush);
|
|
|
|
/* this is my working rectangle */
|
|
r = *rect;
|
|
|
|
if(flags & BF_MONO){
|
|
oPen = blackPen;
|
|
iPen = nullPen;
|
|
}else if(flags & BF_FLAT){
|
|
oPen = shadowPen;
|
|
iPen = facePen;
|
|
}else {
|
|
if(flags & BF_SOFT){
|
|
if(flags & BF_BOTTOM){
|
|
oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
|
|
iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
|
|
}
|
|
else{
|
|
oPen = (edge & BDR_RAISEDOUTER) ? lightPen : blackPen;
|
|
iPen = (edge & BDR_RAISEDINNER) ? grayPen : shadowPen;
|
|
}
|
|
}
|
|
else{
|
|
if(flags & BF_BOTTOM){
|
|
oPen = (edge & BDR_RAISEDOUTER) ? blackPen : lightPen;
|
|
iPen = (edge & BDR_RAISEDINNER) ? shadowPen : grayPen;
|
|
}
|
|
else{
|
|
oPen = (edge & BDR_RAISEDOUTER) ? grayPen : shadowPen;
|
|
iPen = (edge & BDR_RAISEDINNER) ? lightPen : blackPen;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(flags & BF_BOTTOM){
|
|
if(flags & BF_LEFT){
|
|
cr = -1; cl = 0;
|
|
ct = 0; cb = -1;
|
|
mainDiag = TRUE;
|
|
tp.x = r.left; tp.y = r.top;
|
|
}
|
|
else{ /* RIGHT */
|
|
cr = -1; cl = 0;
|
|
ct = 1; cb = 0;
|
|
tp.x = r.left; tp.y = r.bottom-1;
|
|
mainDiag = FALSE;
|
|
}
|
|
}
|
|
else{ /* TOP */
|
|
if(flags & BF_LEFT){
|
|
cr = 0; cl = 1;
|
|
ct = 0; cb = -1;
|
|
mainDiag = FALSE;
|
|
tp.x = r.right; tp.y = r.top;
|
|
}
|
|
else{ /* RIGHT */
|
|
cr = 0; cl = 1;
|
|
ct = 1; cb = 0;
|
|
tp.x = r.right; tp.y = r.bottom-1;
|
|
mainDiag = TRUE;
|
|
}
|
|
}
|
|
|
|
/* if it has external edge, draw it */
|
|
if(edge & BDR_OUTER){
|
|
SelectObject32(hdc, oPen);
|
|
MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
|
|
LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
|
|
r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
|
|
}
|
|
|
|
/* if it has internal edge, draw it */
|
|
if(edge & BDR_INNER){
|
|
SelectObject32(hdc, iPen);
|
|
MoveToEx32(hdc, r.left, mainDiag ? r.bottom-1 : r.top, 0);
|
|
LineTo32(hdc, r.right, mainDiag ? r.top-1 : r.bottom);
|
|
r.left += cl; r.right += cr; r.top += ct; r.bottom += cb;
|
|
}
|
|
|
|
if((flags & BF_MIDDLE) && !(flags & BF_MONO)){
|
|
POINT32 p[3];
|
|
p[0].x = mainDiag ? r.right: r.left;
|
|
p[0].y = r.top;
|
|
p[1].x = mainDiag ? r.left : r.right;
|
|
p[1].y = r.bottom;
|
|
p[2].x = tp.x;
|
|
p[2].y = tp.y;
|
|
SelectObject32(hdc, nullPen);
|
|
SelectObject32(hdc, faceBrush);
|
|
Polygon32(hdc, p, 3);
|
|
}
|
|
|
|
if(flags & BF_ADJUST)
|
|
*rect = r;
|
|
|
|
/* Restore the DC */
|
|
SelectObject32(hdc, oldPen);
|
|
SelectObject32(hdc, oldBrush);
|
|
|
|
/* Clean-up */
|
|
DeleteObject32(facePen);
|
|
DeleteObject32(shadowPen);
|
|
DeleteObject32(lightPen);
|
|
DeleteObject32(grayPen);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawRectEdge
|
|
*
|
|
* Same as DrawEdge, but without BF_DIAGONAL
|
|
* I tested this function and it works very well. You should not change it
|
|
* unless you find a bug. If you don't like the colors, it it not its
|
|
* fault - the system colors are not OK.
|
|
* Again, I tested this function on Win95 and I compared the output with the
|
|
* one generated by the native DrawEdge and it is identical on all cases that
|
|
* I tried, and I tried quite a few.
|
|
*/
|
|
static BOOL32 UITOOLS_DrawRectEdge(HDC32 hdc, RECT32 *rect,
|
|
UINT32 edge, UINT32 flags)
|
|
{
|
|
HBRUSH32 faceBrush, shadowBrush, lightBrush, blackBrush, grayBrush, nullBrush;
|
|
HBRUSH32 iNBrush, iSBrush, iEBrush, iWBrush;
|
|
HBRUSH32 oNBrush, oSBrush, oEBrush, oWBrush;
|
|
HBRUSH32 oldBrush;
|
|
RECT32 r;
|
|
|
|
/* If both rasied and sunken is specified, they anihilate one another */
|
|
if( !((flags & BF_MONO) || (flags & BF_FLAT)) ){
|
|
if( (edge & BDR_RAISEDOUTER) && (edge & BDR_SUNKENOUTER) )
|
|
return FALSE;
|
|
if( (edge & BDR_RAISEDINNER) && (edge & BDR_SUNKENINNER) )
|
|
return FALSE;
|
|
}
|
|
|
|
faceBrush = GetSysColorBrush32(COLOR_BTNFACE);
|
|
shadowBrush = GetSysColorBrush32(COLOR_BTNSHADOW);
|
|
lightBrush = GetSysColorBrush32(COLOR_BTNHILIGHT);
|
|
blackBrush = GetStockObject32(BLACK_BRUSH);
|
|
grayBrush = GetStockObject32(LTGRAY_BRUSH);
|
|
nullBrush = GetStockObject32(NULL_BRUSH);
|
|
oldBrush = SelectObject32(hdc, nullBrush);
|
|
|
|
/* this is my working rectangle */
|
|
r = *rect;
|
|
|
|
if(flags & BF_MONO){
|
|
oNBrush = oSBrush = oEBrush = oWBrush = blackBrush;
|
|
iNBrush = iSBrush = iEBrush = iWBrush = nullBrush;
|
|
}else if(flags & BF_FLAT){
|
|
oNBrush = oSBrush = oEBrush = oWBrush = shadowBrush;
|
|
iNBrush = iSBrush = iEBrush = iWBrush = faceBrush;
|
|
}else {
|
|
if(flags & BF_SOFT){
|
|
oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? lightBrush : blackBrush;
|
|
oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
|
|
iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? grayBrush : shadowBrush;
|
|
iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
|
|
}
|
|
else{
|
|
oNBrush = oWBrush = (edge & BDR_RAISEDOUTER) ? grayBrush : shadowBrush;
|
|
oSBrush = oEBrush = (edge & BDR_RAISEDOUTER) ? blackBrush : lightBrush;
|
|
iNBrush = iWBrush = (edge & BDR_RAISEDINNER) ? lightBrush : blackBrush;
|
|
iSBrush = iEBrush = (edge & BDR_RAISEDINNER) ? shadowBrush : grayBrush;
|
|
}
|
|
}
|
|
|
|
/* if it has external edge, draw it */
|
|
if(edge & BDR_OUTER){
|
|
if(flags & BF_RIGHT){
|
|
SelectObject32(hdc, oEBrush);
|
|
PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
|
|
r.right--;
|
|
}
|
|
if(flags & BF_BOTTOM){
|
|
SelectObject32(hdc, oSBrush);
|
|
PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
|
|
r.bottom--;
|
|
}
|
|
if(flags & BF_LEFT){
|
|
SelectObject32(hdc, oWBrush);
|
|
PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
|
|
r.left++;
|
|
}
|
|
if(flags & BF_TOP){
|
|
SelectObject32(hdc, oNBrush);
|
|
PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
|
|
r.top++;
|
|
}
|
|
}
|
|
|
|
/* if it has internal edge, draw it */
|
|
if(edge & BDR_INNER){
|
|
if(flags & BF_RIGHT){
|
|
SelectObject32(hdc, iEBrush);
|
|
PatBlt32(hdc, r.right-1, r.top, 1, r.bottom - r.top, PATCOPY);
|
|
r.right--;
|
|
}
|
|
if(flags & BF_BOTTOM){
|
|
SelectObject32(hdc, iSBrush);
|
|
PatBlt32(hdc, r.left, r.bottom-1, r.right-r.left, 1, PATCOPY);
|
|
r.bottom--;
|
|
}
|
|
if(flags & BF_LEFT){
|
|
SelectObject32(hdc, iWBrush);
|
|
PatBlt32(hdc, r.left, r.top, 1, r.bottom - r.top, PATCOPY);
|
|
r.left++;
|
|
}
|
|
if(flags & BF_TOP){
|
|
SelectObject32(hdc, iNBrush);
|
|
PatBlt32(hdc, r.left, r.top, r.right-r.left, 1, PATCOPY);
|
|
r.top++;
|
|
}
|
|
}
|
|
|
|
/* if we got to fill the middle, to it now */
|
|
if((flags & BF_MIDDLE) && !(flags & BF_MONO))
|
|
FillRect32(hdc, &r, faceBrush);
|
|
|
|
/* adjust the rectangle if required */
|
|
if(flags & BF_ADJUST)
|
|
*rect = r;
|
|
|
|
/* Restore the DC */
|
|
SelectObject32(hdc, oldBrush);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DrawEdge16 (USER.659)
|
|
*/
|
|
BOOL16 WINAPI DrawEdge16( HDC16 hdc, LPRECT16 rc, UINT16 edge, UINT16 flags )
|
|
{
|
|
RECT32 rect32;
|
|
BOOL32 ret;
|
|
|
|
CONV_RECT16TO32( rc, &rect32 );
|
|
ret = DrawEdge32( hdc, &rect32, edge, flags );
|
|
CONV_RECT32TO16( &rect32, rc );
|
|
return ret;
|
|
}
|
|
|
|
/**********************************************************************
|
|
* DrawEdge32 (USER32.154)
|
|
*/
|
|
BOOL32 WINAPI DrawEdge32( HDC32 hdc, LPRECT32 rc, UINT32 edge, UINT32 flags )
|
|
{
|
|
dprintf_graphics( stddeb, "DrawEdge: %04x %d,%d-%d,%d %04x %04x\n",
|
|
hdc, rc->left, rc->top, rc->right, rc->bottom,
|
|
edge, flags );
|
|
|
|
if(flags & BF_DIAGONAL)
|
|
return UITOOLS_DrawDiagEdge(hdc, rc, edge, flags);
|
|
else
|
|
return UITOOLS_DrawRectEdge(hdc, rc, edge, flags);
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawFrameButton
|
|
*/
|
|
static BOOL32 UITOOLS_DrawFrameButton(HDC32 hdc, LPRECT32 rc, UINT32 uState)
|
|
{
|
|
fprintf( stdnimp,"DrawFrameButton(%x,%p,%x), empty stub!\n",
|
|
hdc,rc,uState );
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawFrameCaption
|
|
*/
|
|
static BOOL32 UITOOLS_DrawFrameCaption(HDC32 hdc, LPRECT32 rc, UINT32 uState)
|
|
{
|
|
fprintf( stdnimp,"DrawFrameCaption(%x,%p,%x), empty stub!\n",
|
|
hdc,rc,uState );
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawFrameMenu
|
|
*/
|
|
static BOOL32 UITOOLS_DrawFrameMenu(HDC32 hdc, LPRECT32 rc, UINT32 uState)
|
|
{
|
|
fprintf( stdnimp,"DrawFrameMenu32(%x,%p,%x), empty stub!\n",
|
|
hdc,rc,uState );
|
|
return FALSE;
|
|
}
|
|
|
|
/***********************************************************************
|
|
* UITOOLS_DrawFrameScroll
|
|
*/
|
|
static BOOL32 UITOOLS_DrawFrameScroll(HDC32 hdc, LPRECT32 rc, UINT32 uState)
|
|
{
|
|
fprintf( stdnimp,"DrawFrameScroll32(%x,%p,%x), empty stub!\n",
|
|
hdc,rc,uState );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DrawFrameControl16 (USER.656)
|
|
*/
|
|
BOOL16 WINAPI DrawFrameControl16( HDC16 hdc, LPRECT16 rc, UINT16 uType,
|
|
UINT16 uState )
|
|
{
|
|
RECT32 rect32;
|
|
BOOL32 ret;
|
|
|
|
CONV_RECT16TO32( rc, &rect32 );
|
|
ret = DrawFrameControl32( hdc, &rect32, uType, uState );
|
|
CONV_RECT32TO16( &rect32, rc );
|
|
return ret;
|
|
}
|
|
|
|
|
|
/**********************************************************************
|
|
* DrawFrameControl32 (USER32.157)
|
|
*/
|
|
BOOL32 WINAPI DrawFrameControl32( HDC32 hdc, LPRECT32 rc, UINT32 uType,
|
|
UINT32 uState )
|
|
{
|
|
switch(uType)
|
|
{
|
|
case DFC_BUTTON:
|
|
return UITOOLS_DrawFrameButton(hdc, rc, uState);
|
|
case DFC_CAPTION:
|
|
return UITOOLS_DrawFrameCaption(hdc, rc, uState);
|
|
case DFC_MENU:
|
|
return UITOOLS_DrawFrameMenu(hdc, rc, uState);
|
|
case DFC_SCROLL:
|
|
return UITOOLS_DrawFrameScroll(hdc, rc, uState);
|
|
default:
|
|
fprintf( stdnimp,"DrawFrameControl32(%x,%p,%d,%x), bad type!\n",
|
|
hdc,rc,uType,uState );
|
|
}
|
|
return FALSE;
|
|
}
|