static
bool
fffSave3dsFile(const FgString &name, const FffMultiObjectC &model)
{
    FgPath      path(name);
    path.ext = "3ds";
    FgString    fname = path.str();
#ifdef _WIN32
    FILE *fptr = _wfopen(fname.as_wstring().c_str(),L"wb,ccs=UNICODE");
#else
    FILE *fptr = fopen(fname.m_str.c_str(),"wb");
#endif
    if (!fptr) {
        return false;
    }
    unsigned short id = M3DMAGIC;
    long chunkSize = sizeof(unsigned short) + sizeof(long);
    long chunkStartPos = ftell(fptr);
    if (!fffWriteChunkHeader_local(fptr,id,chunkSize)) {
        fclose(fptr);
        return false;
    }
    {
        id = M3D_VERSION;
        long version = 3;
        long verChunkSize = sizeof(unsigned short) + sizeof(long)
                            + sizeof(long);
        if (!fffWriteChunkHeader_local(fptr,id,verChunkSize))
        {
            fclose(fptr);
            return false;
        }
        if (fwrite(&version,sizeof(long),1,fptr) != 1)
        {
            fclose(fptr);
            return false;
        }
        chunkSize += verChunkSize;
    }
    long mdataChunkSize=0;
    if (!fffWriteMdataChunk_local(fptr,mdataChunkSize,model)) {
        fclose(fptr);
        return false;
    }
    chunkSize += mdataChunkSize;
    if (!fffUpdateChunkSizeInfo_local(fptr,chunkSize,chunkStartPos)) {
        fclose(fptr);
        return false;
    }
    fclose(fptr);
    return true;
}
    LRESULT
    wndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
    {
        switch (message)
        {
            case WM_CREATE:
            {
//fgout << fgnl << "Button::WM_CREATE";
                // This is the first place we get the hwnd for this instance since this callback
                // happens before 'fgCreateChild' above returns:
                hwndThis = hwnd;
                hwndButton =
                    CreateWindowEx(0,
                        TEXT("button"),     // Standard controls class name for all buttons
                        m_api.label.as_wstring().c_str(),
                        WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
                        0,0,0,0,            // Will be sent MOVEWINDOW messages.
                        hwnd,
                        HMENU(0),
                        s_fgGuiWin.hinst,
                        NULL);              // No WM_CREATE parameter
                FGASSERTWIN(hwndButton != 0);
                return 0;
            }
            case WM_SIZE:
            {
                int     wid = LOWORD(lParam);
                int     hgt = HIWORD(lParam);
                if (wid*hgt > 0) {
//fgout << fgnl << "Button::WM_SIZE: " << wid << "," << hgt;
                    int     buttonHgt = fgMin(int(getMinSize()[1]),hgt),
                            vspace = hgt - buttonHgt;
                    MoveWindow(hwndButton,0,vspace/2,wid,buttonHgt,TRUE);
                }
                return 0;
            }
            case WM_COMMAND:
            {
                WORD    ident = LOWORD(wParam);
                WORD    code = HIWORD(wParam);
                if (code == 0) {
                    FGASSERT(ident == 0);
                    try {
                        m_api.action();
                        g_gg.updateScreen();
                    }
                    catch(FgException const & e) {
                        FgString    txt = e.tr_message() + "\n";
                        fgout << txt;
                        MessageBox(hwnd,txt.as_wstring().c_str(),L"Error",MB_OK);
                    }
                    catch(std::exception const & e) {
                        FgString    txt = FgString("Internal Program Error (std::exception):\n") +
                            e.what() + "\n";
                        fgout << txt;
                        MessageBox(hwnd,txt.as_wstring().c_str(),L"Error",MB_OK);
                    }
                    catch(...) {
                        FgString    txt = FgString("Internal Program Error (unknown exception).\n");
                        fgout << txt;
                        MessageBox(hwnd,txt.as_wstring().c_str(),L"Error",MB_OK);
                    }
                }
                return 0;
            }
//case WM_PAINT:
//fgout << fgnl << "Button::WM_PAINT";
        }
        return DefWindowProc(hwnd,message,wParam,lParam);
    }