blob: b245ebc810cdd1fe3c5062ba3d64cf1767f1b056 [file] [log] [blame]
/*
* 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;
}