SAMPLE: DYNBEDIT Changes From Edit to Bedit Control @ Run-Time

ID: Q90839

The information in this article applies to:

SUMMARY

PENWIN.DLL by default changes an edit control to an hedit control at run- time. However, the Pen Windows system does not have a built-in mechanism to change an edit control to a bedit control at run-time.

DYNBEDIT demonstrates 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.

MORE INFORMATION

The following file is available for download from the Microsoft Software Library:

 ~ DynbEdit.exe (size: 30183 bytes) 

For more information about downloading files from the Microsoft Software Library, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q119591
   TITLE     : How to Obtain Microsoft Support Files from
               Online Services

The basic steps to perform this transition are 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 procedure 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 problem occurs because the Pen system bases the size of the combs on the system font only rather than on the font specified. To work around this problem, the application must 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, the following steps need to be performed 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:

   a. The location of the dialog box in screen coordinates.
   b. The location of the edit control in screen coordinates.
   c. 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, and 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
   used by the original edit control.

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:

       // Calculate 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:

       // Calculate 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 won't 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 of any special font characteristics (for example, italic).

The DYNBEDIT sample has been written to demonstrate the above process. The code that makes the transition is located in ABOUT.C in the WM_INITDIALOG case of PenDlgProc().

Additional query words: Keywords : kbsample kb16bitonly kbKernBase kbWinOS310

Last Reviewed: December 31, 1998