---
dlls/user32/combo.c | 847 +++++++++++++++++++++++---------------------
1 file changed, 445 insertions(+), 402 deletions(-)
diff --git a/dlls/user32/combo.c b/dlls/user32/combo.c
index 31ec6af526..8b7cd17909 100644
--- a/dlls/user32/combo.c
+++ b/dlls/user32/combo.c
@@ -132,9 +132,9 @@ static BOOL COMBO_Init(void)
*/
static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
{
- LPHEADCOMBO lphc;
+ HEADCOMBO *lphc;
- if (COMBO_Init() && (lphc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HEADCOMBO))) )
+ if (COMBO_Init() && (lphc = heap_alloc_zero(sizeof(*lphc))))
{
lphc->self = hwnd;
SetWindowLongPtrW( hwnd, 0, (LONG_PTR)lphc );
@@ -165,20 +165,20 @@ static LRESULT COMBO_NCCreate(HWND hwnd, LONG style)
/***********************************************************************
* COMBO_NCDestroy
*/
-static LRESULT COMBO_NCDestroy( LPHEADCOMBO lphc )
+static LRESULT COMBO_NCDestroy( HEADCOMBO *lphc )
{
+ if (lphc)
+ {
+ TRACE("[%p]: freeing storage\n", lphc->self);
- if( lphc )
- {
- TRACE("[%p]: freeing storage\n", lphc->self);
+ if ( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
+ DestroyWindow( lphc->hWndLBox );
- if( (CB_GETTYPE(lphc) != CBS_SIMPLE) && lphc->hWndLBox )
- DestroyWindow( lphc->hWndLBox );
+ SetWindowLongPtrW( lphc->self, 0, 0 );
+ heap_free( lphc );
+ }
- SetWindowLongPtrW( lphc->self, 0, 0 );
- HeapFree( GetProcessHeap(), 0, lphc );
- }
- return 0;
+ return 0;
}
/***********************************************************************
@@ -684,9 +684,7 @@ static HBRUSH COMBO_PrepareColors(
*
* Paint CBS_DROPDOWNLIST text field / update edit control contents.
*/
-static void CBPaintText(
- LPHEADCOMBO lphc,
- HDC hdc_paint)
+static void CBPaintText(HEADCOMBO *lphc, HDC hdc_paint)
{
RECT rectEdit = lphc->textRect;
INT id, size = 0;
@@ -702,7 +700,7 @@ static void CBPaintText(
size = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, id, 0);
if (size == LB_ERR)
FIXME("LB_ERR probably not handled yet\n");
- if( (pText = HeapAlloc( GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR))) )
+ if ((pText = heap_alloc((size + 1) * sizeof(WCHAR))))
{
/* size from LB_GETTEXTLEN may be too large, from LB_GETTEXT is accurate */
size=SendMessageW(lphc->hWndLBox, LB_GETTEXT, id, (LPARAM)pText);
@@ -800,7 +798,8 @@ static void CBPaintText(
if( !hdc_paint )
ReleaseDC( lphc->self, hdc );
}
- HeapFree( GetProcessHeap(), 0, pText );
+
+ heap_free(pText);
}
/***********************************************************************
@@ -901,8 +900,8 @@ static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
idx = LB_ERR;
length = SendMessageW( lphc->hWndEdit, WM_GETTEXTLENGTH, 0, 0 );
- if( length > 0 )
- pText = HeapAlloc( GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR));
+ if (length > 0)
+ pText = heap_alloc((length + 1) * sizeof(WCHAR));
TRACE("\t edit text length %i\n", length );
@@ -910,7 +909,7 @@ static INT CBUpdateLBox( LPHEADCOMBO lphc, BOOL bSelect )
{
GetWindowTextW( lphc->hWndEdit, pText, length + 1);
idx = SendMessageW(lphc->hWndLBox, LB_FINDSTRING, -1, (LPARAM)pText);
- HeapFree( GetProcessHeap(), 0, pText );
+ heap_free( pText );
}
SendMessageW(lphc->hWndLBox, LB_SETCURSEL, bSelect ? idx : -1, 0);
@@ -940,10 +939,8 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
length = SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, index, 0);
if( length != LB_ERR)
{
- if( (pText = HeapAlloc( GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR))) )
- {
+ if ((pText = heap_alloc((length + 1) * sizeof(WCHAR))))
SendMessageW(lphc->hWndLBox, LB_GETTEXT, index, (LPARAM)pText);
- }
}
}
@@ -957,7 +954,7 @@ static void CBUpdateEdit( LPHEADCOMBO lphc , INT index )
if( lphc->wState & CBF_FOCUSED )
SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
- HeapFree( GetProcessHeap(), 0, pText );
+ heap_free( pText );
}
/***********************************************************************
@@ -1178,7 +1175,7 @@ static void COMBO_KillFocus( LPHEADCOMBO lphc )
if( CB_GETTYPE(lphc) == CBS_DROPDOWNLIST )
SendMessageW(lphc->hWndLBox, LB_CARETOFF, 0, 0);
- lphc->wState &= ~CBF_FOCUSED;
+ lphc->wState &= ~CBF_FOCUSED;
/* redraw text */
if( !(lphc->wState & CBF_EDIT) )
@@ -1349,7 +1346,7 @@ static LRESULT COMBO_ItemOp( LPHEADCOMBO lphc, UINT msg, LPARAM lParam )
/***********************************************************************
* COMBO_GetTextW
*/
-static LRESULT COMBO_GetTextW( LPHEADCOMBO lphc, INT count, LPWSTR buf )
+static LRESULT COMBO_GetTextW( HEADCOMBO *lphc, INT count, LPWSTR buf )
{
INT length;
@@ -1369,7 +1366,7 @@ static LRESULT COMBO_GetTextW( LPHEADCOMBO lphc, INT count, LPWSTR buf )
/* 'length' is without the terminating character */
if (length >= count)
{
- LPWSTR lpBuffer = HeapAlloc(GetProcessHeap(), 0, (length + 1) * sizeof(WCHAR));
+ WCHAR *lpBuffer = heap_alloc((length + 1) * sizeof(WCHAR));
if (!lpBuffer) goto error;
length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)lpBuffer);
@@ -1379,7 +1376,7 @@ static LRESULT COMBO_GetTextW( LPHEADCOMBO lphc, INT count, LPWSTR buf )
lstrcpynW( buf, lpBuffer, count );
length = count;
}
- HeapFree( GetProcessHeap(), 0, lpBuffer );
+ heap_free( lpBuffer );
}
else length = SendMessageW(lphc->hWndLBox, LB_GETTEXT, idx, (LPARAM)buf);
@@ -1786,393 +1783,439 @@ static char *strdupA(LPCSTR str)
*/
LRESULT ComboWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
{
- LPHEADCOMBO lphc = (LPHEADCOMBO)GetWindowLongPtrW( hwnd, 0 );
+ HEADCOMBO *lphc = (HEADCOMBO *)GetWindowLongPtrW( hwnd, 0 );
- TRACE("[%p]: msg %s wp %08lx lp %08lx\n",
- hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam );
+ TRACE("[%p]: msg %s wp %08lx lp %08lx\n",
+ hwnd, SPY_GetMsgName(message, hwnd), wParam, lParam );
- if (!IsWindow(hwnd)) return 0;
+ if (!IsWindow(hwnd)) return 0;
- if( lphc || message == WM_NCCREATE )
- switch(message)
- {
+ if (lphc || message == WM_NCCREATE)
+ switch(message)
+ {
- /* System messages */
+ /* System messages */
- case WM_NCCREATE:
- {
- LONG style = unicode ? ((LPCREATESTRUCTW)lParam)->style :
- ((LPCREATESTRUCTA)lParam)->style;
- return COMBO_NCCreate(hwnd, style);
- }
- case WM_NCDESTROY:
- COMBO_NCDestroy(lphc);
- break;/* -> DefWindowProc */
-
- case WM_CREATE:
- {
- HWND hwndParent;
- LONG style;
- if(unicode)
- {
- hwndParent = ((LPCREATESTRUCTW)lParam)->hwndParent;
- style = ((LPCREATESTRUCTW)lParam)->style;
- }
- else
- {
- hwndParent = ((LPCREATESTRUCTA)lParam)->hwndParent;
- style = ((LPCREATESTRUCTA)lParam)->style;
- }
- return COMBO_Create(hwnd, lphc, hwndParent, style, unicode);
- }
+ case WM_NCCREATE:
+ {
+ LONG style = unicode ? ((LPCREATESTRUCTW)lParam)->style :
+ ((LPCREATESTRUCTA)lParam)->style;
+ return COMBO_NCCreate(hwnd, style);
+ }
+ case WM_NCDESTROY:
+ COMBO_NCDestroy(lphc);
+ break;/* -> DefWindowProc */
- case WM_PRINTCLIENT:
- /* Fallthrough */
- case WM_PAINT:
- /* wParam may contain a valid HDC! */
- return COMBO_Paint(lphc, (HDC)wParam);
+ case WM_CREATE:
+ {
+ HWND hwndParent;
+ LONG style;
+ if(unicode)
+ {
+ hwndParent = ((LPCREATESTRUCTW)lParam)->hwndParent;
+ style = ((LPCREATESTRUCTW)lParam)->style;
+ }
+ else
+ {
+ hwndParent = ((LPCREATESTRUCTA)lParam)->hwndParent;
+ style = ((LPCREATESTRUCTA)lParam)->style;
+ }
+ return COMBO_Create(hwnd, lphc, hwndParent, style, unicode);
+ }
- case WM_ERASEBKGND:
- /* do all painting in WM_PAINT like Windows does */
- return 1;
+ case WM_PRINTCLIENT:
+ case WM_PAINT:
+ /* wParam may contain a valid HDC! */
+ return COMBO_Paint(lphc, (HDC)wParam);
- case WM_GETDLGCODE:
- {
- LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
- if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
- {
- int vk = (int)((LPMSG)lParam)->wParam;
+ case WM_ERASEBKGND:
+ /* do all painting in WM_PAINT like Windows does */
+ return 1;
- if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
- result |= DLGC_WANTMESSAGE;
- }
- return result;
- }
- case WM_SIZE:
- if( lphc->hWndLBox &&
- !(lphc->wState & CBF_NORESIZE) ) COMBO_Size( lphc );
- return TRUE;
- case WM_SETFONT:
- COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
- return TRUE;
- case WM_GETFONT:
- return (LRESULT)lphc->hFont;
- case WM_SETFOCUS:
- if( lphc->wState & CBF_EDIT ) {
- SetFocus( lphc->hWndEdit );
- /* The first time focus is received, select all the text */
- if( !(lphc->wState & CBF_BEENFOCUSED) ) {
- SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
- lphc->wState |= CBF_BEENFOCUSED;
- }
- }
- else
- COMBO_SetFocus( lphc );
- return TRUE;
- case WM_KILLFOCUS:
+ case WM_GETDLGCODE:
+ {
+ LRESULT result = DLGC_WANTARROWS | DLGC_WANTCHARS;
+ if (lParam && (((LPMSG)lParam)->message == WM_KEYDOWN))
+ {
+ int vk = (int)((LPMSG)lParam)->wParam;
+
+ if ((vk == VK_RETURN || vk == VK_ESCAPE) && (lphc->wState & CBF_DROPPED))
+ result |= DLGC_WANTMESSAGE;
+ }
+ return result;
+ }
+
+ case WM_SIZE:
+ if (lphc->hWndLBox && !(lphc->wState & CBF_NORESIZE))
+ COMBO_Size( lphc );
+ return TRUE;
+
+ case WM_SETFONT:
+ COMBO_Font( lphc, (HFONT)wParam, (BOOL)lParam );
+ return TRUE;
+
+ case WM_GETFONT:
+ return (LRESULT)lphc->hFont;
+
+ case WM_SETFOCUS:
+ if (lphc->wState & CBF_EDIT)
+ {
+ SetFocus( lphc->hWndEdit );
+ /* The first time focus is received, select all the text */
+ if (!(lphc->wState & CBF_BEENFOCUSED))
{
- HWND hwndFocus = WIN_GetFullHandle( (HWND)wParam );
- if( !hwndFocus ||
- (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox ))
- COMBO_KillFocus( lphc );
- return TRUE;
+ SendMessageW(lphc->hWndEdit, EM_SETSEL, 0, -1);
+ lphc->wState |= CBF_BEENFOCUSED;
}
- case WM_COMMAND:
- return COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) );
- case WM_GETTEXT:
- return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
- : COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
- case WM_SETTEXT:
- case WM_GETTEXTLENGTH:
- case WM_CLEAR:
- if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
- {
- int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
- if (j == -1) return 0;
- return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0) :
- SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
- }
- else if( lphc->wState & CBF_EDIT )
- {
- LRESULT ret;
- lphc->wState |= CBF_NOEDITNOTIFY;
- ret = unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
- SendMessageA(lphc->hWndEdit, message, wParam, lParam);
- lphc->wState &= ~CBF_NOEDITNOTIFY;
- return ret;
- }
- else return CB_ERR;
- case WM_CUT:
- case WM_PASTE:
- case WM_COPY:
- if( lphc->wState & CBF_EDIT )
- {
- return unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
- SendMessageA(lphc->hWndEdit, message, wParam, lParam);
- }
- else return CB_ERR;
-
- case WM_DRAWITEM:
- case WM_DELETEITEM:
- case WM_COMPAREITEM:
- case WM_MEASUREITEM:
- return COMBO_ItemOp(lphc, message, lParam);
- case WM_ENABLE:
- if( lphc->wState & CBF_EDIT )
- EnableWindow( lphc->hWndEdit, (BOOL)wParam );
- EnableWindow( lphc->hWndLBox, (BOOL)wParam );
-
- /* Force the control to repaint when the enabled state changes. */
- InvalidateRect(lphc->self, NULL, TRUE);
- return TRUE;
- case WM_SETREDRAW:
- if( wParam )
- lphc->wState &= ~CBF_NOREDRAW;
- else
- lphc->wState |= CBF_NOREDRAW;
-
- if( lphc->wState & CBF_EDIT )
- SendMessageW(lphc->hWndEdit, message, wParam, lParam);
- SendMessageW(lphc->hWndLBox, message, wParam, lParam);
- return 0;
- case WM_SYSKEYDOWN:
- if( KEYDATA_ALT & HIWORD(lParam) )
- if( wParam == VK_UP || wParam == VK_DOWN )
- COMBO_FlipListbox( lphc, FALSE, FALSE );
- return 0;
-
- case WM_KEYDOWN:
- if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
- (lphc->wState & CBF_DROPPED))
- {
- CBRollUp( lphc, wParam == VK_RETURN, FALSE );
- return TRUE;
- }
- else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
- {
- COMBO_FlipListbox( lphc, FALSE, FALSE );
- return TRUE;
- }
- /* fall through */
- case WM_CHAR:
- case WM_IME_CHAR:
- {
- HWND hwndTarget;
+ }
+ else
+ COMBO_SetFocus( lphc );
+ return TRUE;
- if( lphc->wState & CBF_EDIT )
- hwndTarget = lphc->hWndEdit;
- else
- hwndTarget = lphc->hWndLBox;
-
- return unicode ? SendMessageW(hwndTarget, message, wParam, lParam) :
- SendMessageA(hwndTarget, message, wParam, lParam);
- }
- case WM_LBUTTONDOWN:
- if( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
- if( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
- return TRUE;
- case WM_LBUTTONUP:
- COMBO_LButtonUp( lphc );
- return TRUE;
- case WM_MOUSEMOVE:
- if( lphc->wState & CBF_CAPTURE )
- COMBO_MouseMove( lphc, wParam, lParam );
- return TRUE;
-
- case WM_MOUSEWHEEL:
- if (wParam & (MK_SHIFT | MK_CONTROL))
- return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
- DefWindowProcA(hwnd, message, wParam, lParam);
-
- if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
- if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
- return TRUE;
-
- /* Combo messages */
-
- case CB_ADDSTRING:
- if( unicode )
- {
- if( lphc->dwStyle & CBS_LOWERCASE )
- CharLowerW((LPWSTR)lParam);
- else if( lphc->dwStyle & CBS_UPPERCASE )
- CharUpperW((LPWSTR)lParam);
- return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
- }
- 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 )
- {
- string = strdupA((LPSTR)lParam);
- CharLowerA(string);
- }
-
- else if( lphc->dwStyle & CBS_UPPERCASE )
- {
- string = strdupA((LPSTR)lParam);
- CharUpperA(string);
- }
-
- ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
- HeapFree(GetProcessHeap(), 0, string);
- return ret;
- }
- case CB_INSERTSTRING:
- if( unicode )
- {
- if( lphc->dwStyle & CBS_LOWERCASE )
- CharLowerW((LPWSTR)lParam);
- else if( lphc->dwStyle & CBS_UPPERCASE )
- CharUpperW((LPWSTR)lParam);
- return SendMessageW(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
- }
- else
- {
- if( lphc->dwStyle & CBS_LOWERCASE )
- CharLowerA((LPSTR)lParam);
- else if( lphc->dwStyle & CBS_UPPERCASE )
- CharUpperA((LPSTR)lParam);
+ case WM_KILLFOCUS:
+ {
+ HWND hwndFocus = WIN_GetFullHandle( (HWND)wParam );
+ if (!hwndFocus || (hwndFocus != lphc->hWndEdit && hwndFocus != lphc->hWndLBox))
+ COMBO_KillFocus( lphc );
+ return TRUE;
+ }
- return SendMessageA(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
- }
- case CB_DELETESTRING:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0) :
- SendMessageA(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
- case CB_SELECTSTRING:
- return COMBO_SelectString(lphc, (INT)wParam, lParam, unicode);
- case CB_FINDSTRING:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam) :
- SendMessageA(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
- case CB_FINDSTRINGEXACT:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam) :
- SendMessageA(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam);
- case CB_SETITEMHEIGHT:
- return COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
- case CB_GETITEMHEIGHT:
- if( (INT)wParam >= 0 ) /* listbox item */
- return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
- return CBGetTextAreaHeight(hwnd, lphc);
- case CB_RESETCONTENT:
- SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
- if( (lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc) )
- {
- static const WCHAR empty_stringW[] = { 0 };
- SendMessageW(lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)empty_stringW);
- }
- else
- InvalidateRect(lphc->self, NULL, TRUE);
- return TRUE;
- case CB_INITSTORAGE:
- return SendMessageW(lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
- case CB_GETHORIZONTALEXTENT:
- return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
- case CB_SETHORIZONTALEXTENT:
- return SendMessageW(lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
- case CB_GETTOPINDEX:
- return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
- case CB_GETLOCALE:
- return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
- case CB_SETLOCALE:
- return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
- case CB_SETDROPPEDWIDTH:
- if( (CB_GETTYPE(lphc) == CBS_SIMPLE) ||
- (INT)wParam >= 32768 )
- return CB_ERR;
- /* new value must be higher than combobox width */
- if((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
- lphc->droppedWidth = wParam;
- else if(wParam)
- lphc->droppedWidth = 0;
-
- /* recalculate the combobox area */
- CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
-
- /* fall through */
- case CB_GETDROPPEDWIDTH:
- if( lphc->droppedWidth )
- return lphc->droppedWidth;
- return lphc->droppedRect.right - lphc->droppedRect.left;
- case CB_GETDROPPEDCONTROLRECT:
- if( lParam ) CBGetDroppedControlRect(lphc, (LPRECT)lParam );
- return CB_OKAY;
- case CB_GETDROPPEDSTATE:
- return (lphc->wState & CBF_DROPPED) != 0;
- case CB_DIR:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam) :
- SendMessageA(lphc->hWndLBox, LB_DIR, wParam, lParam);
-
- case CB_SHOWDROPDOWN:
- if( CB_GETTYPE(lphc) != CBS_SIMPLE )
- {
- if( wParam )
- {
- if( !(lphc->wState & CBF_DROPPED) )
- CBDropDown( lphc );
- }
- else
- if( lphc->wState & CBF_DROPPED )
- CBRollUp( lphc, FALSE, TRUE );
- }
- return TRUE;
- case CB_GETCOUNT:
- return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
- case CB_GETCURSEL:
- return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
- case CB_SETCURSEL:
- lParam = SendMessageW(lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
- if( lParam >= 0 )
- SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
-
- /* no LBN_SELCHANGE in this case, update manually */
- CBPaintText( lphc, NULL );
- lphc->wState &= ~CBF_SELCHANGE;
- return lParam;
- case CB_GETLBTEXT:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam) :
- SendMessageA(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
- case CB_GETLBTEXTLEN:
- return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0) :
- SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
- case CB_GETITEMDATA:
- return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
- case CB_SETITEMDATA:
- return SendMessageW(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
- case CB_GETEDITSEL:
- /* Edit checks passed parameters itself */
- if( lphc->wState & CBF_EDIT )
- return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
- return CB_ERR;
- case CB_SETEDITSEL:
- if( lphc->wState & CBF_EDIT )
- return SendMessageW(lphc->hWndEdit, EM_SETSEL,
- (INT)(SHORT)LOWORD(lParam), (INT)(SHORT)HIWORD(lParam) );
- return CB_ERR;
- case CB_SETEXTENDEDUI:
- if( CB_GETTYPE(lphc) == CBS_SIMPLE )
- return CB_ERR;
- if( wParam )
- lphc->wState |= CBF_EUI;
- else lphc->wState &= ~CBF_EUI;
- return CB_OKAY;
- case CB_GETEXTENDEDUI:
- return (lphc->wState & CBF_EUI) != 0;
- case CB_GETCOMBOBOXINFO:
- return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
- case CB_LIMITTEXT:
- if( lphc->wState & CBF_EDIT )
- return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
- return TRUE;
- default:
- if (message >= WM_USER)
- WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n",
- message - WM_USER, wParam, lParam );
- break;
- }
- return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
- DefWindowProcA(hwnd, message, wParam, lParam);
+ case WM_COMMAND:
+ return COMBO_Command( lphc, wParam, WIN_GetFullHandle( (HWND)lParam ) );
+
+ case WM_GETTEXT:
+ return unicode ? COMBO_GetTextW( lphc, wParam, (LPWSTR)lParam )
+ : COMBO_GetTextA( lphc, wParam, (LPSTR)lParam );
+
+ case WM_SETTEXT:
+ case WM_GETTEXTLENGTH:
+ case WM_CLEAR:
+ if ((message == WM_GETTEXTLENGTH) && !ISWIN31 && !(lphc->wState & CBF_EDIT))
+ {
+ int j = SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+ if (j == -1) return 0;
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, j, 0) :
+ SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, j, 0);
+ }
+ else if ( lphc->wState & CBF_EDIT )
+ {
+ LRESULT ret;
+ lphc->wState |= CBF_NOEDITNOTIFY;
+ ret = unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
+ SendMessageA(lphc->hWndEdit, message, wParam, lParam);
+ lphc->wState &= ~CBF_NOEDITNOTIFY;
+ return ret;
+ }
+ else
+ return CB_ERR;
+
+ case WM_CUT:
+ case WM_PASTE:
+ case WM_COPY:
+ if (lphc->wState & CBF_EDIT)
+ {
+ return unicode ? SendMessageW(lphc->hWndEdit, message, wParam, lParam) :
+ SendMessageA(lphc->hWndEdit, message, wParam, lParam);
+ }
+ else return CB_ERR;
+
+ case WM_DRAWITEM:
+ case WM_DELETEITEM:
+ case WM_COMPAREITEM:
+ case WM_MEASUREITEM:
+ return COMBO_ItemOp(lphc, message, lParam);
+
+ case WM_ENABLE:
+ if (lphc->wState & CBF_EDIT)
+ EnableWindow( lphc->hWndEdit, (BOOL)wParam );
+ EnableWindow( lphc->hWndLBox, (BOOL)wParam );
+
+ /* Force the control to repaint when the enabled state changes. */
+ InvalidateRect(lphc->self, NULL, TRUE);
+ return TRUE;
+
+ case WM_SETREDRAW:
+ if (wParam)
+ lphc->wState &= ~CBF_NOREDRAW;
+ else
+ lphc->wState |= CBF_NOREDRAW;
+
+ if ( lphc->wState & CBF_EDIT )
+ SendMessageW(lphc->hWndEdit, message, wParam, lParam);
+ SendMessageW(lphc->hWndLBox, message, wParam, lParam);
+ return 0;
+
+ case WM_SYSKEYDOWN:
+ if ( KEYDATA_ALT & HIWORD(lParam) )
+ if( wParam == VK_UP || wParam == VK_DOWN )
+ COMBO_FlipListbox( lphc, FALSE, FALSE );
+ return 0;
+
+ case WM_KEYDOWN:
+ if ((wParam == VK_RETURN || wParam == VK_ESCAPE) &&
+ (lphc->wState & CBF_DROPPED))
+ {
+ CBRollUp( lphc, wParam == VK_RETURN, FALSE );
+ return TRUE;
+ }
+ else if ((wParam == VK_F4) && !(lphc->wState & CBF_EUI))
+ {
+ COMBO_FlipListbox( lphc, FALSE, FALSE );
+ return TRUE;
+ }
+ /* fall through */
+ case WM_CHAR:
+ case WM_IME_CHAR:
+ {
+ HWND hwndTarget;
+
+ if ( lphc->wState & CBF_EDIT )
+ hwndTarget = lphc->hWndEdit;
+ else
+ hwndTarget = lphc->hWndLBox;
+
+ return unicode ? SendMessageW(hwndTarget, message, wParam, lParam) :
+ SendMessageA(hwndTarget, message, wParam, lParam);
+ }
+
+ case WM_LBUTTONDOWN:
+ if ( !(lphc->wState & CBF_FOCUSED) ) SetFocus( lphc->self );
+ if ( lphc->wState & CBF_FOCUSED ) COMBO_LButtonDown( lphc, lParam );
+ return TRUE;
+
+ case WM_LBUTTONUP:
+ COMBO_LButtonUp( lphc );
+ return TRUE;
+
+ case WM_MOUSEMOVE:
+ if (lphc->wState & CBF_CAPTURE)
+ COMBO_MouseMove( lphc, wParam, lParam );
+ return TRUE;
+
+ case WM_MOUSEWHEEL:
+ if (wParam & (MK_SHIFT | MK_CONTROL))
+ return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
+ DefWindowProcA(hwnd, message, wParam, lParam);
+
+ if (GET_WHEEL_DELTA_WPARAM(wParam) > 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_UP, 0);
+ if (GET_WHEEL_DELTA_WPARAM(wParam) < 0) return SendMessageW(hwnd, WM_KEYDOWN, VK_DOWN, 0);
+ return TRUE;
+
+ /* Combo messages */
+
+ case CB_ADDSTRING:
+ if( unicode )
+ {
+ if( lphc->dwStyle & CBS_LOWERCASE )
+ CharLowerW((LPWSTR)lParam);
+ else if( lphc->dwStyle & CBS_UPPERCASE )
+ CharUpperW((LPWSTR)lParam);
+ return SendMessageW(lphc->hWndLBox, LB_ADDSTRING, 0, lParam);
+ }
+ 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 )
+ {
+ string = strdupA((LPSTR)lParam);
+ CharLowerA(string);
+ }
+
+ else if( lphc->dwStyle & CBS_UPPERCASE )
+ {
+ string = strdupA((LPSTR)lParam);
+ CharUpperA(string);
+ }
+
+ ret = SendMessageA(lphc->hWndLBox, LB_ADDSTRING, 0, string ? (LPARAM)string : lParam);
+ HeapFree(GetProcessHeap(), 0, string);
+ return ret;
+ }
+ case CB_INSERTSTRING:
+ if( unicode )
+ {
+ if( lphc->dwStyle & CBS_LOWERCASE )
+ CharLowerW((LPWSTR)lParam);
+ else if( lphc->dwStyle & CBS_UPPERCASE )
+ CharUpperW((LPWSTR)lParam);
+ return SendMessageW(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+ }
+ else
+ {
+ if( lphc->dwStyle & CBS_LOWERCASE )
+ CharLowerA((LPSTR)lParam);
+ else if( lphc->dwStyle & CBS_UPPERCASE )
+ CharUpperA((LPSTR)lParam);
+
+ return SendMessageA(lphc->hWndLBox, LB_INSERTSTRING, wParam, lParam);
+ }
+ case CB_DELETESTRING:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_DELETESTRING, wParam, 0) :
+ SendMessageA(lphc->hWndLBox, LB_DELETESTRING, wParam, 0);
+
+ case CB_SELECTSTRING:
+ return COMBO_SelectString(lphc, (INT)wParam, lParam, unicode);
+
+ case CB_FINDSTRING:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam) :
+ SendMessageA(lphc->hWndLBox, LB_FINDSTRING, wParam, lParam);
+
+ case CB_FINDSTRINGEXACT:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam) :
+ SendMessageA(lphc->hWndLBox, LB_FINDSTRINGEXACT, wParam, lParam);
+
+ case CB_SETITEMHEIGHT:
+ return COMBO_SetItemHeight( lphc, (INT)wParam, (INT)lParam);
+
+ case CB_GETITEMHEIGHT:
+ if ((INT)wParam >= 0) /* listbox item */
+ return SendMessageW(lphc->hWndLBox, LB_GETITEMHEIGHT, wParam, 0);
+ return CBGetTextAreaHeight(hwnd, lphc);
+
+ case CB_RESETCONTENT:
+ SendMessageW(lphc->hWndLBox, LB_RESETCONTENT, 0, 0);
+
+ if ((lphc->wState & CBF_EDIT) && CB_HASSTRINGS(lphc))
+ {
+ static const WCHAR empty_stringW[] = { 0 };
+ SendMessageW(lphc->hWndEdit, WM_SETTEXT, 0, (LPARAM)empty_stringW);
+ }
+ else
+ InvalidateRect(lphc->self, NULL, TRUE);
+ return TRUE;
+
+ case CB_INITSTORAGE:
+ return SendMessageW(lphc->hWndLBox, LB_INITSTORAGE, wParam, lParam);
+
+ case CB_GETHORIZONTALEXTENT:
+ return SendMessageW(lphc->hWndLBox, LB_GETHORIZONTALEXTENT, 0, 0);
+
+ case CB_SETHORIZONTALEXTENT:
+ return SendMessageW(lphc->hWndLBox, LB_SETHORIZONTALEXTENT, wParam, 0);
+
+ case CB_GETTOPINDEX:
+ return SendMessageW(lphc->hWndLBox, LB_GETTOPINDEX, 0, 0);
+
+ case CB_GETLOCALE:
+ return SendMessageW(lphc->hWndLBox, LB_GETLOCALE, 0, 0);
+
+ case CB_SETLOCALE:
+ return SendMessageW(lphc->hWndLBox, LB_SETLOCALE, wParam, 0);
+
+ case CB_SETDROPPEDWIDTH:
+ if ((CB_GETTYPE(lphc) == CBS_SIMPLE) || (INT)wParam >= 32768)
+ return CB_ERR;
+
+ /* new value must be higher than combobox width */
+ if ((INT)wParam >= lphc->droppedRect.right - lphc->droppedRect.left)
+ lphc->droppedWidth = wParam;
+ else if (wParam)
+ lphc->droppedWidth = 0;
+
+ /* recalculate the combobox area */
+ CBCalcPlacement(hwnd, lphc, &lphc->textRect, &lphc->buttonRect, &lphc->droppedRect );
+
+ /* fall through */
+ case CB_GETDROPPEDWIDTH:
+ if (lphc->droppedWidth)
+ return lphc->droppedWidth;
+ return lphc->droppedRect.right - lphc->droppedRect.left;
+
+ case CB_GETDROPPEDCONTROLRECT:
+ if (lParam)
+ CBGetDroppedControlRect(lphc, (LPRECT)lParam );
+ return CB_OKAY;
+
+ case CB_GETDROPPEDSTATE:
+ return (lphc->wState & CBF_DROPPED) != 0;
+
+ case CB_DIR:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_DIR, wParam, lParam) :
+ SendMessageA(lphc->hWndLBox, LB_DIR, wParam, lParam);
+
+ case CB_SHOWDROPDOWN:
+ if (CB_GETTYPE(lphc) != CBS_SIMPLE)
+ {
+ if (wParam)
+ {
+ if (!(lphc->wState & CBF_DROPPED))
+ CBDropDown( lphc );
+ }
+ else if (lphc->wState & CBF_DROPPED)
+ CBRollUp( lphc, FALSE, TRUE );
+ }
+ return TRUE;
+
+ case CB_GETCOUNT:
+ return SendMessageW(lphc->hWndLBox, LB_GETCOUNT, 0, 0);
+
+ case CB_GETCURSEL:
+ return SendMessageW(lphc->hWndLBox, LB_GETCURSEL, 0, 0);
+
+ case CB_SETCURSEL:
+ lParam = SendMessageW(lphc->hWndLBox, LB_SETCURSEL, wParam, 0);
+ if (lParam >= 0)
+ SendMessageW(lphc->hWndLBox, LB_SETTOPINDEX, wParam, 0);
+
+ /* no LBN_SELCHANGE in this case, update manually */
+ CBPaintText(lphc, NULL);
+ lphc->wState &= ~CBF_SELCHANGE;
+ return lParam;
+
+ case CB_GETLBTEXT:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXT, wParam, lParam) :
+ SendMessageA(lphc->hWndLBox, LB_GETTEXT, wParam, lParam);
+
+ case CB_GETLBTEXTLEN:
+ return unicode ? SendMessageW(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0) :
+ SendMessageA(lphc->hWndLBox, LB_GETTEXTLEN, wParam, 0);
+
+ case CB_GETITEMDATA:
+ return SendMessageW(lphc->hWndLBox, LB_GETITEMDATA, wParam, 0);
+
+ case CB_SETITEMDATA:
+ return SendMessageW(lphc->hWndLBox, LB_SETITEMDATA, wParam, lParam);
+
+ case CB_GETEDITSEL:
+ /* Edit checks passed parameters itself */
+ if (lphc->wState & CBF_EDIT)
+ return SendMessageW(lphc->hWndEdit, EM_GETSEL, wParam, lParam);
+ return CB_ERR;
+
+ case CB_SETEDITSEL:
+ if (lphc->wState & CBF_EDIT)
+ return SendMessageW(lphc->hWndEdit, EM_SETSEL, (INT)(SHORT)LOWORD(lParam), (INT)(SHORT)HIWORD(lParam) );
+ return CB_ERR;
+
+ case CB_SETEXTENDEDUI:
+ if (CB_GETTYPE(lphc) == CBS_SIMPLE )
+ return CB_ERR;
+ if (wParam)
+ lphc->wState |= CBF_EUI;
+ else
+ lphc->wState &= ~CBF_EUI;
+ return CB_OKAY;
+
+ case CB_GETEXTENDEDUI:
+ return (lphc->wState & CBF_EUI) != 0;
+
+ case CB_GETCOMBOBOXINFO:
+ return COMBO_GetComboBoxInfo(lphc, (COMBOBOXINFO *)lParam);
+
+ case CB_LIMITTEXT:
+ if (lphc->wState & CBF_EDIT)
+ return SendMessageW(lphc->hWndEdit, EM_LIMITTEXT, wParam, lParam);
+ return TRUE;
+
+ default:
+ if (message >= WM_USER)
+ WARN("unknown msg WM_USER+%04x wp=%04lx lp=%08lx\n", message - WM_USER, wParam, lParam );
+ break;
+ }
+ return unicode ? DefWindowProcW(hwnd, message, wParam, lParam) :
+ DefWindowProcA(hwnd, message, wParam, lParam);
}
/*************************************************************************
--
2.19.1