2

我刚刚开始在 Mac System 7.5.5 中使用MetroWerks CodeWarrior 1.1 For Mac 68k,但我需要知道:如何创建一个带有 TextBox 的简单表单?谢谢。

4

2 回答 2

2

我不知道 CodeWarrior 1.1 是否包含 GUI 设计器,但您可以使用本机 C-API (CreateNewWindow) 创建一个窗口。

问题是,不再有 7.5 的在线文档,所以我无法详细帮助您。

于 2009-11-25T19:52:30.877 回答
1

有几种方法可以做到这一点。如果你的 CodeWarrior 版本有它,你最好使用 PowerPlant 框架。这是一个应用程序框架,可以相对轻松地构建遵循 Mac UI 标准的应用程序。已经 10 多年了,所以我已经从记忆中完全清除了 PowerPlant 类层次结构。对不起。

另一种方法是在 ResEdit 中创建一个 DLOG 资源,其中包括一个或多或少适合窗口的 TextEdit 字段。然后你编写你的主应用程序,它将包括典型的工具箱初始化(我完全是从内存中完成的):

DialogPtr myDlog;
short itemHit;
InitGraf( &qd.thePort );
InitFonts();
InitWindows();
InitMenus();
TEInit();
InitDialogs( 0L );
InitCursor();

myDlog = GetNewDialog(myDlogResID, 0L, -1L);
ShowWindow(myDlog);
while (true) {
    ModalDialog(myDlog, &itemHit);
}

这可能会起作用,并且是在 Mac 上做 UI 的最错误的方式,但如果你想要的只是一个带有简单 UI 的盒子,你会没事的。

这段代码的问题是它不能很好地处理事件,循环是无限的,没有处理剪切/复制/粘贴,没有处理菜单事件等等。

那个时代的 Mac 工具箱需要你做的工作比你想象的要多得多。这就是为什么有像 MacApp、Think Class Library 和 PowerPlant 这样的库的原因——它们提供了 OOP 方法来为你处理很多家务琐事。在我进行大部分 Mac 编程时,我构建了一个非类库,它是原始 C 代码,可以更轻松地编写分层窗口(带有浮动调色板)和流畅的 UI,而无需 OOP 开销。基本上,我必须编写一个窗口管理器、一个菜单管理器、一个对话框管理器、一个事件管理器、一个命令调度程序等等。一切都说完了,构建一个典型的应用程序需要大约 18K 的开销。仅供参考,Macintosh 上的 Acrobat Search 直到第 4 版都基于此构建,Acrobat Catalog 也是如此。

你可以在 MacTech 中找到典型的例子,就像上面的代码一样。

在开始使用对话框构建整个 UI 之前,所有旧的 Macintosh 技术说明都说不要这样做。DialogManager 是有史以来被滥用最多的 Macintosh 代码块之一。它的目的是为了方便放置一个盒子,上面写着“你确定要关闭‘Untitled’吗?” 带有一个确定按钮和一个取消按钮。令人惊讶的是它可以被滥用多少。

做事的真正方法是编写一个初始化工具箱项目的主程序,构建一个基本菜单栏,然后​​分配一个您设计的对象,比如 NathanWindow。NathanWindow 可能如下所示:

class NathanWindow {
public:
    NathanWindow();
    virtual ~NathanWindow();
    void Initialize();
    void Click(short part, EventRecord *evt);
    void Show();
    void Hide();
    void Drag();
    void Move();
    // etc;
protected:
    virtual WindowPtr MakeWindow() = 0;
    virtual void OnInit() = 0;
private:
    WindowPtr _win;
};

然后您将使用代码对其进行子类化,以适当的样式调用 NewWindow()。

初始化将如下所示:

void NathanWindow::Initialize()
{
    _win = MakeWindow();
    _win->refCon = this;
    OnInit();
}

现在,这最后一点是棘手的部分——我已将指向 NathanWindow 的指针放入 Macintosh WindowPtr refCon 字段。然后,您将在主代码中构建一个事件循环,如下所示:

void HandleMouseDown(EventRecord *evt)
{
    WindowPtr win;
    short  thePart;

    thePart = FindWindow( eventPtr->where, &win ); 
    if (win) {
        NathanWindow *nw = (NathanWindow *)win->refCon;
        nw->Click(thePart, evt);
    }
}

void  EventLoop( void )
{
    EventRecord evt;

    while ( true ) {
        if ( WaitNextEvent( everyEvent, &evt, kSleep, nil ) ) {
           switch (evt.what) {
           case mouseDown:
               HandleMouseDown(&evt);
               break;
        }
    }
}

然后单击将如下所示:

NathanWindow::Click(short thePart, EventRecord *evt)
{
    switch(thePart) {
        case inGoAway: Close(); break;
        case inDrag: Drag(); break;
        case inGrow: Grow(); break;
    }
}

等等。

即便如此,这(可能)是错误的,因为您真的希望每个 NathanWindow 都连接到管理窗口层和分组的应用程序父级。

NathanWindow 应包含 NathanControls 的列表。NathanControl 是可以绘制、响应事件等的东西。

所有这一切都是为了以防您没有 PowerPlant,它会为您完成所有这些工作。Apple 喜欢吹捧“这很难容易”这句话是有原因的,因为触手可及的 API 太原始了。

于 2009-11-25T20:50:38.793 回答