Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container Registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Alexey Alyaev
wine
Commits
f9c01119
Commit
f9c01119
authored
22 years ago
by
György 'Nog' Jeney
Committed by
Alexandre Julliard
22 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Implemented {G|S}etWindowSubClass, DefSubclassProc,
RemoveWindowSubclass.
parent
fc01fcd2
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
dlls/comctl32/comctl32.h
+14
-0
14 additions, 0 deletions
dlls/comctl32/comctl32.h
dlls/comctl32/comctl32.spec
+6
-0
6 additions, 0 deletions
dlls/comctl32/comctl32.spec
dlls/comctl32/commctrl.c
+253
-0
253 additions, 0 deletions
dlls/comctl32/commctrl.c
include/commctrl.h
+6
-0
6 additions, 0 deletions
include/commctrl.h
with
279 additions
and
0 deletions
dlls/comctl32/comctl32.h
+
14
−
0
View file @
f9c01119
...
...
@@ -260,4 +260,18 @@ inline static DWORD hwnd_notify_mouse(HWND hwnd, UINT code, DWORD spec, DWORD da
DEFINE_TOOLTIPSCREATED_NOTIFICATION(CTRLINFO, hwndSelf) \
struct __forward_dummy_struc_dec_to_catch_missing_semicolon
/* Our internal stack structure of the window procedures to subclass */
typedef
struct
{
struct
{
SUBCLASSPROC
subproc
;
UINT_PTR
id
;
DWORD_PTR
ref
;
}
SubclassProcs
[
31
];
int
stackpos
;
int
stacknum
;
int
stacknew
;
WNDPROC
origproc
;
}
SUBCLASS_INFO
,
*
LPSUBCLASS_INFO
;
#endif
/* __WINE_COMCTL32_H */
This diff is collapsed.
Click to expand it.
dlls/comctl32/comctl32.spec
+
6
−
0
View file @
f9c01119
...
...
@@ -188,3 +188,9 @@ init COMCTL32_LibMain
@ stdcall PropertySheetW(ptr) PropertySheetW
@ stdcall UninitializeFlatSB(long) UninitializeFlatSB
@ stdcall _TrackMouseEvent(ptr) _TrackMouseEvent
# These are only available in comctrl 6
@ stdcall DefSubclassProc(long long long long) DefSubclassProc
@ stdcall GetWindowSubclass(long ptr long ptr) GetWindowSubclass
@ stdcall RemoveWindowSubclass(long ptr long) RemoveWindowSubclass
@ stdcall SetWindowSubclass(long ptr long long) SetWindowSubclass
This diff is collapsed.
Click to expand it.
dlls/comctl32/commctrl.c
+
253
−
0
View file @
f9c01119
...
...
@@ -997,6 +997,259 @@ VOID WINAPI InitMUILanguage (LANGID uiLang)
}
/***********************************************************************
* SetWindowSubclass [COMCTL32.@]
*
* Starts a window subclass
*
* PARAMS
* hWnd [in] handle to window subclass.
* pfnSubclass [in] Pointer to new window procedure.
* uIDSubclass [in] Unique identifier of sublass together with pfnSubclass.
* dwRef [in] Reference data to pass to window procedure.
*
* RETURNS
* Success: non-zero
* Failure: zero
*
* BUGS
* If an application manually subclasses a window after subclassing it with
* this API and then with this API again, then none of the previous
* subclasses get called or the origional window procedure.
*/
BOOL
WINAPI
SetWindowSubclass
(
HWND
hWnd
,
SUBCLASSPROC
pfnSubclass
,
UINT_PTR
uIDSubclass
,
DWORD_PTR
dwRef
)
{
LPSUBCLASS_INFO
stack
;
int
newnum
,
n
;
TRACE
(
"(%x, %p, %x, %x)
\n
"
,
hWnd
,
pfnSubclass
,
uIDSubclass
,
dwRef
);
/* Since the window procedure that we set here has two additional arguments,
* we can't simply set it as the new window procedure of the window. So we
* set our own window procedure and then calculate the other two arguments
* from there. */
/* See if we have been called for this window */
stack
=
(
LPSUBCLASS_INFO
)
GetPropA
(
hWnd
,
COMCTL32_aSubclass
);
if
(
!
stack
)
{
/* allocate stack */
stack
=
(
LPSUBCLASS_INFO
)
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
SUBCLASS_INFO
));
if
(
!
stack
)
{
ERR
(
"Failed to allocate our Subclassing stack"
);
return
FALSE
;
}
SetPropA
(
hWnd
,
COMCTL32_aSubclass
,
(
HANDLE
)
stack
);
/* set window procedure to our own and save the current one */
if
(
IsWindowUnicode
(
hWnd
))
stack
->
origproc
=
(
WNDPROC
)
SetWindowLongW
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
DefSubclassProc
);
else
stack
->
origproc
=
(
WNDPROC
)
SetWindowLongA
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
DefSubclassProc
);
}
/* Check to see if we have called this function with the same uIDSubClass
* and pfnSubclass */
for
(
n
=
0
;
n
<=
stack
->
stacknum
+
stack
->
stacknew
-
1
;
n
++
)
if
((
stack
->
SubclassProcs
[
n
].
id
==
uIDSubclass
)
&&
(
stack
->
SubclassProcs
[
n
].
subproc
==
pfnSubclass
))
{
stack
->
SubclassProcs
[
n
].
ref
=
dwRef
;
return
TRUE
;
}
if
((
stack
->
stacknum
+
stack
->
stacknew
)
>=
32
)
{
ERR
(
"We have a Subclass stack overflow, please increment size"
);
return
FALSE
;
}
/* we can't simply increment both stackpos and stacknum because there might
* be a window procedure running lower in the stack, we can only get them
* up to date once the last window procedure has run */
if
(
stack
->
stacknum
==
stack
->
stackpos
)
{
stack
->
stacknum
++
;
stack
->
stackpos
++
;
}
else
stack
->
stacknew
++
;
newnum
=
stack
->
stacknew
+
stack
->
stacknum
-
1
;
stack
->
SubclassProcs
[
newnum
].
subproc
=
pfnSubclass
;
stack
->
SubclassProcs
[
newnum
].
ref
=
dwRef
;
stack
->
SubclassProcs
[
newnum
].
id
=
uIDSubclass
;
return
TRUE
;
}
/***********************************************************************
* GetWindowSubclass [COMCTL32.@]
*
* Gets the Reference data from a subclass.
*
* PARAMS
* hWnd [in] Handle to window which were subclassing
* pfnSubclass [in] Pointer to the subclass procedure
* iID [in] Unique indentifier of the subclassing procedure
* pdwRef [out] Pointer to the reference data
*
* RETURNS
* Success: non-sero
* Failure: zero
*/
BOOL
WINAPI
GetWindowSubclass
(
HWND
hWnd
,
SUBCLASSPROC
pfnSubclass
,
UINT_PTR
uID
,
DWORD_PTR
*
pdwRef
)
{
LPSUBCLASS_INFO
stack
;
int
n
;
TRACE
(
"(%x, %p, %x, %p)
\n
"
,
hWnd
,
pfnSubclass
,
uID
,
pdwRef
);
/* See if we have been called for this window */
stack
=
(
LPSUBCLASS_INFO
)
GetPropA
(
hWnd
,
COMCTL32_aSubclass
);
if
(
!
stack
)
return
FALSE
;
for
(
n
=
0
;
n
<=
stack
->
stacknum
+
stack
->
stacknew
-
1
;
n
++
)
if
((
stack
->
SubclassProcs
[
n
].
id
==
uID
)
&&
(
stack
->
SubclassProcs
[
n
].
subproc
==
pfnSubclass
))
{
*
pdwRef
=
stack
->
SubclassProcs
[
n
].
ref
;
return
TRUE
;
}
return
FALSE
;
}
/***********************************************************************
* RemoveWindowSubclass [COMCTL32.@]
*
* Removes a window subclass.
*
* PARAMS
* hWnd [in] Handle to the window were subclassing
* pfnSubclass [in] Pointer to the subclass procedure
* uID [in] Unique identifier of this subclass
*
* RETURNS
* Success: non-zero
* Failure: zero
*/
BOOL
WINAPI
RemoveWindowSubclass
(
HWND
hWnd
,
SUBCLASSPROC
pfnSubclass
,
UINT_PTR
uID
)
{
LPSUBCLASS_INFO
stack
;
int
n
;
TRACE
(
"(%x, %p, %x)
\n
"
,
hWnd
,
pfnSubclass
,
uID
);
/* Find the Subclass to remove */
stack
=
(
LPSUBCLASS_INFO
)
GetPropA
(
hWnd
,
COMCTL32_aSubclass
);
if
(
!
stack
)
return
FALSE
;
if
((
stack
->
stacknum
==
stack
->
stackpos
==
1
)
&&
!
stack
->
stacknew
)
{
TRACE
(
"Last Subclass removed, cleaning up
\n
"
);
/* clean up our heap and reset the origional window procedure */
if
(
IsWindowUnicode
(
hWnd
))
SetWindowLongW
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
stack
->
origproc
);
else
SetWindowLongA
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
stack
->
origproc
);
HeapFree
(
GetProcessHeap
(),
0
,
stack
);
return
TRUE
;
}
for
(
n
=
stack
->
stacknum
+
stack
->
stacknew
-
1
;
n
>=
0
;
n
--
)
if
((
stack
->
SubclassProcs
[
n
].
id
==
uID
)
&&
(
stack
->
SubclassProcs
[
n
].
subproc
==
pfnSubclass
))
{
if
(
n
!=
(
stack
->
stacknum
+
stack
->
stacknew
))
/* Fill the hole in the stack */
memmove
(
&
stack
->
SubclassProcs
[
n
],
&
stack
->
SubclassProcs
[
n
+
1
],
sizeof
(
stack
->
SubclassProcs
[
0
])
*
(
stack
->
stacknew
+
stack
->
stacknum
-
n
));
stack
->
SubclassProcs
[
n
].
subproc
=
NULL
;
stack
->
SubclassProcs
[
n
].
ref
=
0
;
stack
->
SubclassProcs
[
n
].
id
=
0
;
/* If we are currently running a window procedure we have to manipulate
* the stack position pointers so that we don't corrupt the stack */
if
((
n
<
stack
->
stackpos
)
||
(
stack
->
stackpos
==
stack
->
stacknum
))
{
stack
->
stacknum
--
;
stack
->
stackpos
--
;
}
else
if
(
n
>=
stack
->
stackpos
)
stack
->
stacknew
--
;
return
TRUE
;
}
return
FALSE
;
}
/***********************************************************************
* DefSubclassProc [COMCTL32.@]
*
* Calls the next window procedure (ie. the one before this subclass)
*
* PARAMS
* hWnd [in] The window that we're subclassing
* uMsg [in] Message
* wParam [in] WPARAM
* lParam [in] LPARAM
*
* RETURNS
* Success: non-zero
* Failure: zero
*/
LRESULT
WINAPI
DefSubclassProc
(
HWND
hWnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
)
{
LPSUBCLASS_INFO
stack
;
int
stackpos
;
LRESULT
ret
;
/* retrieve our little stack from the Properties */
stack
=
(
LPSUBCLASS_INFO
)
GetPropA
(
hWnd
,
COMCTL32_aSubclass
);
if
(
!
stack
)
{
ERR
(
"Our sub classing stack got erased for %x!! Nothing we can do
\n
"
,
hWnd
);
return
0
;
}
/* If we are at pos 0 then we have to call the origional window procedure */
if
(
stack
->
stackpos
==
0
)
{
if
(
IsWindowUnicode
(
hWnd
))
return
CallWindowProcW
(
stack
->
origproc
,
hWnd
,
uMsg
,
wParam
,
lParam
);
else
return
CallWindowProcA
(
stack
->
origproc
,
hWnd
,
uMsg
,
wParam
,
lParam
);
}
stackpos
=
--
stack
->
stackpos
;
/* call the Subclass procedure from the stack */
ret
=
stack
->
SubclassProcs
[
stackpos
].
subproc
(
hWnd
,
uMsg
,
wParam
,
lParam
,
stack
->
SubclassProcs
[
stackpos
].
id
,
stack
->
SubclassProcs
[
stackpos
].
ref
);
stack
->
stackpos
++
;
if
((
stack
->
stackpos
==
stack
->
stacknum
)
&&
stack
->
stacknew
)
{
stack
->
stacknum
+=
stack
->
stacknew
;
stack
->
stackpos
+=
stack
->
stacknew
;
stack
->
stacknew
=
0
;
}
/* If we removed the last entry in our stack while a window procedure was
* running then we have to clean up */
if
(
stack
->
stackpos
==
stack
->
stacknum
==
0
)
{
TRACE
(
"Last Subclass removed, cleaning up
\n
"
);
/* clean up our heap and reset the origional window procedure */
if
(
IsWindowUnicode
(
hWnd
))
SetWindowLongW
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
stack
->
origproc
);
else
SetWindowLongA
(
hWnd
,
GWL_WNDPROC
,
(
LONG
)
stack
->
origproc
);
HeapFree
(
GetProcessHeap
(),
0
,
stack
);
return
TRUE
;
}
return
ret
;
}
/***********************************************************************
* COMCTL32_CreateToolTip [NOT AN API]
*
...
...
This diff is collapsed.
Click to expand it.
include/commctrl.h
+
6
−
0
View file @
f9c01119
...
...
@@ -677,6 +677,12 @@ BOOL WINAPI FlatSB_SetScrollProp(HWND, UINT, INT, BOOL);
BOOL
WINAPI
InitializeFlatSB
(
HWND
);
HRESULT
WINAPI
UninitializeFlatSB
(
HWND
);
/* Subclassing stuff */
typedef
LRESULT
(
CALLBACK
*
SUBCLASSPROC
)(
HWND
,
UINT
,
WPARAM
,
LPARAM
,
UINT_PTR
,
DWORD_PTR
);
BOOL
WINAPI
SetWindowSubclass
(
HWND
,
SUBCLASSPROC
,
UINT_PTR
,
DWORD_PTR
);
BOOL
WINAPI
GetWindowSubclass
(
HWND
,
SUBCLASSPROC
,
UINT_PTR
,
DWORD_PTR
*
);
BOOL
WINAPI
RemoveWindowSubclass
(
HWND
,
SUBCLASSPROC
,
UINT_PTR
);
LRESULT
WINAPI
DefSubclassProc
(
HWND
,
UINT
,
WPARAM
,
LPARAM
);
/* Header control */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment