Add Code to the Handlers

Once you have added the handlers, you are ready to add code to deal with your dialog. This section summarizes what each handler does with a complete listing.

To add code to handlers for the MFC dialog

  1. Add utility functions to convert, display, and validate the values. Use the CAcUiNumeric and CAcUiAngleEdit controls to do this:
    // Utility functions
    void AsdkAcUiDialogSample::DisplayPoint() 
    {
        m_ctrlXPtEdit.SetWindowText(m_strXPt);
        m_ctrlXPtEdit.Convert();
        m_ctrlYPtEdit.SetWindowText(m_strYPt);
        m_ctrlYPtEdit.Convert();
        m_ctrlZPtEdit.SetWindowText(m_strZPt);
        m_ctrlZPtEdit.Convert();
    }
    bool AsdkAcUiDialogSample::ValidatePoint() 
    {
        if (!m_ctrlXPtEdit.Validate())
            return false;
        if (!m_ctrlYPtEdit.Validate())
            return false;
        if (!m_ctrlZPtEdit.Validate())
            return false;
        return true;
    }
    void AsdkAcUiDialogSample::DisplayAngle() 
    {
        m_ctrlAngleEdit.SetWindowText(m_strAngle);
        m_ctrlAngleEdit.Convert();
    }
    bool AsdkAcUiDialogSample::ValidateAngle() 
    {
        if (!m_ctrlAngleEdit.Validate())
            return false;
        return true;
    }
    
  2. Add utility functions to iterate over two symbol tables and display the names in the two list boxes:
    void AsdkAcUiDialogSample::DisplayBlocks() 
    {
        AcDbBlockTable *pBlockTable;
        acdbHostApplicationServices()->workingDatabase()
            ->getSymbolTable(pBlockTable, AcDb::kForRead);
        // Iterate through the block table and display 
        // the names in the list box.
        //
        const char *pName;
        AcDbBlockTableIterator *pBTItr;
        if (pBlockTable->newIterator(pBTItr) == Acad::eOk) {
            while (!pBTItr->done()) {
                AcDbBlockTableRecord *pRecord;
                if (pBTItr->getRecord(pRecord, AcDb::kForRead)
                    == Acad::eOk) {
                    pRecord->getName(pName);
                    m_ctrlBlockListBox.InsertString(-1, pName);
                    pRecord->close();
                }	
                pBTItr->step();
            }
        }
        pBlockTable->close();
    }
    void AsdkAcUiDialogSample::DisplayRegApps() 
    {
        AcDbRegAppTable *pRegAppTable;
        acdbHostApplicationServices()->workingDatabase()
            ->getSymbolTable(pRegAppTable, AcDb::kForRead);
        // Iterate through the reg app table and display the 
        // names in the list box.
        //
        const char *pName;
        AcDbRegAppTableIterator *pItr;
        if (pRegAppTable->newIterator(pItr) == Acad::eOk) {
            while (!pItr->done()) {
                AcDbRegAppTableRecord *pRecord;
                if (pItr->getRecord(pRecord, AcDb::kForRead) 
                    == Acad::eOk) {
                    pRecord->getName(pName);
                    m_ctrlRegAppComboBox.InsertString(-1, pName);
                    pRecord->close();
                }
                pItr->step();
            }
        }
        pRegAppTable->close();
    }
    
  3. Add the declarations for the functions and variables to the class definition in the header file
        void DisplayPoint();	
        bool ValidatePoint();
        void DisplayAngle();
        bool ValidateAngle();
        void DisplayBlocks();
        void DisplayRegApps();
        CString m_strAngle;
        CString m_strXPt;
        CString m_strYPt;
        CString m_strZPt;
    
  4. Add the button handlers for picking a point and angle using the AutoCAD editor. The BeginEditorCommand(), CompleteEditorCommand(), and CancelEditorCommand() functions are used to hide the dialog, allow the call to acedGetPoint and acedGetAngle, and finally, either cancel or redisplay the dialog based on how the user picked:
    // AsdkAcUiDialogSample message handlers
    void AsdkAcUiDialogSample::OnButtonPoint() 
    {
        // Hide the dialog and give control to the editor
        //
        BeginEditorCommand();
        ads_point pt;
        // Get a point
        //
        if (acedGetPoint(NULL, "\nPick a point: ", pt) == RTNORM) {
            // If the point is good, continue
            //
            CompleteEditorCommand();
            m_strXPt.Format("%g", pt[X]);
            m_strYPt.Format("%g", pt[Y]);
            m_strZPt.Format("%g", pt[Z]);
            DisplayPoint();
        } else {
            // otherwise cancel the command (including the dialog)
            CancelEditorCommand();
        }
    }
    void AsdkAcUiDialogSample::OnButtonAngle() 
    {
        // Hide the dialog and give control to the editor
        //
        BeginEditorCommand();
        // Set up the default point for picking an angle
        // based on the m_strXPt, m_strYPt, and m_strZPt values
        //
        ads_point pt; 
        acdbDisToF(m_strXPt, -1, &pt[X]);
        acdbDisToF(m_strYPt, -1, &pt[Y]);
        acdbDisToF(m_strZPt, -1, &pt[Z]);
        double angle;
        // Get a point from the user
        //
        if (acedGetAngle
            (pt, "\nPick an angle: ", &angle) == RTNORM) {
            // If we got an angle, go back to the dialog
            //
            CompleteEditorCommand();
            // Convert the acquired radian value to degrees since 
            // the AcUi control can convert that to the other 
            // formats.
            //
            m_strAngle.Format("%g", angle*(180.0/PI));
            DisplayAngle();
        } else {
        // otherwise cancel the command (including the dialog)
        //
            CancelEditorCommand();
        }
    }
    
  5. Implement the edit box handlers. These functions convert the values to the current Units settings:
    void AsdkAcUiDialogSample::OnKillfocusEditAngle() 
    {
        // Get and update text the user typed in.
        //
        m_ctrlAngleEdit.Convert();
        m_ctrlAngleEdit.GetWindowText(m_strAngle);
    }
    void AsdkAcUiDialogSample::OnKillfocusEditXpt() 
    {
        // Get and update text the user typed in.
        //
        m_ctrlXPtEdit.Convert();
        m_ctrlXPtEdit.GetWindowText(m_strXPt);
    }
    void AsdkAcUiDialogSample::OnKillfocusEditYpt() 
    {
        // Get and update text the user typed in.
        //
        m_ctrlYPtEdit.Convert();
        m_ctrlYPtEdit.GetWindowText(m_strYPt);
    }
    void AsdkAcUiDialogSample::OnKillfocusEditZpt() 
    {
        // Get and update text the user typed in.
        //
        m_ctrlZPtEdit.Convert();
        m_ctrlZPtEdit.GetWindowText(m_strZPt);
    }
    
  6. Implement the combo box handler to allow the user to type in a string, and then register the user's string as an application name. This step, though of little practical value, demonstrates the use of a combo box:
    void AsdkAcUiDialogSample::OnKillfocusComboRegapps() 
    {
        CString strFromEdit;
        m_ctrlRegAppComboBox.GetWindowText(strFromEdit);
        if (m_ctrlRegAppComboBox.FindString(-1, strFromEdit) == CB_ERR)
            if (acdbRegApp(strFromEdit) == RTNORM)
                m_ctrlRegAppComboBox.AddString(strFromEdit);
    }
    
  7. Handle data validation in the OnOk() handler for this example. (Of course, it could be done elsewhere.) Also notice that the OnOk() handler stores the data in the user profile (registry) using the SetDialogData() function:
    void AsdkAcUiDialogSample::OnOK() 
    {
        if (!ValidatePoint()) {
            AfxMessageBox("Sorry, Point out of desired range.");
            m_ctrlXPtEdit.SetFocus();
            return;
        } 
        if (!ValidateAngle()) {
            AfxMessageBox("Sorry, Angle out of desired range.”);
            m_ctrlAngleEdit.SetFocus();
            return;
        }
        CAcUiDialog::OnOK();
        // Store the data into the registry
        //
        SetDialogData("ANGLE", m_strAngle);
        SetDialogData("POINTX", m_strXPt);
        SetDialogData("POINTY", m_strYPt);
        SetDialogData("POINTZ", m_strZPt);
    }
    
  8. Finally, the OnInitDialog() function takes care of initialization, including the resizing and data persistency requirements:

    BOOL AsdkAcUiDialogSample::OnInitDialog() 
    {
        // Set the dialog name for registry lookup and storage
        //
        SetDialogName("AsdkAcUiSample:AsdkAcUiDialog");
        CAcUiDialog::OnInitDialog();
        DLGCTLINFO	dlgSizeInfo[]= {
            { IDC_STATIC_GROUP1, ELASTICX, 20 },
            { IDC_STATIC_GROUP1, ELASTICY, 100 },
            { IDC_EDIT_XPT, ELASTICX, 20 },
            { IDC_EDIT_YPT, ELASTICX, 20 },
            { IDC_EDIT_ZPT, ELASTICX, 20 },
            { IDC_EDIT_ANGLE, ELASTICX, 20 },
            { IDC_STATIC_GROUP2, MOVEX, 20 },
            { IDC_STATIC_GROUP2, ELASTICY, 100 },
            { IDC_STATIC_GROUP2, ELASTICX, 80 },
            { IDC_LIST_BLOCKS, MOVEX, 20 },
            { IDC_LIST_BLOCKS, ELASTICY, 100 },
            { IDC_STATIC_TEXT2, MOVEX, 20 },
            { IDC_STATIC_TEXT2, MOVEY, 100 },
            { IDC_LIST_BLOCKS, ELASTICX, 80 },
            { IDC_STATIC_TEXT2, ELASTICX, 80 },
            { IDC_STATIC_GROUP3, MOVEY, 100 },
            { IDC_STATIC_GROUP3, ELASTICX, 20 },
            { IDC_COMBO_REGAPPS, MOVEY, 100 },
            { IDC_COMBO_REGAPPS, ELASTICX, 20 },
            { IDC_STATIC_TEXT3, MOVEY, 100 },
            { IDC_STATIC_TEXT3, ELASTICX, 20 },
            { IDOK,MOVEX, 100 },
            { IDCANCEL, MOVEX, 100 },
        };
        const DWORD numberofentries = 
            sizeof dlgSizeInfo / sizeof DLGCTLINFO;
        SetControlProperty(dlgSizeInfo, numberofentries);
        // Must be within a 100-unit cube centered about 0,0,0.
        // 
        m_ctrlXPtEdit.SetRange(-50.0, 50.0);
        m_ctrlYPtEdit.SetRange(-50.0, 50.0);
        m_ctrlZPtEdit.SetRange(-50.0, 50.0);
        // Must be between 0 and 90 degrees.
        //
        m_ctrlAngleEdit.SetRange(0.0, 90.0 /*(PI/2.0)*/);
        // Assign a title for the dialog.
        //
        SetWindowText("AcUiDialog Sample");
        // Load the default bitmaps.
        //
        m_ctrlPickButton.AutoLoad();
        m_ctrlAngleButton.AutoLoad();
        // Get and display the preserved data from the registry.
        //
        if (!GetDialogData("ANGLE", m_strAngle))
            m_strAngle = "0.0";
        if (!GetDialogData("POINTX", m_strXPt))
            m_strXPt = "0.0";
        if (!GetDialogData("POINTY", m_strYPt))
            m_strYPt = "0.0";
        if (!GetDialogData("POINTZ", m_strZPt))
            m_strZPt = "0.0";
        DisplayPoint();
        DisplayAngle();
        DisplayBlocks();
        DisplayRegApps();
        // return TRUE unless you set the focus to a control
        return TRUE; 
    }