提交 e7debbc7 编写于 作者: A alexsch

7092551: Double-click in TextField sets caret to the beginning

Reviewed-by: bagiras, serb
上级 099510d8
......@@ -74,135 +74,10 @@ void AwtTextArea::Dispose()
AwtTextComponent::Dispose();
}
LPCTSTR AwtTextArea::GetClassName() {
static BOOL richedLibraryLoaded = FALSE;
if (!richedLibraryLoaded) {
JDK_LoadSystemLibrary("RICHED20.DLL");
richedLibraryLoaded = TRUE;
}
return RICHEDIT_CLASS;
}
/* Create a new AwtTextArea object and window. */
AwtTextArea* AwtTextArea::Create(jobject peer, jobject parent)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
AwtTextArea* c = NULL;
try {
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
c = new AwtTextArea();
{
/* Adjust style for scrollbar visibility and word wrap */
DWORD scroll_style;
jint scrollbarVisibility =
env->GetIntField(target, AwtTextArea::scrollbarVisibilityID);
switch (scrollbarVisibility) {
case java_awt_TextArea_SCROLLBARS_NONE:
scroll_style = ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_VERTICAL_ONLY:
scroll_style = WS_VSCROLL | ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_HORIZONTAL_ONLY:
scroll_style = WS_HSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_BOTH:
scroll_style = WS_VSCROLL | WS_HSCROLL |
ES_AUTOVSCROLL | ES_AUTOHSCROLL;
break;
}
/*
* Specify ES_DISABLENOSCROLL - RichEdit control style to disable
* scrollbars instead of hiding them when not needed.
*/
DWORD style = WS_CHILD | WS_CLIPSIBLINGS | ES_LEFT | ES_MULTILINE |
ES_WANTRETURN | scroll_style | ES_DISABLENOSCROLL;
DWORD exStyle = WS_EX_CLIENTEDGE;
if (GetRTL()) {
exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
if (GetRTLReadingOrder())
exStyle |= WS_EX_RTLREADING;
}
jint x = env->GetIntField(target, AwtComponent::xID);
jint y = env->GetIntField(target, AwtComponent::yID);
jint width = env->GetIntField(target, AwtComponent::widthID);
jint height = env->GetIntField(target, AwtComponent::heightID);
c->CreateHWnd(env, L"", style, exStyle,
x, y, width, height,
awtParent->GetHWnd(),
reinterpret_cast<HMENU>(static_cast<INT_PTR>(
awtParent->CreateControlID())),
::GetSysColor(COLOR_WINDOWTEXT),
::GetSysColor(COLOR_WINDOW),
peer);
// Fix for 4753116.
// If it is not win95 (we are using Richedit 2.0)
// we set plain text mode, in which the control is
// similar to a standard edit control:
// - The text in a plain text control can have only
// one format.
// - The user cannot paste rich text formats, such as RTF
// or embedded objects into a plain text control.
// - Rich text mode controls always have a default
// end-of-document marker or carriage return,
// to format paragraphs.
// kdm@sparc.spb.su
c->SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT, 0);
c->m_backgroundColorSet = TRUE;
/* suppress inheriting parent's color. */
c->UpdateBackground(env, target);
c->SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELPARAM(1, 1));
/*
* Fix for BugTraq Id 4260109.
* Set the text limit to the maximum.
* Use EM_EXLIMITTEXT for RichEdit controls.
* For some reason RichEdit 1.0 becomes read-only if the
* specified limit is greater than 0x7FFFFFFD.
*/
c->SendMessage(EM_EXLIMITTEXT, 0, 0x7FFFFFFD);
/* Unregister RichEdit built-in drop target. */
VERIFY(::RevokeDragDrop(c->GetHWnd()) != DRAGDROP_E_INVALIDHWND);
/* To enforce CF_TEXT format for paste operations. */
VERIFY(c->SendMessage(EM_SETOLECALLBACK, 0,
(LPARAM)&GetOleCallback()));
c->SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE);
}
} catch (...) {
env->DeleteLocalRef(target);
throw;
}
done:
env->DeleteLocalRef(target);
return c;
return (AwtTextArea*) AwtTextComponent::Create(peer, parent, true);
}
void AwtTextArea::EditSetSel(CHARRANGE &cr) {
......@@ -220,11 +95,6 @@ void AwtTextArea::EditGetSel(CHARRANGE &cr) {
SendMessage(EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&cr));
}
LONG AwtTextArea::EditGetCharFromPos(POINT& pt) {
return static_cast<LONG>(SendMessage(EM_CHARFROMPOS, 0,
reinterpret_cast<LPARAM>(&pt)));
}
/* Count how many '\n's are there in jStr */
size_t AwtTextArea::CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen)
{
......@@ -253,34 +123,6 @@ size_t AwtTextArea::CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen)
BOOL AwtTextArea::InheritsNativeMouseWheelBehavior() {return true;}
MsgRouting
AwtTextArea::PreProcessMsg(MSG& msg)
{
MsgRouting mr = mrPassAlong;
static BOOL bPassAlongWmLButtonUp = TRUE;
if (msg.message == WM_LBUTTONDBLCLK) {
bPassAlongWmLButtonUp = FALSE;
}
/*
* For some reason RichEdit 1.0 filters out WM_LBUTTONUP after
* WM_LBUTTONDBLCLK. To work around this "feature" we send WM_LBUTTONUP
* directly to the window procedure and consume instead of passing it
* to the next hook.
*/
if (msg.message == WM_LBUTTONUP && bPassAlongWmLButtonUp == FALSE) {
SendMessage(WM_LBUTTONUP, msg.wParam, msg.lParam);
bPassAlongWmLButtonUp = TRUE;
mr = mrConsume;
}
if (mr == mrPassAlong) {
mr = AwtComponent::PreProcessMsg(msg);
}
return mr;
}
LRESULT
AwtTextArea::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
......@@ -800,54 +642,6 @@ AwtTextArea::HandleEvent(MSG *msg, BOOL synthetic)
return returnVal;
}
/*
* WM_CTLCOLOR is not sent by rich edit controls.
* Use EM_SETCHARFORMAT and EM_SETBKGNDCOLOR to set
* respectively foreground and background color.
*/
void AwtTextArea::SetColor(COLORREF c) {
AwtComponent::SetColor(c);
CHARFORMAT cf;
memset(&cf, 0, sizeof(cf));
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.crTextColor = ::IsWindowEnabled(GetHWnd()) ? GetColor() : ::GetSysColor(COLOR_3DSHADOW);
/*
* The documentation for EM_GETCHARFORMAT is not exactly
* correct. It appears that wParam has the same meaning
* as for EM_SETCHARFORMAT. Our task is to secure that
* all the characters in the control have the required
* formatting. That's why we use SCF_ALL.
*/
VERIFY(SendMessage(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf));
VERIFY(SendMessage(EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf));
}
/*
* In responce to EM_SETBKGNDCOLOR rich edit changes
* its bg color and repaints itself so we don't need
* to force repaint.
*/
void AwtTextArea::SetBackgroundColor(COLORREF c) {
AwtComponent::SetBackgroundColor(c);
SendMessage(EM_SETBKGNDCOLOR, (WPARAM)FALSE, (LPARAM)GetBackgroundColor());
}
/*
* Disabled edit control has grayed foreground.
* Disabled RichEdit 1.0 control has original foreground.
* Thus we have to set grayed foreground manually.
*/
void AwtTextArea::Enable(BOOL bEnable)
{
AwtComponent::Enable(bEnable);
SetColor(GetColor());
}
/* Fix for 4776535, 4648702
* If width is 0 or 1 Windows hides the horizontal scroll bar even
......@@ -1048,133 +842,3 @@ Java_sun_awt_windows_WTextAreaPeer_insertText(JNIEnv *env, jobject self,
} /* extern "C" */
AwtTextArea::OleCallback AwtTextArea::sm_oleCallback;
/************************************************************************
* Inner class OleCallback definition.
*/
AwtTextArea::OleCallback::OleCallback() {
m_refs = 0;
AddRef();
}
STDMETHODIMP
AwtTextArea::OleCallback::QueryInterface(REFIID riid, LPVOID * ppvObj) {
TRY;
if (::IsEqualIID(riid, IID_IUnknown)) {
*ppvObj = (void __RPC_FAR *__RPC_FAR)(IUnknown*)this;
AddRef();
return S_OK;
} else if (::IsEqualIID(riid, IID_IRichEditOleCallback)) {
*ppvObj = (void __RPC_FAR *__RPC_FAR)(IRichEditOleCallback*)this;
AddRef();
return S_OK;
} else {
*ppvObj = NULL;
return E_NOINTERFACE;
}
CATCH_BAD_ALLOC_RET(E_OUTOFMEMORY);
}
STDMETHODIMP_(ULONG)
AwtTextArea::OleCallback::AddRef() {
return ++m_refs;
}
STDMETHODIMP_(ULONG)
AwtTextArea::OleCallback::Release() {
int refs;
if ((refs = --m_refs) == 0) delete this;
return (ULONG)refs;
}
STDMETHODIMP
AwtTextArea::OleCallback::GetNewStorage(LPSTORAGE FAR * ppstg) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextArea::OleCallback::GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
LPOLEINPLACEFRAMEINFO pipfinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextArea::OleCallback::ShowContainerUI(BOOL fShow) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextArea::OleCallback::QueryInsertObject(LPCLSID pclsid,
LPSTORAGE pstg,
LONG cp) {
return NOERROR;
}
STDMETHODIMP
AwtTextArea::OleCallback::DeleteObject(LPOLEOBJECT poleobj) {
return NOERROR;
}
STDMETHODIMP
AwtTextArea::OleCallback::QueryAcceptData(LPDATAOBJECT pdataobj,
CLIPFORMAT *pcfFormat,
DWORD reco,
BOOL fReally,
HGLOBAL hMetaPict) {
if (reco == RECO_PASTE) {
// If CF_TEXT format is available edit controls will select it,
// otherwise if it is CF_UNICODETEXT is available it will be
// selected, otherwise if CF_OEMTEXT is available it will be selected.
if (::IsClipboardFormatAvailable(CF_TEXT)) {
*pcfFormat = CF_TEXT;
} else if (::IsClipboardFormatAvailable(CF_UNICODETEXT)) {
*pcfFormat = CF_UNICODETEXT;
} else if (::IsClipboardFormatAvailable(CF_OEMTEXT)) {
*pcfFormat = CF_OEMTEXT;
} else {
// Don't allow rich edit to paste clipboard data
// in other formats.
*pcfFormat = CF_TEXT;
}
}
return NOERROR;
}
STDMETHODIMP
AwtTextArea::OleCallback::ContextSensitiveHelp(BOOL fEnterMode) {
return NOERROR;
}
STDMETHODIMP
AwtTextArea::OleCallback::GetClipboardData(CHARRANGE *pchrg,
DWORD reco,
LPDATAOBJECT *ppdataobj) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextArea::OleCallback::GetDragDropEffect(BOOL fDrag,
DWORD grfKeyState,
LPDWORD pdwEffect) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextArea::OleCallback::GetContextMenu(WORD seltype,
LPOLEOBJECT lpoleobj,
CHARRANGE FAR * lpchrg,
HMENU FAR * lphmenu) {
return E_NOTIMPL;
}
......@@ -51,15 +51,11 @@ public:
virtual void Dispose();
LPCTSTR GetClassName();
static AwtTextArea* Create(jobject self, jobject parent);
static size_t CountNewLines(JNIEnv *env, jstring jStr, size_t maxlen);
static size_t GetALength(JNIEnv* env, jstring jStr, size_t maxlen);
MsgRouting PreProcessMsg(MSG& msg);
LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
static LRESULT CALLBACK EditProc(HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
......@@ -72,9 +68,6 @@ public:
INLINE void SetIgnoreEnChange(BOOL b) { m_bIgnoreEnChange = b; }
virtual void SetColor(COLORREF c);
virtual void SetBackgroundColor(COLORREF c);
virtual void Enable(BOOL bEnable);
virtual BOOL InheritsNativeMouseWheelBehavior();
virtual void Reshape(int x, int y, int w, int h);
......@@ -87,40 +80,8 @@ public:
protected:
/*****************************************************************
* Inner class OleCallback declaration.
*/
class OleCallback : public IRichEditOleCallback {
public:
OleCallback();
STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
LPOLEINPLACEFRAMEINFO pipfinfo);
STDMETHODIMP ShowContainerUI(BOOL fShow);
STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
LPDATAOBJECT *ppdataobj);
STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
LPDWORD pdwEffect);
STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
private:
ULONG m_refs; // Reference count
};//OleCallback class
INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
void EditSetSel(CHARRANGE &cr);
void EditGetSel(CHARRANGE &cr);
LONG EditGetCharFromPos(POINT& pt);
private:
// RichEdit 1.0 control generates EN_CHANGE notifications not only
// on text changes, but also on any character formatting change.
......@@ -140,8 +101,6 @@ protected:
LONG m_lVDeltaAccum;
static OleCallback sm_oleCallback;
};
#endif /* AWT_TEXTAREA_H */
......@@ -25,6 +25,8 @@
#include "awt_Toolkit.h"
#include "awt_TextComponent.h"
#include "awt_TextArea.h"
#include "awt_TextField.h"
#include "awt_Canvas.h"
#include "jni.h"
......@@ -70,7 +72,152 @@ AwtTextComponent::AwtTextComponent() {
}
LPCTSTR AwtTextComponent::GetClassName() {
return TEXT("EDIT"); /* System provided edit control class */
static BOOL richedLibraryLoaded = FALSE;
if (!richedLibraryLoaded) {
JDK_LoadSystemLibrary("RICHED20.DLL");
richedLibraryLoaded = TRUE;
}
return RICHEDIT_CLASS;
}
/* Create a new AwtTextArea or AwtTextField object and window. */
AwtTextComponent* AwtTextComponent::Create(jobject peer, jobject parent, BOOL isMultiline)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
AwtTextComponent* c = NULL;
try {
if (env->EnsureLocalCapacity(1) < 0) {
return NULL;
}
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
if(isMultiline){
c = new AwtTextArea();
}else{
c = new AwtTextField();
}
{
/* Adjust style for scrollbar visibility and word wrap */
DWORD scroll_style;
if(isMultiline){
jint scrollbarVisibility =
env->GetIntField(target, AwtTextArea::scrollbarVisibilityID);
switch (scrollbarVisibility) {
case java_awt_TextArea_SCROLLBARS_NONE:
scroll_style = ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_VERTICAL_ONLY:
scroll_style = WS_VSCROLL | ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_HORIZONTAL_ONLY:
scroll_style = WS_HSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL;
break;
case java_awt_TextArea_SCROLLBARS_BOTH:
scroll_style = WS_VSCROLL | WS_HSCROLL |
ES_AUTOVSCROLL | ES_AUTOHSCROLL;
break;
}
}
DWORD style = WS_CHILD | WS_CLIPSIBLINGS | ES_LEFT;
/*
* Specify ES_DISABLENOSCROLL - RichEdit control style to disable
* scrollbars instead of hiding them when not needed.
*/
style |= isMultiline ? ES_MULTILINE | ES_WANTRETURN | scroll_style
| ES_DISABLENOSCROLL : ES_AUTOHSCROLL;
DWORD exStyle = WS_EX_CLIENTEDGE;
if (GetRTL()) {
exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
if (GetRTLReadingOrder())
exStyle |= WS_EX_RTLREADING;
}
jint x = env->GetIntField(target, AwtComponent::xID);
jint y = env->GetIntField(target, AwtComponent::yID);
jint width = env->GetIntField(target, AwtComponent::widthID);
jint height = env->GetIntField(target, AwtComponent::heightID);
c->CreateHWnd(env, L"", style, exStyle,
x, y, width, height,
awtParent->GetHWnd(),
reinterpret_cast<HMENU>(static_cast<INT_PTR>(
awtParent->CreateControlID())),
::GetSysColor(COLOR_WINDOWTEXT),
::GetSysColor(COLOR_WINDOW),
peer);
// Fix for 4753116.
// If it is not win95 (we are using Richedit 2.0)
// we set plain text mode, in which the control is
// similar to a standard edit control:
// - The text in a plain text control can have only
// one format.
// - The user cannot paste rich text formats, such as RTF
// or embedded objects into a plain text control.
// - Rich text mode controls always have a default
// end-of-document marker or carriage return,
// to format paragraphs.
// kdm@sparc.spb.su
c->SendMessage(EM_SETTEXTMODE, TM_PLAINTEXT, 0);
c->m_backgroundColorSet = TRUE;
/* suppress inheriting parent's color. */
c->UpdateBackground(env, target);
c->SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELPARAM(1, 1));
/*
* Fix for BugTraq Id 4260109.
* Set the text limit to the maximum.
* Use EM_EXLIMITTEXT for RichEdit controls.
* For some reason RichEdit 1.0 becomes read-only if the
* specified limit is greater than 0x7FFFFFFD.
*/
c->SendMessage(EM_EXLIMITTEXT, 0, 0x7FFFFFFD);
/* Unregister RichEdit built-in drop target. */
VERIFY(::RevokeDragDrop(c->GetHWnd()) != DRAGDROP_E_INVALIDHWND);
/* To enforce CF_TEXT format for paste operations. */
VERIFY(c->SendMessage(EM_SETOLECALLBACK, 0,
(LPARAM)&GetOleCallback()));
c->SendMessage(EM_SETEVENTMASK, 0, ENM_CHANGE);
}
} catch (...) {
env->DeleteLocalRef(target);
throw;
}
done:
env->DeleteLocalRef(target);
return c;
}
LONG AwtTextComponent::EditGetCharFromPos(POINT& pt) {
return static_cast<LONG>(SendMessage(EM_CHARFROMPOS, 0,
reinterpret_cast<LPARAM>(&pt)));
}
/* Set a suitable font to IME against the component font. */
......@@ -463,6 +610,54 @@ ret:
delete ees;
}
/*
* Disabled edit control has grayed foreground.
* Disabled RichEdit 1.0 control has original foreground.
* Thus we have to set grayed foreground manually.
*/
void AwtTextComponent::Enable(BOOL bEnable)
{
AwtComponent::Enable(bEnable);
SetColor(GetColor());
}
/*
* WM_CTLCOLOR is not sent by rich edit controls.
* Use EM_SETCHARFORMAT and EM_SETBKGNDCOLOR to set
* respectively foreground and background color.
*/
void AwtTextComponent::SetColor(COLORREF c) {
AwtComponent::SetColor(c);
CHARFORMAT cf;
memset(&cf, 0, sizeof(cf));
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR;
cf.crTextColor = ::IsWindowEnabled(GetHWnd()) ? GetColor() : ::GetSysColor(COLOR_3DSHADOW);
/*
* The documentation for EM_GETCHARFORMAT is not exactly
* correct. It appears that wParam has the same meaning
* as for EM_SETCHARFORMAT. Our task is to secure that
* all the characters in the control have the required
* formatting. That's why we use SCF_ALL.
*/
VERIFY(SendMessage(EM_SETCHARFORMAT, SCF_ALL, (LPARAM)&cf));
VERIFY(SendMessage(EM_SETCHARFORMAT, SCF_DEFAULT, (LPARAM)&cf));
}
/*
* In responce to EM_SETBKGNDCOLOR rich edit changes
* its bg color and repaints itself so we don't need
* to force repaint.
*/
void AwtTextComponent::SetBackgroundColor(COLORREF c) {
AwtComponent::SetBackgroundColor(c);
SendMessage(EM_SETBKGNDCOLOR, (WPARAM)FALSE, (LPARAM)GetBackgroundColor());
}
/************************************************************************
* WTextComponentPeer native methods
......@@ -623,6 +818,127 @@ Java_sun_awt_windows_WTextComponentPeer_initIDs(JNIEnv *env, jclass cls)
CATCH_BAD_ALLOC;
}
AwtTextComponent::OleCallback AwtTextComponent::sm_oleCallback;
/************************************************************************
* Inner class OleCallback definition.
*/
AwtTextComponent::OleCallback::OleCallback() {
m_refs = 0;
AddRef();
}
STDMETHODIMP
AwtTextComponent::OleCallback::QueryInterface(REFIID riid, LPVOID * ppvObj) {
if (::IsEqualIID(riid, IID_IUnknown) ||::IsEqualIID(riid, IID_IRichEditOleCallback) ) {
*ppvObj = static_cast<IRichEditOleCallback*>(this);
AddRef();
return S_OK;
}
*ppvObj = NULL;
return E_NOINTERFACE;
}
STDMETHODIMP_(ULONG)
AwtTextComponent::OleCallback::AddRef() {
return ++m_refs;
}
STDMETHODIMP_(ULONG)
AwtTextComponent::OleCallback::Release() {
return (ULONG)--m_refs;
}
STDMETHODIMP
AwtTextComponent::OleCallback::GetNewStorage(LPSTORAGE FAR * ppstg) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextComponent::OleCallback::GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
LPOLEINPLACEFRAMEINFO pipfinfo)
{
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextComponent::OleCallback::ShowContainerUI(BOOL fShow) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextComponent::OleCallback::QueryInsertObject(LPCLSID pclsid,
LPSTORAGE pstg,
LONG cp) {
return S_OK;
}
STDMETHODIMP
AwtTextComponent::OleCallback::DeleteObject(LPOLEOBJECT poleobj) {
return S_OK;
}
STDMETHODIMP
AwtTextComponent::OleCallback::QueryAcceptData(LPDATAOBJECT pdataobj,
CLIPFORMAT *pcfFormat,
DWORD reco,
BOOL fReally,
HGLOBAL hMetaPict) {
if (reco == RECO_PASTE) {
// If CF_TEXT format is available edit controls will select it,
// otherwise if it is CF_UNICODETEXT is available it will be
// selected, otherwise if CF_OEMTEXT is available it will be selected.
if (::IsClipboardFormatAvailable(CF_TEXT)) {
*pcfFormat = CF_TEXT;
} else if (::IsClipboardFormatAvailable(CF_UNICODETEXT)) {
*pcfFormat = CF_UNICODETEXT;
} else if (::IsClipboardFormatAvailable(CF_OEMTEXT)) {
*pcfFormat = CF_OEMTEXT;
} else {
// Don't allow rich edit to paste clipboard data
// in other formats.
*pcfFormat = CF_TEXT;
}
}
return S_OK;
}
STDMETHODIMP
AwtTextComponent::OleCallback::ContextSensitiveHelp(BOOL fEnterMode) {
return S_OK;
}
STDMETHODIMP
AwtTextComponent::OleCallback::GetClipboardData(CHARRANGE *pchrg,
DWORD reco,
LPDATAOBJECT *ppdataobj) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextComponent::OleCallback::GetDragDropEffect(BOOL fDrag,
DWORD grfKeyState,
LPDWORD pdwEffect) {
return E_NOTIMPL;
}
STDMETHODIMP
AwtTextComponent::OleCallback::GetContextMenu(WORD seltype,
LPOLEOBJECT lpoleobj,
CHARRANGE FAR * lpchrg,
HMENU FAR * lphmenu) {
return E_NOTIMPL;
}
//
// Accessibility support
//
......
......@@ -47,6 +47,8 @@ public:
AwtTextComponent();
static AwtTextComponent* Create(jobject self, jobject parent, BOOL isMultiline);
virtual LPCTSTR GetClassName();
int RemoveCR(WCHAR *pStr);
......@@ -71,6 +73,10 @@ public:
void SetFont(AwtFont* font);
virtual void Enable(BOOL bEnable);
virtual void SetColor(COLORREF c);
virtual void SetBackgroundColor(COLORREF c);
/*
* Windows message handler functions
*/
......@@ -113,7 +119,40 @@ public:
// Used to prevent untrusted code from synthesizing a WM_PASTE message
// by posting a <CTRL>-V KeyEvent
BOOL m_synthetic;
virtual LONG EditGetCharFromPos(POINT& pt) = 0;
LONG EditGetCharFromPos(POINT& pt);
/*****************************************************************
* Inner class OleCallback declaration.
*/
class OleCallback : public IRichEditOleCallback {
public:
OleCallback();
STDMETHODIMP QueryInterface(REFIID riid, LPVOID * ppvObj);
STDMETHODIMP_(ULONG) AddRef();
STDMETHODIMP_(ULONG) Release();
STDMETHODIMP GetNewStorage(LPSTORAGE FAR * ppstg);
STDMETHODIMP GetInPlaceContext(LPOLEINPLACEFRAME FAR * ppipframe,
LPOLEINPLACEUIWINDOW FAR* ppipuiDoc,
LPOLEINPLACEFRAMEINFO pipfinfo);
STDMETHODIMP ShowContainerUI(BOOL fShow);
STDMETHODIMP QueryInsertObject(LPCLSID pclsid, LPSTORAGE pstg, LONG cp);
STDMETHODIMP DeleteObject(LPOLEOBJECT poleobj);
STDMETHODIMP QueryAcceptData(LPDATAOBJECT pdataobj, CLIPFORMAT *pcfFormat,
DWORD reco, BOOL fReally, HGLOBAL hMetaPict);
STDMETHODIMP ContextSensitiveHelp(BOOL fEnterMode);
STDMETHODIMP GetClipboardData(CHARRANGE *pchrg, DWORD reco,
LPDATAOBJECT *ppdataobj);
STDMETHODIMP GetDragDropEffect(BOOL fDrag, DWORD grfKeyState,
LPDWORD pdwEffect);
STDMETHODIMP GetContextMenu(WORD seltype, LPOLEOBJECT poleobj,
CHARRANGE FAR * pchrg, HMENU FAR * phmenu);
private:
ULONG m_refs; // Reference count
};//OleCallback class
INLINE static OleCallback& GetOleCallback() { return sm_oleCallback; }
private:
......@@ -126,6 +165,7 @@ private:
HFONT m_hFont;
//im --- end
static OleCallback sm_oleCallback;
//
// Accessibility support
......
......@@ -42,84 +42,23 @@ struct SetEchoCharStruct {
*/
AwtTextField::AwtTextField()
: m_initialRescrollFlag( true )
{
}
/* Create a new AwtTextField object and window. */
AwtTextField* AwtTextField::Create(jobject peer, jobject parent)
{
JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
jobject target = NULL;
AwtTextField* c = NULL;
try {
PDATA pData;
AwtCanvas* awtParent;
JNI_CHECK_PEER_GOTO(parent, done);
awtParent = (AwtCanvas*)pData;
JNI_CHECK_NULL_GOTO(awtParent, "null awtParent", done);
target = env->GetObjectField(peer, AwtObject::targetID);
JNI_CHECK_NULL_GOTO(target, "null target", done);
c = new AwtTextField();
{
DWORD style = WS_CHILD | WS_CLIPSIBLINGS |
ES_LEFT | ES_AUTOHSCROLL;
DWORD exStyle = WS_EX_CLIENTEDGE;
if (GetRTL()) {
exStyle |= WS_EX_RIGHT | WS_EX_LEFTSCROLLBAR;
if (GetRTLReadingOrder())
exStyle |= WS_EX_RTLREADING;
}
jint x = env->GetIntField(target, AwtComponent::xID);
jint y = env->GetIntField(target, AwtComponent::yID);
jint width = env->GetIntField(target, AwtComponent::widthID);
jint height = env->GetIntField(target, AwtComponent::heightID);
c->CreateHWnd(env, L"", style, exStyle,
x, y, width, height,
awtParent->GetHWnd(),
reinterpret_cast<HMENU>(static_cast<INT_PTR>(
awtParent->CreateControlID())),
::GetSysColor(COLOR_WINDOWTEXT),
::GetSysColor(COLOR_WINDOW),
peer);
c->m_backgroundColorSet = TRUE;
/* suppress inheriting parent's color. */
c->UpdateBackground(env, target);
c->SendMessage(EM_SETMARGINS, EC_LEFTMARGIN | EC_RIGHTMARGIN,
MAKELPARAM(1, 1));
/*
* Fix for BugTraq Id 4260109.
* Set the text limit to the maximum.
*/
c->SendMessage(EM_SETLIMITTEXT);
}
} catch (...) {
env->DeleteLocalRef(target);
throw;
}
done:
env->DeleteLocalRef(target);
return c;
return (AwtTextField*) AwtTextComponent::Create(peer, parent, false);
}
void AwtTextField::EditSetSel(CHARRANGE &cr) {
SendMessage(EM_SETSEL, cr.cpMin, cr.cpMax);
}
SendMessage(EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&cr));
// 6417581: force expected drawing
if (IS_WINVISTA && cr.cpMin == cr.cpMax) {
::InvalidateRect(GetHWnd(), NULL, TRUE);
}
LONG AwtTextField::EditGetCharFromPos(POINT& pt) {
return static_cast<LONG>(SendMessage(EM_CHARFROMPOS, 0, MAKELPARAM(pt.x, pt.y)));
}
LRESULT AwtTextField::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
......@@ -162,10 +101,18 @@ AwtTextField::HandleEvent(MSG *msg, BOOL synthetic)
* to allow dnd of the current selection.
*/
if (msg->message == WM_LBUTTONDBLCLK) {
SetStartSelectionPos(static_cast<LONG>(SendMessage(
EM_FINDWORDBREAK, WB_MOVEWORDLEFT, lCurPos)));
SetEndSelectionPos(static_cast<LONG>(SendMessage(
EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, lCurPos)));
jchar echo = SendMessage(EM_GETPASSWORDCHAR);
if(echo == 0){
SetStartSelectionPos(static_cast<LONG>(SendMessage(
EM_FINDWORDBREAK, WB_MOVEWORDLEFT, lCurPos)));
SetEndSelectionPos(static_cast<LONG>(SendMessage(
EM_FINDWORDBREAK, WB_MOVEWORDRIGHT, lCurPos)));
}else{
SetStartSelectionPos(0);
SetEndSelectionPos(GetTextLength());
}
} else {
SetStartSelectionPos(lCurPos);
SetEndSelectionPos(lCurPos);
......@@ -307,46 +254,6 @@ ret:
delete secs;
}
void AwtTextField::Reshape(int x, int y, int w, int h)
{
AwtTextComponent::Reshape( x, y, w, h );
// Another option would be to call this
// after WM_SIZE notification is handled
initialRescroll();
}
// Windows' Edit control features:
// (i) if text selection is set while control's width or height is 0,
// text is scrolled oddly.
// (ii) if control's size is changed, text seems never be automatically
// rescrolled.
//
// This method is designed for the following scenario: AWT spawns Edit
// control with 0x0 dimensions, then sets text selection, then resizes the
// control (couple of times). This might cause text appear undesirably scrolled.
// So we reset/set selection again to rescroll text. (see also CR 6480547)
void AwtTextField::initialRescroll()
{
if( ! m_initialRescrollFlag ) {
return;
}
::RECT r;
BOOL ok = ::GetClientRect( GetHWnd(), &r );
if( ! ok || r.right==0 || r.bottom==0 ) {
return;
}
m_initialRescrollFlag = false;
DWORD start, end;
SendMessage( EM_GETSEL, (WPARAM)&start, (LPARAM)&end );
SendMessage( EM_SETSEL, (WPARAM)0, (LPARAM)0 );
SendMessage( EM_SETSEL, (WPARAM)start, (LPARAM)end );
}
/************************************************************************
* WTextFieldPeer native methods
......
......@@ -54,15 +54,11 @@ public:
// invoked on Toolkit thread
static void _SetEchoChar(void *param);
protected:
LONG EditGetCharFromPos(POINT& pt);
virtual void Reshape(int x, int y, int w, int h);
protected:
private:
void EditSetSel(CHARRANGE &cr);
void initialRescroll();
bool m_initialRescrollFlag;
};
#endif /* AWT_TEXTFIELD_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册