merged changes from wine to button and combobox code. Modified: trunk/reactos/lib/user32/controls/button.c Modified: trunk/reactos/lib/user32/controls/combo.c _____
Modified: trunk/reactos/lib/user32/controls/button.c --- 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); } _____
Modified: trunk/reactos/lib/user32/controls/combo.c --- 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); }