(Phoenix) The Edit-Control and a custom PopUp-Menu

Started by Theo Gottwald, May 19, 2007, 03:43:42 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Theo Gottwald

To get a custom PopUp-Menu for any control (like a treeview) in Phoenix (Visual Designer for PowerBasic) is a snap.

Just add a Popup-Menu (via Drag'n Drop) and link it with that control.
Finally enter the Properties of the Popup-menu and add the menu-items.
No need for a single line of code-writing.

Not with the Edit-Control. Because it has an own PopUp-Menu (and this own menu is version dependent).
It is different from Vista  to XP, for example.

Therefore I had to ask Dominic how to make this properly in Phoenix.

He took so much time (again) to explain it in detail, that I wanted to share this example with all other Phoenix users out there.

Question: How do I get a custom menu on my edit-control?

Answer:
The edit control processes the WM_RBUTTONUP (or maybe it's WM_CONTEXTMENU) to display its built-in popup menu
That is why, when you right-click over the edit control, the WM_CONTEXTMENU handler for the form never gets called
There a two possible solutions.

Method 1
1) Select the edit control.
2) Open the WindowClass property editor.
3) Subclass the edit control.
4) Check the WM_RBUTTONUP and WM_CONTEXTMENU messages.
5) Build project.

Add the following code to the WM_RBUTTONUP and WM_CONTEXTMENU handlers:

FUNCTION Form1_Edit1_OnRButtonUp _
  ( _
  BYVAL hWnd  AS DWORD, _ ' control handle
  BYVAL fKeys AS LONG, _  ' key flags
  BYVAL x     AS LONG, _  ' horizontal position of cursor
  BYVAL y     AS LONG _   ' vertical position of cursor
  ) AS LONG

  ' Send a WM_CONTEXTMENU to the form(parent of the edit control).
  ' Note: we do this by calling DefWindowProc with the handle of the form.
  '       This causes DefWindowProc to send a WM_CONTEXTMENU message to the form
  '       instead of the edit control.
  DefWindowProc GetParent(hWnd), %WM_RBUTTONUP, fKeys, MAKLNG(x, y)

  ' Do not let the edit control process this message
  FUNCTION = %TRUE
 
END FUNCTION

FUNCTION Form1_Edit1_OnContextMenu _
  ( _
  BYVAL hWnd        AS DWORD, _ ' control handle
  BYVAL hWndClicked AS DWORD, _ ' handle of window that was right-clicked
  BYVAL x           AS LONG, _  ' horizontal position of the mouse
  BYVAL y           AS LONG _   ' vertical position of the mouse
  ) AS LONG


  ' User pressed Shift+F10
  ' Forward this message to the parent of the edit control
  SendMessage GetParent(hWnd), %WM_CONTEXTMENU, hWndClicked, MAKLNG(x, y)

  ' Do not let the edit control process this message 
  FUNCTION = %TRUE
 
END FUNCTION


Or,

Method 2
1) Set the PopupMenu property of the form to (None).
2) Select the edit control.
3) Open the WindowClass property editor.
4) Subclass the edit control.
5) Check the WM_RBUTTONUP and WM_CONTEXTMENU messages.
6) Build project.

Add the following code to the WM_RBUTTONUP handler:

FUNCTION Form1_Edit1_OnRButtonUp _
  ( _
  BYVAL hWnd  AS DWORD, _ ' control handle
  BYVAL fKeys AS LONG, _  ' key flags
  BYVAL x     AS LONG, _  ' horizontal position of cursor
  BYVAL y     AS LONG _   ' vertical position of cursor
  ) AS LONG

  LOCAL tpt         AS POINTAPI
  LOCAL dwFlags     AS DWORD
  LOCAL lRetVal     AS LONG

  DefWindowProc GetParent(hWnd), %WM_RBUTTONUP, fKeys, MAKLNG(x, y)

  GetCursorPos tpt
  ' Display the context menu associated with the window
  dwFlags = %TPM_LEFTBUTTON OR %TPM_LEFTALIGN OR %TPM_TOPALIGN OR %TPM_HORIZONTAL
  lRetVal = phnxContextMenu(GetParent(hWnd), hWnd, MAKLNG(tpt.x, tpt.y), ghInstance, %IDR_FORM1_POPUPMENU1, dwFlags)
  ' Do not let the edit control process this message
  FUNCTION = %TRUE

END FUNCTION

FUNCTION Form1_Edit1_OnContextMenu _
  ( _
  BYVAL hWnd        AS DWORD, _ ' control handle
  BYVAL hWndClicked AS DWORD, _ ' handle of window that was right-clicked
  BYVAL x           AS LONG, _  ' horizontal position of the mouse
  BYVAL y           AS LONG _   ' vertical position of the mouse
  ) AS LONG


  ' User pressed Shift+F10
  ' Forward this message to the parent of the edit control
  SendMessage GetParent(hWnd), %WM_CONTEXTMENU, hWndClicked, MAKLNG(x, y)

  ' Do not let the edit control process this message 
  FUNCTION = %TRUE
 
END FUNCTION


Regards.

Dominic.