/* * User Interface Functions * * Copyright 1997 Dimitrie O. Paun */ #include #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; }