标签存档: Mac

[Cocoa学习] 限制 NSTextField 中输入文本的长度

需求

NSTextField 作为一个常用的输入控件,有些在使用时需要去限制其中可以输入文本的长度,而 NSTextField 本身并没有提供这个功能,这就需要我们自己去想办法来实现了。

方法

在网上找了一下,发现可以通过继承 NSFormatter 实现一个子类来实现这个功能,参考了一下找到的代码[1],再将主要的 isPartialStringValid 方法根据自己的需要改了一下。

 
- (BOOL)isPartialStringValid:(NSString **)partialStringPtr
       proposedSelectedRange:(NSRangePointer)proposedSelRangePtr
              originalString:(NSString *)origString
       originalSelectedRange:(NSRange)origSelRange
            errorDescription:(NSString **)error 
{
    int size = [*partialStringPtr length];
    if ( size > maxLength ) {
        if (origSelRange.location == [origString length]) {
            // 如果修改的位置在原来字符串的最后,则不做修改,只是拒绝内容修改
        } else {
            // 如果修改的位置在原来字符串的中间,就根据剩余的可用的长度把新增加的字符串进行截取
            int preLen = origSelRange.location + (maxLength - [origString length]) + origSelRange.length;
            *partialStringPtr = [NSString stringWithFormat:@"%@%@",
                                 [*partialStringPtr substringToIndex:preLen],
                                 [origString substringFromIndex:origSelRange.location+origSelRange.length]];
 
            (*proposedSelRangePtr).location = preLen;
        }
 
        return NO;
    }
    return YES;
}

参考资料

[HOWTO] 在 Mac 下的 Safari 中直接打开 iWangWang 进行聊天

鉴于支付宝已经发布供 Safari 使用的安全登录控件,并且 Safari 可以自动调用关联程序来打开自定义协议,所有 Safari 下的点击旺旺图标打开 iWangWang 进行聊天比较容易实现,使用一个用户脚本就行。

要实现在 Safari 中点击旺旺图标进行聊天,步骤如下:

  1. 安装 SIMBL
    下载地址:http://www.culater.net/software/SIMBL/SIMBL.php
    SIMBL 可以理解为一个扩展加载器,因为 Safari 本身并不支持扩展机制,所有 SIMBL 使用了一种 Hack 的方式来方便加载第三方扩展。
  2. 安装 GreaseKit
    下载地址:http://8-p.info/greasekit/
    GreaseKit 是一个类似于 GreaseMonkey 的扩展,可以通过它在 Safari 运行用户脚本。
    如果你的系统是 Mac OS X Leopard,那么可能会出现安装 GreaseKit 失败的情况,这时可以试试一位网友重新编译的 GreaseKit,下载地址,关于这个问题的讨论可以看这里
  3. 最后,安装 iWangWang 聊天用户脚本
    安装地址:https://iwangwang.googlecode.com/hg/wwprotocol.user.js
    如果已经正确安装了 GreaseKit,那么在访问这个地址时,浏览器会询问是否安装“WangWang Protocol Handler”,选择“是”即可。

如果你已经将 iWangWang 放到了应用程序目录,那么在点击旺旺图标聊天时,会自动打开 iWangWang,如果 iWangWang 没有放到应用程序目录,那么你可能需要先运行 iWangWang 才可以使用点击旺旺图标进行聊天的功能。

如果有任何问题请联系我 ohdarling88 # gmail dot com

iWangWang v0.1.2 for Mac 发布

iWangWang 是一个在 Mac OS X 下使用的 Web 旺旺的客户端,使用 Mac 用户在淘宝购物时也可以方便地与卖家沟通,不需要每次打开 Web 旺旺,以及弥补 Web 旺旺不支持联系人列表及聊天记录的缺陷,并且目前只支持淘宝网帐号登录。

iWangWang 使用 REALbasic 编写,因为是基于 Web 旺旺的,所以 Web 旺旺不支持的功能 iWangWang 也没有实现,包括但不限于旺旺群、自定义表情、文件传送,并且和某一个联系人第一次聊天时,需要输入验证码。

