mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Very basic (and incomplete) implementation of DrawStateA, DrawStateW and some internal helper functions, based on the code from WINE. It works well enough to display text on buttons, but doesn't handle any state drawing yet. I hope to implement this over the next few days.
svn path=/trunk/; revision=5609
This commit is contained in:
parent
e0aedc01c3
commit
96a1097b2d
1 changed files with 222 additions and 53 deletions
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: draw.c,v 1.19 2003/08/15 13:44:30 royce Exp $
|
||||
/* $Id: draw.c,v 1.20 2003/08/17 02:51:42 silverblade Exp $
|
||||
*
|
||||
* PROJECT: ReactOS user32.dll
|
||||
* FILE: lib/user32/windows/input.c
|
||||
|
@ -31,6 +31,10 @@
|
|||
#include <windows.h>
|
||||
#include <user32.h>
|
||||
|
||||
// Needed for DrawState
|
||||
#include <string.h>
|
||||
#include <unicode.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
@ -1598,6 +1602,221 @@ DrawFocusRect(
|
|||
}
|
||||
|
||||
|
||||
// These are internal functions, based on the WINE sources. Currently they
|
||||
// are only implemented for DSS_NORMAL and DST_TEXT, although some handling
|
||||
// for DST_BITMAP has been included.
|
||||
|
||||
WINBOOL DrawStateDraw(HDC hdc, UINT type, DRAWSTATEPROC func, LPARAM lData,
|
||||
WPARAM wData, LPRECT rc, UINT dtflags, BOOL unicode)
|
||||
{
|
||||
// HDC MemDC;
|
||||
// HBITMAP MemBMP;
|
||||
BOOL retval = FALSE;
|
||||
// INT cx = rc->right - rc->left;
|
||||
// INT cy = rc->bottom - rc->top;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case DST_TEXT :
|
||||
case DST_PREFIXTEXT :
|
||||
{
|
||||
if (unicode)
|
||||
return DrawTextW(hdc, (LPWSTR)lData, (INT)wData, rc, dtflags);
|
||||
else
|
||||
return DrawTextA(hdc, (LPSTR)lData, (INT)wData, rc, dtflags);
|
||||
}
|
||||
|
||||
case DST_ICON :
|
||||
{
|
||||
// TODO
|
||||
return retval;
|
||||
}
|
||||
|
||||
case DST_BITMAP :
|
||||
{
|
||||
// TODO
|
||||
return retval;
|
||||
}
|
||||
|
||||
case DST_COMPLEX :
|
||||
{
|
||||
// TODO
|
||||
return retval;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
WINBOOL DoDrawState(
|
||||
HDC hdc,
|
||||
HBRUSH hbr,
|
||||
DRAWSTATEPROC lpOutputFunc,
|
||||
LPARAM lData,
|
||||
WPARAM wData,
|
||||
int x,
|
||||
int y,
|
||||
int cx,
|
||||
int cy,
|
||||
UINT fuFlags,
|
||||
BOOL unicode)
|
||||
{
|
||||
// AG: Experimental, unfinished, and most likely buggy! I haven't been
|
||||
// able to test this - my intention was to implement some things needed
|
||||
// by the button control.
|
||||
|
||||
if ((! lpOutputFunc) && (fuFlags & DST_COMPLEX))
|
||||
return FALSE;
|
||||
|
||||
UINT type = fuFlags & 0xf;
|
||||
UINT state = fuFlags & 0x7ff0; // Correct?
|
||||
INT len = wData;
|
||||
RECT rect, subrect;
|
||||
UINT dtflags = DT_NOCLIP;
|
||||
BOOL retval = FALSE;
|
||||
// HBRUSH ourbrush = NULL;
|
||||
|
||||
// Call lpOutputFunc, if necessary
|
||||
if (((type == DST_COMPLEX) || (type == DST_TEXT)) && (lpOutputFunc))
|
||||
lpOutputFunc(hdc, lData, wData, cx, cy);
|
||||
|
||||
|
||||
DbgPrint("[draw.c] In DrawState()\n");
|
||||
|
||||
if ((type == DST_TEXT || type == DST_PREFIXTEXT) && ! len)
|
||||
{
|
||||
// The string is NULL-terminated
|
||||
if (unicode)
|
||||
len = lstrlenW((LPWSTR) lData);
|
||||
else
|
||||
len = strlen((LPSTR) lData);
|
||||
}
|
||||
|
||||
// Identify the image size if not specified
|
||||
if (!cx || !cy)
|
||||
{
|
||||
SIZE s;
|
||||
// CURSORICONINFO *ici;
|
||||
BITMAP bm;
|
||||
|
||||
switch(type) // TODO
|
||||
{
|
||||
case DST_TEXT :
|
||||
case DST_PREFIXTEXT :
|
||||
{
|
||||
BOOL success;
|
||||
if (unicode)
|
||||
success = GetTextExtentPoint32W(hdc, (LPWSTR) lData, len, &s);
|
||||
else
|
||||
success = GetTextExtentPoint32A(hdc, (LPSTR) lData, len, &s);
|
||||
|
||||
if (!success) return FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
case DST_ICON :
|
||||
{
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case DST_BITMAP :
|
||||
{
|
||||
if (!GetObjectA((HBITMAP) lData, sizeof(bm), &bm))
|
||||
return FALSE;
|
||||
|
||||
s.cx = bm.bmWidth;
|
||||
s.cy = bm.bmHeight;
|
||||
break;
|
||||
}
|
||||
|
||||
case DST_COMPLEX : // cx and cy must be set in this mode
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (! cx) cx = s.cx;
|
||||
if (! cy) cy = s.cy;
|
||||
}
|
||||
|
||||
SetRect(&rect, x, y, x + cx, y + cy);
|
||||
SetRect(&subrect, 0, 0, cx, cy);
|
||||
|
||||
// Flags for DrawText
|
||||
// if (fuFlags & DSS_RIGHT) // Undocumented
|
||||
// dtflags |= DT_RIGHT;
|
||||
if (type == DST_TEXT)
|
||||
dtflags |= DT_NOPREFIX;
|
||||
|
||||
// We need to do additional processing if not DSS_NORMAL
|
||||
if (state == DSS_NORMAL)
|
||||
{
|
||||
return DrawStateDraw(hdc, type, lpOutputFunc, lData, wData, &rect, dtflags, unicode);
|
||||
}
|
||||
|
||||
HDC MemDC = NULL;
|
||||
HBITMAP MemBMP = NULL, OldBMP = NULL;
|
||||
|
||||
MemDC = CreateCompatibleDC(hdc);
|
||||
if (! MemDC) goto cleanup;
|
||||
|
||||
MemBMP = CreateCompatibleBitmap(hdc, cx, cy);
|
||||
if (! MemBMP) goto cleanup;
|
||||
|
||||
OldBMP = (HBITMAP) SelectObject(MemDC, MemBMP);
|
||||
if (! OldBMP) goto cleanup;
|
||||
|
||||
DbgPrint("[draw.c] MemDC = 0x%x MemBMP = 0x%x OldBMP = 0x%x\n", MemDC, MemBMP, OldBMP);
|
||||
|
||||
// Copy the actual image into the memory DC (necessary?)
|
||||
BitBlt(MemDC, 0, 0, cx, cy, hdc, x, y, SRCCOPY);
|
||||
|
||||
|
||||
// Apply state(s?)
|
||||
|
||||
if (state & DSS_UNION)
|
||||
{
|
||||
// Dither the image
|
||||
// TODO
|
||||
}
|
||||
|
||||
if (state & DSS_DISABLED)
|
||||
{
|
||||
hbr = CreateSolidBrush(GetSysColor(COLOR_3DHILIGHT));
|
||||
if (! hbr) goto cleanup;
|
||||
}
|
||||
else if (! hbr)
|
||||
{
|
||||
hbr = (HBRUSH) GetStockObject(BLACK_BRUSH);
|
||||
}
|
||||
|
||||
// else if (state & DSS_DEFAULT)
|
||||
// ....
|
||||
|
||||
if (state & (DSS_DISABLED /*|DSS_DEFAULT*/))
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// HBRUSH oldbrush = (HBRUSH) SelectObject(MemDC, ourbrush);
|
||||
|
||||
// Copy to hdc from MemDC
|
||||
if (! BitBlt(hdc, x, y, cx, cy, MemDC, 0, 0, SRCCOPY)) goto cleanup;
|
||||
|
||||
DbgPrint("[draw.c] Success!\n");
|
||||
|
||||
retval = TRUE;
|
||||
|
||||
|
||||
cleanup :
|
||||
if (OldBMP) SelectObject(MemDC, OldBMP);
|
||||
if (MemBMP) DeleteObject(MemBMP);
|
||||
if (MemDC) DeleteDC(MemDC);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
|
@ -1615,8 +1834,7 @@ DrawStateA(
|
|||
int cy,
|
||||
UINT fuFlags)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return FALSE;
|
||||
return DoDrawState(hdc, hbr, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags, FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1637,54 +1855,5 @@ DrawStateW(
|
|||
int cy,
|
||||
UINT fuFlags)
|
||||
{
|
||||
// AG: Experimental, unfinished, and most likely buggy! I haven't been
|
||||
// able to test this - my intention was to implement some things needed
|
||||
// by the button control.
|
||||
|
||||
DbgPrint("[draw.c] In DrawState()\n");
|
||||
|
||||
if ((! lpOutputFunc) && (fuFlags & DST_COMPLEX))
|
||||
return FALSE;
|
||||
|
||||
RECT r;
|
||||
SetRect(&r, x, y, cx, cy);
|
||||
|
||||
HBITMAP MemBMP = CreateCompatibleBitmap(hdc, cx, cy);
|
||||
HDC MemDC = CreateCompatibleDC(hdc);
|
||||
|
||||
HBITMAP OldBMP = (HBITMAP) SelectObject(MemDC, MemBMP);
|
||||
|
||||
// Does this work?
|
||||
SetBkColor(MemDC, GetBkColor(hdc));
|
||||
// Test stuff...
|
||||
FillRect(MemDC, &r, WHITE_BRUSH);
|
||||
|
||||
// Do drawing first
|
||||
|
||||
if (lpOutputFunc)
|
||||
lpOutputFunc(MemDC, lData, wData, cx, cy);
|
||||
|
||||
else if (fuFlags & DST_TEXT)
|
||||
{
|
||||
int count;
|
||||
if (wData == 0) count = -1;
|
||||
else count = wData;
|
||||
DrawTextW(MemDC, (WCHAR*) lData, count, &r, 0);
|
||||
}
|
||||
|
||||
// Now apply state effect
|
||||
// not implemented yet ...
|
||||
|
||||
|
||||
// Copy to hdc
|
||||
|
||||
BitBlt(hdc, x, y, cx, cy, MemDC, 0, 0, SRCCOPY);
|
||||
|
||||
SelectObject(MemDC, OldBMP);
|
||||
DeleteObject(MemBMP);
|
||||
DeleteDC(MemDC);
|
||||
|
||||
DbgPrint("[draw.c] Success!\n");
|
||||
|
||||
return TRUE;
|
||||
return DoDrawState(hdc, hbr, lpOutputFunc, lData, wData, x, y, cx, cy, fuFlags, TRUE);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue