mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 02:41:22 +00:00
merged changes from wine to button and combobox code.
svn path=/trunk/; revision=20032
This commit is contained in:
parent
711bd1e8ae
commit
87c69dc1fe
2 changed files with 152 additions and 78 deletions
|
@ -24,8 +24,8 @@
|
|||
/* GetWindowLong offsets for window extra information */
|
||||
#define STATE_GWL_OFFSET 0
|
||||
#define HFONT_GWL_OFFSET (sizeof(LONG))
|
||||
#define HIMAGE_GWL_OFFSET (2*sizeof(LONG))
|
||||
#define NB_EXTRA_BYTES (3*sizeof(LONG))
|
||||
#define HIMAGE_GWL_OFFSET (HFONT_GWL_OFFSET*sizeof(LONG))
|
||||
#define NB_EXTRA_BYTES (HIMAGE_GWL_OFFSET*sizeof(LONG))
|
||||
|
||||
/* Button state values */
|
||||
#define BUTTON_UNCHECKED 0x00
|
||||
|
@ -39,6 +39,14 @@
|
|||
#define BUTTON_UNKNOWN2 0x20
|
||||
#define BUTTON_UNKNOWN3 0x10
|
||||
|
||||
#define BUTTON_NOTIFY_PARENT(hWnd, code) \
|
||||
do { /* Notify parent which has created this button control */ \
|
||||
TRACE("notification " #code " sent to hwnd=%p\n", GetParent(hWnd)); \
|
||||
SendMessageW(GetParent(hWnd), WM_COMMAND, \
|
||||
MAKEWPARAM(GetWindowLongPtrW((hWnd),GWLP_ID), (code)), \
|
||||
(LPARAM)(hWnd)); \
|
||||
} while(0)
|
||||
|
||||
static UINT BUTTON_CalcLabelRect( HWND hwnd, HDC hdc, RECT *rc );
|
||||
static void PB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
static void CB_Paint( HWND hwnd, HDC hDC, UINT action );
|
||||
|
@ -116,22 +124,22 @@ const struct builtin_class_descr BUTTON_builtin_class =
|
|||
|
||||
__inline static LONG get_button_state( HWND hwnd )
|
||||
{
|
||||
return GetWindowLongA( hwnd, STATE_GWL_OFFSET );
|
||||
return GetWindowLongW( hwnd, STATE_GWL_OFFSET );
|
||||
}
|
||||
|
||||
__inline static void set_button_state( HWND hwnd, LONG state )
|
||||
{
|
||||
SetWindowLongA( hwnd, STATE_GWL_OFFSET, state );
|
||||
SetWindowLongW( hwnd, STATE_GWL_OFFSET, state );
|
||||
}
|
||||
|
||||
__inline static HFONT get_button_font( HWND hwnd )
|
||||
{
|
||||
return (HFONT)GetWindowLongA( hwnd, HFONT_GWL_OFFSET );
|
||||
return (HFONT)GetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET );
|
||||
}
|
||||
|
||||
__inline static void set_button_font( HWND hwnd, HFONT font )
|
||||
{
|
||||
SetWindowLongA( hwnd, HFONT_GWL_OFFSET, (LONG)font );
|
||||
SetWindowLongPtrW( hwnd, HFONT_GWL_OFFSET, (LONG)font );
|
||||
}
|
||||
|
||||
__inline static UINT get_button_type( LONG window_style )
|
||||
|
@ -167,7 +175,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
{
|
||||
RECT rect;
|
||||
POINT pt;
|
||||
LONG style = GetWindowLongA( hWnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hWnd, GWL_STYLE );
|
||||
UINT btn_type = get_button_type( style );
|
||||
LONG state;
|
||||
HANDLE oldHbitmap;
|
||||
|
@ -180,10 +188,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
case WM_GETDLGCODE:
|
||||
switch(btn_type)
|
||||
{
|
||||
case BS_USERBUTTON:
|
||||
case BS_PUSHBUTTON: return DLGC_BUTTON | DLGC_UNDEFPUSHBUTTON;
|
||||
case BS_DEFPUSHBUTTON: return DLGC_BUTTON | DLGC_DEFPUSHBUTTON;
|
||||
case BS_RADIOBUTTON:
|
||||
case BS_AUTORADIOBUTTON: return DLGC_BUTTON | DLGC_RADIOBUTTON;
|
||||
case BS_GROUPBOX: return DLGC_STATIC;
|
||||
default: return DLGC_BUTTON;
|
||||
}
|
||||
|
||||
|
@ -222,6 +232,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
}
|
||||
return 1;
|
||||
|
||||
case WM_PRINTCLIENT:
|
||||
case WM_PAINT:
|
||||
if (btnPaintFunc[btn_type])
|
||||
{
|
||||
|
@ -248,17 +259,15 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
btn_type == BS_USERBUTTON ||
|
||||
btn_type == BS_OWNERDRAW)
|
||||
{
|
||||
SendMessageW( GetParent(hWnd), WM_COMMAND,
|
||||
MAKEWPARAM( GetWindowLongA(hWnd,GWL_ID), BN_DOUBLECLICKED ),
|
||||
(LPARAM)hWnd);
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_DOUBLECLICKED);
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case WM_LBUTTONDOWN:
|
||||
SetCapture( hWnd );
|
||||
SetFocus( hWnd );
|
||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||
set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
|
||||
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
|
||||
break;
|
||||
|
||||
case WM_KEYUP:
|
||||
|
@ -294,8 +303,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
(state & BUTTON_3STATE) ? 0 : ((state & 3) + 1), 0 );
|
||||
break;
|
||||
}
|
||||
SendMessageW( GetParent(hWnd), WM_COMMAND,
|
||||
MAKEWPARAM( GetWindowLongA(hWnd,GWL_ID), BN_CLICKED ), (LPARAM)hWnd);
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_CLICKED);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -361,11 +369,20 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
case WM_SETFOCUS:
|
||||
set_button_state( hWnd, get_button_state(hWnd) | BUTTON_HASFOCUS );
|
||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||
if (style & BS_NOTIFY)
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_SETFOCUS);
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
set_button_state( hWnd, get_button_state(hWnd) & ~BUTTON_HASFOCUS );
|
||||
state = get_button_state( hWnd );
|
||||
set_button_state( hWnd, state & ~BUTTON_HASFOCUS );
|
||||
paint_button( hWnd, btn_type, ODA_FOCUS );
|
||||
|
||||
if ((state & BUTTON_BTNPRESSED) && GetCapture() == hWnd)
|
||||
ReleaseCapture();
|
||||
if (style & BS_NOTIFY)
|
||||
BUTTON_NOTIFY_PARENT(hWnd, BN_KILLFOCUS);
|
||||
|
||||
break;
|
||||
|
||||
case WM_SYSCOLORCHANGE:
|
||||
|
@ -379,7 +396,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
if ((wParam & 0x0f) >= MAX_BTN_TYPE) break;
|
||||
btn_type = wParam & 0x0f;
|
||||
style = (style & ~0x0f) | btn_type;
|
||||
SetWindowLongA( hWnd, GWL_STYLE, style );
|
||||
SetWindowLongW( hWnd, GWL_STYLE, style );
|
||||
|
||||
/* Only redraw if lParam flag is set.*/
|
||||
if (lParam)
|
||||
|
@ -405,12 +422,12 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
default:
|
||||
return 0;
|
||||
}
|
||||
oldHbitmap = (HBITMAP)SetWindowLongA( hWnd, HIMAGE_GWL_OFFSET, lParam );
|
||||
oldHbitmap = (HBITMAP)SetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET, lParam );
|
||||
InvalidateRect( hWnd, NULL, FALSE );
|
||||
return (LRESULT)oldHbitmap;
|
||||
|
||||
case BM_GETIMAGE:
|
||||
return GetWindowLongA( hWnd, HIMAGE_GWL_OFFSET );
|
||||
return GetWindowLongPtrW( hWnd, HIMAGE_GWL_OFFSET );
|
||||
|
||||
#ifndef __REACTOS__
|
||||
case BM_GETCHECK16:
|
||||
|
@ -428,7 +445,7 @@ static LRESULT WINAPI ButtonWndProc_common(HWND hWnd, UINT uMsg,
|
|||
{
|
||||
if (wParam) style |= WS_TABSTOP;
|
||||
else style &= ~WS_TABSTOP;
|
||||
SetWindowLongA( hWnd, GWL_STYLE, style );
|
||||
SetWindowLongW( hWnd, GWL_STYLE, style );
|
||||
}
|
||||
if ((state & 3) != wParam)
|
||||
{
|
||||
|
@ -556,7 +573,7 @@ static UINT BUTTON_BStoDT(DWORD style)
|
|||
*/
|
||||
static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
||||
{
|
||||
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
WCHAR *text;
|
||||
ICONINFO iconInfo;
|
||||
BITMAP bm;
|
||||
|
@ -579,7 +596,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
break;
|
||||
|
||||
case BS_ICON:
|
||||
if (!GetIconInfo((HICON)GetWindowLongA( hwnd, HIMAGE_GWL_OFFSET ), &iconInfo))
|
||||
if (!GetIconInfo((HICON)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), &iconInfo))
|
||||
goto empty_rect;
|
||||
|
||||
GetObjectW (iconInfo.hbmColor, sizeof(BITMAP), &bm);
|
||||
|
@ -592,7 +609,7 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
break;
|
||||
|
||||
case BS_BITMAP:
|
||||
if (!GetObjectW( (HANDLE)GetWindowLongA( hwnd, HIMAGE_GWL_OFFSET ), sizeof(BITMAP), &bm))
|
||||
if (!GetObjectW( (HANDLE)GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET ), sizeof(BITMAP), &bm))
|
||||
goto empty_rect;
|
||||
|
||||
r.right = r.left + bm.bmWidth;
|
||||
|
@ -601,8 +618,8 @@ static UINT BUTTON_CalcLabelRect(HWND hwnd, HDC hdc, RECT *rc)
|
|||
|
||||
default:
|
||||
empty_rect:
|
||||
r.right = r.left;
|
||||
r.bottom = r.top;
|
||||
rc->right = r.left;
|
||||
rc->bottom = r.top;
|
||||
return (UINT)(LONG)-1;
|
||||
}
|
||||
|
||||
|
@ -671,7 +688,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc)
|
|||
HBRUSH hbr = 0;
|
||||
UINT flags = IsWindowEnabled(hwnd) ? DSS_NORMAL : DSS_DISABLED;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
WCHAR *text = NULL;
|
||||
|
||||
/* FIXME: To draw disabled label in Win31 look-and-feel, we probably
|
||||
|
@ -697,12 +714,12 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc)
|
|||
|
||||
case BS_ICON:
|
||||
flags |= DST_ICON;
|
||||
lp = GetWindowLongA( hwnd, HIMAGE_GWL_OFFSET );
|
||||
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
|
||||
break;
|
||||
|
||||
case BS_BITMAP:
|
||||
flags |= DST_BITMAP;
|
||||
lp = GetWindowLongA( hwnd, HIMAGE_GWL_OFFSET );
|
||||
lp = GetWindowLongPtrW( hwnd, HIMAGE_GWL_OFFSET );
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -711,7 +728,7 @@ static void BUTTON_DrawLabel(HWND hwnd, HDC hdc, UINT dtFlags, RECT *rc)
|
|||
|
||||
DrawStateW(hdc, hbr, lpOutputProc, lp, wp, rc->left, rc->top,
|
||||
rc->right - rc->left, rc->bottom - rc->top, flags);
|
||||
if (text) HeapFree( GetProcessHeap(), 0, text );
|
||||
HeapFree( GetProcessHeap(), 0, text );
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -721,14 +738,13 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
{
|
||||
RECT rc, focus_rect, r;
|
||||
UINT dtFlags, uState;
|
||||
HRGN hRgn;
|
||||
HPEN hOldPen;
|
||||
HBRUSH hOldBrush;
|
||||
INT oldBkMode;
|
||||
COLORREF oldTxtColor;
|
||||
HFONT hFont;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
BOOL pushedState = (state & BUTTON_HIGHLIGHTED);
|
||||
HWND parent;
|
||||
|
||||
|
@ -782,16 +798,13 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
if (pushedState)
|
||||
OffsetRect(&r, 1, 1);
|
||||
|
||||
hRgn = CreateRectRgn(rc.left, rc.top, rc.right, rc.bottom);
|
||||
SelectClipRgn(hDC, hRgn);
|
||||
IntersectClipRect(hDC, rc.left, rc.top, rc.right, rc.bottom);
|
||||
|
||||
oldTxtColor = SetTextColor( hDC, GetSysColor(COLOR_BTNTEXT) );
|
||||
|
||||
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &r);
|
||||
|
||||
SetTextColor( hDC, oldTxtColor );
|
||||
SelectClipRgn(hDC, 0);
|
||||
DeleteObject(hRgn);
|
||||
|
||||
if (state & BUTTON_HASFOCUS)
|
||||
{
|
||||
|
@ -806,6 +819,7 @@ static void PB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
SetBkMode(hDC, oldBkMode);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Check Box & Radio Button Functions
|
||||
*/
|
||||
|
@ -816,10 +830,9 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
HBRUSH hBrush;
|
||||
int delta;
|
||||
UINT dtFlags;
|
||||
HRGN hRgn;
|
||||
HFONT hFont;
|
||||
LONG state = get_button_state( hwnd );
|
||||
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
HWND parent;
|
||||
|
||||
if (style & BS_PUSHLIKE)
|
||||
|
@ -853,7 +866,7 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
rtext.left += checkBoxWidth + 4;
|
||||
rbox.right = checkBoxWidth;
|
||||
}
|
||||
|
||||
|
||||
/* Since WM_ERASEBKGND does nothing, first prepare background */
|
||||
if (action == ODA_SELECT) FillRect( hDC, &rbox, hBrush );
|
||||
if (action == ODA_DRAWENTIRE) FillRect( hDC, &client, hBrush );
|
||||
|
@ -861,9 +874,14 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
/* Draw label */
|
||||
client = rtext;
|
||||
dtFlags = BUTTON_CalcLabelRect(hwnd, hDC, &rtext);
|
||||
|
||||
/* Only adjust rbox when rtext is valid */
|
||||
if (dtFlags != (UINT)-1L)
|
||||
{
|
||||
rbox.top = rtext.top;
|
||||
rbox.bottom = rtext.bottom;
|
||||
}
|
||||
|
||||
rbox.top = rtext.top;
|
||||
rbox.bottom = rtext.bottom;
|
||||
/* Draw the check-box bitmap */
|
||||
if (action == ODA_DRAWENTIRE || action == ODA_SELECT)
|
||||
{
|
||||
|
@ -881,20 +899,20 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
|
||||
/* rbox must have the correct height */
|
||||
delta = rbox.bottom - rbox.top - checkBoxHeight;
|
||||
|
||||
|
||||
if (style & BS_TOP) {
|
||||
if (delta > 0) {
|
||||
rbox.bottom = rbox.top + checkBoxHeight;
|
||||
} else {
|
||||
} else {
|
||||
rbox.top -= -delta/2 + 1;
|
||||
rbox.bottom += rbox.top + checkBoxHeight;
|
||||
rbox.bottom = rbox.top + checkBoxHeight;
|
||||
}
|
||||
} else if (style & BS_BOTTOM) {
|
||||
if (delta > 0) {
|
||||
rbox.top = rbox.bottom - checkBoxHeight;
|
||||
} else {
|
||||
rbox.bottom += -delta/2 + 1;
|
||||
rbox.top = rbox.bottom -= checkBoxHeight;
|
||||
rbox.top = rbox.bottom - checkBoxHeight;
|
||||
}
|
||||
} else { /* Default */
|
||||
if (delta > 0) {
|
||||
|
@ -913,9 +931,8 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
|
||||
if (dtFlags == (UINT)-1L) /* Noting to draw */
|
||||
return;
|
||||
hRgn = CreateRectRgn(client.left, client.top, client.right, client.bottom);
|
||||
SelectClipRgn(hDC, hRgn);
|
||||
DeleteObject(hRgn);
|
||||
|
||||
IntersectClipRect(hDC, client.left, client.top, client.right, client.bottom);
|
||||
|
||||
if (action == ODA_DRAWENTIRE)
|
||||
BUTTON_DrawLabel(hwnd, hDC, dtFlags, &rtext);
|
||||
|
@ -929,7 +946,6 @@ static void CB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
IntersectRect(&rtext, &rtext, &client);
|
||||
DrawFocusRect( hDC, &rtext );
|
||||
}
|
||||
SelectClipRgn(hDC, 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -949,7 +965,7 @@ static void BUTTON_CheckAutoRadioButton( HWND hwnd )
|
|||
{
|
||||
if (!sibling) break;
|
||||
if ((hwnd != sibling) &&
|
||||
((GetWindowLongA( sibling, GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
|
||||
((GetWindowLongW( sibling, GWL_STYLE) & 0x0f) == BS_AUTORADIOBUTTON))
|
||||
SendMessageW( sibling, BM_SETCHECK, BUTTON_UNCHECKED, 0 );
|
||||
sibling = GetNextDlgGroupItem( parent, sibling, FALSE );
|
||||
} while (sibling != start);
|
||||
|
@ -967,7 +983,7 @@ static void GB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
HFONT hFont;
|
||||
UINT dtFlags;
|
||||
TEXTMETRICW tm;
|
||||
LONG style = GetWindowLongA( hwnd, GWL_STYLE );
|
||||
LONG style = GetWindowLongW( hwnd, GWL_STYLE );
|
||||
HWND parent;
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) SelectObject( hDC, hFont );
|
||||
|
@ -1037,7 +1053,6 @@ static void UB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
DrawFocusRect( hDC, &rc );
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Ownerdrawn Button Functions
|
||||
*/
|
||||
|
@ -1048,8 +1063,9 @@ static void OB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
DRAWITEMSTRUCT dis;
|
||||
HRGN clipRegion;
|
||||
RECT clipRect;
|
||||
UINT id = GetWindowLongA( hwnd, GWL_ID );
|
||||
LONG_PTR id = GetWindowLongPtrW( hwnd, GWLP_ID );
|
||||
HWND parent;
|
||||
HFONT hFont, hPrevFont = 0;
|
||||
|
||||
dis.CtlType = ODT_BUTTON;
|
||||
dis.CtlID = id;
|
||||
|
@ -1073,9 +1089,11 @@ static void OB_Paint( HWND hwnd, HDC hDC, UINT action )
|
|||
DPtoLP(hDC, (LPPOINT) &clipRect, 2);
|
||||
IntersectClipRect(hDC, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom);
|
||||
|
||||
if ((hFont = get_button_font( hwnd ))) hPrevFont = SelectObject( hDC, hFont );
|
||||
parent = GetParent(hwnd);
|
||||
if (!parent) parent = hwnd;
|
||||
SendMessageW( parent, WM_CTLCOLORBTN, (WPARAM)hDC, (LPARAM)hwnd );
|
||||
SendMessageW( GetParent(hwnd), WM_DRAWITEM, id, (LPARAM)&dis );
|
||||
if (hPrevFont) SelectObject(hDC, hPrevFont);
|
||||
SelectClipRgn(hDC, clipRegion);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,20 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* FIXME: roll up in Netscape 3.01.
|
||||
* NOTES
|
||||
*
|
||||
* This code was audited for completeness against the documented features
|
||||
* of Comctl32.dll version 6.0 on Oct. 4, 2004, by Dimitrie O. Paun.
|
||||
*
|
||||
* Unless otherwise noted, we believe this code to be complete, as per
|
||||
* the specification mentioned above.
|
||||
* If you discover missing features, or bugs, please note them below.
|
||||
*
|
||||
* TODO:
|
||||
* - ComboBox_[GS]etMinVisible()
|
||||
* - CB_GETMINVISIBLE, CB_SETMINVISIBLE
|
||||
* - CB_LIMITTEXT
|
||||
* - CB_SETTOPINDEX
|
||||
*/
|
||||
|
||||
#include <user32.h>
|
||||
|
@ -36,7 +49,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(combo);
|
|||
|
||||
#define CB_NOTIFY( lphc, code ) \
|
||||
(SendMessageW((lphc)->owner, WM_COMMAND, \
|
||||
MAKEWPARAM(GetWindowLongA((lphc)->self,GWL_ID), (code)), (LPARAM)(lphc)->self))
|
||||
MAKEWPARAM(GetWindowLongPtrW((lphc)->self,GWLP_ID), (code)), (LPARAM)(lphc)->self))
|
||||
|
||||
#define CB_DISABLED( lphc ) (!IsWindowEnabled((lphc)->self))
|
||||
#define CB_OWNERDRAWN( lphc ) ((lphc)->dwStyle & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE))
|
||||
|
@ -136,23 +149,23 @@ static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
|
|||
if (COMBO_Init() && (lphc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEADCOMBO))) )
|
||||
{
|
||||
lphc->self = hwnd;
|
||||
SetWindowLongA( hwnd, 0, (LONG)lphc );
|
||||
SetWindowLongW( hwnd, 0, (LONG)lphc );
|
||||
|
||||
/* some braindead apps do try to use scrollbar/border flags */
|
||||
|
||||
lphc->dwStyle = style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL);
|
||||
SetWindowLongA( hwnd, GWL_STYLE, style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL) );
|
||||
SetWindowLongW( hwnd, GWL_STYLE, style & ~(WS_BORDER | WS_HSCROLL | WS_VSCROLL) );
|
||||
|
||||
/*
|
||||
* We also have to remove the client edge style to make sure
|
||||
* we don't end-up with a non client area.
|
||||
*/
|
||||
SetWindowLongA( hwnd, GWL_EXSTYLE,
|
||||
GetWindowLongA( hwnd, GWL_EXSTYLE ) & ~WS_EX_CLIENTEDGE );
|
||||
SetWindowLongW( hwnd, GWL_EXSTYLE,
|
||||
GetWindowLongW( hwnd, GWL_EXSTYLE ) & ~WS_EX_CLIENTEDGE );
|
||||
|
||||
if( !(style & (CBS_OWNERDRAWFIXED | CBS_OWNERDRAWVARIABLE)) )
|
||||
lphc->dwStyle |= CBS_HASSTRINGS;
|
||||
if( !(GetWindowLongA( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY) )
|
||||
if( !(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY) )
|
||||
lphc->wState |= CBF_NOTIFY;
|
||||
|
||||
TRACE("[%p], style = %08x\n", lphc, lphc->dwStyle );
|
||||
|
@ -174,7 +187,7 @@ static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
|
|||
if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
|
||||
DestroyWindow( lphc->hWndLBox );
|
||||
|
||||
SetWindowLongA( lphc->self, 0, 0 );
|
||||
SetWindowLongPtrW( lphc->self, 0, 0 );
|
||||
HeapFree( GetProcessHeap(), 0, lphc );
|
||||
}
|
||||
return 0;
|
||||
|
@ -240,7 +253,7 @@ static INT CBGetTextAreaHeight(
|
|||
MEASUREITEMSTRUCT measureItem;
|
||||
RECT clientRect;
|
||||
INT originalItemHeight = iTextItemHeight;
|
||||
UINT id = GetWindowLongA( lphc->self, GWL_ID );
|
||||
UINT id = GetWindowLongPtrW( lphc->self, GWLP_ID );
|
||||
|
||||
/*
|
||||
* We use the client rect for the width of the item.
|
||||
|
@ -542,8 +555,11 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
|
|||
if( CB_GETTYPE(lphc) == CBS_DROPDOWN )
|
||||
lphc->droppedRect.left += COMBO_EDITBUTTONSPACE();
|
||||
|
||||
ClientToScreen(hwnd, (LPPOINT)&lphc->droppedRect);
|
||||
ClientToScreen(hwnd, (LPPOINT)&lphc->droppedRect.right);
|
||||
if (lphc->droppedRect.bottom < lphc->droppedRect.top)
|
||||
lphc->droppedRect.bottom = lphc->droppedRect.top;
|
||||
if (lphc->droppedRect.right < lphc->droppedRect.left)
|
||||
lphc->droppedRect.right = lphc->droppedRect.left;
|
||||
MapWindowPoints( hwnd, 0, (LPPOINT)&lphc->droppedRect, 2 );
|
||||
}
|
||||
|
||||
/* create listbox popup */
|
||||
|
@ -583,7 +599,7 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
|
|||
lphc->droppedRect.right - lphc->droppedRect.left,
|
||||
lphc->droppedRect.bottom - lphc->droppedRect.top,
|
||||
hwnd, (HMENU)ID_CB_LISTBOX,
|
||||
(HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), lphc );
|
||||
(HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE ), lphc );
|
||||
else
|
||||
lphc->hWndLBox = CreateWindowExA(lbeExStyle, "ComboLBox", NULL, lbeStyle,
|
||||
lphc->droppedRect.left,
|
||||
|
@ -591,7 +607,7 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
|
|||
lphc->droppedRect.right - lphc->droppedRect.left,
|
||||
lphc->droppedRect.bottom - lphc->droppedRect.top,
|
||||
hwnd, (HMENU)ID_CB_LISTBOX,
|
||||
(HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), lphc );
|
||||
(HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE ), lphc );
|
||||
|
||||
if( lphc->hWndLBox )
|
||||
{
|
||||
|
@ -617,14 +633,14 @@ static LRESULT COMBO_Create( HWND hwnd, LPHEADCOMBO lphc, HWND hwndParent, LONG
|
|||
lphc->textRect.right - lphc->textRect.left,
|
||||
lphc->textRect.bottom - lphc->textRect.top,
|
||||
hwnd, (HMENU)ID_CB_EDIT,
|
||||
(HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), NULL );
|
||||
(HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE ), NULL );
|
||||
else
|
||||
lphc->hWndEdit = CreateWindowExA(0, "Edit", NULL, lbeStyle,
|
||||
lphc->textRect.left, lphc->textRect.top,
|
||||
lphc->textRect.right - lphc->textRect.left,
|
||||
lphc->textRect.bottom - lphc->textRect.top,
|
||||
hwnd, (HMENU)ID_CB_EDIT,
|
||||
(HINSTANCE)GetWindowLongA( hwnd, GWL_HINSTANCE ), NULL );
|
||||
(HINSTANCE)GetWindowLongPtrW( hwnd, GWLP_HINSTANCE ), NULL );
|
||||
|
||||
if( !lphc->hWndEdit )
|
||||
bEdit = FALSE;
|
||||
|
@ -736,7 +752,7 @@ static void CBPaintText(
|
|||
{
|
||||
DRAWITEMSTRUCT dis;
|
||||
HRGN clipRegion;
|
||||
UINT ctlid = GetWindowLongA( lphc->self, GWL_ID );
|
||||
UINT ctlid = (UINT)GetWindowLongPtrW( lphc->self, GWLP_ID );
|
||||
|
||||
/* setup state for DRAWITEM message. Owner will highlight */
|
||||
if ( (lphc->wState & CBF_FOCUSED) &&
|
||||
|
@ -1047,8 +1063,7 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
|
|||
if( lphc->wState & CBF_FOCUSED )
|
||||
SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, (LPARAM)(-1));
|
||||
|
||||
if( pText )
|
||||
HeapFree( GetProcessHeap(), 0, pText );
|
||||
HeapFree( GetProcessHeap(), 0, pText );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -1399,7 +1414,7 @@ static LRESULT COMBO_Command( LPHEADCOMBO lphc, WPARAM wParam, HWND hWnd )
|
|||
static LRESULT COMBO_ItemOp( LPHEADCOMBO lphc, UINT msg, LPARAM lParam )
|
||||
{
|
||||
HWND hWnd = lphc->self;
|
||||
UINT id = GetWindowLongA( hWnd, GWL_ID );
|
||||
UINT id = (UINT)GetWindowLongPtrW( hWnd, GWLP_ID );
|
||||
|
||||
TRACE("[%p]: ownerdraw op %04x\n", lphc->self, msg );
|
||||
|
||||
|
@ -1506,7 +1521,7 @@ static LRESULT COMBO_GetTextA( LPHEADCOMBO lphc, INT count, LPSTR buf )
|
|||
if (!count || !buf) return 0;
|
||||
if( lphc->hWndLBox )
|
||||
{
|
||||
INT idx = SendMessageA(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
|
||||
INT idx = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
|
||||
if (idx == LB_ERR) goto error;
|
||||
length = SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, idx, 0 );
|
||||
if (length == LB_ERR) goto error;
|
||||
|
@ -1809,6 +1824,36 @@ static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam )
|
|||
}
|
||||
}
|
||||
|
||||
static LRESULT COMBO_GetComboBoxInfo(LPHEADCOMBO lphc, COMBOBOXINFO *pcbi)
|
||||
{
|
||||
if (!pcbi || (pcbi->cbSize < sizeof(COMBOBOXINFO)))
|
||||
return FALSE;
|
||||
|
||||
pcbi->rcItem = lphc->textRect;
|
||||
pcbi->rcButton = lphc->buttonRect;
|
||||
pcbi->stateButton = 0;
|
||||
if (lphc->wState & CBF_BUTTONDOWN)
|
||||
pcbi->stateButton |= STATE_SYSTEM_PRESSED;
|
||||
if (IsRectEmpty(&lphc->buttonRect))
|
||||
pcbi->stateButton |= STATE_SYSTEM_INVISIBLE;
|
||||
pcbi->hwndCombo = lphc->self;
|
||||
pcbi->hwndItem = lphc->hWndEdit;
|
||||
pcbi->hwndList = lphc->hWndLBox;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *strdupA(LPCSTR str)
|
||||
{
|
||||
char *ret;
|
||||
DWORD len;
|
||||
|
||||
if(!str) return NULL;
|
||||
|
||||
len = strlen(str);
|
||||
ret = HeapAlloc(GetProcessHeap(), 0, len + 1);
|
||||
memcpy(ret, str, len + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* ComboWndProc_common
|
||||
|
@ -1818,7 +1863,7 @@ static void COMBO_MouseMove( LPHEADCOMBO lphc, WPARAM wParam, LPARAM lParam )
|
|||
static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
|
||||
WPARAM wParam, LPARAM lParam, BOOL unicode )
|
||||
{
|
||||
LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongA( hwnd, 0 );
|
||||
LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongPtrW( hwnd, 0 );
|
||||
|
||||
//TRACE("[%p]: msg %s wp %08x lp %08lx\n",
|
||||
// hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam );
|
||||
|
@ -2045,13 +2090,24 @@ static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
|
|||
struprW((LPWSTR)lParam);
|
||||
return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
|
||||
}
|
||||
else
|
||||
else /* unlike the unicode version, the ansi version does not overwrite
|
||||
the string if converting case */
|
||||
{
|
||||
char *string = NULL;
|
||||
LRESULT ret;
|
||||
if( lphc->dwStyle & CBS_LOWERCASE )
|
||||
_strlwr((LPSTR)lParam);
|
||||
{
|
||||
string = strdupA((LPSTR)lParam);
|
||||
_strlwr(string);
|
||||
}
|
||||
else if( lphc->dwStyle & CBS_UPPERCASE )
|
||||
_strupr((LPSTR)lParam);
|
||||
return SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
|
||||
{
|
||||
string = strdupA((LPSTR)lParam);
|
||||
_strupr(string);
|
||||
}
|
||||
ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
|
||||
HeapFree(GetProcessHeap(), 0, string);
|
||||
return ret;
|
||||
}
|
||||
#ifndef __REACTOS__
|
||||
case CB_INSERTSTRING16:
|
||||
|
@ -2291,6 +2347,8 @@ static LRESULT ComboWndProc_common( HWND hwnd, UINT message,
|
|||
#endif
|
||||
case CB_GETEXTENDEDUI:
|
||||
return (lphc->wState & CBF_EUI) ? TRUE : FALSE;
|
||||
case CB_GETCOMBOBOXINFO:
|
||||
return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
|
||||
|
||||
default:
|
||||
if (message >= WM_USER)
|
||||
|
@ -2329,7 +2387,5 @@ static LRESULT WINAPI ComboWndProcW( HWND hwnd, UINT message, WPARAM wParam, LPA
|
|||
BOOL WINAPI GetComboBoxInfo(HWND hwndCombo, /* [in] handle to combo box */
|
||||
PCOMBOBOXINFO pcbi /* [in/out] combo box information */)
|
||||
{
|
||||
FIXME("\n");
|
||||
return FALSE;
|
||||
|
||||
return SendMessageW(hwndCombo, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue