How to prevent form controls showing, when popup menu is displayed?
- in form is positioned intrinsic VB.TextBox (black area), which height is enlarged in GotFocus event, if there are more than one line of text.
- in below of this enlarged textbox there are other texbox controls fex. in red rectangle position.
Textbox_MouseDown ie. popup menu initialization routine has
Now when user clicks this enlarged textbox with right mouse button, some of these other textboxes comes visible, if mouse cursor position happens to be in that other control area (fex. red rectangle) - even when that enlarged textbox is brought to top with TextBox.Zorder 0.
Tried to;
- change Form AutoRedraw=True, but it did not help.
- set textboxes positioned below that enlarged multiline textbox to .Enabled=False, but this did not help either.
Any idea how to prevent these kind of drawing quirks?
Found the solution by repositioning, LockWindowUpdate and TextBox.Enabled codelines just above popupmenu command.
Code:
If Button = vbRightButton Then
' LockWindowUpdate TextBox.hWnd 'Commented out from here...
' TextBox.Enabled = False
.
. Lengthy dynamic menu building...
.
DoEvents 'Give the previous line time to complete
LockWindowUpdate TextBox.hWnd
TexBox.Enabled = False
PopupMenu mnuMain 'Display our own context/popup menu
TextBox.Enabled = True
LockWindowUpdate 0&
Priefly tested this and it seems to draw correctly, without displaying controls under this enlarged textbox.
Is this the proper solution, any comments on that?
Thanks, wqweto for your comment, however... See this post there is a quote form that same old new thing blog.
The purpose of LockWindowUpdate is to assist code that is drawing drag/drop feedback. If you are drawing the cursor for a drag/drop operation, you don't want the window beneath the cursor to start drawing (and thereby overwrite your beautiful cursor). So you lock the window while you draw the cursor and unlock it when the cursor leaves the window.
'Declaration
Private Const WM_SETREDRAW As Long = &HB
Private Declare Function SendMessage Lib "user32" Alias "SendMessageW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByRef lParam As Any) As Long
Private Const RDW_INVALIDATE As Long = &H1
Private Const RDW_ERASE As Long = &H4
Private Const RDW_ALLCHILDREN As Long = &H80
Private Const RDW_UPDATENOW As Long = &H100
Private Declare Function RedrawWindow Lib "user32" (ByVal hWnd As Long, ByVal lprcUpdate As Long, ByVal hrgnUpdate As Long, ByVal fuRedraw As Long) As Long
Code:
'Usage
If Button = vbRightButton Then
.
. Lengthy dynamic menu building...
.
DoEvents 'Give the previous line time to complete
SendMessage hMyform.Wnd, WM_SETREDRAW, 0&, ByVal 0& 'Disable 'call void
TexBox.Enabled = False
PopupMenu mnuMain 'Display our own context/popup menu
TextBox.Enabled = True
SendMessage Myform.hWnd, WM_SETREDRAW, 1&, ByVal 0& 'Enable 'call void
RedrawWindow Myform.hWnd, 0&, 0&, RDW_UPDATENOW Or RDW_INVALIDATE Or RDW_ERASE Or RDW_ALLCHILDREN
is called. All mouse operations - when cursor is not in popupmenu area, even if it is in application window area, targets to underlying window - now when there is other app underneat this foreground window app receives mouse input.
Now after some more testing, i ended up 'still' using LockWindowUpdate, SendMessage WM_SETREDRAW has more problems - but now position PopupMenu so, that it is left aligned with textbox and hence overlaps other controls under that textbox. Likewise made sure that mouse is in y co-ordinate wise, under the menu area. Whole menu display procedure thus is...
Code:
DoEvents 'Give the previous line time to complete
LockWindowUpdate TextBox.hWnd 'Avoid disabled 'grayed out' text.
TextBox.Enabled = False 'Prevent standard popup menu.
PopupMenu mnuMain, , TextBox.Left, Textbox.Top + 180 'Display our own context/popup menu
TextBox.Enabled = True
LockWindowUpdate 0&
TextBox.SetFocus 'Set focus back to textbox.