A New Technique to Add Additional Functions to Windows Controls; a Built-In Expression Calculator in the CEdit Control



Click here for a larger image.

Environment: Visual C++ 6

This technique is based on objects called Function Controllers and Controller Dispatch System.

  1. The Controllers are represented by the FLbase_Controller class. If you want to add any additional functions, you have to make your own Controller by deriving this class and writing these functions in it. All functions must have the following prototype:
  2. protected: void FunctionName(void* pCtrlObject);
    

    The parameter pCtrlObject is a pointer to the Windows control that you are using (CEdit, for example). You can cast it to the control class—but you must be sure it is the proper class, so keep your own convention for this. In these functions, you can work with this object.

    For example:

    void MyController::MyAction1(void *pCtrlObject)
    {
      CEdit* pEdit=(CEdit*)pCtrlObject;
      if (pEdit)
        pEdit->SetWindowText(_T("Sample text..."));
    }
    

  3. The linking between the Control and the Controller is performed by the Control Dispatcher (class FL_ControlDisp).
    The dispatcher has a list that contains pointers to Controllers (you can add them using the FL_ControlDisp::AddController method). FL_ControlDisp::DoAction(unsigned int nIDcontroller, unsigned int nIDaction) can call any function from your Controllers by its ID and the Controller’s ID.
    Each Controller must have its own unique ID to make this controller accessible in the list by this ID. The assignment of ID is made by the FLbase_Controller::Register(unsigned int nID) method.
    The base controller class also has the method virtual void DoAction(unsigned int nIDac, void* pCtrlObject);
    This is the interface to all your functions in the Controller. By using the “nIDac” parameter, you can specify which function must be called. The pCtrlObject parameter is the object to the Windows control. You must override this method in your controller class to assign IDs for your functions. But do not forget to call the overridden method of the derived class.

    Example:

    
    void MyController::DoAction(unsigned int nIDac, void
         *pCtrlObject)
    {
      if (!pCtrlObject)
        return;
      switch (nIDac)
      {
      case FL_MYACTION1:
        MyAction1(pCtrlObject); // calling your function
        return;
      case FL_MYACTION2:
        MyAction2(pCtrlObject); // calling your function
        return;
      //...
      }
      FLbase_Controller::DoAction(nIDac,pCtrlObject);
          //DO NOT FORGET IT
    }
    

    For convenience, you can define all your Controller’s and Function’s IDs in the file “action_def.h”.

  4. Then, you have to make your own class deriving any MFC control class (CEdit, for example).
    In this class, add a member variable of type FL_ControlDisp (this is the Controller Dispatcher for this control).
    Add controller(s) to the dispatcher (the controllers must be existing objects).
    And one very important thing: To attach the dispatcher to the control, call SetCtrlObject(this). The Control Dispatcher contains a pointer to the control object to which it is being attached. Actually, this is the *pCtrlObject pointer that is passed to your functions.
    And finally, you have to call the FL_ControlDisp::DoAction(nIDcontroller, nIDaction); method. You can call it on any key or pop-up menu command.

I have tested this technique with CEdit controls, but it also has to work with other controls. My main purpose was to embed a simple expression calculator in an ordinary CEdit control. I think this extra functionality would be very useful and comfortable for any kind of software that is full of little calculations, such as business and CAD products. I’m sure you can think of your own functionalities.


I wrote a simple Expression Calculator. It is represented by the CFL_Calc class. It uses reverse Polish notification to parse the expression. It can parse braced expressions and can calculate the basic arithmetic operations +, -, *, and /; it also can calcualte power (^) and factorial (!) operations. Also, the negative numbers can be written with a minus (-) sign.
After you type the expression, just press the equal (=) sign to calculate it.
The CFL_CalcEx class inherits CFL_Calc and extends its functionality. You can type any expression and, after you press the equal sign, the parser calculates only the expression enclosed between the Start Mark (# sign) and the equal (=) sign.
For example:
“The apples are #(2+3)*4=” -> “The apples are 20”
The Start Mark sign can be changed.

Downloads


Download demo project – 24 Kb


Download source – 9 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read