| /* |
| * 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; |
| } |