Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Calling a WinAPI Macro problem

ratzeputz
Beginner
1,165 Views
Hi there.
I have a problem with a macro of the WinAPI.
In one of my ListViews, i have to use Checkboxes to select/deselect items for interacting with them in the next step.
For that, i set the style of the ListView by using SendMessage withLVM_SETEXTENDEDLISTVIEWSTYLE.
So far so good...works like a charm and the checkboxes too.
The main problem is, that i am not able to read out the states of the checkboxes.
What i found through MSDN searching is, that there seems to be only one possible way to find out the state ... using the ListView_GetCheckState macro.Sadly it seems not to be implemented withing the Fortran Compiler (vers. 11) so i decided to use an interface (which i did on TrayIcon Balloontips before and worked).
My Interface looks like this:
[fxfortran]INTERFACE logical(BOOL) function ListViewGetCheckState(hwndLV, iIndex) !DEC$ ATTRIBUTES DEFAULT :: ListViewGetCheckState !DEC$ ATTRIBUTES STDCALL, DECORATE :: ListViewGetCheckState !DEC$ ATTRIBUTES ALIAS:'ListView_GetCheckState' :: ListViewGetCheckState use comctl32 IMPLICIT NONE integer(HANDLE) hwndLV ! Handle of Listview integer(UINT) iIndex ! Index of the item, which should be checked on its checkstate end function ListViewGetCheckState END INTERFACE [/fxfortran] The MSDN info of the macro says, that the macro is "stored" withinCommctrl.h...i guess this is comctl32, so i used it within the interface.
Compiling works, but during the linking of the programm, i get a fault, that there is a link to a non-external symbol called " ListView_GetCheckState@8"...copying the error code does not make sense, cause i am working with the german version of visual studio and i dont know, how many of you are speaking german ;)

I do have a workaround, by using self made checkbox icons, and adding them as icon to the listview and implement a select/deselect method by myself...but thats the last option, cause i want to use the standard windows ones.
Does anyone have an idea, what i am making wrong, or a solution for my problem?
Best regards
Oliver
0 Kudos
3 Replies
IanH
Honored Contributor III
1,165 Views
The name of the macro in the Windows API has a _ in between the ListView and the GetCheckState. That macro is defined in the C headers for the Window's API in terms of other API functions (have a look at the definition of the macro in the relevant header (commctrl.h) for the details). From the C language point of view it is just a simple text subsitution thing - consequently there is no symbol in a library to link to.

You can replicate the macro with something like:

[fortran]FUNCTION ListView_GetCheckState(hwndLV, i) RESULT(state) USE IFWIN IMPLICIT NONE INTEGER(HANDLE), INTENT(IN) :: hwndLV INTEGER(UINT), INTENT(IN) :: i INTEGER(BOOL) :: state !---- INTEGER(LRESULT) :: rc !**** rc = SendMessage(hwndLV, LVM_GETITEMSTATE, KIND(i,UINT_PTR), LVIS_STATEIMAGEMASK) state = ISHFT(rc, -12) - 1 END FUNCTION ListView_GetCheckState[/fortran]
Note that BOOL is an integer kind, not a logical kind.
0 Kudos
ratzeputz
Beginner
1,165 Views
Hi Ian and thx for your answer.
Well sadly i dont need a solution for that anymore :)
I made it the "went by foot" way by using a HookUp Process on the main window and listen for WM_NOTIFY messages. By pointing the lparam to a t_nmhdr struct and controlling its code attribute comparing toLVN_ITEMCHANGED, i can then point lparam to a t_nmlv struct and controlling their uOldState and uNewState values which are 4096 for unchecked and 8192 for checked.
But your solution was not complete for nothing :)
Because i have to set checkbox states to checked or unchecked during dialog initialization, i can use you way for ListView_SetCheckState macro :)
So in that case...many thanks again :)
Greetz
Oliver
0 Kudos
SergeyKostrov
Valued Contributor II
1,165 Views
The macro is declared in 'commctrl.h' header file and it is a part of aPlatform SDK. Since this is a macro
it is always used as inline and never stored in any Win32 API library.

This is howthe macrois declared:

...
#if (_WIN32_IE >= 0x0300)

#define ListView_GetCheckState(hwndLV, i) \
((((UINT)(SNDMSG((hwndLV), LVM_GETITEMSTATE, (WPARAM)(i), LVIS_STATEIMAGEMASK))) >> 12) -1)
#endif
...

I think a linkererror text has to be posted even if it is in German.

Best regards,
Sergey
0 Kudos
Reply