Discussion:
Problems with CAPEDIT control's input mode
(too old to reply)
OldSkool
2003-07-04 14:10:27 UTC
Permalink
Hi all!

I'm pissed off quite a bit trying to get that damn thing to work :((( But no
luck however hard I try :(

The problem is simple. I'm creating popup window that has a static text
label and an edit control on it, nothing more. In WM_CREATE handler I set
edit control's input mode explicitly to EIM_SPELL. But it works only for the
first time the window is shown. After the first create/destroy window
lifecycle input mode selection fails and remains EIM_NUMBER all the time.

During my shamanic dances around the fire I tried the following: created the
second edit control and voila! it has the required input mode. But it
doesn't solve the problem, I need only one edit control :(

Has anyone ever met with such a problem? Or does anybody have a clue of what
is going on and how to fix it? Please help.

PS: The device I'm working with is RedE. But the situation with input mode
is the same on device and emulator both.

PPS: Sorry for my poor english.
Alex Feinman [MVP]
2003-07-05 05:22:43 UTC
Permalink
Without seeing the code it's hard to tell, but the obvious things to check
would be:
1) That you are not trying to use the old handle with the newly-created
window (check IsSindow(hEditControl))
2) That EM_GETINPUTMODE works on the same window
3) Just for the fun of it try posting yourself a custom message (WM_USER)
from WM_CREATE handler and set input mode from the handler for that custom
message.
Post by OldSkool
Hi all!
I'm pissed off quite a bit trying to get that damn thing to work :((( But no
luck however hard I try :(
The problem is simple. I'm creating popup window that has a static text
label and an edit control on it, nothing more. In WM_CREATE handler I set
edit control's input mode explicitly to EIM_SPELL. But it works only for the
first time the window is shown. After the first create/destroy window
lifecycle input mode selection fails and remains EIM_NUMBER all the time.
During my shamanic dances around the fire I tried the following: created the
second edit control and voila! it has the required input mode. But it
doesn't solve the problem, I need only one edit control :(
Has anyone ever met with such a problem? Or does anybody have a clue of what
is going on and how to fix it? Please help.
PS: The device I'm working with is RedE. But the situation with input mode
is the same on device and emulator both.
PPS: Sorry for my poor english.
OldSkool
2003-07-07 10:00:41 UTC
Permalink
Hi, Alex!

First of all, thanks for the reply.

AFM> Without seeing the code it's hard to tell, but the obvious things
AFM> to check would be:

Ok, I put the code at the end of this post.

AFM> 1) That you are not trying to use the old handle with the
AFM> newly-created window (check IsSindow(hEditControl))

Definitely not. Edit_SetInputMode() is called along with SetLimitText() and
SetFocus(), which work just fine.

AFM> 2) That EM_GETINPUTMODE works on the same window

Weird, but it doesn't. It returns 0xFFFFFFFF all the time, except the very
first call. What could be wrong here?

AFM> 3) Just for the fun of it try posting yourself a custom message
AFM> (WM_USER) from WM_CREATE handler and set input mode from the handler
for that
AFM> custom message.

Thanks for idea, but it didn't help :-(

By the way, I haven't noticed before: mode is set successfully on the first
call after _emulator_, not application startup! If I try to restart the
application during the same emulator session, EM_SETINPUTMODE won't work at
all.

Here is the code, it could be useful to clarify what's going on:

// here is a wrapper class for CAPEDIT control that I wrote
namespace WTL {
template <class TBase>
class CCapEditT : public CEditT<TBase>
{
public:
static LPCTSTR GetWndClassName()
{
return WC_CAPEDIT;
}
// Smartphone extensions
BOOL SetInputMode( UINT _mode )
{
return Edit_SetInputMode(m_hWnd,_mode);
}
UINT GetInputMode( BOOL _local )
{
return Edit_GetInputMode(m_hWnd,_local);
}
// CAPEDIT extensions
void EnableUpcase( BOOL _enable )
{
::SendMessage(m_hWnd,CEM_ENABLEUPCASE,_enable,0);
}
void UpcaseAllWords( BOOL _enable )
{
::SendMessage(m_hWnd,CEM_UPCASEALLWORDS,_enable,0);
}
};
typedef CCapEditT<CWindow> CCapEdit;
}; // end of namespace WTL

