使用 Clozure CL 在 Cocoa 窗口组件中实现显示中文字符串的简单方法
目录
0 概述
我们知道, 在 Cocoa 中提供了两种字符串类: NSString 和 NSMutableString, 前者用于处理内容不变, 固定的字符串, 比如窗口标题; 后者用于处理内容可变的字符串, 当然后者也可以用于前者的使用场合.
因为后者 NSMutableString 类是在继承 NSString 类的继承上创建的, 所以 NSMutableString 具有NSString 中所有的功能.
1 Objective-C 和 Lisp 的不同方法
在 Objective-C 代码中通常会使用如下的格式来定义字符串:
NSString string = @"This is my string";
语法非常简单明了, 但是有一个问题:使用加 @ 符号的方式只能定义英文数字字符串, 如果想定义中文等多字节字符串, 这种方法是不支持的.
下面给出一种 Objective-C 中定义中文字符串的示例:
NSString* string;
string = [NSString stringWithCString:"你好,我是中文字符串!"
encoding:NSUTF8StringEncoding];
是不是觉得这段代码特别繁琐, 如果转化为 Common Lisp 代码, 也比较麻烦, 不过 Clozure CL 已经提供了一种非常简单的生成中文字符串的方法, 如下:
(ccl::%make-nsstring "这是使用中文字符串的简单方法")
2 英文标题代码示例
举个实际的例子, 先绘制一个小窗口, 窗口标题为英文:
(in-package "CL-USER")
(require "COCOA")
(defclass window-view (ns:ns-view)
()
(:metaclass ns:+ns-object))
(objc:defmethod (#/drawRect: :void) ((self window-view) (rect :<NSR>ect))
(#/set (#/blueColor ns:ns-color))
(#_NSRectFill (#/bounds self)))
(defun show-window ()
(ccl::with-autorelease-pool
(let* ((rect (ns:make-ns-rect 0 0 350 350))
(w (make-instance 'ns:ns-window
:with-content-rect rect
:style-mask (logior #$NSTitledWindowMask
#$NSClosableWindowMask
#$NSMiniaturizableWindowMask)
:backing #$NSBackingStoreBuffered
:defer t)))
(#/setTitle: w #@"This is a English Title!")
(#/setContentView: w (#/autorelease (make-instance 'window-view)))
(#/center w)
(#/orderFront: w nil)
(#/contentView w))))
(show-window)
截图如下:
3 中文标题代码示例
接着我们修改一下这句:
(#/setTitle: w #@"This is a English Title!")
把它改为:
(#/setTitle: w (ccl::%make-nsstring "这是使用中文字符串的简单方法"))
当然了, 我们可以直接运行上述两段生成英文字符串和中文字符串的代码, 比较一下它们返回的结果,如下:
? #@"This is a English Title!"
#<NS-CONSTANT-STRING "This is a English Title!" (#x65BBD0)>
? (ccl::%make-nsstring "这是使用中文字符串的简单方法")
#<NS-MUTABLE-STRING "这是使用中文字符串的简单方法" (#x662600)>
?
很显然, 它们返回的对象类型不同, 一个是 NS-CONSTANT-STRING , 一个是 NS-MUTABLE-STRING.
全部代码形如:
(in-package "CL-USER")
(require "COCOA")
(defclass window-view (ns:ns-view)
()
(:metaclass ns:+ns-object))
(objc:defmethod (#/drawRect: :void) ((self window-view) (rect :<NSR>ect))
(#/set (#/blueColor ns:ns-color))
(#_NSRectFill (#/bounds self)))
(defun show-window ()
(ccl::with-autorelease-pool
(let* ((rect (ns:make-ns-rect 0 0 350 350))
(w (make-instance 'ns:ns-window
:with-content-rect rect
:style-mask (logior #$NSTitledWindowMask
#$NSClosableWindowMask
#$NSMiniaturizableWindowMask)
:backing #$NSBackingStoreBuffered
:defer t)))
(#/setTitle: w (ccl::%make-nsstring "这是使用中文字符串的简单方法"))
(#/setContentView: w (#/autorelease (make-instance 'window-view)))
(#/center w)
(#/orderFront: w nil)
(#/contentView w))))
(show-window)
然后再次运行, 截图如下:
是不是很简单. :)
以上的示例代码可以作为一个简单的用 Lisp 写苹果 APP 程序的窗口模板, 你可以慢慢自己添加一些其他的功能, 很快就能得到一个不太大但是能够提供一些简单功能的 APP 程序了!
来源:oschina
链接:https://my.oschina.net/u/219279/blog/150002