import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.internal.Callback;
import org.eclipse.swt.internal.carbon.CGRect;
import org.eclipse.swt.internal.carbon.OS;
import org.eclipse.swt.internal.carbon.Rect;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class EnterKeyBug extends Composite{
Callback textInputCallback;
int textInputProc;
int childWnd = 0;
int[] outControl = new int[1];
int iFrameOptions = OS.kTXNDontDrawCaretWhenInactiveMask
| OS.kTXNMonostyledTextMask;
public EnterKeyBug(Composite parent, int style) {
super(parent, style);
// create carbon HITextView
OS.HITextViewCreate(null, 0, iFrameOptions, outControl);
if (outControl[0] == 0){
System.out.println(SWT.ERROR_NO_HANDLES);
SWT.error(SWT.ERROR);
}
childWnd = outControl[0];
OS.HIViewSetVisible(childWnd, true);
OS.HIViewAddSubview(handle, childWnd);
//add handler to handle keyboard event.
int[] mask5 = new int[] { OS.kEventClassTextInput,
OS.kEventTextInputUnicodeForKeyEvent, OS.kEventClassTextInput,
OS.kEventTextInputUpdateActiveInputArea,
OS.kEventClassTextInput, OS.kEventTextInputOffsetToPos,
OS.kEventClassTextInput, OS.kEventTextInputPosToOffset,
OS.kEventClassTextInput, OS.kEventTextInputGetSelectedText, };
textInputCallback = new Callback(this, "textInputProc", 3);
textInputProc = textInputCallback.getAddress();
OS.InstallEventHandler(OS.GetControlEventTarget(childWnd), textInputProc, mask5.length / 2,
mask5, 0, null);
this.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent arg0) {
// if(childWnd==0 && !isCreatingNative){
CGRect r = new CGRect();
r.width = r.height = 300;
OS.HIViewSetFrame(handle, r);
Rect inset = new Rect();
inset.left = inset.top = inset.right = inset.bottom = 1;
r.x += inset.left;
r.y += inset.top;
r.width -= inset.left + inset.right;
r.height -= inset.top + inset.bottom;
OS.HIViewSetFrame(childWnd, r);
}
});
}
int textInputProc(int nextHandler, int theEvent, int userData) {
int [] keyboardEvent = new int [1];
OS.GetEventParameter (theEvent, OS.kEventParamTextInputSendKeyboardEvent, OS.typeEventRef, null, keyboardEvent.length * 4, null, keyboardEvent);
int [] keyCode = new int [1];
OS.GetEventParameter (keyboardEvent [0], OS.kEventParamKeyCode, OS.typeUInt32, null, keyCode.length * 4, null, keyCode);
System.out.print("I get the keyCode is "+keyCode[0]+"/n");
return OS.eventNotHandledErr;
// return OS.noErr;
}
public static void main (String [] args)
{
System.out.println("The keyCode of /"return/" is 36, ");
System.out.println("The keyCode of /"enter/" is 76");
System.out.println("Please type the two key into application, test in SWT3.4 and SWT3.5");
Display display = new Display ();
Shell shell = new Shell (display);
shell.setMinimumSize(300, 350);
shell.setLayout (new RowLayout ());
EnterKeyBug composite = new EnterKeyBug(shell, SWT.BOLD);
composite.setLayout (new RowLayout ());
composite.setBackground(new Color(null, 125, 255, 255));
shell.pack ();
shell.open ();
while (!shell.isDisposed())
{
if (!display.readAndDispatch ())
display.sleep ();
}
display.dispose ();
}
}
这个程序可以监听到键盘的输入事件(即OS.kEventClassTextInput)。并且添加了事件的回调函数(即 事件发生了,程序怎么样处理)。
每一个SWT的Control 对应着一个Mac操作系统的Control,这个是通过句柄来表现的(这个是自己理解的,不一定正确)。在本例中handle就是Composite的句柄。程序在handle上添加了一个Carbon 的HIView。
句柄:就是标识资源的一个整数,和指针差不多。
下面是翻译的Mac ADC 上的一段关于事件的文档。
用户点击鼠标,在键盘上输入字符,在菜单上选择一个command,将有一个事件通知你。当你的windows需要重画、移动、调整大小,你也将收到一个事件。
Carbon Event Manager (CEM) 是推荐的API,在Carbon应用中。
用这个API,你可以处理事件和创建事件。
可以处理的事件有:
1 Window events:关闭,激活,移动等等。
2 Menu events:菜单的跟踪,选择,键盘的快捷键等等。
3 Conrol events:选择,改变焦点等等
4 Mouse events:鼠标的按下,抬起,双击等等
5 Text and keyboard:文本输入、粗键盘按下
6 Application events:应用的激活,请求退出等等
7 Apple events: 详细参见Dispatching Apple Events in Your Application in Apple Events Programming Guide
8 Volume events:插入和弹出CD和磁盘事件
9 Tablet events: 不太清楚
Carbon 事件管理器中的基本概念
1 Carbon 事件处理理论
The Event Loop
通过事件驱动的程序必须有一个事件循环。当做完必要的初始化之后,应用程序将进入主循环。
1) 应用处于暂停的状态,等待事件的到来。这个时候,程序不占用 CPU。
2) 当一个需要该程序处理的事件产生后,这个应用将被唤醒,来处理这个事件。一般Carbon Event Manager 回调事件处理者。当然应用必须在此之前安装了事件的处理者。
3 )在处理结束后,应用返回到暂停状态,等到下个事件。
Event Types
每个事件都通过一个事件类型来表示。一个事件类型由两部分组成:事件(种)类、事件类型(码)。事件类表示一个事件种类,如:鼠标事件、窗体事件等。事件类型码表示在分类中更加详细的事件,如:鼠标按下,鼠标抬起等等。
Event Targets and Conrainment Hierachies
每个事件处理者必须关联一个特殊的对象,这个对象叫做event target。
2 事件模型
3 Carbon 事件 VS WaitNextEvent
说明:所有的键盘事件和输入事件都被发送给用户正在聚焦的目标上。你可以在"user focus event target (你可以调用GetUserFocusEventTarget方法来等到)" 上安装一个事件处理者,这样发送给用户焦点目标的事件都将先给你的处理者处理,如果你不处理这个事件,这个事件将传给真正的用户聚焦的控件上。
Introduction to Understanding Test Input and the Text Services Manager in Carbon