WM_NCCALCSIZE using the lParam in fortran

WM_NCCALCSIZE using the lParam in fortran

Hi
I am trying to modify the size of the non-client area of a window (actually to make line numbers in an edit control).

I found examples showing this in C taking use of the fact that the lParamcontains the adress of a structure with the client rectangle:

"If wParam is TRUE, lParam points to an NCCALCSIZE_PARAMS structure that contains information an application can use to calculate the new size and position of the client rectangle. If wParam is FALSE, lParam points to a RECT structure. On entry, the structure contains the proposed window rectangle for the window. On exit, the structure should contain the screen coordinates of the corresponding window client area."

The way I have seen this done is (in c++):
RECT *prect;
case WM_NCCALCSIZE:
prect = (RECT *)lParam;
// modify prect...
return 0;

I think this solution is very elegant and straight forward. But is there an equivalent way of doing this in fortran? Can I somehow make a pointer of type T_RECT point toward the adress as specified by lParam (lParam is an integer)?

Regards

Lars

11 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Assuming you have something like:

type(T_RECT), pointer :: prect

You can do this:

use, intrinsic :: iso_c_binding ! This goes at the top of the procedure
...
call C_F_POINTER (TRANSFER(lParam,C_NULL_PTR), prect)

The TRANSFER "casts" lParam into something of type C_PTR and then C_F_POINTER converts that to a Fortran pointer.

Steve - Intel Developer Support

This is a ubiquitous Windows strategy, and the Fortran realization is extremely simple. Here is an example with a different Win type, but pointing to a RECT would be exactly the same:

INTEGER(HANDLE),  INTENT(IN)   :: hwnd

INTEGER(UINT),    INTENT(IN)   :: msg

INTEGER(fWPARAM), INTENT(IN)   :: wParam

INTEGER(fLPARAM), INTENT(IN)   :: lParam
TYPE(T_NMHDR)                  :: nmhdr

POINTER(lParam, nmhdr)


and then your message loop code can simply use nmhdr%whatever.

Thank you Steve.

This did excatly what I wanted. Just a small correction - I think is should say just use :: iso_c_binding

I will definitely have to look more trough the features in the iso_c_binding.

Regards

Lars

Thank you Paul

Thisalso did the trick and is a very simple solutionindeed.

Regards

Lars

The intrinsic keyword removes any doubt as to which module the programmer wants, just in case the programmer happens to have created a module with exactly the same name elsewhere.

Note that the POINTER(xxx,yyy) syntax is not standard Fortran, though the requirement that a windowing system that sends WM_NCCALCSIZE messages sit behind the application is equally not standard, so perhaps that doesn't matter.

I do not know why, but my first attempt at using the intrinsic keyword failed - that was why I suggestedonly to use"use iso_c_binding" - but I see know that it compiles.Sorry about that.

In the help file, I can see that the usage of "use" have evolved since compaq visual fortran and it is now legal tohave [, mod-nature ::] in the declaration - this is new to me.

Regards

Lars

"...POINTER(xxx,yyy) syntax is not standard Fortran..."

Really?

I have been using this construction for accessing Windows data types passed via standard Windows proc function arguments, and this simplest possible mechanism has been working, perfectly, at least since about 1998 or earlier: Digital Visual Fortran (DVF), then Compaq Visual Fortran (CVF) and now IVF.

Really. That's an extension popularly known as "Cray Pointers", though Cray doesn't care for the term. However, it is a very popular extension that has been in compilers for decades (I added it to VAX Fortran in the early 90s.) In the Intel documentation, we refer to it as "integer pointers".

Steve - Intel Developer Support

Yes, integer pointers, very simple, work perfectly, been around for donkey's years.
So why then would something horribly complex such as

call C_F_POINTER (TRANSFER(lParam,C_NULL_PTR), prect)

ever be recommended as preferable to POINTER(lParam, rect)?

I agree that in many cases the integer pointer extension is easy to use. But there are limitations - for example, you can't use it to point to an array of varying bounds or shape. Use what works for you, but my general preference is to show standard-conforming syntax where it is available.

Steve - Intel Developer Support

Leave a Comment

Please sign in to add a comment. Not a member? Join today