Microsoft KB Archive/156266

= BUG: Adding Menu Shifts Controls and Reduces SDI Form Height =

Article ID: 156266

Article Last Modified on 10/16/2002

-

APPLIES TO


 * Microsoft Visual FoxPro 5.0 Standard Edition
 * Microsoft Visual FoxPro 5.0a
 * Microsoft Visual FoxPro 6.0 Professional Edition

-



This article was previously published under Q156266



SYMPTOMS
When a menu is added to a Single-Document Interface (SDI) form, the Height of the form is reduced by the height of the menu. The window size remains the same, but all the controls shift downward, causing some controls to be moved partially or fully off the bottom of the form.



WORKAROUND
After adding the menu, increase the form Height by adding the menu height to it.

-or-

After adding the menu, reduce the Top property of all controls contained in the form by subtracting the menu height.



STATUS
Microsoft Microsoft has confirmed this problem in the products listed above and will post new information here in the Microsoft Knowledge Base as it becomes available.



Steps to Reproduce Behavior
 Create a new menu. Make it a Menu rather than a Shortcut. On the Menu menu, click Quick Menu to create a default quick menu. On the View menu, click General Options. In the General Options dialog box, select the Top-Level Form check box, then click OK. On the Menu menu, click Generate. Save the menu as Testmenu, then select the Generate button to generate the default .mpr file.  Run the following code from a program (.prg) file: * Start of code example *  PUBLIC oform1 oform1=CREATEOBJECT("form1") oform1.SHOW RETURN

DEFINE CLASS form1 AS FORM HEIGHT = 210 WIDTH = 387 SHOWWINDOW = 2 AUTOCENTER = .T.     CAPTION = "SDI form with Menu"

ADD OBJECT command1 AS COMMANDBUTTON WITH ; TOP = 180, ; LEFT = 144, ; HEIGHT = 27, ; WIDTH = 84, ; CAPTION = "E\<xit", ; NAME = "Command1"

ADD OBJECT line1 AS LINE WITH ; HEIGHT = 0, ; LEFT = 24, ; TOP = 209, ; WIDTH = 348, ; NAME = "Line1"

ADD OBJECT line2 AS LINE WITH ; HEIGHT = 0, ; LEFT = 24, ; TOP = 0, ; WIDTH = 348, ; NAME = "Line2"

PROCEDURE INIT * DO Testmenu.mpr WITH THIS, .T. && Remove * to add menu - Step 7 * Add workaround code after this line...       * ... And before this line =MESSAGEBOX('Form Height = '+ALLTR(STR(THIS.HEIGHT)),0) ENDPROC

PROCEDURE command1.CLICK THISFORM.RELEASE ENDPROC ENDDEFINE *  * End of code example  The message box appears showing the form Height as 210. Click OK. The form appears with no menu. The upper and lower lines and the Exit button appear on the form. Close the form by clicking the Exit button.</li>  Remove the * from the following line in the Init procedure code: * DO Testmenu.mpr WITH THIS, .T. && Remove * to add menu - Step 7 </li> Rerun the .prg. The message box appears showing the form Height as 210 minus the menu height (by default the menu height should be 19, so 191 should appear). Click OK. The form appears with its menu. The upper line is visible just below the menu, but the lower line is not visible and neither is the lower half of the Exit button. Close the form by clicking the visible portion of the Exit button.</li></ol>

How to Compensate for the Menu in an SDI Form
The menu height is a configurable component of the Windows operating system. This is can be changed in Windows 95 or Windows NT 4.0 by opening Control Panel then selecting Display. Under the Appearance tab, there is an Item drop-down list. Selecting Menu from the Item drop-down list allows the Size spinner to adjust the menu height.

Make adjustments to the form's appearance by compensating for menu height. Because the menu height is configurable, you must query the operating system for the current setting of the menu height. This is done by making an API call to the GetSystemMetrics function.

Demonstration of Workaround 1: Maintaining Constant Form Height
With the first workaround, the form's window height is increased by the height of the menu, and all controls retain the same proximity to each other:

<ol>  Modify the Init code in the above example by adding the following code to the Init procedure between the two lines beginning with the * character: #DEFINE sm_cymenu  15    && From Winuser.h      DECLARE INTEGER GetSystemMetrics IN Win32API ; AS GetSysMet INTEGER nIndex THISFORM.HEIGHT = THISFORM.HEIGHT + GetSysMet(sm_cymenu) </li> Run the program again. The message box appears showing the form Height as 210. Click OK, then the form appears with its menu. Both lines and the Exit button are fully visible. The form's window size increases by the menu height. Close the form by clicking the Exit button.</li></ol>

Demonstration of Workaround 2: Maintaining Constant Window Height
With the second workaround, the form's window size remains the same, but any controls within a menu height's distance of the top of the form may be partially or fully moved off the top of the form.

<ol>  Remove the code added in Workaround 1, and modify the Init code in the above example by adding the following code to the Init procedure between the two lines beginning with the * character: #DEFINE sm_cymenu  15    && From Winuser.h      DECLARE INTEGER GetSystemMetrics IN Win32API ; AS GetSysMet INTEGER nIndex FOR EACH CONTROL IN THISFORM.CONTROLS CONTROL.TOP = CONTROL.TOP - GetSysMet(sm_cymenu) ENDFOR </li> Run the program again. The message box appears showing the form Height as 210 minus the menu height (191 by default). Click OK. The form appears with its menu. The lower line and the Exit button is fully visible, but the upper line has moved off the top of the form. Note that the form's window size has not increased. Close the form by clicking the Exit button.</li></ol>

NOTE: Workaround 2 is roughly the same technique used in the SDI form example (\Vfp\samples\solution\forms\Sdiform.scx) in the Solutions.app sample application.

<div class="references_section">