Code: Select all
EnableExplicit
Structure ComboBoxInfo
cbSize.l
rcItem.RECT
rcButton.RECT
stateButton.l
hwndCombo.i
hwndEdit.i
hwndList.i
EndStructure
Global CombBoxOrigProc.i, ComboListOrigProc.i, TheLookUpWord.s, StopComboListBoxWindowUpdate.i
Global EventId.i
Enumeration Menus
#PopupMenu
#PopupLookup
#PopupCancel
EndEnumeration
Enumeration Messages
#ShowComboBoxListBoxPopupMenu = #PB_Event_FirstCustomValue
#ShowComboBoxPopupMenu
EndEnumeration
Enumeration Gadgets
#ComboBox1
#ComboBox2
EndEnumeration
#Main = 0
#MaxLetters = 16
#LB_ITEMFROMPOINT = $1A9
Procedure ShowPopUpMenuForComboBox(theHwnd)
Protected Dim WordBuffer.c(#MaxLetters) ; Allows for trailing 0
If SendMessage_(theHwnd, #WM_GETTEXTLENGTH, 0, 0) <= #MaxLetters ; a check on max length
If SendMessage_(theHwnd, #WM_GETTEXT, #MaxLetters + 1, @WordBuffer(0)) <> 0 ; a check that there is some text
TheLookUpWord = LCase(PeekS(@WordBuffer(0)))
SetMenuItemText(#PopupMenu, #PopupLookup, "Look up " + Chr(34) + TheLookUpWord + Chr(34))
DisplayPopupMenu(#PopupMenu, WindowID(#Main))
EndIf
EndIf
EndProcedure
Procedure ShowPopUpMenuForListBoxSubclasser()
Protected Dim WordBuffer.c(#MaxLetters) ; Allows for trailing 0
SetMenuItemText(#PopupMenu, #PopupLookup, "Look up " + Chr(34) + TheLookUpWord + Chr(34))
DisplayPopupMenu(#PopupMenu, WindowID(#Main))
EndProcedure
Procedure.i ComboBoxListSubclasser(hWnd.i, Msg.i, wParam.i, lParam.i)
Protected ItemIndex.i
Protected Dim WordBuffer.c(#MaxLetters) ; Allows for trailing 0
Protected MousePoint.Point, MouseDownHwnd.i
Select Msg
Case #WM_RBUTTONDOWN
ItemIndex = SendMessage_(hwnd, #LB_ITEMFROMPOINT, 0, lParam)
If ItemIndex & $FFFF0000 = 0 ; the cursor is in the list box window
If SendMessage_(hwnd, #LB_GETTEXT, ItemIndex, @WordBuffer()) > 0
TheLookUpWord = PeekS(@WordBuffer())
SendMessage_(hwnd, #LB_SETCURSEL, ItemIndex, 0)
PostEvent(#ShowComboBoxListBoxPopupMenu, #Main, 0, #PB_EventType_FirstCustomValue, hwnd)
ProcedureReturn 0
EndIf
Else
MousePoint\x = lparam & $0000FFFF
MousePoint\Y = lparam >>16
ClientToScreen_(hwnd, @MousePoint)
MouseDownHwnd = WindowFromPoint_(MousePoint\X + MousePoint\y<<32)
If MouseDownHwnd = GadgetID(#ComboBox1) Or MouseDownHwnd = GadgetID(#ComboBox2)
If SendMessage_(MouseDownHwnd, #CB_GETDROPPEDSTATE, 0, 0) ; it's the combo box For this List box
SendMessage_(MouseDownHwnd, #CB_SHOWDROPDOWN, #False, 0)
PostEvent(#ShowComboBoxPopupMenu, #Main, 0, #PB_EventType_FirstCustomValue, MouseDownHwnd)
ProcedureReturn 0
EndIf
EndIf
EndIf
Case #WM_CAPTURECHANGED
If StopComboListBoxWindowUpdate
ProcedureReturn 0
EndIf
EndSelect
ProcedureReturn CallWindowProc_(ComboListOrigProc, hWnd, Msg, wParam, lParam)
EndProcedure
Procedure.i ComboBoxSubclasser(hWnd.i, Msg.i, wParam.i, lParam.i)
Select Msg
Case #WM_RBUTTONDOWN
PostEvent(#ShowComboBoxPopupMenu, #Main, 0, #PB_EventType_FirstCustomValue, hwnd)
EndSelect
;Call the Default window Procedure
ProcedureReturn CallWindowProc_(CombBoxOrigProc, hWnd, Msg, wParam, lParam)
EndProcedure
Procedure SetComboBoxSubclassers(ComboBoxGadgetNo)
Protected ComboInfo.ComboBoxInfo
ComboInfo\cbSize = SizeOf(ComboBoxInfo)
If GetComboBoxInfo_(GadgetID(ComboBoxGadgetNo), @ComboInfo)
ComboListOrigProc = GetWindowLongPtr_(ComboInfo\hwndList, #GWL_WNDPROC)
SetWindowLongPtr_(ComboInfo\hwndList, #GWL_WNDPROC, @ComboBoxListSubclasser())
EndIf
CombBoxOrigProc = GetWindowLongPtr_(GadgetID(ComboBoxGadgetNo), #GWL_WNDPROC)
SetWindowLongPtr_(GadgetID(ComboBoxGadgetNo), #GWL_WNDPROC, @ComboBoxSubclasser())
EndProcedure
If OpenWindow(#Main, 0, 0, 270, 180, "Combo Box with context menu", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
If CreatePopupMenu(#PopupMenu)
MenuItem(#PopupLookup, "Look up this word in a dictionary")
MenuItem(#PopupCancel, "Cancel")
EndIf
ComboBoxGadget(#ComboBox1, 10, 10, 250, 21)
AddGadgetItem(#ComboBox1, -1, "acorn")
AddGadgetItem(#ComboBox1, -1, "beehive")
AddGadgetItem(#ComboBox1, -1, "carpenter")
AddGadgetItem(#ComboBox1, -1, "dancer")
AddGadgetItem(#ComboBox1, -1, "elephant")
SetGadgetState(#ComboBox1, 0)
SetComboBoxSubclassers(#ComboBox1)
ComboBoxGadget(#ComboBox2, 10, 70, 250, 21)
AddGadgetItem(#ComboBox2, -1,"factory")
AddGadgetItem(#ComboBox2, -1,"graphical")
AddGadgetItem(#ComboBox2, -1,"hotel")
AddGadgetItem(#ComboBox2, -1,"inveterate")
AddGadgetItem(#ComboBox2, -1,"jalopy")
AddGadgetItem(#ComboBox2, -1,"knee")
SetGadgetState(#ComboBox2, 0)
SetComboBoxSubclassers(#ComboBox2)
Repeat
EventId = WaitWindowEvent()
Select EventId
Case #ShowComboBoxListBoxPopupMenu
StopComboListBoxWindowUpdate = #True
ShowPopUpMenuForListBoxSubclasser()
SetCapture_(EventData()) ; this is the combo list box hwnd
StopComboListBoxWindowUpdate = #False
Case #ShowComboBoxPopupMenu
ShowPopUpMenuForComboBox(EventData()) ; EventData has the combo box hwnd)
Case #PB_Event_Menu
Select EventMenu()
Case #PopupLookup
RunProgram("http://www.collinsdictionary.com/dictionary/english/" + TheLookUpWord)
EndSelect
EndSelect
Until EventId = #PB_Event_CloseWindow
EndIf