Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
2ce799c4
Commit
2ce799c4
authored
Aug 08, 2007
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user32: Support for the magic WM_CHAR W->A conversion in Get/PeekMessage.
parent
b9540cf9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
129 additions
and
25 deletions
+129
-25
message.c
dlls/user32/message.c
+60
-25
msg.c
dlls/user32/tests/msg.c
+68
-0
user_private.h
dlls/user32/user_private.h
+1
-0
No files found.
dlls/user32/message.c
View file @
2ce799c4
...
...
@@ -307,6 +307,18 @@ static inline BOOL check_hwnd_filter( const MSG *msg, HWND hwnd_filter )
return
(
msg
->
hwnd
==
hwnd_filter
||
IsChild
(
hwnd_filter
,
msg
->
hwnd
));
}
/* check for pending WM_CHAR message with DBCS trailing byte */
static
inline
BOOL
get_pending_wmchar
(
MSG
*
msg
,
UINT
first
,
UINT
last
,
BOOL
remove
)
{
struct
wm_char_mapping_data
*
data
=
get_user_thread_info
()
->
wmchar_data
;
if
(
!
data
||
!
data
->
get_msg
.
message
)
return
FALSE
;
if
((
first
||
last
)
&&
(
first
>
WM_CHAR
||
last
<
WM_CHAR
))
return
FALSE
;
if
(
!
msg
)
return
FALSE
;
*
msg
=
data
->
get_msg
;
if
(
remove
)
data
->
get_msg
.
message
=
0
;
return
TRUE
;
}
/***********************************************************************
* broadcast_message_callback
...
...
@@ -435,39 +447,60 @@ BOOL map_wparam_AtoW( UINT message, WPARAM *wparam, enum wm_char_mapping mapping
*
* Convert the wparam of a Unicode message to ASCII.
*/
static
WPARAM
map_wparam_WtoA
(
UINT
message
,
WPARAM
wparam
)
static
void
map_wparam_WtoA
(
MSG
*
msg
,
BOOL
remove
)
{
switch
(
message
)
BYTE
ch
[
2
];
WCHAR
wch
[
2
];
DWORD
len
;
switch
(
msg
->
message
)
{
case
WM_CHAR
:
if
(
!
HIWORD
(
msg
->
wParam
))
{
wch
[
0
]
=
LOWORD
(
msg
->
wParam
);
ch
[
0
]
=
ch
[
1
]
=
0
;
RtlUnicodeToMultiByteN
(
(
LPSTR
)
ch
,
2
,
&
len
,
wch
,
sizeof
(
wch
[
0
])
);
if
(
len
==
2
)
/* DBCS char */
{
struct
wm_char_mapping_data
*
data
=
get_user_thread_info
()
->
wmchar_data
;
if
(
!
data
)
{
if
(
!
(
data
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
sizeof
(
*
data
)
)))
return
;
get_user_thread_info
()
->
wmchar_data
=
data
;
}
if
(
remove
)
{
data
->
get_msg
=
*
msg
;
data
->
get_msg
.
wParam
=
ch
[
1
];
}
msg
->
wParam
=
ch
[
0
];
return
;
}
}
/* else fall through */
case
WM_CHARTOITEM
:
case
EM_SETPASSWORDCHAR
:
case
WM_CHAR
:
case
WM_DEADCHAR
:
case
WM_SYSCHAR
:
case
WM_SYSDEADCHAR
:
case
WM_MENUCHAR
:
{
WCHAR
wch
[
2
];
BYTE
ch
[
2
];
wch
[
0
]
=
LOWORD
(
wparam
);
wch
[
1
]
=
HIWORD
(
wparam
);
WideCharToMultiByte
(
CP_ACP
,
0
,
wch
,
2
,
(
LPSTR
)
ch
,
2
,
NULL
,
NULL
);
wparam
=
MAKEWPARAM
(
ch
[
0
]
|
(
ch
[
1
]
<<
8
),
0
);
}
wch
[
0
]
=
LOWORD
(
msg
->
wParam
);
wch
[
1
]
=
HIWORD
(
msg
->
wParam
);
ch
[
0
]
=
ch
[
1
]
=
0
;
RtlUnicodeToMultiByteN
(
(
LPSTR
)
ch
,
2
,
NULL
,
wch
,
sizeof
(
wch
)
);
msg
->
wParam
=
MAKEWPARAM
(
ch
[
0
]
|
(
ch
[
1
]
<<
8
),
0
);
break
;
case
WM_IME_CHAR
:
{
WCHAR
wch
=
LOWORD
(
wparam
);
BYTE
ch
[
2
];
if
(
WideCharToMultiByte
(
CP_ACP
,
0
,
&
wch
,
1
,
(
LPSTR
)
ch
,
2
,
NULL
,
NULL
)
==
2
)
wparam
=
MAKEWPARAM
(
(
ch
[
0
]
<<
8
)
|
ch
[
1
],
HIWORD
(
wparam
)
);
else
wparam
=
MAKEWPARAM
(
ch
[
0
],
HIWORD
(
wparam
)
);
}
wch
[
0
]
=
LOWORD
(
msg
->
wParam
);
ch
[
0
]
=
ch
[
1
]
=
0
;
RtlUnicodeToMultiByteN
(
(
LPSTR
)
ch
,
2
,
&
len
,
wch
,
sizeof
(
wch
[
0
])
);
if
(
len
==
2
)
msg
->
wParam
=
MAKEWPARAM
(
(
ch
[
0
]
<<
8
)
|
ch
[
1
],
HIWORD
(
msg
->
wParam
)
);
else
msg
->
wParam
=
MAKEWPARAM
(
ch
[
0
],
HIWORD
(
msg
->
wParam
)
);
break
;
}
return
wparam
;
}
...
...
@@ -2876,9 +2909,10 @@ BOOL WINAPI PeekMessageW( MSG *msg_out, HWND hwnd, UINT first, UINT last, UINT f
*/
BOOL
WINAPI
PeekMessageA
(
MSG
*
msg
,
HWND
hwnd
,
UINT
first
,
UINT
last
,
UINT
flags
)
{
BOOL
ret
=
PeekMessageW
(
msg
,
hwnd
,
first
,
last
,
flags
);
if
(
ret
)
msg
->
wParam
=
map_wparam_WtoA
(
msg
->
message
,
msg
->
wParam
);
return
ret
;
if
(
get_pending_wmchar
(
msg
,
first
,
last
,
(
flags
&
PM_REMOVE
)
))
return
TRUE
;
if
(
!
PeekMessageW
(
msg
,
hwnd
,
first
,
last
,
flags
))
return
FALSE
;
map_wparam_WtoA
(
msg
,
(
flags
&
PM_REMOVE
)
);
return
TRUE
;
}
...
...
@@ -2940,8 +2974,9 @@ BOOL WINAPI GetMessageW( MSG *msg, HWND hwnd, UINT first, UINT last )
*/
BOOL
WINAPI
GetMessageA
(
MSG
*
msg
,
HWND
hwnd
,
UINT
first
,
UINT
last
)
{
if
(
get_pending_wmchar
(
msg
,
first
,
last
,
TRUE
))
return
TRUE
;
GetMessageW
(
msg
,
hwnd
,
first
,
last
);
m
sg
->
wParam
=
map_wparam_WtoA
(
msg
->
message
,
msg
->
wParam
);
m
ap_wparam_WtoA
(
msg
,
TRUE
);
return
(
msg
->
message
!=
WM_QUIT
);
}
...
...
dlls/user32/tests/msg.c
View file @
2ce799c4
...
...
@@ -9281,6 +9281,8 @@ static void test_dbcs_wm_char(void)
WCHAR
wch
,
bad_wch
;
HWND
hwnd
,
hwnd2
;
MSG
msg
;
DWORD
time
;
POINT
pt
;
DWORD_PTR
res
;
CPINFOEXA
cpinfo
;
UINT
i
,
j
,
k
;
...
...
@@ -9481,6 +9483,72 @@ static void test_dbcs_wm_char(void)
ok
(
msg
.
wParam
==
bad_wch
,
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
bad_wch
);
ok
(
!
PeekMessageW
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"got message %x
\n
"
,
msg
.
message
);
/* test retrieving messages */
PostMessageW
(
hwnd
,
WM_CHAR
,
wch
,
0
);
ok
(
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
0
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
1
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
!
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"got message %x
\n
"
,
msg
.
message
);
/* message filters */
PostMessageW
(
hwnd
,
WM_CHAR
,
wch
,
0
);
ok
(
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
0
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
/* message id is filtered, hwnd is not */
ok
(
!
PeekMessageA
(
&
msg
,
hwnd
,
WM_MOUSEFIRST
,
WM_MOUSELAST
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
PeekMessageA
(
&
msg
,
hwnd2
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
1
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
!
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"got message %x
\n
"
,
msg
.
message
);
/* mixing GetMessage and PostMessage */
PostMessageW
(
hwnd
,
WM_CHAR
,
wch
,
0xbeef
);
ok
(
GetMessageA
(
&
msg
,
hwnd
,
0
,
0
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
0
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
msg
.
lParam
==
0xbeef
,
"bad lparam %lx
\n
"
,
msg
.
lParam
);
time
=
msg
.
time
;
pt
=
msg
.
pt
;
ok
(
time
-
GetTickCount
()
<=
100
,
"bad time %x
\n
"
,
msg
.
time
);
ok
(
PeekMessageA
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
1
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
msg
.
lParam
==
0xbeef
,
"bad lparam %lx
\n
"
,
msg
.
lParam
);
ok
(
msg
.
time
==
time
,
"bad time %x/%x
\n
"
,
msg
.
time
,
time
);
ok
(
msg
.
pt
.
x
==
pt
.
x
&&
msg
.
pt
.
y
==
pt
.
y
,
"bad point %u,%u/%u,%u
\n
"
,
msg
.
pt
.
x
,
msg
.
pt
.
y
,
pt
.
x
,
pt
.
y
);
ok
(
!
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"got message %x
\n
"
,
msg
.
message
);
/* without PM_REMOVE */
PostMessageW
(
hwnd
,
WM_CHAR
,
wch
,
0
);
ok
(
PeekMessageA
(
&
msg
,
0
,
0
,
0
,
PM_NOREMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
0
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
PeekMessageA
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
0
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
PeekMessageA
(
&
msg
,
0
,
0
,
0
,
PM_NOREMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
1
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
PeekMessageA
(
&
msg
,
0
,
0
,
0
,
PM_REMOVE
),
"no message
\n
"
);
ok
(
msg
.
hwnd
==
hwnd
,
"unexpected hwnd %p
\n
"
,
msg
.
hwnd
);
ok
(
msg
.
message
==
WM_CHAR
,
"unexpected message %x
\n
"
,
msg
.
message
);
ok
(
msg
.
wParam
==
dbch
[
1
],
"bad wparam %lx/%x
\n
"
,
msg
.
wParam
,
dbch
[
0
]
);
ok
(
!
PeekMessageA
(
&
msg
,
hwnd
,
0
,
0
,
PM_REMOVE
),
"got message %x
\n
"
,
msg
.
message
);
DestroyWindow
(
hwnd
);
}
...
...
dlls/user32/user_private.h
View file @
2ce799c4
...
...
@@ -185,6 +185,7 @@ enum wm_char_mapping
struct
wm_char_mapping_data
{
BYTE
lead_byte
[
WMCHAR_MAP_COUNT
];
MSG
get_msg
;
};
/* this is the structure stored in TEB->Win32ClientInfo */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment