DYNBEDIT.ZIP  - Changing an edit control to a bedit control at run time


This sample shows how to change a normal edit control to a bedit control
at run time.  This allows an application to run unmodified in either
Pen Windows or retail Windows.

The PENWIN DLL will by default take care of changing an edit control
to an hedit control at run time.  However, the Pen Windows system
does not have a mechanism built in to change an edit control to a
bedit control at run time.

The basic steps to perform this transition is to query the information
from the edit control, destroy the edit control, and then call
CreateWindow to make the new bedit control.  However, there is a
problem with this when using a font other than the system
default font in a dialog box.  If a font statement is given
(for example:  FONT 8,"Helv"), the combs of the bedit control
will appear below the bottom border of the control.  This is due
to the Pen system basing size of the combs off of the system
font only rather than the font specified.  To get around this
problem, the application needs to modify the GUIDE structure in
the RC structure for the new control.  By reducing the size of
the GUIDE structure, the Pen system will pick a new font which
matches the new GUIDE size.

To accomplish this, you need to perform the following at either
WM_INITDIALOG, or WM_CREATE depending upon the location of the
edit control.

1)  Check to see if Pen Windows is running.  If so, proceed to
    step 2.

2)  Get the handle to the edit control, the text in the edit
    control, and three different sets of dimensions. (1) The
    location of the dialog box in screen coordinates. (2) The
    location of the edit control in screen coordinates. (3)
    The size of the edit control in pixels.  The first two
    measurements can be accomplished with the GetWindowRect
    function, and the third measurement can be accomplished
    with the GetClientRect function.

3)  Destroy the original edit control.

4)  Create the new bedit control with a call to CreateWindow.
    Use the following equations to calculate the values of
    x,y,dx,dy.


      // EditRect is the location of the edit control in screen coordinates
      // DlgRect is the location of the dialog box in screen coordinates
      // rect is the size of the edit control in pixels

      x  = (EditRect.left - DlgRect.left)
      y  = (EditRect.top - DlgRect.top)
      dx = (rect.right - rect.left)
      dy = (rect.bottom - rect.top)

    You should also use the same id number in the call to
    CreateWindow as the original edit control used.

5)  Send a WM_HEDITCTL message to the new bedit control with the wParam
    set to HE_GETRC to retrieve the RC structure. This will allow the
    application to modify the GUIDE structure.

6)  Calculate the new cyBox value.  cyBox is the height of one cell
    in the bedit control.  For example:

         // New cyBox value  (height of one box)
         NewcyBox = (rect.bottom - rect.top);

7)  Calculate the new cxBox value by using a ratio between
    the old cyBox and the new cyBox.  cxBox is the width of one
    cell in the control.  For example:

         // Calc new cxBox value by changing window ratio
         rc.guide.cxBox   = NewcyBox * rc.guide.cxBox / rc.guide.cyBox;

8)  Calculate the new cyBase value.  cyBase is the distance from
    the top of the cell to the baseline of the comb.  Again, use
    a ratio based upon the change between the old cyBox and the
    new cyBox.  For example:

         // Calc the new cyBase (distance from top of box to baseline)
         rc.guide.cyBase  = NewcyBox * rc.guide.cyBase / rc.guide.cyBox;

9)  Calculate the number of cells that can now fit inside of the
    control.  This is done by taking the width of the control, and
    dividing it by the width of a single cell.  For example:

         // Calculate the number of cells that can fit in the bedit control.
         rc.guide.cHorzBox = (rect.right - rect.left) / rc.guide.cxBox;

10) Complete any additional changes needed for the control, and then
    replace the RC structure with the new one by sending a WM_HEDITCTL
    message with the wParam set to HE_SETRC.  For example:

         // replace the RC structure.
         SendMessage (hBEdit, WM_HEDITCTL, HE_SETRC, (long)(LPRC) &rc);


At this point, the Pen system will generate the correct font to fit
inside of the new GUIDE dimensions.

If the application chooses to send a WM_SETFONT message to the control,
the application then assumes responsibility for choosing a font that
will fit inside of the comb.  The Pen system will not do any font
picking if the application uses the WM_SETFONT message.  Using a
WM_SETFONT message is necessary if the application requires the use
any special font characteristics (eg: italic).

A sample has been written that demonstrates the above process.
It is called DYNBEDIT.ZIP, and the code the makes the transition
is located in ABOUT.C in the WM_INITDIALOG case of PenDlgProc.
