On Windows I have already made a workaround (see below), but I don't know how it could be done on MacOSX (cocoa) or Linux.
Code: Select all
Procedure.i Focus_Callback(hWnd.i,uMsg,wParam,lParam) ;hWnd=0,uMsg=Gadget,wParam=Window,lParam=1,lParam=0=>remove focusevent
CompilerIf #PB_Compiler_OS=#PB_OS_Windows
Static Dim OldProc.i(0)
Static size.l=0
Protected tl.l,id.i
If hWnd=0
Select GadgetType(uMsg)
Case #PB_GadgetType_ComboBox
id=FindWindowEx_(GadgetID(uMsg),0,"Edit",0)
Default
id=GadgetID(uMsg)
EndSelect
If lParam=0
For tl=1 To size
If id=OldProc(tl*4-1)
SetWindowLong_(id,#GWL_WNDPROC,OldProc(tl*4))
OldProc(tl*4-1)=0
Break
EndIf
Next
Else
For tl=1 To size
If OldProc(tl*4-1)=0
Break
EndIf
Next
If tl>size
size=tl
ReDim OldProc.i(tl*4)
EndIf
OldProc(tl*4-1)=id
OldProc(tl*4-2)=uMsg
OldProc(tl*4-3)=wParam
OldProc(tl*4)=SetWindowLong_(id,#GWL_WNDPROC,@Focus_Callback())
EndIf
Else
For tl=1 To size
If hWnd=OldProc(tl*4-1)
Select uMsg
Case #WM_SETFOCUS
PostEvent(#PB_Event_Gadget,OldProc(tl*4-3),OldProc(tl*4-2),#PB_EventType_Focus)
Case #WM_KILLFOCUS
PostEvent(#PB_Event_Gadget,OldProc(tl*4-3),OldProc(tl*4-2),#PB_EventType_LostFocus)
Case #WM_DESTROY
SetWindowLong_(hWnd,#GWL_WNDPROC,OldProc(tl*4))
OldProc(tl*4-1)=0
EndSelect
ProcedureReturn CallWindowProc_(OldProc(tl*4),hwnd,uMsg,wParam,lParam)
EndIf
Next
EndIf
CompilerEndIf ;MacOSX, Linux -> TODO
ProcedureReturn 1
EndProcedure
If OpenWindow(0, 0, 0, 140, 150, "SpinGadget Focus", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SpinGadget(1, 20, 20, 100, 25, 0, 1000)
SpinGadget(2, 20, 50, 100, 25, 0, 1000)
ComboBoxGadget(3, 20, 80, 100, 25,#PB_ComboBox_Editable) ;already supports focus/lostfocus
Focus_Callback(0,1,0,1)
Focus_Callback(0,2,0,1)
SetActiveGadget(1)
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
Select EventType()
Case #PB_EventType_Focus
Debug Str(EventGadget())+" -> focus"
Case #PB_EventType_Change
Debug Str(EventGadget())+" -> change"
Case #PB_EventType_LostFocus
Debug Str(EventGadget())+" -> lostfocus"
EndSelect
EndIf
Until Event = #PB_Event_CloseWindow
EndIf
End