r2 - 05 May 2010 - 22:27:10 - MingmingKillerYou are here: TWiki >  Columns Web > MingmingKillerArticle10

MiniGUI修改心得3

作者:胡明明

邮箱:mingming_killer@126.com

在使用MiniGUI的时候总有有些功能MiniGUI没有的,或者是MiniGUI的某些功能不太适用的。这就需要我们开发人员动手稍微改一下MiniGUI了。这次我遇到的情况就是要去掉MiniGUI ime输入法窗口的自动出现和消失功能。我使用的MiniGUI版本是GPL的1.3.3(该方法同样适用于2.0.4的ime输入法,但是可能需要稍微改一下下,不过思路是一样的),thread模式。

一、问题来源

用过MiniGUI的ime输入法的兄弟们都知道1.3.3(2.0.4)的输入法窗口只要你创建了以后,但凡遇到可编辑的控件得到输入焦点(Edit控件),就会自动出现(即便你把它手动关闭了);可编辑的控件失去输入焦点ime窗口就会自动关闭。这个功能估计本意是想让ime输入法窗口比较人性化的,但是不少用户(至少我原来这家公司的不少用户有这个要求)还是比较喜欢类似于桌边操作系统那样的输入法,需要时自己手动切换出来,不需要的时候就换回去(QQ拼音、搜狗、google等等)。

二、解决思路

要解决这个问题首先要弄清楚为什么MiniGUI的ime输入法窗口会有上述说的那些自动功能。经过我的研究1.3.3的源代码发现实现上述功能主要是MiniGUI的默认窗口处理函数(DefaultMainWinProc())和Edit控件做了些“多余”的事。

首先DefaultMainWinProc()中的DefaultPostMsgHandler()这个函数在接受到MSG_SETFOCUS和MSG_KILLFOCU这两消息后,向当前处于焦点(或是失去焦点)的控件发送MSG_DOESNEEDIME消息来确认是否是需要自动开启、关闭ime输入法的功能。如果该控件响应了MSG_DOESNEEDIME消息,并返回TRUE的话自动的开启、关闭ime输入法(目前只有Edit控件相应这个消息)。

OK我们明白了这个原理后,要想去掉这个功能就好办了,我只需要在DefaultPostMsgHandler()里再MSG_SETFOCUS和MSG_KILLFOCUS消息里不自动调用向控件发送MSG_DOESNEEDIME消息的函数就可以了(open_ime_window())。不过我的修改MiniGUI的一个基本原则就是尽量保持与原来功能的兼容性,所以我决定增加一个BOOL变量开关来让外部应用程序来控制是否关闭MiniGUI ime的自动开启、关闭功能。当外部应用程序通过消息接口设置为TRUE时,则开启ime的自动开启、关闭功能;当设置成FALSE时则关闭ime的自动开启、关闭功能(此时应用程序可以自行控制ime窗口的开启、关闭)。

三、实现方法

有了上面的思路就好办多了,好了现在就开始修改。首先是要增加相应的BOOL开关变量的应用声明和相应的设置消息接口。我把这些放在libminigui-1.3.3/include/window.h下:

// ********************************************************
// hack by mingming-killer 2010.3.22

//#define MSG_LASTWINDOWMSG    0x010F

// choose whether auto switch ime windows
// lParam = (LPARAM)bAuto;
// TRUE: auto; FALSE: manual

extern BOOL bAutoIme;

#define MSG_SETAUTOIME    0x010F

#define MSG_LASTWINDOWMSG    0x0110

// ********************************************************

注意要注释掉原来的MSG_LASTWINDOWMSG定义,然后把这个值加大些,因为我们这里多出一个消息接口了(MSG_SETAUTOIME)。

然后就是增加响应MSG_SETAUTOIME这个消息的代码。这里要找一个依托的窗口过程处理函数。这时找桌面过程处理函数我认为最适合不过啦,所以就在libminigui-1.3.3/src/kernel/desktop-comm.c里的WindowMessageHandler()函数里的switch部分增加如下代码:

// ********************************************************
// hack by mingming-killer 2010.3.22
// Provide a interface to external application that can set auto or manual switch the ime window.

case MSG_SETAUTOIME:{
        bAutoIme = (BOOL)lParam;
        break;
}

// ********************************************************

接下来就是在libminigui-1.3.3/src/gui/window.c里加入BOOL开关变量的定义:

// ********************************************************
// hack by mingming-killer 2010.3.22
// ime window auto switch flag
// TRUE: auto; FALSE: manual

BOOL bAutoIme = TRUE;

// ********************************************************

最后是在的DefaultPostMsgHandler()里的switch部分的MSG_SETFOCUS和MSG_KILLFOUCS那调用open_ime_window()前加上我们之前新增加的开关变量的判断:

case MSG_SETFOCUS:
case MSG_KILLFOCUS:
if (pWin->hActiveChild)
SendNotifyMessage (pWin->hActiveChild, message, 0, 0);

// ********************************************************
// hack by mingming-killer 2010.3.22
// Provide a interface to external application that can set auto or manual switch the ime window.

if ( TRUE == bAutoIme ) 
open_ime_window (pWin, message, (HWND)wParam);

// ********************************************************

break;

OK,改好后重新编译libminigui。然后在应用程序中的MiniGUIMain入口函数那,在开始主窗口消息循环前调用SendMessage,向桌面(HWND_DESKTOP)发送MSG_SETAUTOIME即可设置ime窗口的自动开启、状态。

由于1.3.3是GPL的,所以这里附上我修改好的1.3.3的源代码文件以及一个测试该功能的一个小例子程序。x86 redhat9 framebuffer下测试通过。

参考资料:飞漫MiniGUI 1.3.3 API手册

-- MingmingKiller - 06 Apr 2010

Topic attachments
I Attachment Action Size Date Who Comment
elserar minigui_1.3.3_hack.rar manage 74.1 K 06 Apr 2010 - 21:59 MingmingKiller  
Edit | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r2 < r1 | More topic actions
 
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the Feynman Software and/or the contributing authors. All material on this collaboration platform is the property of Feynman Software and/or the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback