add nsIKBStateControl for IME force commit and password field disable. Change window implementation to implement nsIKBStateControl in nsWindow. Fix 12250 by filtering out the composition window flag in OnIMESetContext. r=erik

This commit is contained in:
ftang%netscape.com 1999-11-15 20:57:41 +00:00
Родитель f0fed40b89
Коммит b125de60fe
7 изменённых файлов: 257 добавлений и 21 удалений

Просмотреть файл

@ -4,6 +4,7 @@
nsIDragSessionMac.h
nsIWidget.h
nsIKBStateControl.h
nsIButton.h
nsICheckButton.h
nsIListWidget.h

Просмотреть файл

@ -40,6 +40,7 @@ EXPORTS = \
nsIFileWidget.h \
nsStringUtil.h \
nsIWidget.h \
nsIKBStateControl.h \
nsIButton.h \
nsICheckButton.h \
nsIListWidget.h \

Просмотреть файл

@ -47,6 +47,7 @@ EXPORTS=\
nsIFontRetrieverService.h \
nsIFileWidget.h \
nsIWidget.h \
nsIKBStateControl.h \
nsIButton.h \
nsICheckButton.h \
nsIListWidget.h \

Просмотреть файл

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
* Frank Tang <ftang@netscape.com>
*/
#ifndef nsIKBStateControl_h__
#define nsIKBStateControl_h__
#include "nsISupports.h"
// {6A9AC731-988A-11d3-86CC-005004832142}
#define NS_IKBSTATECONTROL_IID \
{ 0x6a9ac731, 0x988a, 0x11d3, \
{ 0x86, 0xcc, 0x0, 0x50, 0x4, 0x83, 0x21, 0x42 } }
/**
* interface to control keyboard input state
*/
class nsIKBStateControl : public nsISupports {
public:
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IKBSTATECONTROL_IID)
/*
* Force Input Method Editor to commit the uncommited input
*/
NS_IMETHOD ResetInputState()=0;
/*
* This method is called in the init stage of a password field
*/
NS_IMETHOD PasswordFieldInit()=0;
};
#endif // nsIKBStateControl_h__

Просмотреть файл

