Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

DarkBASIC Professional Discussion / Has anyone had success setting a new wincallback?

Author
Message
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 29th Nov 2007 23:42 Edited at: 29th Nov 2007 23:43
I created a plugin that sets a new wincallback pointer for the dbp window using SetWindowCallback() from the Win32 API and returns the old pointer to which I forward the parameters receievd in my new callback.

When I run this the DBP window opens and closes. Does anyone know what I'm doing wrong?

I'm using IanM's MatrixUtil 20 dll for a few of the functions used here.

Argh.. and the title should read "Has anyone had success setting a new wincallback?"



http://3dfolio.com
HowDo
23
Years of Service
User Offline
Joined: 28th Nov 2002
Location: United Kingdom
Posted: 30th Nov 2007 05:47 Edited at: 30th Nov 2007 06:00
Try download the Platform SDK from Microsoft. (may not be the right starting point but its there. )

Plus you might find might do something if you loaded the user32.dll but more likey not.

Dark Physics makes any hot drink go cold.
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 30th Nov 2007 07:13 Edited at: 30th Nov 2007 07:16
As far as I know DBP functions use the cdecl calling convention, whereas WinAPI functions use stdcall. The only difference between these is that stdcall functions clean themselves up, but this is a pretty big difference. The place you're probably getting the crash is where you call the old window procedure, as I'm guessing bother the caller and the callee will try to do the cleaning up which will damage the stack.

I think you'll need an intermediate stdcall function that will clean up after the DBP procedure function, and you'll need a stdcall version of call function ptr.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 30th Nov 2007 12:11 Edited at: 30th Nov 2007 12:12
I forgot to return the result of DBP's callback. I've fixed it now.

And thanks to whomever corrected the spelling in my subject.

http://3dfolio.com
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 30th Nov 2007 12:35
About all that I can currently guarantee for a callback to a DBPro function is a crash.

The problem is that functions that use the stdcall function clear the parameters from the stack themselves, and it's difficult (if not impossible) to know how much to clear without outside assistance (your WinCallback function above needs 16 bytes popped from the stack).

There is some stuff I could do to get around this, but you'd have to specify the size in bytes of the stack to clear, and it'd take me a little time to assemble it.

Utility plugins collection and
http://www.matrix1.demon.co.uk for older plug-ins and example code
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 30th Nov 2007 23:17
Everything seems to work ok.

http://3dfolio.com/files/wincallback.zip



http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 1st Dec 2007 01:09
Eventually you'll run out of stack space as the parameters are never cleared from it.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 1st Dec 2007 02:20
I don't understand. How can this be fixed?

http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 1st Dec 2007 10:19 Edited at: 1st Dec 2007 10:32
I don't know, it's not like two people already explained it in this thread before.

Well as I said, there are two things you need.

1. You need a function to call your DBP function and clean up after it. You then set this function as the callback.

2. You need a version of call function ptr that doesn't clean up after calling the old function (as the old window procedure will clean up after itself already). This assumes it doesn't cleverly check and adjust the stack after calling the function.

Let me briefly explain what's going on here.

When a cdecl function is called (standard C/C++ functions, DBP functions, etc) the caller pushes the parameters onto the stack, and then calls the function. After the function returns, the caller then removes these parameters from the stack.

When a stdcall function is called (Win API functions are all stdcall) operation is similar except it is the callee (the function) that removes the parameters from the stack, rather than the caller. Obviously if you have both the caller and callee remove the parameters, you'll end up removing twice as much data from the stack, half of which belongs to another function. Likewise, if you don't remove the parameters from the stack at all you may confuse functions higher up the calling chain that will think this data is theirs.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 1st Dec 2007 11:39
I don't use call function ptr() anymore. I created a new function CallOldWndProc() that calls the old wincallback ptr using stdcall.

http://3dfolio.com
IanM
Retired Moderator
23
Years of Service
User Offline
Joined: 11th Sep 2002
Location: In my moon base
Posted: 1st Dec 2007 11:45
...except that in this case it might just all work together to solve the stack issues.

