在 C++ 中创建表单

发布于 2024-08-12 21:13:55 字数 114 浏览 5 评论 0原文

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

I'm just starting to use MetroWerks CodeWarrior 1.1 For Mac 68k in a Mac System 7.5.5, but I need to know: How can I create a simple Form with a TextBox on it? Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

全部不再 2024-08-19 21:13:55

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

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

I don't know if CodeWarrior 1.1 contains a GUI designer, but you can create a window using the native C-API (CreateNewWindow).

Problem is, there is no online documentation for 7.5 anymore, so I cannot help you in detail.

甜味超标? 2024-08-19 21:13:55

有几种方法可以做到这一点。如果您的 CodeWarrior 版本有它,那么您最好使用 PowerPlant 框架。这是一个应用程序框架,可以相对轻松地构建遵循 Mac UI 标准的应用程序。十多年过去了,我已经完全从记忆中清除了 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 的最错误方法,但如果您想要的是一个带有简单用户界面的盒子,就可以了。

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

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

您可以在 MacTech 中找到规范示例,这样 与上面的代码类似。

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

真正的做事方法是编写一个 main 来初始化工具箱项,构建一个基本菜单栏,然后​​分配一个您设计的对象,例如 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;
        }
    }
}

然后 Click 将如下所示:

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,它会为您完成所有这些工作。苹果喜欢宣扬“变得简单很难”是有原因的,因为你触手可及的 API 太原始了。

There are a couple ways to do it. If your version of CodeWarrior has it, you would be best off using the PowerPlant framework. This is an application framework that makes it relatively easy to build applications that follow the Mac UI standards. It's been more than 10 years, so I have fully purged the PowerPlant class hierarchy from my memory. Sorry.

Another way to do this is to create a DLOG resource in ResEdit which includes a TextEdit field that more or less fits the window. Then you write your main app, which is going to include the typical toolbox initializations (I'm doing this TOTALLY from memory):

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);
}

Which will probably work and is the most wrong way to do UI on the Mac, but if all you want is a box with a simple, simple UI, you'll be OK.

The problem with this code is that it doesn't handle the events well, the loop is infinite, there is no handling of cut/copy/paste, there is no honoring of menu events, and so on.

The Mac toolbox of that era requires you to do a hell of a lot more work than you might think. This is why there were libraries like MacApp, Think Class Library and PowerPlant - they provided OOP methods to handle a lot of the housekeeping crap for you. At the time that I did most of my Mac programming, I build a non-class library that was raw C code that made it easier to write layered windows (with floating palettes) and fluid UI without the overhead of OOP. Basically, I had to write a window manager, a menu manager, a dialog manager, an event manager, a command dispatcher and so on. When all was said and done, there was something like 18K of overhead to build a typical application. FYI, Acrobat Search on the Macintosh up until version 4 was built on this, as was Acrobat Catalog.

You can find canonical examples in MacTech, like this which is similar code to the above.

Before you start building your entire UI out of Dialog Boxes, all the old Macintosh tech notes said DON'T DO THIS. The DialogManager is one of the most abused chunks of Macintosh code there ever was. It was built for the purpose of making it easy to put of a box that says, "Are you sure you want to close 'Untitled'?" with an OK button and a cancel button. It's surprising how much it can be abused.

The real way to do things is to write a main that initializes the toolbox items, builds a basic menu bar then allocates an object that you design, say NathanWindow. NathanWindow might look like this:

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;
};

then you will subclass this with code to call NewWindow() in the appropriate style.

Initialize will look something like this:

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

now, this last little bit is the tricky part - I've put a pointer to the NathanWindow into the Macintosh WindowPtr refCon field. Then you'll build an event loop in your main code that will look like this:

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;
        }
    }
}

and then Click will look like this:

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

and so on.

And even still, this is (potentially) wrong in that you really want to have every NathanWindow to be hooked into an application parent that manages layers and groupings of windows.

A NathanWindow should contain a list of NathanControls. A NathanControl is something that can draw, responds to events, and so on.

All of this is in case you don't have PowerPlant, which does all of this for you. There was a reason why Apple liked to tout the line "it's hard to be easy", because the API that you had at your fingertips was so damn primitive.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文