--- trunk/reactos/lib/user32/controls/button.c 2005-12-10 00:07:40 UTC (rev 20031)
+++ trunk/reactos/lib/user32/controls/button.c 2005-12-10 00:15:17 UTC (rev 20032)
@@ -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 @@
__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 @@
{
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 @@
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 @@
}
return 1;
+ case WM_PRINTCLIENT:
case WM_PAINT:
if (btnPaintFunc[btn_type])
{
@@ -248,17 +259,15 @@
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 );
+ set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
SendMessageW( hWnd, BM_SETSTATE, TRUE, 0 );
- set_button_state( hWnd, get_button_state( hWnd ) | BUTTON_BTNPRESSED );
break;
case WM_KEYUP:
@@ -294,8 +303,7 @@
(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 @@
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 @@
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 @@
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 @@
{
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_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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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 @@
SetBkMode(hDC, oldBkMode);
}
+
/**********************************************************************
* Check Box & Radio Button Functions
*/
@@ -816,10 +830,9 @@
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 @@
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 @@
/* 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 @@
/* 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,10 +931,9 @@
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 @@
IntersectRect(&rtext, &rtext, &client);
DrawFocusRect( hDC, &rtext );
}
- SelectClipRgn(hDC, 0);
}
@@ -949,7 +965,7 @@
{
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 @@
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 @@
DrawFocusRect( hDC, &rc );
}
-
/**********************************************************************
* Ownerdrawn Button Functions
*/
@@ -1048,8 +1063,9 @@
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 @@
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);
}
--- trunk/reactos/lib/user32/controls/combo.c 2005-12-10 00:07:40 UTC (rev 20031)
+++ trunk/reactos/lib/user32/controls/combo.c 2005-12-10 00:15:17 UTC (rev 20032)
@@ -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 @@
#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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
{
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 @@
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_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 @@
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,7 +1824,37 @@
}
}
+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 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 @@
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 @@
#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 @@
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);
}