class CProblemDialog : public CWindowImpl<CProblemDialog>
{
public:
CProblemDialog() {}
BEGIN_MSG_MAP_EX(CProblemDialog)
MSG_WM_CREATE(OnCreate)
MESSAGE_HANDLER(WM_INITEDITCONTROLS,OnInitEditControls)
// unnecessary code skipped
...
END_MSG_MAP()

LRESULT OnCreate( LPCREATESTRUCT _lpcs )
{
RECT rc;

GetClientRect( &rc );
// make offsets to improve visual appearance
rc.left += 3;
rc.right -= 3;

// create menu bar
SHMENUBARINFO shmbi;
ZeroMemory(&shmbi, sizeof(shmbi));
shmbi.cbSize = sizeof(shmbi);
shmbi.hwndParent = m_hWnd;
shmbi.nToolBarId = IDR_MENU;
shmbi.hInstRes = _Module.m_hInst;
if( !::SHCreateMenuBar( &shmbi) )
{
DWORD dwError = GetLastError();
return -1;
}

// override BACK key behavior
::SendMessage( shmbi.hwndMB, SHCMBM_OVERRIDEKEY, VK_TBACK,
MAKELPARAM(SHMBOF_NODEFAULT | SHMBOF_NOTIFY,
SHMBOF_NODEFAULT | SHMBOF_NOTIFY) );

// create static text label
RECT rcStatic = rc;
{
CWindowDC dc(*this);
RECT rctmp = rc;
rcStatic.bottom = rcStatic.top + dc.DrawText( TEXT(" "), -1, &rctmp,
DT_CALCRECT|DT_SINGLELINE );
}
m_Label.Create( m_hWnd, rcStatic, NULL, WS_VISIBLE );
m_Label.SetWindowText( TEXT("Name") );

// create edit control
rc.top = rcStatic.bottom;
rc.bottom = rc.top + EDITCONTROL_HEIGHT;
m_Name.Create( m_hWnd, rc, NULL,
WS_VISIBLE|WS_TABSTOP|WS_BORDER|ES_AUTOHSCROLL );
m_Name.SetLimitText( MAX_NAME_LEN );
m_Name.SetFocus();
// this is the hack that Alex Feinman advised to try:
PostMessage( WM_INITEDITCONTROLS );

return 0;
}
LRESULT OnInitEditControls( UINT _msg, WPARAM _wParam, LPARAM _lParam,
BOOL& _bHandled )
{
UINT mode = m_Name.GetInputMode( TRUE ); // this returns 0 on the first
call, 0xFFFFFFFF all the time after that
int err = ::GetLastError(); // this returns 6 (Invalid
handle)
if( TRUE != m_Name.SetInputMode( EIM_SPELL ) )
{
// just in case...
::MessageBox( 0, TEXT("Input mode setting failed!"), TEXT(""),
MB_OK|MB_ICONERROR );
}
mode = m_Name.GetInputMode( TRUE ); // this returns 0xFFFFFFFF ALL THE
TIME
err = ::GetLastError(); // this returns 6 all the time
m_Name.EnableUpcase( TRUE );
return 0;
}
// unnecessary code skipped
...
protected:
WTL::CStatic m_Label;
WTL::CCapEdit m_Name;
};
// here is the code by which CProblemDialog gets created:
void CAppClass::CreateProblemDialog()
{
ShowWaitIcon();
static CEditPlayerDialog dlg;
RECT rc;
SystemParametersInfo( SPI_GETWORKAREA, 0, &rc, 0 );
// make window really fullscreen
rc.top = 0;
dlg.Create( m_hWnd, rc, TEXT("Problem dialog"),
WS_CAPTION|WS_CLIPSIBLINGS|WS_POPUP );
dlg.UpdateWindow();
dlg.ShowWindow( SW_SHOW );
ShowWaitIcon( false );
}
// and at last, here is some application initialization code:
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPWSTR lpCmdLine,
int CmdShow)

{
// unnecessary code skipped
...
// Init common controls.
INITCOMMONCONTROLSEX comctrex;
comctrex.dwSize = sizeof(comctrex);
comctrex.dwICC = ICC_DATE_CLASSES | ICC_UPDOWN_CLASS |
ICC_CAPEDIT_CLASS;
InitCommonControlsEx(&comctrex);


// is it the redundant call?
// does InitCommonControlsEx with ICC_CAPEDIT_CLASS flag set do the
same?
if( !SHInitExtraControls() )
{
return 0;
}
...
}

See ya!

Loading...