Author | Topic: Calling conventions and SetWindowLong() API | |
---|---|---|
Hannes Ziegler | Calling conventions and SetWindowLong() API on Wed, 26 Apr 2006 02:47:25 +0200 Hi all, I have a question for this DLLFUNCTION DLLFUNCTION SetWindowLongA( nHWnd, nIndex, nValue ) USING STDCALL FROM User32.dll I call this func with nHWnd := oXbp:getHWND() nIndex := GWL_WNDPROC nValue := Xbase++ function address The result should be that the Window procedure for an Xbase Part is redefined. That is, I supply the function address of an Xbase++ function as a new Window procedure. The result I get is an XPPFATAL.LOG as soon as the mouse pointer hovers over the XBP with the redefinded Window procedure. It is not very informative and looks like this: FATAL ERROR LOG Not recoverable Error! SYS Thread-ID: 520 Module: EH Error Codes: EH: 900 Sub: 0(0) OS: 0 XPP: 0 Call Stack of Thread 1 (384): EVENTHANDLER(70) MAIN(35) File: E:\src\progs\win\testwinproc.exe TimeStamp: 20060426 01:39 End of FATAL ERROR LOG. Is it possible that different calling conventions cause this error? What is the difference between the calling conventions DLL_SYSTEM, DLL_CDECL, DLL_STDCALL and DLL_XPPCALL? TIA for your input -- Hannes | |
Guenter Beyes | Re: Calling conventions and SetWindowLong() API on Wed, 26 Apr 2006 14:37:09 +0200 Hi Hannes! > SetWindowLong( hwnd, GWL_WNDPROC, Xpp_Func_ProcAddress) > (...) > Is it possible that different calling conventions cause this error? What is > the difference between the calling conventions DLL_SYSTEM, DLL_CDECL, > DLL_STDCALL and DLL_XPPCALL? Google and Ye Shall Find (Maybe) "calling convention" -> approx. 539.000 hits (duh) "calling convention" site:microsoft.com -> approx. 17.800 (no less) Seriously, as far as the Xbase++ specialties are concerned, DLL_XPPCALL should actually be equivalent to XPPENTRY (as defined in xppdef.h), i.e. cdecl, single parameter of type XppParamList. DLL_SYSTEM appears to be for OS/2 (of which I know zero). Now, Windows uses and expects stdcall, in most cases. If you want Windows to call an Xbase++ function, it must be placed inside an appropriate wrapper first. You may have seen this, but in this NG, you'll find two different approaches to stdcall wrappers, in source code form: ANN:Free Callback Compiler for Xbase++ by Pablo Botella public.third-party-products 24 Feb 2006 Re: lParam by Yours Truly public.xbase++.generic 17 Aug 2005 Otherwise, from the myriad of more-or-less relevant Google links, this one's excellent, in my opinion: Calling Conventions unter Windows (in German) http://www.3rd-evolution.de/docs/windows/callconv/ and of course from the horse's mouth: Microsoft C++ Language Reference Calling Conventions http://msdn2.microsoft.com/en-us/library/k2b2ssfy.aspx Hope that helps, and best regards, Günter | |
Hannes Ziegler | Re: Calling conventions and SetWindowLong() API on Thu, 27 Apr 2006 03:21:33 +0200 Guenter, thanks a million for the links. Need some time for studies. Hannes "Guenter Beyes" <gbeyes at gmx.de> schrieb im Newsbeitrag news:kaku42t47kt66vuadu06lg8u3t475urrl0@4ax.com... > Hi Hannes! > > > SetWindowLong( hwnd, GWL_WNDPROC, Xpp_Func_ProcAddress) > > (...) > > Is it possible that different calling conventions cause this error? What is > > the difference between the calling conventions DLL_SYSTEM, DLL_CDECL, > > DLL_STDCALL and DLL_XPPCALL? > > Google and Ye Shall Find (Maybe) > > "calling convention" -> approx. 539.000 hits (duh) > > "calling convention" site:microsoft.com -> approx. 17.800 (no less) > > Seriously, as far as the Xbase++ specialties are concerned, > DLL_XPPCALL should actually be equivalent to XPPENTRY (as defined in > xppdef.h), i.e. cdecl, single parameter of type XppParamList. > > DLL_SYSTEM appears to be for OS/2 (of which I know zero). > > Now, Windows uses and expects stdcall, in most cases. If you want > Windows to call an Xbase++ function, it must be placed inside an > appropriate wrapper first. > > You may have seen this, but in this NG, you'll find two different > approaches to stdcall wrappers, in source code form: > > ANN:Free Callback Compiler for Xbase++ > by Pablo Botella > public.third-party-products > 24 Feb 2006 > > Re: lParam > by Yours Truly > public.xbase++.generic > 17 Aug 2005 > > Otherwise, from the myriad of more-or-less relevant Google links, > this one's excellent, in my opinion: > Calling Conventions unter Windows (in German) > http://www.3rd-evolution.de/docs/windows/callconv/ > > and of course from the horse's mouth: > Microsoft C++ Language Reference > Calling Conventions > http://msdn2.microsoft.com/en-us/library/k2b2ssfy.aspx > > Hope that helps, and best regards, > > Gnter > > | |
Guenter Beyes | Re: Calling conventions and SetWindowLong() API on Thu, 27 Apr 2006 13:15:04 +0200 Hannes, Which Xbase++ version is involved? FWIW, I noticed that 1.9x seems to be required for codeblock-based subclassing of XbaseParts. Regards, Günter | |
Pablo Botella | Re: Calling conventions and SetWindowLong() API on Thu, 27 Apr 2006 15:34:44 +0200 Hi > FWIW, I noticed that 1.9x seems to be required for codeblock-based > subclassing of XbaseParts. Have true, the test I post in my last message below only works properly with 1.9 I've subclased XBPs previously in 1.8 in C++ and experienced some troubles that was required some ugly workarrounds, but with 1.9 seems to work properly without any trouble. Regards, Pablo Botella | |
Hannes Ziegler | Re: Calling conventions and SetWindowLong() API on Fri, 28 Apr 2006 18:29:56 +0200 Guenter, > Which Xbase++ version is involved? 1.82 > FWIW, I noticed that 1.9x seems to be required for codeblock-based > subclassing of XbaseParts. Well, that would explain the XPPFATAL I encountered. Thanks for the info, -- Hannes | |
Pablo Botella | Re: Calling conventions and SetWindowLong() API on Wed, 26 Apr 2006 16:27:54 +0200 Hi Hannes, The trouble is that when your WNDPROC is called by the system the Xbp is locked and you cannot access any method or var from the Xbp. But you can post a custom Xbase++ event ( and optionally call the previous WNDPROC) and process it within your Xbase++ event loop. I will write and post a small PRG sample to show it. Regards, Pablo Botella ------------------------------------------------------- Get The Open Tools for Xbase++ here: http://www.xbwin.com ------------------------------------------------------- | |
Pablo Botella | Re: Calling conventions and SetWindowLong() API on Wed, 26 Apr 2006 23:36:27 +0200 | |
Hannes Ziegler | Re: Calling conventions and SetWindowLong() API on Thu, 27 Apr 2006 03:20:41 +0200 Pablo, thanks a lot. Seems I have I have to dig deeper into your CBK system. If questions remain, I'll come back to you. Hannes "Pablo Botella" <pbn_NOSPAM_@pablob.com> schrieb im Newsbeitrag news:4d8c9065$1c0a13e8$714bf@news.alaska-software.com... > See attached > > > | |
Eka Muratova | NOTE! Re: Calling conventions and SetWindowLong() API on Wed, 14 Jun 2006 13:28:50 +0800 Hi Pablo! > Hi Hannes, > > The trouble is that when your WNDPROC is called by the system the Xbp is > locked and you cannot access any method or var from the Xbp. But you can > post a custom Xbase++ event ( and optionally call the previous WNDPROC) and > process it within your Xbase++ event loop. > > I will write and post a small PRG sample to show it. Your sample is good enough. But Hoffman's solution of Xbp subclassing was done years ago on any version of Xbase. He use special thread for processing messages. Today, alaska change a initialization of evm-thread (internal thread that handle all Xbps messages) so we can run Xbase++ code on it. But anyway this "solutions" is not good enough. Your and Michael code have some significant flow -- subclassed code runs on different thread, not AppEvent/handleEvent thread. So you can't use any thread specific code, you can't access Privates, can't use databases and so on.. -- Eka Muratova, http://www.eleussoft.com, developer tools for Alaska Xbase++ check our software: > insiderTools: set of debugging, profiling and error checking tools > XFuncs: easy extend your app with script functions | |
Pablo Botella | Re: NOTE! Re: Calling conventions and SetWindowLong() API on Wed, 14 Jun 2006 10:11:52 +0200 Hi Eka, I was subclass Xbps with 1.8 but was need to delay some dispatch using PostAppEvent() like Thomas Braun was done in his taskbar. Michael also was was using a separate thread as a workarround having the thread limitation you described. But the subclass sample in ot4xb works well ( only in 1.9 ) in the same thread, review the code again http://www.xbwin.com/download/ot4xb/Samples/Xbp19Subclass/ and you will see that all run in the main thread with a single AppEvent/handleEven loop, so you can access databases or Tls data without any trouble. Regards, Pablo Botella PS: Have you build the Insider Tools with the final release of 1.9 ? I think this is a must have tool and would be nice to have it updated. | |
Eka Muratova | Re: NOTE! Re: Calling conventions and SetWindowLong() API on Thu, 15 Jun 2006 13:44:25 +0800 Hi Pablo! > Hi Eka, > > I was subclass Xbps with 1.8 but was need to delay some dispatch using > PostAppEvent() like Thomas Braun was done in his taskbar. This is not subclassing at all. ) You know that very well. ) Using PostAppEvent() you can't alter message processing by return value. Alaska's Xbe-messages just notifications, but in Windows messages we can change parameters, can call/not call next windows proc in chain and can do documented tricks by return value (most known and amazing sample, return HTCAPTION in WM_NCHITTEST processing, so you can drag window by holding mouse button anywhere in windows, not only in caption). > Michael also was > was using a separate thread as a workarround having the thread limitation > you described. Yes, I see. > But the subclass sample in ot4xb works well ( only in 1.9 ) in the same > thread, review the code again > http://www.xbwin.com/download/ot4xb/Samples/Xbp19Subclass/ > and you will see that all run in the main thread with a single > AppEvent/handleEven loop, so you can access databases or Tls data without > any trouble. Did you check this? Before making my statement, I'm check your sample and add two qouts, one before message loop, and second in method MOVING(). The qout was: ?ThreadObject():threadId First qout show "1", all next - "2". > > Regards, > Pablo Botella > > PS: Have you build the Insider Tools with the final release of 1.9 ? I think > this is a must have tool and would be nice to have it updated. It work good in 1.9 release. We currently in final testing on next release. It have new part -- Xbase++ Inspector. This is a hot-key activated pop-up window with expression evaluator. You type expression (or list of expressions), select target thread, press Ctrl-Enter and this code evaluated in this selected thread and result shown in Xbase++ Inspector. We have similar tool for our Clipper projects more than 10(!) years. Currently our local support team (about 20 peoples) use this pop-up window everyday for different tasks: check variable or field value, view list of currently opened databases, view callstack, or just for 2+2 calculations. ) Its really must have on everyday programming work or to find troubles in user side (sometimes I'm can hear how our girls speaking by phone with user: "Press Ctrl-Alt-V", "Type .......", "What is shown below?"). So I'm think in next week we release this new feature. -- Eka Muratova, http://www.eleussoft.com, developer tools for Alaska Xbase++ check our software: > insiderTools: set of debugging, profiling and error checking tools > smartGC: addon tool to speedup garbage collector > XFuncs: easy extend your app with script functions | |
Pablo Botella | Re: NOTE! Re: Calling conventions and SetWindowLong() API on Thu, 15 Jun 2006 10:06:19 +0200 Hi Eka, > ?ThreadObject():threadId > First qout show "1", all next - "2". True. Again you have reason, but not all lost, I 've implemented a class to manage a workspace from difirent thread , I'm using it with xb2net to attach a workspace to a Xb2net session as requests can came on diferent threads, maybe it's time to release it as a comercial library. > .... It have new part -- Xbase++ Inspector. Wow, sound prety interesting. Regards, Pablo Botella | |
Eka Muratova | Re: NOTE! Re: Calling conventions and SetWindowLong() API on Thu, 15 Jun 2006 18:59:50 +0800 Hi Pablo! > > ?ThreadObject():threadId > > First qout show "1", all next - "2". > True. Again you have reason, but not all lost, I 've implemented a class to > manage a workspace from difirent thread , I'm using it with xb2net to attach > a workspace to a Xb2net session as requests can came on diferent threads, > maybe it's time to release it as a comercial library. In new insiderTools we add :threadEval(code,thread) function to evaluate expressions on any thread. So, using threadEval() may be possible such tricks and more. Anyway, after some weeks we plan to release SmartXbaseParts library with ability to process native windows messages in right threads, cool layout manager and skinnable windows. -- Eka Muratova, http://www.eleussoft.com, developer tools for Alaska Xbase++ check our software: > insiderTools: set of debugging, profiling and error checking tools > smartGC: addon tool to speedup garbage collector > XFuncs: easy extend your app with script functions | |
Thomas Braun | Re: Calling conventions and SetWindowLong() API on Wed, 26 Apr 2006 17:05:16 +0200 Hannes Ziegler wrote: > > The result should be that the Window procedure for an Xbase Part is > redefined. That is, I supply the function address of an Xbase++ function as > a new Window procedure. Is that possible at all? Apart from the problem of getting the function address (how do you do this?), an Xbase++ function expects to receive parameters in the form of container handles... not sure what you will get in hwnd, message, wParam and lParam in that case... Thomas | |
Hannes Ziegler | Re: Calling conventions and SetWindowLong() API on Thu, 27 Apr 2006 03:38:21 +0200 Thomas, I create the function address with my RegisterCallback() function contained in XbStruct.dll This works without a flaw for all callbacks I came across, until I tried to replace the window procedure for XbaseParts. FYI, RegisterCallback() injects a function into the process's address space. The function receives parameters from the OS, packs them into ContainerHandles for Xbase++, evaluates a codeblock and finally cleans up everything. That means, parameter passing is not the problem. I suspect that I do something wrong with calling conventions. That's why I started this thread ... Hannes "Thomas Braun" <spam@software-braun.de> schrieb im Newsbeitrag news:y8px33asbqnh$.15tiyx3yjffmk$.dlg@40tude.net... > Hannes Ziegler wrote: > > > > > The result should be that the Window procedure for an Xbase Part is > > redefined. That is, I supply the function address of an Xbase++ function as > > a new Window procedure. > > Is that possible at all? > > Apart from the problem of getting the function address (how do you do > this?), an Xbase++ function expects to receive parameters in the form of > container handles... not sure what you will get in hwnd, message, wParam > and lParam in that case... > > Thomas | |
Thomas Braun | Re: Calling conventions and SetWindowLong() API on Fri, 28 Apr 2006 10:47:18 +0200 Hannes Ziegler wrote: > FYI, RegisterCallback() injects a function into the process's address space. > The function receives parameters from the OS, packs them into > ContainerHandles for Xbase++, evaluates a codeblock and finally cleans up > everything. That means, parameter passing is not the problem. > > I suspect that I do something wrong with calling conventions. That's why I > started this thread ... ah - ok, that explains it Thomas |