在C ++中创建表单

时间:2009-11-25 15:58:41

标签: c++ forms user-interface obsolete

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

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分: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的最错误的方法,但如果你想要的只是一个简单,简单的用户界面,你就可以了。

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

那个时代的Mac工具箱要求你做比你想象的更多的工作。这就是为什么有像MacApp,Think Class Library和PowerPlant这样的库 - 他们提供了OOP方法来为你处理大量的内务处理垃圾。在我完成大部分Mac编程的时候,我构建了一个非类库,它是原始C代码,可以更轻松地编写分层窗口(带有浮动调色板)和流畅的UI,而不需要OOP的开销。基本上,我必须编写一个窗口管理器,一个菜单管理器,一个对话管理器,一个事件管理器,一个命令调度程序等等。完成所有操作后,构建典型应用程序的开销大约为18K。仅供参考,仅使用版本4的Macintosh版本的Acrobat Search,以及Acrobat目录。

您可以在MacTech中找到规范示例like this,其代码与上述类似。

在开始从对话框中构建整个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()。

Initialize看起来像这样:

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,它可以为你完成所有这些工作。有一个原因,苹果喜欢吹嘘“它很难变得容易”,因为你触手可及的API非常原始。