Setting the window callback for a window outside of PB?
Setting the window callback for a window outside of PB?
Is there a way to do something similar to SetWindowCallback(function_ptr,#window) but to a window handle outside of PB?
I program in DarkBasic and would like to wrap something like this into a plugin so that I can capture window events from the DBP window and send them to a function.
I program in DarkBasic and would like to wrap something like this into a plugin so that I can capture window events from the DBP window and send them to a function.
I'm not sure you can do this in a cross-process manner Trond. Well, I've just tried it and it didn't work, and using GetLastError_() returned an access denied error.
I think the only way to do this if the Window in question is from another process is to use a global hook.
I think the only way to do this if the Window in question is from another process is to use a global hook.
I may look like a mule, but I'm not a complete ass.
Am I doing something wrong? I can't make it work in this test program.
Code: Select all
Global ptr
Procedure EnumProc(hwnd, lParam)
*hwnd.LONG = lParam
*hwnd\l = hwnd
ProcedureReturn 0
EndProcedure
Procedure GetCallingHwnd()
*hwnd.LONG = AllocateMemory(SizeOf(LONG))
EnumThreadWindows_(GetCurrentThreadId_(), @EnumProc(), *hwnd)
ProcedureReturn *hwnd\l
EndProcedure
Procedure WinCallback(hWnd,uMsg,wParam,lParam)
Select uMsg
Case #WM_SIZE
; do nothing
Case #WM_LBUTTONUP
MessageRequester("","Hello!")
EndSelect
If ptr
CallFunctionFast(ptr,hWnd,uMsg,wParam,lParam)
EndIf
ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure
ProcedureCDLL _SetWindowCallback()
hwnd=GetCallingHwnd()
ptr=GetWindowLong_(hwnd,#GWL_WNDPROC) ; capture the old callback ptr
SetWindowLong_(hwnd,#GWL_WNDPROC,@WinCallback()) ; set the new callback ptr
EndProcedure
OpenWindow(0,100,200,320,240,"Window",#PB_Window_SystemMenu)
OpenLibrary(0,"windowcallback.dll")
CallFunction(0,"_SetWindowCallback")
Repeat
Until WaitWindowEvent()=#PB_Event_CloseWindow
Well first you need to separate this into 2 programs; one for the dll and one a separate program to open the window and call the dll etc. At the moment you are combining it all into one which is a big no-no!
Secondly, you're mixing calling conventions. Change the ProcedureCDLL for just ProcedureDLL.
Secondly, you're mixing calling conventions. Change the ProcedureCDLL for just ProcedureDLL.
I may look like a mule, but I'm not a complete ass.
I'm being told on the Dark Basic Professional board that there is a problem with the method I came up with for using an alternative callback. I don't understand what the problem is because I only see it working. Would someone explain to me what's wrong?
http://forum.thegamecreators.com/?m=for ... 60&b=1&p=0
This is the source for my callback.dll.
http://forum.thegamecreators.com/?m=for ... 60&b=1&p=0
This is the source for my callback.dll.
Code: Select all
Define old_wndproc.l
Procedure EnumProc(hwnd, lParam)
*hwnd.LONG = lParam
*hwnd\l = hwnd
ProcedureReturn 0
EndProcedure
Procedure GetCallingHwnd()
*hwnd.LONG = AllocateMemory(SizeOf(LONG))
EnumThreadWindows_(GetCurrentThreadId_(), @EnumProc(), *hwnd)
ProcedureReturn *hwnd\l
EndProcedure
ProcedureCDLL _SetWindowCallback(wndproc)
Shared old_wndproc ; the old callback ptr to be used for passing on the old events
; hWnd, handle of the window to register the callback to
; wndproc, the pointer for the procedure to be used for this callback
dbp_hwnd=GetCallingHwnd()
old_wndproc=GetWindowLong_(dbp_hwnd,#GWL_WNDPROC) ; capture the old callback ptr
SetWindowLong_(dbp_hwnd,#GWL_WNDPROC,wndproc) ; pet the new callback ptr
ProcedureReturn old_wndproc ; return the old callback ptr to pass-through the old events
EndProcedure
ProcedureCDLL CallOldWndProc(hWnd,uMsg,wParam,lParam)
Shared old_wndproc ; the old callback ptr to be used for passing on the old events
result=CallFunctionFast(old_wndproc,hWnd,uMsg,wParam,lParam)
ProcedureReturn result
EndProcedure
Well, putting aside the fact that the very idea of what you are doing strikes me as a little odd, the code looks okay.
Just remember that because you have used ProcedureCDLL() that you have declared your two exported procedures as using the CDECL calling convention.
Thus if you are calling these dll procedures from PB, then use either CallCFunction() or CallCFunctionFast() or ImportC etc. Do not use CallFunction() or CallfunctionFast() or Import etc. If calling from another language then ensure that language is setup to use the CDECL convention.
Just remember that because you have used ProcedureCDLL() that you have declared your two exported procedures as using the CDECL calling convention.
Thus if you are calling these dll procedures from PB, then use either CallCFunction() or CallCFunctionFast() or ImportC etc. Do not use CallFunction() or CallfunctionFast() or Import etc. If calling from another language then ensure that language is setup to use the CDECL convention.
I may look like a mule, but I'm not a complete ass.
This dll allows me to register my own wincallback function natively within DBP. This is really useful for trapping critical system messages and acting upon them while the game is in a critical loop.Well, putting aside the fact that the very idea of what you are doing strikes me as a little odd, the code looks okay.
It's basically the same as SetWinCallback() for PB but this one preserves the original callback and is specificall written for DBP.
Now I can work with the wincallback just like any other function.
Code: Select all
function WinCallback(hWnd,uMsg,wParam,lParam)
Select uMsg
Case WM_SIZE
` do nothing
EndCase
Case WM_LBUTTONUP
print "lbutton up"
EndCase
EndSelect
result=CallOldWndProc(hWnd,uMsg,wParam,lParam)
endfunction result
-
- User
- Posts: 45
- Joined: Mon Mar 27, 2006 5:44 am