1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Win32k subsystem 4 * PURPOSE: Win32ss internal drawing support. 5 * FILE: win32ss/user/ntuser/draw.c 6 * PROGRAMER: 7 */ 8 9 // 10 // Original code from Wine see user32/windows/draw.c. 11 // 12 // 13 14 #include <win32k.h> 15 16 /* These tables are used in: 17 * UITOOLS_DrawDiagEdge() 18 * UITOOLS_DrawRectEdge() 19 */ 20 static const signed char LTInnerNormal[] = { 21 -1, -1, -1, -1, 22 -1, COLOR_BTNHIGHLIGHT, COLOR_BTNHIGHLIGHT, -1, 23 -1, COLOR_3DDKSHADOW, COLOR_3DDKSHADOW, -1, 24 -1, -1, -1, -1 25 }; 26 27 static const signed char LTOuterNormal[] = { 28 -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, 29 COLOR_BTNHIGHLIGHT, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, 30 COLOR_3DDKSHADOW, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1, 31 -1, COLOR_3DLIGHT, COLOR_BTNSHADOW, -1 32 }; 33 34 static const signed char RBInnerNormal[] = { 35 -1, -1, -1, -1, 36 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, 37 -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, 38 -1, -1, -1, -1 39 }; 40 41 static const signed char RBOuterNormal[] = { 42 -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, 43 COLOR_BTNSHADOW, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, 44 COLOR_3DLIGHT, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1, 45 -1, COLOR_3DDKSHADOW, COLOR_BTNHIGHLIGHT, -1 46 }; 47 48 static const signed char LTInnerSoft[] = { 49 -1, -1, -1, -1, 50 -1, COLOR_3DLIGHT, COLOR_3DLIGHT, -1, 51 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, -1, 52 -1, -1, -1, -1 53 }; 54 55 static const signed char LTOuterSoft[] = { 56 -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, 57 COLOR_3DLIGHT, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, 58 COLOR_BTNSHADOW, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1, 59 -1, COLOR_BTNHIGHLIGHT, COLOR_3DDKSHADOW, -1 60 }; 61 62 #define RBInnerSoft RBInnerNormal /* These are the same */ 63 #define RBOuterSoft RBOuterNormal 64 65 static const signed char LTRBOuterMono[] = { 66 -1, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, 67 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, 68 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, 69 COLOR_WINDOW, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, COLOR_WINDOWFRAME, 70 }; 71 72 static const signed char LTRBInnerMono[] = { 73 -1, -1, -1, -1, 74 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, 75 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, 76 -1, COLOR_WINDOW, COLOR_WINDOW, COLOR_WINDOW, 77 }; 78 79 static const signed char LTRBOuterFlat[] = { 80 -1, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, 81 COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, 82 COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, 83 COLOR_BTNFACE, COLOR_BTNSHADOW, COLOR_BTNSHADOW, COLOR_BTNSHADOW, 84 }; 85 86 static const signed char LTRBInnerFlat[] = { 87 -1, -1, -1, -1, 88 -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, 89 -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, 90 -1, COLOR_BTNFACE, COLOR_BTNFACE, COLOR_BTNFACE, 91 }; 92 93 /* Ported from WINE20020904 */ 94 /* Same as DrawEdge invoked with BF_DIAGONAL */ 95 BOOL FASTCALL IntDrawDiagEdge(HDC hdc, LPRECT rc, UINT uType, UINT uFlags) 96 { 97 POINT Points[4]; 98 signed char InnerI, OuterI; 99 HPEN InnerPen, OuterPen; 100 POINT SavePoint; 101 HPEN SavePen; 102 int spx, spy; 103 int epx, epy; 104 int Width = rc->right - rc->left; 105 int Height= rc->bottom - rc->top; 106 int SmallDiam = Width > Height ? Height : Width; 107 BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER 108 || (uType & BDR_OUTER) == BDR_OUTER) 109 && !(uFlags & (BF_FLAT|BF_MONO)) ); 110 int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) 111 + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); 112 113 /* Init some vars */ 114 OuterPen = InnerPen = (HPEN)NtGdiGetStockObject(NULL_PEN); 115 SavePen = (HPEN)NtGdiSelectPen(hdc, InnerPen); 116 spx = spy = epx = epy = 0; /* Satisfy the compiler... */ 117 118 /* Determine the colors of the edges */ 119 if(uFlags & BF_MONO) 120 { 121 InnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; 122 OuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; 123 } 124 else if(uFlags & BF_FLAT) 125 { 126 InnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; 127 OuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; 128 } 129 else if(uFlags & BF_SOFT) 130 { 131 if(uFlags & BF_BOTTOM) 132 { 133 InnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; 134 OuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; 135 } 136 else 137 { 138 InnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; 139 OuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; 140 } 141 } 142 else 143 { 144 if(uFlags & BF_BOTTOM) 145 { 146 InnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; 147 OuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; 148 } 149 else 150 { 151 InnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; 152 OuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; 153 } 154 } 155 156 if(InnerI != -1) 157 InnerPen = NtGdiGetStockObject(DC_PEN); 158 if(OuterI != -1) 159 OuterPen = NtGdiGetStockObject(DC_PEN); 160 161 GreMoveTo(hdc, 0, 0, &SavePoint); 162 163 /* Don't ask me why, but this is what is visible... */ 164 /* This must be possible to do much simpler, but I fail to */ 165 /* see the logic in the MS implementation (sigh...). */ 166 /* So, this might look a bit brute force here (and it is), but */ 167 /* it gets the job done;) */ 168 169 switch(uFlags & BF_RECT) 170 { 171 case 0: 172 case BF_LEFT: 173 case BF_BOTTOM: 174 case BF_BOTTOMLEFT: 175 /* Left bottom endpoint */ 176 epx = rc->left-1; 177 spx = epx + SmallDiam; 178 epy = rc->bottom; 179 spy = epy - SmallDiam; 180 break; 181 182 case BF_TOPLEFT: 183 case BF_BOTTOMRIGHT: 184 /* Left top endpoint */ 185 epx = rc->left-1; 186 spx = epx + SmallDiam; 187 epy = rc->top-1; 188 spy = epy + SmallDiam; 189 break; 190 191 case BF_TOP: 192 case BF_RIGHT: 193 case BF_TOPRIGHT: 194 case BF_RIGHT|BF_LEFT: 195 case BF_RIGHT|BF_LEFT|BF_TOP: 196 case BF_BOTTOM|BF_TOP: 197 case BF_BOTTOM|BF_TOP|BF_LEFT: 198 case BF_BOTTOMRIGHT|BF_LEFT: 199 case BF_BOTTOMRIGHT|BF_TOP: 200 case BF_RECT: 201 /* Right top endpoint */ 202 spx = rc->left; 203 epx = spx + SmallDiam; 204 spy = rc->bottom-1; 205 epy = spy - SmallDiam; 206 break; 207 } 208 209 GreMoveTo(hdc, spx, spy, NULL); 210 NtGdiSelectPen(hdc, OuterPen); 211 IntSetDCPenColor(hdc, IntGetSysColor(OuterI)); 212 NtGdiLineTo(hdc, epx, epy); 213 214 NtGdiSelectPen(hdc, InnerPen); 215 IntSetDCPenColor(hdc, IntGetSysColor(InnerI)); 216 217 switch(uFlags & (BF_RECT|BF_DIAGONAL)) 218 { 219 case BF_DIAGONAL_ENDBOTTOMLEFT: 220 case (BF_DIAGONAL|BF_BOTTOM): 221 case BF_DIAGONAL: 222 case (BF_DIAGONAL|BF_LEFT): 223 GreMoveTo(hdc, spx-1, spy, NULL); 224 NtGdiLineTo(hdc, epx, epy-1); 225 Points[0].x = spx-add; 226 Points[0].y = spy; 227 Points[1].x = rc->left; 228 Points[1].y = rc->top; 229 Points[2].x = epx+1; 230 Points[2].y = epy-1-add; 231 Points[3] = Points[2]; 232 break; 233 234 case BF_DIAGONAL_ENDBOTTOMRIGHT: 235 GreMoveTo(hdc, spx-1, spy, NULL); 236 NtGdiLineTo(hdc, epx, epy+1); 237 Points[0].x = spx-add; 238 Points[0].y = spy; 239 Points[1].x = rc->left; 240 Points[1].y = rc->bottom-1; 241 Points[2].x = epx+1; 242 Points[2].y = epy+1+add; 243 Points[3] = Points[2]; 244 break; 245 246 case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP): 247 case (BF_DIAGONAL|BF_BOTTOM|BF_RIGHT|BF_TOP|BF_LEFT): 248 case BF_DIAGONAL_ENDTOPRIGHT: 249 case (BF_DIAGONAL|BF_RIGHT|BF_TOP|BF_LEFT): 250 GreMoveTo(hdc, spx+1, spy, NULL); 251 NtGdiLineTo(hdc, epx, epy+1); 252 Points[0].x = epx-1; 253 Points[0].y = epy+1+add; 254 Points[1].x = rc->right-1; 255 Points[1].y = rc->top+add; 256 Points[2].x = rc->right-1; 257 Points[2].y = rc->bottom-1; 258 Points[3].x = spx+add; 259 Points[3].y = spy; 260 break; 261 262 case BF_DIAGONAL_ENDTOPLEFT: 263 GreMoveTo(hdc, spx, spy-1, NULL); 264 NtGdiLineTo(hdc, epx+1, epy); 265 Points[0].x = epx+1+add; 266 Points[0].y = epy+1; 267 Points[1].x = rc->right-1; 268 Points[1].y = rc->top; 269 Points[2].x = rc->right-1; 270 Points[2].y = rc->bottom-1-add; 271 Points[3].x = spx; 272 Points[3].y = spy-add; 273 break; 274 275 case (BF_DIAGONAL|BF_TOP): 276 case (BF_DIAGONAL|BF_BOTTOM|BF_TOP): 277 case (BF_DIAGONAL|BF_BOTTOM|BF_TOP|BF_LEFT): 278 GreMoveTo(hdc, spx+1, spy-1, NULL); 279 NtGdiLineTo(hdc, epx, epy); 280 Points[0].x = epx-1; 281 Points[0].y = epy+1; 282 Points[1].x = rc->right-1; 283 Points[1].y = rc->top; 284 Points[2].x = rc->right-1; 285 Points[2].y = rc->bottom-1-add; 286 Points[3].x = spx+add; 287 Points[3].y = spy-add; 288 break; 289 290 case (BF_DIAGONAL|BF_RIGHT): 291 case (BF_DIAGONAL|BF_RIGHT|BF_LEFT): 292 case (BF_DIAGONAL|BF_RIGHT|BF_LEFT|BF_BOTTOM): 293 GreMoveTo(hdc, spx, spy, NULL); 294 NtGdiLineTo(hdc, epx-1, epy+1); 295 Points[0].x = spx; 296 Points[0].y = spy; 297 Points[1].x = rc->left; 298 Points[1].y = rc->top+add; 299 Points[2].x = epx-1-add; 300 Points[2].y = epy+1+add; 301 Points[3] = Points[2]; 302 break; 303 } 304 305 /* Fill the interior if asked */ 306 if((uFlags & BF_MIDDLE) && retval) 307 { 308 HBRUSH hbsave; 309 HPEN hpsave; 310 hbsave = (HBRUSH)NtGdiSelectBrush(hdc, NtGdiGetStockObject(DC_BRUSH)); 311 hpsave = (HPEN)NtGdiSelectPen(hdc, NtGdiGetStockObject(DC_PEN)); 312 IntSetDCBrushColor(hdc, IntGetSysColor(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE)); 313 IntSetDCPenColor(hdc, IntGetSysColor(uFlags & BF_MONO ? COLOR_WINDOW : COLOR_BTNFACE)); 314 IntPolygon(hdc, Points, 4); 315 NtGdiSelectBrush(hdc, hbsave); 316 NtGdiSelectPen(hdc, hpsave); 317 } 318 319 /* Adjust rectangle if asked */ 320 if(uFlags & BF_ADJUST) 321 { 322 if(uFlags & BF_LEFT) 323 rc->left += add; 324 if(uFlags & BF_RIGHT) 325 rc->right -= add; 326 if(uFlags & BF_TOP) 327 rc->top += add; 328 if(uFlags & BF_BOTTOM) 329 rc->bottom -= add; 330 } 331 332 /* Cleanup */ 333 NtGdiSelectPen(hdc, SavePen); 334 GreMoveTo(hdc, SavePoint.x, SavePoint.y, NULL); 335 336 return retval; 337 } 338 339 /* Ported from WINE20020904 */ 340 /* Same as DrawEdge invoked without BF_DIAGONAL 341 * 342 * 23-Nov-1997: Changed by Bertho Stultiens 343 * 344 * Well, I started testing this and found out that there are a few things 345 * that weren't quite as win95. The following rewrite should reproduce 346 * win95 results completely. 347 * The colorselection is table-driven to avoid awfull if-statements. 348 * The table below show the color settings. 349 * 350 * Pen selection table for uFlags = 0 351 * 352 * uType | LTI | LTO | RBI | RBO 353 * ------+-------+-------+-------+------- 354 * 0000 | x | x | x | x 355 * 0001 | x | 22 | x | 21 356 * 0010 | x | 16 | x | 20 357 * 0011 | x | x | x | x 358 * ------+-------+-------+-------+------- 359 * 0100 | x | 20 | x | 16 360 * 0101 | 20 | 22 | 16 | 21 361 * 0110 | 20 | 16 | 16 | 20 362 * 0111 | x | x | x | x 363 * ------+-------+-------+-------+------- 364 * 1000 | x | 21 | x | 22 365 * 1001 | 21 | 22 | 22 | 21 366 * 1010 | 21 | 16 | 22 | 20 367 * 1011 | x | x | x | x 368 * ------+-------+-------+-------+------- 369 * 1100 | x | x | x | x 370 * 1101 | x | x (22)| x | x (21) 371 * 1110 | x | x (16)| x | x (20) 372 * 1111 | x | x | x | x 373 * 374 * Pen selection table for uFlags = BF_SOFT 375 * 376 * uType | LTI | LTO | RBI | RBO 377 * ------+-------+-------+-------+------- 378 * 0000 | x | x | x | x 379 * 0001 | x | 20 | x | 21 380 * 0010 | x | 21 | x | 20 381 * 0011 | x | x | x | x 382 * ------+-------+-------+-------+------- 383 * 0100 | x | 22 | x | 16 384 * 0101 | 22 | 20 | 16 | 21 385 * 0110 | 22 | 21 | 16 | 20 386 * 0111 | x | x | x | x 387 * ------+-------+-------+-------+------- 388 * 1000 | x | 16 | x | 22 389 * 1001 | 16 | 20 | 22 | 21 390 * 1010 | 16 | 21 | 22 | 20 391 * 1011 | x | x | x | x 392 * ------+-------+-------+-------+------- 393 * 1100 | x | x | x | x 394 * 1101 | x | x (20)| x | x (21) 395 * 1110 | x | x (21)| x | x (20) 396 * 1111 | x | x | x | x 397 * 398 * x = don't care; (n) = is what win95 actually uses 399 * LTI = left Top Inner line 400 * LTO = left Top Outer line 401 * RBI = Right Bottom Inner line 402 * RBO = Right Bottom Outer line 403 * 15 = COLOR_BTNFACE 404 * 16 = COLOR_BTNSHADOW 405 * 20 = COLOR_BTNHIGHLIGHT 406 * 21 = COLOR_3DDKSHADOW 407 * 22 = COLOR_3DLIGHT 408 */ 409 BOOL FASTCALL IntDrawRectEdge(HDC hdc, LPRECT rc, UINT uType, UINT uFlags) 410 { 411 signed char LTInnerI, LTOuterI; 412 signed char RBInnerI, RBOuterI; 413 HPEN LTInnerPen, LTOuterPen; 414 HPEN RBInnerPen, RBOuterPen; 415 RECT InnerRect = *rc; 416 POINT SavePoint; 417 HPEN SavePen; 418 int LBpenplus = 0; 419 int LTpenplus = 0; 420 int RTpenplus = 0; 421 int RBpenplus = 0; 422 BOOL retval = !( ((uType & BDR_INNER) == BDR_INNER 423 || (uType & BDR_OUTER) == BDR_OUTER) 424 && !(uFlags & (BF_FLAT|BF_MONO)) ); 425 /* Init some vars */ 426 LTInnerPen = LTOuterPen = RBInnerPen = RBOuterPen = (HPEN)NtGdiGetStockObject(NULL_PEN); 427 SavePen = (HPEN)NtGdiSelectPen(hdc, LTInnerPen); 428 429 /* Determine the colors of the edges */ 430 if(uFlags & BF_MONO) 431 { 432 LTInnerI = RBInnerI = LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)]; 433 LTOuterI = RBOuterI = LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)]; 434 } 435 else if(uFlags & BF_FLAT) 436 { 437 LTInnerI = RBInnerI = LTRBInnerFlat[uType & (BDR_INNER|BDR_OUTER)]; 438 LTOuterI = RBOuterI = LTRBOuterFlat[uType & (BDR_INNER|BDR_OUTER)]; 439 440 /* Bertho Stultiens states above that this function exactly matches win95 441 * In win98 BF_FLAT rectangles have an inner border same color as the 442 * middle (COLOR_BTNFACE). I believe it's the same for win95 but since 443 * I don't know I go with Bertho and just sets it for win98 until proven 444 * otherwise. 445 * Dennis Björklund, 10 June, 99 446 */ 447 if( LTInnerI != -1 ) 448 LTInnerI = RBInnerI = COLOR_BTNFACE; 449 } 450 else if(uFlags & BF_SOFT) 451 { 452 LTInnerI = LTInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; 453 LTOuterI = LTOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; 454 RBInnerI = RBInnerSoft[uType & (BDR_INNER|BDR_OUTER)]; 455 RBOuterI = RBOuterSoft[uType & (BDR_INNER|BDR_OUTER)]; 456 } 457 else 458 { 459 LTInnerI = LTInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; 460 LTOuterI = LTOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; 461 RBInnerI = RBInnerNormal[uType & (BDR_INNER|BDR_OUTER)]; 462 RBOuterI = RBOuterNormal[uType & (BDR_INNER|BDR_OUTER)]; 463 } 464 465 if((uFlags & BF_BOTTOMLEFT) == BF_BOTTOMLEFT) 466 LBpenplus = 1; 467 if((uFlags & BF_TOPRIGHT) == BF_TOPRIGHT) 468 RTpenplus = 1; 469 if((uFlags & BF_BOTTOMRIGHT) == BF_BOTTOMRIGHT) 470 RBpenplus = 1; 471 if((uFlags & BF_TOPLEFT) == BF_TOPLEFT) 472 LTpenplus = 1; 473 474 if(LTInnerI != -1) 475 LTInnerPen = NtGdiGetStockObject(DC_PEN); 476 if(LTOuterI != -1) 477 LTOuterPen = NtGdiGetStockObject(DC_PEN); 478 if(RBInnerI != -1) 479 RBInnerPen = NtGdiGetStockObject(DC_PEN); 480 if(RBOuterI != -1) 481 RBOuterPen = NtGdiGetStockObject(DC_PEN); 482 if((uFlags & BF_MIDDLE) && retval) 483 { 484 FillRect(hdc, &InnerRect, IntGetSysColorBrush(uFlags & BF_MONO ? 485 COLOR_WINDOW : COLOR_BTNFACE)); 486 } 487 GreMoveTo(hdc, 0, 0, &SavePoint); 488 489 /* Draw the outer edge */ 490 NtGdiSelectPen(hdc, LTOuterPen); 491 IntSetDCPenColor(hdc, IntGetSysColor(LTOuterI)); 492 if(uFlags & BF_TOP) 493 { 494 GreMoveTo(hdc, InnerRect.left, InnerRect.top, NULL); 495 NtGdiLineTo(hdc, InnerRect.right, InnerRect.top); 496 } 497 if(uFlags & BF_LEFT) 498 { 499 GreMoveTo(hdc, InnerRect.left, InnerRect.top, NULL); 500 NtGdiLineTo(hdc, InnerRect.left, InnerRect.bottom); 501 } 502 NtGdiSelectPen(hdc, RBOuterPen); 503 IntSetDCPenColor(hdc, IntGetSysColor(RBOuterI)); 504 if(uFlags & BF_BOTTOM) 505 { 506 GreMoveTo(hdc, InnerRect.left, InnerRect.bottom-1, NULL); 507 NtGdiLineTo(hdc, InnerRect.right, InnerRect.bottom-1); 508 } 509 if(uFlags & BF_RIGHT) 510 { 511 GreMoveTo(hdc, InnerRect.right-1, InnerRect.top, NULL); 512 NtGdiLineTo(hdc, InnerRect.right-1, InnerRect.bottom); 513 } 514 515 /* Draw the inner edge */ 516 NtGdiSelectPen(hdc, LTInnerPen); 517 IntSetDCPenColor(hdc, IntGetSysColor(LTInnerI)); 518 if(uFlags & BF_TOP) 519 { 520 GreMoveTo(hdc, InnerRect.left+LTpenplus, InnerRect.top+1, NULL); 521 NtGdiLineTo(hdc, InnerRect.right-RTpenplus, InnerRect.top+1); 522 } 523 if(uFlags & BF_LEFT) 524 { 525 GreMoveTo(hdc, InnerRect.left+1, InnerRect.top+LTpenplus, NULL); 526 NtGdiLineTo(hdc, InnerRect.left+1, InnerRect.bottom-LBpenplus); 527 } 528 NtGdiSelectPen(hdc, RBInnerPen); 529 IntSetDCPenColor(hdc, IntGetSysColor(RBInnerI)); 530 if(uFlags & BF_BOTTOM) 531 { 532 GreMoveTo(hdc, InnerRect.left+LBpenplus, InnerRect.bottom-2, NULL); 533 NtGdiLineTo(hdc, InnerRect.right-RBpenplus, InnerRect.bottom-2); 534 } 535 if(uFlags & BF_RIGHT) 536 { 537 GreMoveTo(hdc, InnerRect.right-2, InnerRect.top+RTpenplus, NULL); 538 NtGdiLineTo(hdc, InnerRect.right-2, InnerRect.bottom-RBpenplus); 539 } 540 541 if( ((uFlags & BF_MIDDLE) && retval) || (uFlags & BF_ADJUST) ) 542 { 543 int add = (LTRBInnerMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0) 544 + (LTRBOuterMono[uType & (BDR_INNER|BDR_OUTER)] != -1 ? 1 : 0); 545 546 if(uFlags & BF_LEFT) 547 InnerRect.left += add; 548 if(uFlags & BF_RIGHT) 549 InnerRect.right -= add; 550 if(uFlags & BF_TOP) 551 InnerRect.top += add; 552 if(uFlags & BF_BOTTOM) 553 InnerRect.bottom -= add; 554 555 if(uFlags & BF_ADJUST) 556 *rc = InnerRect; 557 } 558 559 /* Cleanup */ 560 NtGdiSelectPen(hdc, SavePen); 561 GreMoveTo(hdc, SavePoint.x, SavePoint.y, NULL); 562 return retval; 563 } 564 565 int FASTCALL UITOOLS_MakeSquareRect(LPRECT src, LPRECT dst) 566 { 567 int Width = src->right - src->left; 568 int Height = src->bottom - src->top; 569 int SmallDiam = Width > Height ? Height : Width; 570 571 *dst = *src; 572 573 /* Make it a square box */ 574 if(Width < Height) /* SmallDiam == Width */ 575 { 576 dst->top += (Height-Width)/2; 577 dst->bottom = dst->top + SmallDiam; 578 } 579 else if(Width > Height) /* SmallDiam == Height */ 580 { 581 dst->left += (Width-Height)/2; 582 dst->right = dst->left + SmallDiam; 583 } 584 585 return SmallDiam; 586 } 587 588 /* Ported from WINE20020904 */ 589 void FASTCALL UITOOLS_DrawCheckedRect( HDC dc, LPRECT rect ) 590 { 591 if(IntGetSysColor(COLOR_BTNHIGHLIGHT) == RGB(255, 255, 255)) 592 { 593 HBRUSH hbsave; 594 COLORREF bg; 595 596 FillRect(dc, rect, IntGetSysColorBrush(COLOR_BTNFACE)); 597 bg = IntGdiSetBkColor(dc, RGB(255, 255, 255)); 598 hbsave = NtGdiSelectBrush(dc, gpsi->hbrGray); 599 NtGdiPatBlt(dc, rect->left, rect->top, rect->right-rect->left, rect->bottom-rect->top, 0x00FA0089); 600 NtGdiSelectBrush(dc, hbsave); 601 IntGdiSetBkColor(dc, bg); 602 } 603 else 604 { 605 FillRect(dc, rect, IntGetSysColorBrush(COLOR_BTNHIGHLIGHT)); 606 } 607 } 608 609 /* Ported from WINE20020904 */ 610 /* Draw a push button coming from DrawFrameControl() 611 * 612 * Does a pretty good job in emulating MS behavior. Some quirks are 613 * however there because MS uses a TrueType font (Marlett) to draw 614 * the buttons. 615 * 616 * FIXME: This looks a little bit strange, needs to be rewritten completely 617 * (several quirks with adjust, DFCS_CHECKED aso) 618 */ 619 BOOL FASTCALL UITOOLS95_DFC_ButtonPush(HDC dc, LPRECT r, UINT uFlags) 620 { 621 UINT edge; 622 RECT myr = *r; 623 624 if(uFlags & (DFCS_PUSHED | DFCS_CHECKED | DFCS_FLAT)) 625 edge = EDGE_SUNKEN; 626 else 627 edge = EDGE_RAISED; 628 629 if(uFlags & DFCS_CHECKED) 630 { 631 if(uFlags & DFCS_MONO) 632 IntDrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); 633 else 634 IntDrawRectEdge(dc, &myr, edge, (uFlags&DFCS_FLAT)|BF_RECT|BF_SOFT|BF_ADJUST); 635 636 UITOOLS_DrawCheckedRect( dc, &myr ); 637 } 638 else 639 { 640 if(uFlags & DFCS_MONO) 641 { 642 IntDrawRectEdge(dc, &myr, edge, BF_MONO|BF_RECT|BF_ADJUST); 643 FillRect(dc, &myr, IntGetSysColorBrush(COLOR_BTNFACE)); 644 } 645 else 646 { 647 IntDrawRectEdge(dc, r, edge, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT | BF_SOFT); 648 } 649 } 650 651 /* Adjust rectangle if asked */ 652 if(uFlags & DFCS_ADJUSTRECT) 653 { 654 r->left += 2; 655 r->right -= 2; 656 r->top += 2; 657 r->bottom -= 2; 658 } 659 660 return TRUE; 661 } 662 663 BOOL FASTCALL UITOOLS95_DFC_ButtonCheckRadio(HDC dc, LPRECT r, UINT uFlags, BOOL Radio) 664 { 665 LOGFONTW lf; 666 HFONT hFont, hOldFont; 667 int i; 668 WCHAR OutRight, OutLeft, InRight, InLeft, Center; 669 670 if (Radio) 671 { 672 OutRight = 'j'; // Outer right 673 OutLeft = 'k'; // Outer left 674 InRight = 'l'; // inner left 675 InLeft = 'm'; // inner right 676 Center = 'n'; // center 677 } else 678 { 679 OutRight = 'c'; // Outer right 680 OutLeft = 'd'; // Outer left 681 InRight = 'e'; // inner left 682 InLeft = 'f'; // inner right 683 Center = 'g'; // center 684 } 685 686 RtlZeroMemory(&lf, sizeof(LOGFONTW)); 687 lf.lfHeight = r->top - r->bottom; 688 lf.lfWidth = 0; 689 lf.lfWeight = FW_NORMAL; 690 lf.lfCharSet = DEFAULT_CHARSET; 691 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); 692 hFont = GreCreateFontIndirectW(&lf); 693 hOldFont = NtGdiSelectFont(dc, hFont); 694 695 if(Radio && ((uFlags & 0xff) == DFCS_BUTTONRADIOMASK)) 696 { 697 IntGdiSetBkMode(dc, OPAQUE); 698 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); 699 GreTextOutW(dc, r->left, r->top, &Center, 1); 700 IntGdiSetBkMode(dc, TRANSPARENT); 701 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); 702 GreTextOutW(dc, r->left, r->top, &OutRight, 1); 703 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); 704 GreTextOutW(dc, r->left, r->top, &OutLeft, 1); 705 } 706 else 707 { 708 IntGdiSetBkMode(dc, TRANSPARENT); 709 710 /* Center section, white for active, grey for inactive */ 711 i= !(uFlags & (DFCS_INACTIVE|DFCS_PUSHED)) ? COLOR_WINDOW : COLOR_BTNFACE; 712 IntGdiSetTextColor(dc, IntGetSysColor(i)); 713 GreTextOutW(dc, r->left, r->top, &Center, 1); 714 715 if(uFlags & (DFCS_FLAT | DFCS_MONO)) 716 { 717 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); 718 GreTextOutW(dc, r->left, r->top, &OutRight, 1); 719 GreTextOutW(dc, r->left, r->top, &OutLeft, 1); 720 GreTextOutW(dc, r->left, r->top, &InRight, 1); 721 GreTextOutW(dc, r->left, r->top, &InLeft, 1); 722 } 723 else 724 { 725 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNSHADOW)); 726 GreTextOutW(dc, r->left, r->top, &OutRight, 1); 727 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); 728 GreTextOutW(dc, r->left, r->top, &OutLeft, 1); 729 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_3DDKSHADOW)); 730 GreTextOutW(dc, r->left, r->top, &InRight, 1); 731 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_3DLIGHT)); 732 GreTextOutW(dc, r->left, r->top, &InLeft, 1); 733 } 734 } 735 736 if(uFlags & DFCS_CHECKED) 737 { 738 WCHAR Check = (Radio) ? 'i' : 'b'; 739 740 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWTEXT)); 741 GreTextOutW(dc, r->left, r->top, &Check, 1); 742 } 743 744 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWTEXT)); 745 NtGdiSelectFont(dc, hOldFont); 746 GreDeleteObject(hFont); 747 748 return TRUE; 749 } 750 751 /* Ported from WINE20020904 */ 752 BOOL FASTCALL UITOOLS95_DrawFrameButton(HDC hdc, LPRECT rc, UINT uState) 753 { 754 switch(uState & 0xff) 755 { 756 case DFCS_BUTTONPUSH: 757 return UITOOLS95_DFC_ButtonPush(hdc, rc, uState); 758 759 case DFCS_BUTTONCHECK: 760 case DFCS_BUTTON3STATE: 761 return UITOOLS95_DFC_ButtonCheckRadio(hdc, rc, uState, FALSE); 762 763 case DFCS_BUTTONRADIOIMAGE: 764 case DFCS_BUTTONRADIOMASK: 765 case DFCS_BUTTONRADIO: 766 return UITOOLS95_DFC_ButtonCheckRadio(hdc, rc, uState, TRUE); 767 768 /* 769 default: 770 DbgPrint("Invalid button state=0x%04x\n", uState); 771 */ 772 } 773 return FALSE; 774 } 775 776 BOOL FASTCALL UITOOLS95_DrawFrameCaption(HDC dc, LPRECT r, UINT uFlags) 777 { 778 LOGFONTW lf; 779 HFONT hFont, hOldFont; 780 COLORREF clrsave; 781 RECT myr; 782 INT bkmode; 783 WCHAR Symbol; 784 switch(uFlags & 0xff) 785 { 786 case DFCS_CAPTIONCLOSE: 787 Symbol = 'r'; 788 break; 789 case DFCS_CAPTIONHELP: 790 Symbol = 's'; 791 break; 792 case DFCS_CAPTIONMIN: 793 Symbol = '0'; 794 break; 795 case DFCS_CAPTIONMAX: 796 Symbol = '1'; 797 break; 798 case DFCS_CAPTIONRESTORE: 799 Symbol = '2'; 800 break; 801 default: 802 return FALSE; 803 } 804 IntDrawRectEdge(dc,r,(uFlags&DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, BF_RECT | BF_MIDDLE | BF_SOFT); 805 RtlZeroMemory(&lf, sizeof(LOGFONTW)); 806 UITOOLS_MakeSquareRect(r, &myr); 807 myr.left += 1; 808 myr.top += 1; 809 myr.right -= 1; 810 myr.bottom -= 1; 811 if(uFlags & DFCS_PUSHED) 812 RECTL_vOffsetRect(&myr,1,1); 813 lf.lfHeight = myr.bottom - myr.top; 814 lf.lfWidth = 0; 815 lf.lfWeight = FW_NORMAL; 816 lf.lfCharSet = DEFAULT_CHARSET; 817 lf.lfQuality = NONANTIALIASED_QUALITY; 818 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); 819 hFont = GreCreateFontIndirectW(&lf); 820 /* save font and text color */ 821 hOldFont = NtGdiSelectFont(dc, hFont); 822 clrsave = GreGetTextColor(dc); 823 bkmode = GreGetBkMode(dc); 824 /* set color and drawing mode */ 825 IntGdiSetBkMode(dc, TRANSPARENT); 826 if(uFlags & DFCS_INACTIVE) 827 { 828 /* draw shadow */ 829 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); 830 GreTextOutW(dc, myr.left + 1, myr.top + 1, &Symbol, 1); 831 } 832 IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); 833 /* draw selected symbol */ 834 GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); 835 /* restore previous settings */ 836 IntGdiSetTextColor(dc, clrsave); 837 NtGdiSelectFont(dc, hOldFont); 838 IntGdiSetBkMode(dc, bkmode); 839 GreDeleteObject(hFont); 840 return TRUE; 841 } 842 843 BOOL FASTCALL UITOOLS95_DrawFrameScroll(HDC dc, LPRECT r, UINT uFlags) 844 { 845 LOGFONTW lf; 846 HFONT hFont, hOldFont; 847 COLORREF clrsave; 848 RECT myr; 849 INT bkmode; 850 WCHAR Symbol; 851 switch(uFlags & 0xff) 852 { 853 case DFCS_SCROLLCOMBOBOX: 854 case DFCS_SCROLLDOWN: 855 Symbol = '6'; 856 break; 857 858 case DFCS_SCROLLUP: 859 Symbol = '5'; 860 break; 861 862 case DFCS_SCROLLLEFT: 863 Symbol = '3'; 864 break; 865 866 case DFCS_SCROLLRIGHT: 867 Symbol = '4'; 868 break; 869 870 case DFCS_SCROLLSIZEGRIP: 871 case DFCS_SCROLLSIZEGRIPRIGHT: 872 RtlZeroMemory(&lf, sizeof(LOGFONTW)); 873 UITOOLS_MakeSquareRect(r, &myr); 874 lf.lfHeight = myr.bottom - myr.top; 875 lf.lfWidth = 0; 876 lf.lfWeight = FW_NORMAL; 877 lf.lfCharSet = DEFAULT_CHARSET; 878 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); 879 hFont = GreCreateFontIndirectW(&lf); 880 /* save font and text color */ 881 hOldFont = NtGdiSelectFont(dc, hFont); 882 clrsave = GreGetTextColor(dc); 883 bkmode = GreGetBkMode(dc); 884 /* set color and drawing mode */ 885 IntGdiSetBkMode(dc, TRANSPARENT); 886 if (!(uFlags & (DFCS_MONO | DFCS_FLAT))) 887 { 888 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); 889 /* draw selected symbol */ 890 Symbol = ((uFlags & 0xff) == DFCS_SCROLLSIZEGRIP) ? 'o' : 'x'; 891 GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); 892 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNSHADOW)); 893 } else 894 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_WINDOWFRAME)); 895 /* draw selected symbol */ 896 Symbol = ((uFlags & 0xff) == DFCS_SCROLLSIZEGRIP) ? 'p' : 'y'; 897 GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); 898 /* restore previous settings */ 899 IntGdiSetTextColor(dc, clrsave); 900 NtGdiSelectFont(dc, hOldFont); 901 IntGdiSetBkMode(dc, bkmode); 902 GreDeleteObject(hFont); 903 return TRUE; 904 default: 905 return FALSE; 906 } 907 IntDrawRectEdge(dc, r, (uFlags & DFCS_PUSHED) ? EDGE_SUNKEN : EDGE_RAISED, (uFlags&DFCS_FLAT) | BF_MIDDLE | BF_RECT); 908 RtlZeroMemory(&lf, sizeof(LOGFONTW)); 909 UITOOLS_MakeSquareRect(r, &myr); 910 myr.left += 1; 911 myr.top += 1; 912 myr.right -= 1; 913 myr.bottom -= 1; 914 if(uFlags & DFCS_PUSHED) 915 RECTL_vOffsetRect(&myr,1,1); 916 lf.lfHeight = myr.bottom - myr.top; 917 lf.lfWidth = 0; 918 lf.lfWeight = FW_NORMAL; 919 lf.lfCharSet = DEFAULT_CHARSET; 920 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); 921 hFont = GreCreateFontIndirectW(&lf); 922 /* save font and text color */ 923 hOldFont = NtGdiSelectFont(dc, hFont); 924 clrsave = GreGetTextColor(dc); 925 bkmode = GreGetBkMode(dc); 926 /* set color and drawing mode */ 927 IntGdiSetBkMode(dc, TRANSPARENT); 928 if(uFlags & DFCS_INACTIVE) 929 { 930 /* draw shadow */ 931 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); 932 GreTextOutW(dc, myr.left + 1, myr.top + 1, &Symbol, 1); 933 } 934 IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); 935 /* draw selected symbol */ 936 GreTextOutW(dc, myr.left, myr.top, &Symbol, 1); 937 /* restore previous settings */ 938 IntGdiSetTextColor(dc, clrsave); 939 NtGdiSelectFont(dc, hOldFont); 940 IntGdiSetBkMode(dc, bkmode); 941 GreDeleteObject(hFont); 942 return TRUE; 943 } 944 945 BOOL FASTCALL UITOOLS95_DrawFrameMenu(HDC dc, LPRECT r, UINT uFlags) 946 { 947 LOGFONTW lf; 948 HFONT hFont, hOldFont; 949 WCHAR Symbol; 950 switch(uFlags & 0xff) 951 { 952 case DFCS_MENUARROWUP: 953 Symbol = '5'; 954 break; 955 956 case DFCS_MENUARROWDOWN: 957 Symbol = '6'; 958 break; 959 960 case DFCS_MENUARROW: 961 Symbol = '8'; 962 break; 963 964 case DFCS_MENUARROWRIGHT: 965 Symbol = 'w'; // FIXME: needs to confirm 966 break; 967 968 case DFCS_MENUBULLET: 969 Symbol = 'h'; 970 break; 971 972 case DFCS_MENUCHECK: 973 Symbol = 'a'; 974 break; 975 976 default: 977 /* 978 DbgPrint("Invalid menu; flags=0x%04x\n", uFlags); 979 */ 980 return FALSE; 981 } 982 /* acquire ressources only if valid menu */ 983 RtlZeroMemory(&lf, sizeof(LOGFONTW)); 984 lf.lfHeight = r->bottom - r->top; 985 lf.lfWidth = 0; 986 lf.lfWeight = FW_NORMAL; 987 lf.lfCharSet = DEFAULT_CHARSET; 988 RtlCopyMemory(lf.lfFaceName, L"Marlett", sizeof(L"Marlett")); 989 hFont = GreCreateFontIndirectW(&lf); 990 /* save font */ 991 hOldFont = NtGdiSelectFont(dc, hFont); 992 993 if ((uFlags & 0xff) == DFCS_MENUARROWUP || 994 (uFlags & 0xff) == DFCS_MENUARROWDOWN ) 995 { 996 #if 0 997 if (uFlags & DFCS_INACTIVE) 998 { 999 /* draw shadow */ 1000 IntGdiSetTextColor(dc, IntGetSysColor(COLOR_BTNHIGHLIGHT)); 1001 GreTextOutW(dc, r->left + 1, r->top + 1, &Symbol, 1); 1002 } 1003 #endif 1004 IntGdiSetTextColor(dc, IntGetSysColor((uFlags & DFCS_INACTIVE) ? COLOR_BTNSHADOW : COLOR_BTNTEXT)); 1005 } 1006 /* draw selected symbol */ 1007 GreTextOutW(dc, r->left, r->top, &Symbol, 1); 1008 /* restore previous settings */ 1009 NtGdiSelectFont(dc, hOldFont); 1010 GreDeleteObject(hFont); 1011 return TRUE; 1012 } 1013 1014 // 1015 // 1016 // Win32ss API support. 1017 // 1018 // 1019 1020 1021 INT WINAPI 1022 FrameRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr) 1023 { 1024 HBRUSH oldbrush; 1025 RECT r = *lprc; 1026 1027 if ((r.right <= r.left) || (r.bottom <= r.top)) return 0; 1028 if (!(oldbrush = NtGdiSelectBrush(hDC, hbr))) return 0; 1029 1030 NtGdiPatBlt(hDC, r.left, r.top, 1, r.bottom - r.top, PATCOPY); 1031 NtGdiPatBlt(hDC, r.right - 1, r.top, 1, r.bottom - r.top, PATCOPY); 1032 NtGdiPatBlt(hDC, r.left, r.top, r.right - r.left, 1, PATCOPY); 1033 NtGdiPatBlt(hDC, r.left, r.bottom - 1, r.right - r.left, 1, PATCOPY); 1034 1035 NtGdiSelectBrush(hDC, oldbrush); 1036 return TRUE; 1037 } 1038 1039 1040 INT WINAPI 1041 FillRect(HDC hDC, CONST RECT *lprc, HBRUSH hbr) 1042 { 1043 BOOL Ret; 1044 HBRUSH prevhbr = NULL; 1045 1046 /* Select brush if specified */ 1047 if (hbr) 1048 { 1049 /* Handle system colors */ 1050 if (hbr <= (HBRUSH)(COLOR_MENUBAR + 1)) 1051 hbr = IntGetSysColorBrush(PtrToUlong(hbr) - 1); 1052 1053 prevhbr = NtGdiSelectBrush(hDC, hbr); 1054 if (prevhbr == NULL) 1055 return (INT)FALSE; 1056 } 1057 1058 Ret = NtGdiPatBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, 1059 lprc->bottom - lprc->top, PATCOPY); 1060 1061 /* Select old brush */ 1062 if (prevhbr) 1063 NtGdiSelectBrush(hDC, prevhbr); 1064 1065 return (INT)Ret; 1066 } 1067 1068 BOOL WINAPI 1069 DrawEdge(HDC hDC, LPRECT rc, UINT edge, UINT flags) 1070 { 1071 if (flags & BF_DIAGONAL) 1072 return IntDrawDiagEdge(hDC, rc, edge, flags); 1073 else 1074 return IntDrawRectEdge(hDC, rc, edge, flags); 1075 } 1076 1077 BOOL WINAPI 1078 DrawFrameControl(HDC hDC, LPRECT rc, UINT uType, UINT uState) 1079 { 1080 if (GreGetMapMode(hDC) != MM_TEXT) 1081 return FALSE; 1082 1083 switch(uType) 1084 { 1085 case DFC_BUTTON: 1086 return UITOOLS95_DrawFrameButton(hDC, rc, uState); 1087 case DFC_CAPTION: 1088 return UITOOLS95_DrawFrameCaption(hDC, rc, uState); 1089 case DFC_MENU: 1090 return UITOOLS95_DrawFrameMenu(hDC, rc, uState); 1091 #if 0 1092 case DFC_POPUPMENU: 1093 UNIMPLEMENTED; 1094 break; 1095 #endif 1096 case DFC_SCROLL: 1097 return UITOOLS95_DrawFrameScroll(hDC, rc, uState); 1098 } 1099 return FALSE; 1100 } 1101 1102