Given a MS Windows Control whose handle is hCtl, acquire its window proc:
var wprc:WNDPROC = GetWindowLongPtr(hCtl,GWL_WNDPROC) #statement 1
Inside an alternate window proc for a subclass of hCtl, final default execution is:
CallWindowProc(wprc,handle,message,wparam,lparam) #statement 2
Compiler either rejects statement 1 as written or when statement 1 is rewritten as:
var wprc:LONG_PTR = GetWindowLongPtr(hCtl,GWL_WNDPROC)
then rejects statement 2.
How do I convert the LONG_PTR result from the GetWindowLongPtr into the WNDPROC parameter of GetWindowLongPtr? I tried wprc.WNDPROC or equivalently WNDPROC(wprc) but those are rejected also.
They are probably the same type, so try just casting:
var wprc = cast[WNDPROC](GetWindowLongPtr(hCtl,GWL_WNDPROC))
That FIXED it. Many Thanks.
Although I need to understand better why
cast[WNDPROC]value
works but
value.WNDPROC
i.e. WNDPROC(value)
does not ?
Like that:
someType(someValue) (or, what's the same, someValue.someType) means "convert this value to this type", and compiler should consider these types (that of the value, and to which you convert) as compatible to allow this operation, and it can use an additional transformation for this (you can define it creating a converter for these types).
cast[someType](someValue), on the other hand, means just "interpret this value (its bits sequence) as being of such a type"; it doesn't involve any compatibility-checks nor transformations of the value - you relief the compiler of responsibility for validity of type change; so you can convert between formally incompatible types - just make sure, that the cast really makes sense (as in this instance - one type is pointer, the other - a procedure - is really a pointer too).
I think you can find it in the manual, and possibly it's better described there.
WNDPROC(value) is a C++ replacement: "functional style" for the c-cast (WNDPROC)value. Convenient, but you don't know that it is basically a cast. Nim uses casts explicitly. Not so convenient, but an explicit cast remembers you always that you have to know what you are doing.
By the way, what is the simplest way to import the windows GUI into Nim?
Thanks for the clarification on casting.
It has been a while, but I used nimble to get the oldwinapi package and then I just put
import windows
at the top of my source. However I am on a Linux box using wine, so I also have to define a nim.cfg in my source folder:
i386.windows.gcc.path = "/usr/bin"
i386.windows.gcc.exe = "i686-w64-mingw32-gcc"
i386.windows.gcc.linkerexe = "i686-w64-mingw32-gcc"
which meant I must have installed the mingw32 tool chain (I don't exactly remember - I'm 76 so sometimes suffer from oldsheimers)
I also have a Makefile entry like:
msnBare.exe: msnBare.nim
nim --cpu:i386 --os:windows -o:msnBare.exe -r c msnBare.nim
Sorry if that is not much help. I would love to see an extended tutorial on using oldwinapi - I am working mostly blind.