@ -311,37 +311,37 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
if (mClassID.Equals(kCWindow)) {
inst = (nsISupports*)new nsWindow();
inst = (nsISupports*)(nsBaseWidget*)new nsWindow();
}
else if (mClassID.Equals(kCChild)) {
inst = (nsISupports*)new ChildWindow();
inst = (nsISupports*)(nsBaseWidget*)new ChildWindow();
}
else if (mClassID.Equals(kCButton)) {
inst = (nsISupports*)(nsWindow*)new nsButton();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsButton();
}
else if (mClassID.Equals(kCCheckButton)) {
inst = (nsISupports*)(nsWindow*)new nsCheckButton();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsCheckButton();
}
else if (mClassID.Equals(kCCombobox)) {
inst = (nsISupports*)(nsWindow*)new nsComboBox();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsComboBox();
}
else if (mClassID.Equals(kCRadioButton)) {
inst = (nsISupports*)(nsWindow*)new nsRadioButton();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsRadioButton();
}
@ -353,31 +353,31 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
else if (mClassID.Equals(kCListbox)) {
inst = (nsISupports*)(nsWindow*)new nsListBox();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsListBox();
}
else if (mClassID.Equals(kCHorzScrollbar)) {
inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_FALSE);
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_FALSE);
}
else if (mClassID.Equals(kCVertScrollbar)) {
inst = (nsISupports*)(nsWindow*)new nsScrollbar(PR_TRUE);
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsScrollbar(PR_TRUE);
}
else if (mClassID.Equals(kCTextArea)) {
inst = (nsISupports*)(nsWindow*)new nsTextAreaWidget();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextAreaWidget();
}
else if (mClassID.Equals(kCTextField)) {
inst = (nsISupports*)(nsWindow*)new nsTextWidget();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsTextWidget();
}
@ -401,7 +401,7 @@ nsresult nsWidgetFactory::CreateInstance( nsISupports* aOuter,
else if (mClassID.Equals(kCLabel)) {
inst = (nsISupports*)(nsWindow*)new nsLabel();
inst = (nsISupports*)(nsBaseWidget*)(nsWindow*)new nsLabel();
}

Просмотреть файл

@ -21,8 +21,9 @@
*/
#if defined(DEBUG_ftang)
#define KE_DEBUG
#define DEBUG_IME
//#define KE_DEBUG
//#define DEBUG_IME
//#define DEBUG_KBSTATE
#endif
#include "nsWindow.h"
@ -122,6 +123,8 @@ static PRBool NS_IsDBCSLeadByte(UINT aCP, BYTE aByte)
}
#endif // IME_FROM_ON_CHAR
#define IS_IME_CODEPAGE(cp) ((932==(cp))||(936==(cp))||(949==(cp))||(950==(cp)))
static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
{
int localeid=MAKELCID(aLangID,SORT_DEFAULT);
@ -145,6 +148,28 @@ static PRBool LangIDToCP(WORD aLangID, UINT& oCP)
}
}
//-------------------------------------------------------------------------
//
// nsISupport stuff
//
//-------------------------------------------------------------------------
NS_IMPL_ADDREF(nsWindow)
NS_IMPL_RELEASE(nsWindow)
NS_IMETHODIMP nsWindow::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if (NULL == aInstancePtr) {
return NS_ERROR_NULL_POINTER;
}
if (aIID.Equals(nsIKBStateControl::GetIID())) {
*aInstancePtr = (void*) ((nsIKBStateControl*)this);
NS_ADDREF((nsBaseWidget*)this);
// NS_ADDREF_THIS();
return NS_OK;
}
return nsBaseWidget::QueryInterface(aIID,aInstancePtr);
}
//-------------------------------------------------------------------------
//
// nsWindow constructor
@ -581,7 +606,7 @@ LRESULT CALLBACK nsWindow::WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
// is not really an interface.
nsCOMPtr<nsISupports> kungFuDeathGrip;
if (!someWindow->mIsDestroying) // not if we're in the destructor!
kungFuDeathGrip = do_QueryInterface(someWindow);
kungFuDeathGrip = do_QueryInterface((nsBaseWidget*)someWindow);
// Re-direct a tab change message destined for its parent window to the
// the actual window which generated the event.
@ -2707,6 +2732,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
case WM_LBUTTONDOWN:
//SetFocus(); // this is bad
//RelayMouseEvent(msg,wParam, lParam);
if(mIMEIsComposing) {
nsresult res = ResetInputState();
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
}
result = DispatchMouseEvent(NS_MOUSE_LEFT_BUTTON_DOWN);
break;
@ -2720,6 +2749,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
break;
case WM_MBUTTONDOWN:
if(mIMEIsComposing) {
nsresult res = ResetInputState();
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
}
result = DispatchMouseEvent(NS_MOUSE_MIDDLE_BUTTON_DOWN);
break;
@ -2732,6 +2765,10 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT
break;
case WM_RBUTTONDOWN:
if(mIMEIsComposing) {
nsresult res = ResetInputState();
NS_ASSERTION(NS_SUCCEEDED(res) , "ResetInputState failed");
}
result = DispatchMouseEvent(NS_MOUSE_RIGHT_BUTTON_DOWN);
break;
@ -4198,7 +4235,48 @@ BOOL nsWindow::OnIMEEndComposition()
BOOL nsWindow::OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult)
{
#ifdef DEBUG_IME
printf("OnIMENotify\n");
printf("OnIMENotify ");
switch(aIMN) {
case IMN_CHANGECANDIDATE:
printf("IMN_CHANGECANDIDATE %x\n", aData);
break;
case IMN_CLOSECANDIDATE:
printf("IMN_CLOSECANDIDATE %x\n", aData);
break;
case IMN_CLOSESTATUSWINDOW:
printf("IMN_CLOSESTATUSWINDOW\n");
break;
case IMN_GUIDELINE:
printf("IMN_GUIDELINE\n");
break;
case IMN_OPENCANDIDATE:
printf("IMN_OPENCANDIDATE %x\n", aData);
break;
case IMN_OPENSTATUSWINDOW:
printf("IMN_OPENSTATUSWINDOW\n");
break;
case IMN_SETCANDIDATEPOS:
printf("IMN_SETCANDIDATEPOS %x\n", aData);
break;
case IMN_SETCOMPOSITIONFONT:
printf("IMN_SETCOMPOSITIONFONT\n");
break;
case IMN_SETCOMPOSITIONWINDOW:
printf("IMN_SETCOMPOSITIONWINDOW\n");
break;
case IMN_SETCONVERSIONMODE:
printf("IMN_SETCONVERSIONMODE\n");
break;
case IMN_SETOPENSTATUS:
printf("IMN_SETOPENSTATUS\n");
break;
case IMN_SETSENTENCEMODE:
printf("IMN_SETSENTENCEMODE\n");
break;
case IMN_SETSTATUSWINDOWPOS:
printf("IMN_SETSTATUSWINDOWPOS\n");
break;
};
#endif
// not implement yet
@ -4225,13 +4303,26 @@ BOOL nsWindow::OnIMESelect(BOOL aSelected, WORD aLangID)
return PR_FALSE;
}
//==========================================================================
BOOL nsWindow::OnIMESetContext(BOOL aActive, LPARAM aISC)
BOOL nsWindow::OnIMESetContext(BOOL aActive, LPARAM& aISC)
{
#ifdef DEBUG_IME
printf("OnIMESetContext\n");
printf("OnIMESetContext %x %s %s %s Candidate[%s%s%s%s]\n", this,
(aActive ? "Active" : "Deactiv"),
((aISC & ISC_SHOWUICOMPOSITIONWINDOW) ? "[Comp]" : ""),
((aISC & ISC_SHOWUIGUIDELINE) ? "[GUID]" : ""),
((aISC & ISC_SHOWUICANDIDATEWINDOW) ? "0" : ""),
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<1)) ? "1" : ""),
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<2)) ? "2" : ""),
((aISC & (ISC_SHOWUICANDIDATEWINDOW<<3)) ? "3" : "")
);
#endif
if(! aActive)
ResetInputState();
// not implement yet
aISC &= ~ ISC_SHOWUICOMPOSITIONWINDOW;
// We still return false here because we need to pass the
// aISC w/ ISC_SHOWUICOMPOSITIONWINDOW clear to the default
// window proc so it will draw the candidcate window for us...
return PR_FALSE;
}
//==========================================================================
@ -4254,3 +4345,74 @@ BOOL nsWindow::OnIMEStartComposition()
::ImmReleaseContext(mWnd,hIMEContext);
return PR_TRUE;
}
//==========================================================================
NS_IMETHODIMP nsWindow::ResetInputState()
{
#ifdef DEBUG_KBSTATE
printf("ResetInputState\n");
#endif
if(mIMEIsComposing) {
HIMC hIMC = ::ImmGetContext(mWnd);
if(hIMC) {
BOOL ret = ::ImmNotifyIME(hIMC,NI_COMPOSITIONSTR,CPS_COMPLETE,NULL);
NS_ASSERTION(ret, "ImmNotify failed");
::ImmReleaseContext(mWnd,hIMC);
}
}
return NS_OK;
}
NS_IMETHODIMP nsWindow::PasswordFieldInit()
{
#ifdef DEBUG_KBSTATE
printf("PasswordFieldInit\n");
#endif
return NS_OK;
}
NS_IMETHODIMP nsWindow::PasswordFieldEnter(PRUint32& oState)
{
#ifdef DEBUG_KBSTATE
printf("PasswordFieldEnter\n");
#endif
if(IS_IME_CODEPAGE(mCurrentKeyboardCP))
{
HIMC hIMC = ::ImmGetContext(mWnd);
if(hIMC) {
DWORD st1,st2;
BOOL ret = ::ImmGetConversionStatus(hIMC, &st1, &st2);
NS_ASSERTION(ret, "ImmGetConversionStatus failed");
if(ret) {
oState = st1;
ret = ::ImmSetConversionStatus(hIMC, IME_CMODE_NOCONVERSION, st2);
NS_ASSERTION(ret, "ImmSetConversionStatus failed");
}
::ImmReleaseContext(mWnd,hIMC);
}
}
return NS_OK;
}
NS_IMETHODIMP nsWindow::PasswordFieldExit(PRUint32 aState)
{
#ifdef DEBUG_KBSTATE
printf("PasswordFieldExit\n");
#endif
if(IS_IME_CODEPAGE(mCurrentKeyboardCP))
{
HIMC hIMC = ::ImmGetContext(mWnd);
if(hIMC) {
DWORD st1,st2;
BOOL ret = ::ImmGetConversionStatus(hIMC, &st1, &st2);
NS_ASSERTION(ret, "ImmGetConversionStatus failed");
if(ret) {
ret = ::ImmSetConversionStatus(hIMC, (DWORD)aState, st2);
NS_ASSERTION(ret, "ImmSetConversionStatus failed");
}
::ImmReleaseContext(mWnd,hIMC);
}
}
return NS_OK;
}

