Alaska Software Inc. - Calling conventions and SetWindowLong() API
Username: Password:
AuthorTopic: Calling conventions and SetWindowLong() API
Hannes ZieglerCalling 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 ZieglerRe: 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 BotellaRe: 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 ZieglerRe: 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 BotellaRe: 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 BotellaRe: Calling conventions and SetWindowLong() API
on Wed, 26 Apr 2006 23:36:27 +0200
See attached




XbpSubclass.Zip
Hannes ZieglerRe: 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 MuratovaNOTE! 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 BotellaRe: 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 MuratovaRe: 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 BotellaRe: 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 MuratovaRe: 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 ZieglerRe: 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