diff --git a/dlls/user/class.c b/dlls/user/class.c index e9aec25c8be..f1f82cf45c7 100644 --- a/dlls/user/class.c +++ b/dlls/user/class.c @@ -151,9 +151,8 @@ static BOOL set_server_info( HWND hwnd, INT offset, LONG newval ) */ static WNDPROC16 CLASS_GetProc16( CLASS *classPtr ) { - WNDPROC proc = classPtr->winprocA; - if (!proc) proc = classPtr->winprocW; - return WINPROC_GetProc16( proc ); + if (classPtr->winprocA) return WINPROC_GetProc16( classPtr->winprocA, FALSE ); + else return WINPROC_GetProc16( classPtr->winprocW, TRUE ); } diff --git a/dlls/user/msg16.c b/dlls/user/msg16.c index db3da018d99..e61fef3c777 100644 --- a/dlls/user/msg16.c +++ b/dlls/user/msg16.c @@ -369,7 +369,7 @@ LONG WINAPI DispatchMessage16( const MSG16* msg ) else SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return 0; } - winproc = WINPROC_GetProc16( wndPtr->winproc ); + winproc = WINPROC_GetProc16( wndPtr->winproc, wndPtr->flags & WIN_ISUNICODE ); WIN_ReleasePtr( wndPtr ); SPY_EnterMessage( SPY_DISPATCHMESSAGE16, hwnd, msg->message, msg->wParam, msg->lParam ); diff --git a/dlls/user/win.c b/dlls/user/win.c index 5a785c542b6..d79cd03c960 100644 --- a/dlls/user/win.c +++ b/dlls/user/win.c @@ -2162,7 +2162,7 @@ LONG WINAPI GetWindowLong16( HWND16 hwnd, INT16 offset ) } } retvalue = GetWindowLongA( WIN_Handle32(hwnd), offset ); - if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue ); + if (is_winproc) retvalue = (LONG_PTR)WINPROC_GetProc16( (WNDPROC)retvalue, FALSE ); return retvalue; } @@ -2212,7 +2212,7 @@ LONG WINAPI SetWindowLong16( HWND16 hwnd, INT16 offset, LONG newval ) { WNDPROC new_proc = WINPROC_AllocProc16( (WNDPROC16)newval ); WNDPROC old_proc = (WNDPROC)SetWindowLongA( WIN_Handle32(hwnd), offset, (LONG_PTR)new_proc ); - return (LONG)WINPROC_GetProc16( (WNDPROC)old_proc ); + return (LONG)WINPROC_GetProc16( (WNDPROC)old_proc, FALSE ); } else return SetWindowLongA( WIN_Handle32(hwnd), offset, newval ); } diff --git a/dlls/user/winproc.c b/dlls/user/winproc.c index ba011276857..d01f13757f9 100644 --- a/dlls/user/winproc.c +++ b/dlls/user/winproc.c @@ -144,8 +144,8 @@ static inline WINDOWPROC *find_winproc( WNDPROC func, BOOL unicode ) return NULL; } -/* allocate and initialize a new winproc */ -static inline WINDOWPROC *alloc_winproc(void) +/* initialize a new winproc */ +static inline WINDOWPROC *init_winproc(void) { WINDOWPROC *proc; @@ -217,6 +217,36 @@ static inline WNDPROC proc_to_handle( WINDOWPROC *proc ) return (WNDPROC)(ULONG_PTR)((proc - winproc_array) | (WINPROC_HANDLE << 16)); } +/* allocate and initialize a new winproc */ +static inline WINDOWPROC *alloc_winproc( WNDPROC func, BOOL unicode ) +{ + WINDOWPROC *proc; + + if (!func) return NULL; + + /* check if the function is already a win proc */ + if ((proc = handle_to_proc( func ))) return proc; + + EnterCriticalSection( &winproc_cs ); + + /* check if we already have a winproc for that function */ + if (!(proc = find_winproc( func, unicode ))) + { + if ((proc = init_winproc())) + { + proc->type = unicode ? WIN_PROC_32W : WIN_PROC_32A; + proc->u.proc32 = func; + TRACE( "allocated %p for %p %c (%d/%d used)\n", + proc_to_handle(proc), func, unicode ? 'W' : 'A', winproc_used, MAX_WINPROCS ); + } + else FIXME( "too many winprocs, cannot allocate one for %p %c\n", func, unicode ? 'W' : 'A' ); + } + else TRACE( "reusing %p for %p %c\n", proc_to_handle(proc), func, unicode ? 'W' : 'A' ); + + LeaveCriticalSection( &winproc_cs ); + return proc; +} + #ifdef __i386__ /* Some window procedures modify register they shouldn't, or are not @@ -456,9 +486,9 @@ static LRESULT WINAPI WINPROC_CallWndProc16( WNDPROC16 proc, HWND16 hwnd, * * Get a window procedure pointer that can be passed to the Windows program. */ -WNDPROC16 WINPROC_GetProc16( WNDPROC proc ) +WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode ) { - WINDOWPROC *ptr = handle_to_proc( proc ); + WINDOWPROC *ptr = alloc_winproc( proc, unicode ); if (!ptr) return 0; @@ -507,7 +537,7 @@ WNDPROC WINPROC_AllocProc16( WNDPROC16 func ) /* then check if we already have a winproc for that function */ if (!(proc = find_winproc16( func ))) { - if ((proc = alloc_winproc())) + if ((proc = init_winproc())) { proc->type = WIN_PROC_16; proc->u.proc16 = func; @@ -537,29 +567,7 @@ WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode ) { WINDOWPROC *proc; - if (!func) return NULL; - - /* check if the function is already a win proc */ - if (!(proc = handle_to_proc( func ))) - { - EnterCriticalSection( &winproc_cs ); - - /* then check if we already have a winproc for that function */ - if (!(proc = find_winproc( func, unicode ))) - { - if ((proc = alloc_winproc())) - { - proc->type = unicode ? WIN_PROC_32W : WIN_PROC_32A; - proc->u.proc32 = func; - TRACE( "allocated %p for %p %c (%d/%d used)\n", - proc_to_handle(proc), func, unicode ? 'W' : 'A', winproc_used, MAX_WINPROCS ); - } - else FIXME( "too many winprocs, cannot allocate one for %p %c\n", func, unicode ? 'W' : 'A' ); - } - else TRACE( "reusing %p for %p %c\n", proc_to_handle(proc), func, unicode ? 'W' : 'A' ); - - LeaveCriticalSection( &winproc_cs ); - } + if (!(proc = alloc_winproc( func, unicode ))) return NULL; return proc_to_handle( proc ); } diff --git a/dlls/user/winproc.h b/dlls/user/winproc.h index 58943ba015d..12b9a259163 100644 --- a/dlls/user/winproc.h +++ b/dlls/user/winproc.h @@ -44,7 +44,7 @@ typedef struct struct tagWINDOWPROC; -extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc ); +extern WNDPROC16 WINPROC_GetProc16( WNDPROC proc, BOOL unicode ); extern WNDPROC WINPROC_AllocProc16( WNDPROC16 func ); extern WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode ); extern WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode ); diff --git a/dlls/user/wnd16.c b/dlls/user/wnd16.c index 327c95623b6..5471f368b1e 100644 --- a/dlls/user/wnd16.c +++ b/dlls/user/wnd16.c @@ -1357,8 +1357,7 @@ BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASSEX16 * if (ret) { - WNDPROC proc = WINPROC_AllocProc( wc32.lpfnWndProc, FALSE ); - wc->lpfnWndProc = WINPROC_GetProc16( proc ); + wc->lpfnWndProc = WINPROC_GetProc16( wc32.lpfnWndProc, FALSE ); wc->style = wc32.style; wc->cbClsExtra = wc32.cbClsExtra; wc->cbWndExtra = wc32.cbWndExtra;