Просмотреть файл

@ -28,6 +28,7 @@
#include "nsToolkit.h"
#include "nsIWidget.h"
#include "nsIKBStateControl.h"
#include "nsIMenuBar.h"
@ -50,13 +51,19 @@ class nsIRollupListener;
*/
class nsWindow : public nsSwitchToUIThread,
public nsBaseWidget
public nsBaseWidget,
public nsIKBStateControl
{
public:
nsWindow();
virtual ~nsWindow();
// nsISupports
NS_IMETHOD_(nsrefcnt) AddRef(void);
NS_IMETHOD_(nsrefcnt) Release(void);
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
// nsIWidget interface
NS_IMETHOD Create(nsIWidget *aParent,
const nsRect &aRect,
@ -135,6 +142,11 @@ public:
NS_IMETHOD CaptureRollupEvents(nsIRollupListener * aListener, PRBool aDoCapture, PRBool aConsumeRollupEvent);
// nsIKBStateControl interface
NS_IMETHOD ResetInputState();
NS_IMETHOD PasswordFieldInit();
HWND mBorderlessParent;
// nsSwitchToUIThread interface
@ -191,7 +203,7 @@ protected:
BOOL OnIMENotify(WPARAM aIMN, LPARAM aData, LRESULT *oResult);
BOOL OnIMERequest(WPARAM aIMR, LPARAM aData, LRESULT *oResult);
BOOL OnIMESelect(BOOL aSelected, WORD aLangID);
BOOL OnIMESetContext(BOOL aActive, LPARAM aISC);
BOOL OnIMESetContext(BOOL aActive, LPARAM& aISC);
BOOL OnIMEStartComposition();
ULONG IsSpecialChar(UINT aVirtualKeyCode, WORD *aAsciiKey);
@ -219,6 +231,9 @@ protected:
void HandleEndComposition(void);
void MapDBCSAtrributeArrayToUnicodeOffsets(PRUint32* textRangeListLengthResult, nsTextRangeArray* textRangeListResult);
NS_IMETHOD PasswordFieldEnter(PRUint32& oSavedState);
NS_IMETHOD PasswordFieldExit(PRUint32 aRestoredState);
private:
#ifdef DEBUG