Callback
Callback
What is the Callback parameters?
"(hWnd, Msg, wParam, lParam)" what means each one?
Im trying to make a windows "waitevent" in a callback, to use in a .DLL
Can someone help me with that?
To make a callback function instead of a main loop.
"(hWnd, Msg, wParam, lParam)" what means each one?
Im trying to make a windows "waitevent" in a callback, to use in a .DLL
Can someone help me with that?
To make a callback function instead of a main loop.
Having a 'waitevent' in a callback doesn't really (depending on exactly what it is you're trying to do?) make sense because you have no control over when the callback is called; that is Window's job in conjunction with your message retrieval loop.
Now, standard Purebasic code hides the GetMessage/DespatchMessage construct behind the WaitWindowEvent() command and it really wouldn't make sense to place this within a callback.
The window who's events you wish to process, is it created inside or outside of the dll?
Now, standard Purebasic code hides the GetMessage/DespatchMessage construct behind the WaitWindowEvent() command and it really wouldn't make sense to place this within a callback.
The window who's events you wish to process, is it created inside or outside of the dll?
I may look like a mule, but I'm not a complete ass.
Inside.The window who's events you wish to process, is it created inside or outside of the dll?

I will explain what im trying to do. Maybe you knows a better way to do it.
I have an application in a 3D engine, and it needs to have some windows to control the options. These windows should been made in WinApi. So i chose the PB for it.
So i have a DLL with procedures like, InitWindows() and LoopWindows().
The LoopWindows() is a function to process al the events, my idea was to put the LoopWindows() function in the 3D application main loop. But it didn't works cause it makes the window dont respond to every command.
Now im trying to make a callback to run the LoopWindows() only when needed.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
This is an all-API solution, if that's what you're looking for:
Adapted from various codes found on this forum and PureArea.net
Code: Select all
Procedure WindowCallback(Window, Message, wParam, lParam)
Select Message
Case #WM_CLOSE
If MessageBox_(Window, "You sure?", "EXIT", #MB_YESNO) = #IDYES
DestroyWindow_(Window)
Else
Result = 0
EndIf
Case #WM_DESTROY
PostQuitMessage_(0)
Result = 0
Default
Result = DefWindowProc_(Window, Message, wParam, lParam)
EndSelect
ProcedureReturn Result
EndProcedure
#Style = #WS_VISIBLE | #WS_CAPTION | #WS_SYSMENU
WindowClass.s = "Button"
wc.WNDCLASSEX
wc\cbSize = SizeOf(WNDCLASSEX)
wc\hbrBackground = CreateSolidBrush_(GetSysColor_(#COLOR_BTNFACE))
wc\hCursor = LoadCursor_(0, #IDC_ARROW)
wc\lpfnWndProc = @WindowCallback()
wc\lpszClassName = @WindowClass
RegisterClassEx_(@wc)
screenx = GetSystemMetrics_(#SM_CXSCREEN)/2-320/2
screeny = GetSystemMetrics_(#SM_CYSCREEN)/2-240/2
hWndMain = CreateWindowEx_(0, WindowClass, "Test-Window", #Style, screenx, screeny, 320, 240, 0, 0, 0, 0)
While GetMessage_(msg.MSG, #Null, 0, 0 )
TranslateMessage_(msg)
DispatchMessage_(msg)
Wend
BERESHEIT
I'm not really sure I understand.
If you're using win api to create the windows (rather than native Purebasic commands) then, by a callback you mean a Window Procedure (and not using SetWindowCallback() which is only for windows created by PB commands).
Window's created in a dll can be a little fiddly when it comes to the main application recognising the window and visa versa if the windows are created using PB commands.
Try the following example. you'll see that when the dll window is open, you cannot close the main window until after you close the dll one.
In my next post I'll give a better version using a callback:
Compile to "test.dll"
Compile to "test.exe"
A better example will follow...
If you're using win api to create the windows (rather than native Purebasic commands) then, by a callback you mean a Window Procedure (and not using SetWindowCallback() which is only for windows created by PB commands).
Window's created in a dll can be a little fiddly when it comes to the main application recognising the window and visa versa if the windows are created using PB commands.
Try the following example. you'll see that when the dll window is open, you cannot close the main window until after you close the dll one.
In my next post I'll give a better version using a callback:
Compile to "test.dll"
Code: Select all
ProcedureDLL OpenWinDll()
OpenWindow(0, 0, 0, 230, 90, "Window from dll", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
MessageRequester("Hi!", "Hello from dll!")
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseWindow(0)
EndProcedure
Code: Select all
If OpenLibrary(0, "test.dll")
OpenWindow(0, 0, 0, 230, 90, "Demo", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
CallFunction(0, "OpenWinDll")
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseLibrary(0)
EndIf
A better example will follow...

I may look like a mule, but I'm not a complete ass.
Second example.
This one uses a callback in the dll to process windows messages for the window opened in the dll.
This allows the main application to continue running and processing events whilst the dll window remains open. Try it, compile the dll and run the client program. Click the button and this time you'll be able to close the main window whilst the dll one remains open.
"test.dll
"test.pb"
If you prefer to use api to open the window in the dll then you'll simply need to combine this (with a few alterations) with netmaestro's code above.
Personally I tend to always use callbacks rather than Purebasic event loops anyhow. More flexible.
This one uses a callback in the dll to process windows messages for the window opened in the dll.
This allows the main application to continue running and processing events whilst the dll window remains open. Try it, compile the dll and run the client program. Click the button and this time you'll be able to close the main window whilst the dll one remains open.
"test.dll
Code: Select all
Procedure.l MyCallback(hWnd, uMsg, wParam, lParam)
Result = #PB_ProcessPureBasicEvents
Select uMsg
Case #WM_CLOSE
CloseWindow(0)
result=0
Case #WM_COMMAND
If wParam>>16=#BN_CLICKED
MessageRequester("Hi!", "Hello from dll!")
EndIf
EndSelect
ProcedureReturn result
EndProcedure
ProcedureDLL OpenWinDll()
OpenWindow(0, 0, 0, 230, 90, "Window from dll", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
SetWindowCallback(@MyCallback(),0)
EndProcedure
Code: Select all
If OpenLibrary(0, "test.dll")
OpenWindow(0, 0, 0, 230, 90, "Demo", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
CallFunction(0, "OpenWinDll")
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseLibrary(0)
EndIf
Personally I tend to always use callbacks rather than Purebasic event loops anyhow. More flexible.
I may look like a mule, but I'm not a complete ass.
Sorry for my bad inglish, i will reformulate the question:I'm not really sure I understand.
I have an application, made in a 3D engine. (irrilich per example.)
The 3d application doesn't have a WaitWindowsEvent(), it just have a main loop that doesn't wait nothing.
This aplication needs a interface to give to the user the controls, A interface in form of Windows
I chose the PureBasic for it. Now i'm using the native purebasic commands to create that windows.
Now every command button or radio in the windows created should affect the 3D application.
The 3D application structure is something like this:
Code: Select all
StartTheNeededThings
InitTheDLL()
MainLoop
Result=ReciveAnswerFromDLL()
ReactUsingResult(Result)
RefreshGraphics()
EndLoop
End
The ReciveAnswerFromDLL is a function in the DLL that will return the last action done, Example: "0=Nothing 1=Changed Resolution, 2=Move Forward, 3=TurnRight" etc
Then the ReactUsingResult will make the result happen in the application.
Until here no problem, but here comes the pain.
When i call the dll, it starts perfectly, but it doesn't refresh after that. No Re-Draw, No Button Clicks, Nothing! Cause the only way to make the window reacts is through a callback inside the DLL (i think).
I need to do the dll have it's own reactions, when the users clicks on it, and the 3D applications needs to still running the loop.
It's like a WaitWindowEvent() select inside the callback.
But its important to denote that the netmaestro example uses a callback to react in a fully WinApi Commands based window.
So how can i get the EventGadget(), EventType() of an occured event inside a callback?[/code]
Right, my last attempt to figure out what it is you want!
If you wish to open a window in a dll, but have the main application respond to events in the dll window, then you're better of sticking the callback in the main application.
Now because the following uses PB commands in the dll to open the window, there may be a small memory leak. This is because the dll uses it's own memory to store info on open windows etc. and the main application will not see this data and has no access to the dll's Window#'s etc. I can get around this, but the best way would be to use native win api in the dll to create the windows and controls etc.
'test.dll'
'client.pb'
If this doesn't help, then I give up and I'm going to join the French foreign legion! 

If you wish to open a window in a dll, but have the main application respond to events in the dll window, then you're better of sticking the callback in the main application.
Now because the following uses PB commands in the dll to open the window, there may be a small memory leak. This is because the dll uses it's own memory to store info on open windows etc. and the main application will not see this data and has no access to the dll's Window#'s etc. I can get around this, but the best way would be to use native win api in the dll to create the windows and controls etc.
'test.dll'
Code: Select all
ProcedureDLL OpenWinDll(callbackaddress)
MainWinProc = callbackaddress
OpenWindow(0, 0, 0, 230, 90, "Window from dll", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
oldcallback = GetWindowLong_(WindowID(win), #GWL_WNDPROC)
SetProp_(WindowID(win), "__oldProc", oldcallback)
SetWindowLong_(WindowID(win), #GWL_WNDPROC, callbackaddress)
EndProcedure
Code: Select all
Procedure.l MyCallback(hWnd, uMsg, wParam, lParam)
oldproc = GetProp_(hWnd, "__oldProc")
Select uMsg
Case #WM_CLOSE
DestroyWindow_(hWnd)
Case #WM_NCDESTROY
RemoveProp_(hWnd, "__oldProc")
Case #WM_COMMAND
If wParam>>16=#BN_CLICKED
MessageRequester("Hi!", "Hello from Main program!")
EndIf
result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
Default
result = CallWindowProc_(oldproc, hWnd, uMsg, wParam, lParam)
EndSelect
ProcedureReturn result
EndProcedure
If OpenLibrary(0, "test.dll")
OpenWindow(0, 0, 0, 230, 90, "Demo", #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ButtonGadget (1, 10, 10, 200, 20, "Click me")
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_Gadget
Select EventGadget()
Case 1
CallFunction(0, "OpenWinDll", @MyCallback())
EndSelect
EndSelect
Until Event = #PB_Event_CloseWindow
CloseLibrary(0)
EndIf

I may look like a mule, but I'm not a complete ass.
-
- Enthusiast
- Posts: 746
- Joined: Fri Jul 14, 2006 8:53 pm
- Location: Malta
- Contact:
Re: Callback
I know that this post is old but i read somewhere on forum that:
WaitWindowEvent hide API GetMessage/DispatchMessage functions.
As i know and see WaitWindowEvent return Message,right?
So my question is how look in a API way this WaitWindowEvent function/procedure..
because there is no default return of DefWindowProc hwnd,wMsg,wParam,lParam.
Any ideas?
WaitWindowEvent hide API GetMessage/DispatchMessage functions.
As i know and see WaitWindowEvent return Message,right?
So my question is how look in a API way this WaitWindowEvent function/procedure..
because there is no default return of DefWindowProc hwnd,wMsg,wParam,lParam.
Any ideas?
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Callback
You can't return anything in response to a message received in a WaitWindowEvent() loop, however you can examine wParam and lParam with EventWparam() and EventlParam(). Also bear in mind that not all of the messages received in a callback will appear in the PB loop. Best approach is to use either all API or all PureBasic event processing.
BERESHEIT
Re: Callback
Thanks...
no i understand that i cannot return nothing to loop,of course but as i said
I am interested what kind of API functions contain PB function WaitWindowEvent
and it is obvious that WaitWindowEvent return event (message),right?
I really will appreciate if someone can explain me this method with pure APi coding.
thanks...
no i understand that i cannot return nothing to loop,of course but as i said
I am interested what kind of API functions contain PB function WaitWindowEvent
and it is obvious that WaitWindowEvent return event (message),right?
I really will appreciate if someone can explain me this method with pure APi coding.
thanks...
