merged changes from wine to button and combobox code.

svn path=/trunk/; revision=20032
This commit is contained in:
Sebastian Gasiorek 2005-12-10 00:15:17 +00:00
parent 711bd1e8ae
commit 87c69dc1fe
2 changed files with 152 additions and 78 deletions

View file

@ -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);
}

View file

@ -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);
}