注意:

  1. 这纯粹是我个人出于兴趣而制作的一个程序,与公司无关。
  2. 因为使用非公开接口,协议通过黑盒分析所得,因此有可能会由于 Web 旺旺修改通信协议而导致程序无法使用。
  3. 由于缺乏艺术细胞,因此程序界面仿照 MacQQ,如果觉得有内容侵犯了您的权利,请及时联系我修改,谢谢 :)
  4. 因为淘宝帐号涉及到金钱,所以如果不放心请不要使用这个程序 :)

如果有任何问题或建议,请联系 ohdarling88 # gmail dot com,或者点击菜单“文件》填写使用反馈”来填写反馈内容。

14:40 Update 更新下载链接,修正了接收带有自定义表情的消息时会导致程序崩溃的bug,如果已经下载,可以直接点击菜单“iWangWang > 检查更新”

下载地址:http://iwangwang.googlecode.com/files/iWangWang-v0.1.2.zip

在 REALbasic 中注册 AppleEvent

之前为了注册一个自定义协议,需要通过注册 AppleEvent 来实现,在 Objective-C 中,可以很方便的使用 NSAppleEventManager 来注册 AppleEvent 句柄,但是在 REALbaisc 中,是没有办法直接去调用 NSAppleEventManager 的,所以需要通过声明然后调用 C API 来实现相应的功能。

与 NSAppleEventManager 中功能相对应的 C API 有 AEInstallEventHandler, NewAEEventHandlerUPP 等,通过这些 API 我们也可以在 REALbasic 中来注册 AppleEvent 了,再配合 Info.plist 中的 URLScheme 声明,即可实现 URL 自定义协议处理句柄。

#if TargetCarbon
    soft declare function AEInstallEventHandler Lib CarbonLib ( _
    theAEEventClass as Integer, _
    theAEEventID as Integer, _
    handler as Integer, _
    handlerRefcon as Integer, _
    isSysHandler as Boolean) as Integer
 
    Soft Declare Function NewAEEventHandlerUPP Lib CarbonLib (userRoutine as Ptr) as Integer
 
    Static CallbackUPP as Integer = 0
    If CallbackUPP = 0 then
      dim m as MemoryBlock =  AddressOf ForwardCarbonAEEventToObject
      If m is nil then
        Return
      End if
      CallbackUPP = NewAEEventHandlerUPP(m)
    End if
 
    dim v as Variant = me
 
    dim OSError as Integer = AEInstallEventHandler( _
    OSTypeToUInt(kInternetEventClass), _
    OSTypeToUInt(kAEGetURL), _
    CallbackUPP, _
    v.Hash, false)
 
    msgbox str(OSError)
#endif

先使用 NewAEEventHandlerUPP 来生成一个 AppleEvent 回调函数的句柄,然后调用 AEInstallEventHandler 来注册一个共享函数 ForwardCarbonAEEventToObject 为 AppleEvent 事件处理句柄。

AEInstallEventHandler 所需的 AEEventClass 和 AEEventID 都是一个 4 字节的整型,但是通常我们在调用的时候,是用的一个 4 字符的字符串,因此需要一个函数来将 4 字符转换为 4 字节的整形。

// code from ToolbarSearchField by The ZAZ Studios
// http://www.thezaz.com/opensource/realbasic/macosx/searchfield/
static m as new MemoryBlock(4)
m.LittleEndian = false
m.StringValue(0, 4) = s
return m.UInt32Value(0)

在 ForwardCartonAEEventToObject 里,参数 theEvent 和 replyEvent 都量个整形,为了从这两个参数里拿到数据,还需要使用 AEGetParamPtr 来从 AppleEvent 中拿到数据。

soft declare function AEGetParamPtr lib CarbonLib ( _
    theAppleEvent as Integer, theAEKeyword as Integer, _
    desiredType as Integer, byref actualType as Integer, _
    dataPtr as Ptr, maximumSize as Integer, _
    byref actualSize as Integer) as Integer

当然还有一系列的 AEGetDataDesc、AEGetDescSize 等函数可以,具体可以查 Xocde 随带的库文档。

关于注册自定义协议,可以参考这篇文章

通过 Core Foundation 中的一些 C API,在 REALbasic 也可以完成一些平台相关的工作,虽然麻烦了些:)

Chromium Updater for Mac

图片附件为了随时更新到 Chromium 的最新 nightly build,又不想每次去 Chromium 的网站下,还有解压,移动,麻烦……为了省事,直接用 REALbasic 写了一个 Chromium Updater,专门用来更新 Chromium。目前只支持 Mac :)