WinCallback is called using stdcall, but it's a cdecl function. This will leave 16 bytes on the stack when it returns. However CallOldWndProc is being called using cdecl from DBPro, but it's a stdcall function, which will result in 16 extra bytes being removed from the stack (both the caller and the callee will remove from the stack).

In this case it all balances out.

That would be impressive if you had actually planned it

Utility plugins collection and
http://www.matrix1.demon.co.uk for older plug-ins and example code
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 1st Dec 2007 20:23
Quote: "That would be impressive if you had actually planned it "


I knew exactly what I was doing.

http://3dfolio.com
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 6th Dec 2007 00:29 Edited at: 6th Dec 2007 00:30
I have a new problem. After I set the new wincallback the runtime errors produced on a crash are no longer being sent to the IDE.

How are these messages normally sent to the IDE?



http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 6th Dec 2007 00:44 Edited at: 6th Dec 2007 01:46
Quote: "In this case it all balances out."

Surely the DBP function prematurely removing its parameters from the stack will affect any values pushed after they are (such as any saved registers, and the return address)?

1. WinCallback is called (parameters pushed, return address pushed).
2. WinCallback stores necessary registers (prolog).
3. WinCallback calls original stdcall callback function using the cdecl calling convention. The function cleans up after itself.
4. WinCallback rapes its stack thinking it is removing the called function's parameters from it.
5. WinCallback restores registers (or at least would under normal conditions if the stack hadn't been messed up).
6. WinCallback returns (surprisingly).

The fact that it doesn't crash doesn't say whether everything is doing what it should do.

(Edit 54: Ok I'll stop editing this post now )

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 6th Dec 2007 00:51 Edited at: 6th Dec 2007 01:14
Maybe it can still be salvaged?

http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 6th Dec 2007 01:31 Edited at: 6th Dec 2007 01:34
To me, it doesn't seem logically possible for the clean-up to occur inside the DBP function itself as it must be able to perform its exit code before the stack is restored. At the point where the ret instruction is called to return from a cdecl function, the nearest data on the stack is the return value. Once this is popped (which the CPU does itself as part of the instruction), the values remaining on the stack are then just the parameters. It's for this reason that you can't remove the parameters from the stack before the return value (stdcall does it by using a variation of the ret instruction that allows one to specify the amount of bytes to clear from the stack). Thus I suggest my original solution.

... Unless of course I've made a mistake and your problem has nothing to do with this. In which case I'll promptly be quiet.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 6th Dec 2007 01:59
Yay! I fixed it by matching up all of the correct function calls.

Thanks, Benjamin. ^^

http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 6th Dec 2007 02:02
Matching up all of the correct function calls?

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 6th Dec 2007 02:21
I wrote an intermediate stdcall function that called the new DBP wincallback function using cdecl, then called the old wincallback using stdcall.

http://3dfolio.com
Benjamin
23
Years of Service
User Offline
Joined: 24th Nov 2002
Location: France
Posted: 6th Dec 2007 02:22
Oh, cool. Glad you've got it working.

Tempest (DBP/DBCe)
Multisync V1 (DBP/DBCe)
Cash Curtis II
21
Years of Service
User Offline
Joined: 8th Apr 2005
Location: Corpus Christi Texas
Posted: 11th Dec 2007 10:43
Hey Mistrel, are you going to post an example of this? I'd be interested to see it work.


Come see the WIP!
jason p sage
18
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 11th Dec 2007 15:11
Pretty Easy to Toss Junk on the stack and let the "cleanup" strip what you plan... but sometimes this kind of stuff is a nightmare - especially when everything seems fine - and you add more and more - THEN an issues rears up that takes days to figure out!

My only suggestion is make sure its bullet proof before you expand the functionality!

Mistrel
Retired Moderator
20
Years of Service
User Offline
Joined: 9th Nov 2005
Location:
Posted: 12th Dec 2007 03:29
DBP starts having a seizure when sync on is used with this plugin. The problem occurs somewhere during the call to the callback function written in DBP.

I don't see a work-around for this.

http://3dfolio.com

Login to post a reply

Server time is: 2026-06-05 04:24:58
Your offset time is: 2026-06-05 04:24:58