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
314f45dc
Commit
314f45dc
authored
Dec 19, 2005
by
Aric Stewart
Committed by
Alexandre Julliard
Dec 19, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
user: Make the edit control IME aware and implement inline editing.
Makes for a significantly better user experience for CJK users.
parent
a06aa5e9
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
211 additions
and
0 deletions
+211
-0
Makefile.in
dlls/user/Makefile.in
+1
-0
edit.c
dlls/user/edit.c
+210
-0
No files found.
dlls/user/Makefile.in
View file @
314f45dc
...
...
@@ -6,6 +6,7 @@ VPATH = @srcdir@
MODULE
=
user32.dll
IMPORTLIB
=
libuser32.
$(IMPLIBEXT)
IMPORTS
=
gdi32 advapi32 kernel32 ntdll
DELAYIMPORTS
=
imm32
EXTRALIBS
=
$(LIBUNICODE)
SPEC_SRCS16
=
\
...
...
dlls/user/edit.c
View file @
314f45dc
...
...
@@ -53,6 +53,7 @@
#include "winnt.h"
#include "wownt32.h"
#include "win.h"
#include "imm.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "wine/unicode.h"
...
...
@@ -151,6 +152,11 @@ typedef struct
or EM_SETHANDLE16 */
HLOCAL
hloc32A
;
/* alias for ANSI control receiving EM_GETHANDLE
or EM_SETHANDLE */
/*
* IME Data
*/
UINT
composition_len
;
/* lenght of composition, 0 == no composition */
int
composition_start
;
/* the character position for the composition */
}
EDITSTATE
;
...
...
@@ -280,6 +286,7 @@ static void EDIT_WM_Timer(EDITSTATE *es);
static
LRESULT
EDIT_WM_VScroll
(
EDITSTATE
*
es
,
INT
action
,
INT
pos
);
static
void
EDIT_UpdateText
(
EDITSTATE
*
es
,
LPRECT
rc
,
BOOL
bErase
);
static
void
EDIT_UpdateTextRegion
(
EDITSTATE
*
es
,
HRGN
hrgn
,
BOOL
bErase
);
static
void
EDIT_ImeComposition
(
HWND
hwnd
,
LPARAM
CompFlag
,
EDITSTATE
*
es
);
LRESULT
WINAPI
EditWndProcA
(
HWND
hWnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
);
LRESULT
WINAPI
EditWndProcW
(
HWND
hWnd
,
UINT
uMsg
,
WPARAM
wParam
,
LPARAM
lParam
);
...
...
@@ -993,6 +1000,52 @@ static LRESULT WINAPI EditWndProc_common( HWND hwnd, UINT msg,
}
}
break
;
/* IME messages to make the edit control IME aware */
case
WM_IME_SETCONTEXT
:
break
;
case
WM_IME_STARTCOMPOSITION
:
/*
* FIXME in IME: This message is not always sent like it should be
*/
if
(
es
->
selection_start
!=
es
->
selection_end
)
{
static
const
WCHAR
empty_stringW
[]
=
{
0
};
EDIT_EM_ReplaceSel
(
es
,
TRUE
,
empty_stringW
,
TRUE
,
TRUE
);
}
es
->
composition_start
=
es
->
selection_end
;
es
->
composition_len
=
0
;
break
;
case
WM_IME_COMPOSITION
:
if
(
es
->
composition_len
==
0
)
{
if
(
es
->
selection_start
!=
es
->
selection_end
)
{
static
const
WCHAR
empty_stringW
[]
=
{
0
};
EDIT_EM_ReplaceSel
(
es
,
TRUE
,
empty_stringW
,
TRUE
,
TRUE
);
}
es
->
composition_start
=
es
->
selection_end
;
}
EDIT_ImeComposition
(
hwnd
,
lParam
,
es
);
break
;
case
WM_IME_ENDCOMPOSITION
:
es
->
composition_len
=
0
;
break
;
case
WM_IME_COMPOSITIONFULL
:
break
;
case
WM_IME_SELECT
:
break
;
case
WM_IME_CONTROL
:
break
;
default:
result
=
DefWindowProcT
(
hwnd
,
msg
,
wParam
,
lParam
,
unicode
);
break
;
...
...
@@ -2188,6 +2241,9 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col
{
COLORREF
BkColor
;
COLORREF
TextColor
;
LOGFONTW
underline_font
;
HFONT
hUnderline
=
0
;
HFONT
old_font
=
0
;
INT
ret
;
INT
li
;
INT
BkMode
;
...
...
@@ -2199,10 +2255,21 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col
BkColor
=
GetBkColor
(
dc
);
TextColor
=
GetTextColor
(
dc
);
if
(
rev
)
{
if
(
es
->
composition_len
==
0
)
{
SetBkColor
(
dc
,
GetSysColor
(
COLOR_HIGHLIGHT
));
SetTextColor
(
dc
,
GetSysColor
(
COLOR_HIGHLIGHTTEXT
));
SetBkMode
(
dc
,
OPAQUE
);
}
else
{
HFONT
current
=
GetCurrentObject
(
dc
,
OBJ_FONT
);
GetObjectW
(
current
,
sizeof
(
LOGFONTW
),
&
underline_font
);
underline_font
.
lfUnderline
=
TRUE
;
hUnderline
=
CreateFontIndirectW
(
&
underline_font
);
old_font
=
SelectObject
(
dc
,
hUnderline
);
}
}
li
=
EDIT_EM_LineIndex
(
es
,
line
);
if
(
es
->
style
&
ES_MULTILINE
)
{
ret
=
(
INT
)
LOWORD
(
TabbedTextOutW
(
dc
,
x
,
y
,
es
->
text
+
li
+
col
,
count
,
...
...
@@ -2216,10 +2283,20 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col
HeapFree
(
GetProcessHeap
(),
0
,
text
);
}
if
(
rev
)
{
if
(
es
->
composition_len
==
0
)
{
SetBkColor
(
dc
,
BkColor
);
SetTextColor
(
dc
,
TextColor
);
SetBkMode
(
dc
,
BkMode
);
}
else
{
if
(
old_font
)
SelectObject
(
dc
,
old_font
);
if
(
hUnderline
)
DeleteObject
(
hUnderline
);
}
}
return
ret
;
}
...
...
@@ -5216,3 +5293,136 @@ static void EDIT_UpdateText(EDITSTATE *es, LPRECT rc, BOOL bErase)
}
InvalidateRect
(
es
->
hwndSelf
,
rc
,
bErase
);
}
/********************************************************************
*
* The Following code is to handle inline editing from IMEs
*/
static
void
EDIT_GetCompositionStr
(
HWND
hwnd
,
LPARAM
CompFlag
,
EDITSTATE
*
es
)
{
DWORD
dwBufLen
;
LPWSTR
lpCompStr
=
NULL
;
HIMC
hIMC
;
LPSTR
lpCompStrAttr
=
NULL
;
DWORD
dwBufLenAttr
;
if
(
!
(
hIMC
=
ImmGetContext
(
hwnd
)))
return
;
dwBufLen
=
ImmGetCompositionStringW
(
hIMC
,
GCS_COMPSTR
,
NULL
,
0
);
if
(
dwBufLen
<=
0
)
{
ImmReleaseContext
(
hwnd
,
hIMC
);
return
;
}
lpCompStr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
dwBufLen
);
if
(
!
lpCompStr
)
{
ERR
(
"Unable to allocate IME CompositionString
\n
"
);
ImmReleaseContext
(
hwnd
,
hIMC
);
return
;
}
ImmGetCompositionStringW
(
hIMC
,
GCS_COMPSTR
,
lpCompStr
,
dwBufLen
);
lpCompStr
[
dwBufLen
/
sizeof
(
WCHAR
)]
=
0
;
if
(
CompFlag
&
GCS_COMPATTR
)
{
/*
* We do not use the attributes yet. it would tell us what characters
* are in transition and which are converted or decided upon
*/
dwBufLenAttr
=
ImmGetCompositionStringW
(
hIMC
,
GCS_COMPATTR
,
NULL
,
0
);
if
(
dwBufLenAttr
)
{
dwBufLenAttr
++
;
lpCompStrAttr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
dwBufLenAttr
);
if
(
!
lpCompStrAttr
)
{
ERR
(
"Unable to allocate IME Attribute String
\n
"
);
HeapFree
(
GetProcessHeap
(),
0
,
lpCompStr
);
ImmReleaseContext
(
hwnd
,
hIMC
);
return
;
}
ImmGetCompositionStringW
(
hIMC
,
GCS_COMPATTR
,
lpCompStrAttr
,
dwBufLenAttr
);
lpCompStrAttr
[
dwBufLenAttr
]
=
0
;
}
else
lpCompStrAttr
=
NULL
;
}
/* check for change in composition start */
if
(
es
->
selection_end
<
es
->
composition_start
)
es
->
composition_start
=
es
->
selection_end
;
/* replace existing selection string */
es
->
selection_start
=
es
->
composition_start
;
if
(
es
->
composition_len
>
0
)
es
->
selection_end
=
es
->
composition_start
+
es
->
composition_len
;
else
es
->
selection_end
=
es
->
selection_start
;
EDIT_EM_ReplaceSel
(
es
,
FALSE
,
lpCompStr
,
TRUE
,
TRUE
);
es
->
composition_len
=
abs
(
es
->
composition_start
-
es
->
selection_end
);
es
->
selection_start
=
es
->
composition_start
;
es
->
selection_end
=
es
->
selection_start
+
es
->
composition_len
;
HeapFree
(
GetProcessHeap
(),
0
,
lpCompStrAttr
);
HeapFree
(
GetProcessHeap
(),
0
,
lpCompStr
);
ImmReleaseContext
(
hwnd
,
hIMC
);
}
static
void
EDIT_GetResultStr
(
HWND
hwnd
,
EDITSTATE
*
es
)
{
DWORD
dwBufLen
;
LPWSTR
lpResultStr
;
HIMC
hIMC
;
if
(
!
(
hIMC
=
ImmGetContext
(
hwnd
)))
return
;
dwBufLen
=
ImmGetCompositionStringW
(
hIMC
,
GCS_RESULTSTR
,
NULL
,
0
);
if
(
dwBufLen
<=
0
)
{
ImmReleaseContext
(
hwnd
,
hIMC
);
return
;
}
lpResultStr
=
HeapAlloc
(
GetProcessHeap
(),
0
,
dwBufLen
);
if
(
!
lpResultStr
)
{
ERR
(
"Unable to alloc buffer for IME string
\n
"
);
ImmReleaseContext
(
hwnd
,
hIMC
);
return
;
}
ImmGetCompositionStringW
(
hIMC
,
GCS_RESULTSTR
,
lpResultStr
,
dwBufLen
);
lpResultStr
[
dwBufLen
/
sizeof
(
WCHAR
)]
=
0
;
/* check for change in composition start */
if
(
es
->
selection_end
<
es
->
composition_start
)
es
->
composition_start
=
es
->
selection_end
;
es
->
selection_start
=
es
->
composition_start
;
es
->
selection_end
=
es
->
composition_start
+
es
->
composition_len
;
EDIT_EM_ReplaceSel
(
es
,
TRUE
,
lpResultStr
,
TRUE
,
TRUE
);
es
->
composition_start
=
es
->
selection_end
;
es
->
composition_len
=
0
;
HeapFree
(
GetProcessHeap
(),
0
,
lpResultStr
);
ImmReleaseContext
(
hwnd
,
hIMC
);
}
static
void
EDIT_ImeComposition
(
HWND
hwnd
,
LPARAM
CompFlag
,
EDITSTATE
*
es
)
{
if
(
CompFlag
&
GCS_RESULTSTR
)
EDIT_GetResultStr
(
hwnd
,
es
);
if
(
CompFlag
&
GCS_COMPSTR
)
EDIT_GetCompositionStr
(
hwnd
,
CompFlag
,
es
);
}
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