详细说明

下载(使用右键下载):ChromiumUpdater (3.5M)

图片附件

解决 Finder 中挂载 Samba 出现“输入的文本似乎不是可识别的 URL 格式”错误

在公司里为了让笔记本和台式机共享文档,决定用内部的 Samba 做中转,但是在 Finder 中直接使用“连接到服务器”时,会出现“输入的文本似乎不是可识别的 URL 格式”错误,但是我输入的地址明明是 smb:// 开头的。

用这个错误信息在网上找了找,没有找到任何解决文案,遂放弃。

今天决定再尝试一下,换了个关键字,直接用“iDeneb samba”作为关键字来搜索,慢慢发掘之后还真找到了有用的信息:http://www.hackint0sh.org/f179/81233.htm

按照文中说明,到 /System/Library/Filesystems 目录下,把 afpfs.fs 删除,并重新创建到 /System/Library/Filesystems/AppleShare/afpfs.kext 的软链接,但是操作完之后还是会提示“输入的文本似乎不是可识别的 URL 格式”。

再找了找,找到了这篇:http://www.insanelymac.com/forum/i … opic=92989&st=580,似乎说是系统安装完成时 afpfs.fs 到 /System/Library/Filesystems/AppleShare/afpfs.kext 的软链接少了开头的斜杠,也就是说它的软链接地址是 System/Library/Filesystems/AppleShare/afpfs.kext

好吧,我在之前操作的时候为了省事,直接进入 Filesystems 目录用相对路径来创建软链接的,看了文章之后,老老实实的用全路径再次创建软链接,Command+K,双击,成功连上 Samba 服务器:)

完整的操作步骤也只有两步:

sudo rm /System/Library/Filesystems/afpfs.fs

sudo ln -s /System/Library/Filesystems/AppleShare/afpfs.kext /System/Library/Filesystems/afpfs.fs

注意:一定不能省略了路径最开始的斜杠(/)或者使用相对路径。

所以,如果你也是用黑苹果的,也碰到了这个问题,不妨试试这个解决方法吧。

1000E 升级到 2G 内存时安装 OSX 需要用到的 dsdt.aml

上周去把 EPC 的内存升级到了 2G,直接发现开机进不了 OSX 了。

在两天没有电脑用之后,下定决心重装系统。重装之后,能进系统,但是重新启动之后键盘和触摸板就不能用了,电池状态指示挂了,郁闷。

在网上找了找,发现可能是 dsdt 的问题。由于内存大小变了,dsdt 中的信息不正确,继而导致 ACPI 失效,然后就整个玩完了。

一个老外找到了解决方法,通过修改 dsdt.aml 文件中的内存大小信息,就可以正确进入系统了。直接下载他提供的压缩包中的 dsdt.aml,开机直接四国了……

好吧,这个老外蛮厚道的,给出了手动处理的方法:

For the 1GB:

Name (SMBS, 0×0400)
OperationRegion (BIOS, SystemMemory, 0x3F7AE064, 0xFF)
Field (BIOS, ByteAcc, NoLock, Preserve)
{

For the 2GB:

Name (SMBS, 0×0400)
OperationRegion (BIOS, SystemMemory, 0x7F7AE064, 0xFF)
Field (BIOS, ByteAcc, NoLock, Preserve)
{

手动修改步骤

1. 首先要下载一个 dsdt.aml 反编译的工具:ACPICA – Windows Binary Tools

2. 解压后有一个 iasl.exe,把它拷贝到 dsdt.aml 所在的目录或者把 dsdt.aml 拷贝到 iasl 的目录都行,然后在命令行中运行:iasl -d dsdt.aml

3. 按照上面的说明,使用文本编辑器打开 dsdt.aml.dsl,根据你的内存大小修改 SystemMemory 后面的数值,1G 就用 0x3F7AE064,2G 就用 0x7F7AE064。

4. 再到命令行中,运行 iasl dsdt.aml.dsl,它会生成一个 dsdt.aml.aml,把它拷贝到 OSX 所在分区的根目录,覆盖原来的 dsdt.aml 即可。或者也可以把原来的文件备份一下,方便出错的还原。

参考资料

  1. eee 1000H(E) – DSDT files and the memory problem