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

WM_NOTIFY question

ahasan
Beginner
1,117 Views
In the SDK, an example is given for custom draw for a List View control which I translated into IVF code. It works, but I do not understand why the double use of the lparam in the abreviated code below works. If both structures had HDR asthe first element I could understand how this works, but the LVCD structure does not have an HDR element. Baffeled???? Any explanation would be appreciated.
type(T_NMLISTVIEW) NMLV ; pointer(p_NMLV, NMLV)
type(T_NMLVCUSTOMDRAW) LVCD ; pointer(p_LVCD, LVCD)
type(T_NMCUSTOMDRAW) NMCD
case(WM_NOTIFY)
p_NMLV = lparam
select case(NMLV%HDR%code)
case(NM_CUSTOMDRAW)
p_LVCD = lparam
select case(LVCD%NMCD%dwDrawStage)
case()
....
case()
.....
end select
....
end select
....
0 Kudos
5 Replies
Paul_Curtis
Valued Contributor I
1,117 Views
The meaning of lParam, in this case the object to which it points, varies with the type of message. In your example, if the intent is to selectively color the items in a list, you only needa pointer toNMLVCUSTOMDRAW.
Code:
! this is a larger structure which contains an NMHDR as its initial element
TYPE(T_NMLVCUSTOMDRAW)			:: nmlvcd
POINTER (lParam, nmlvcd)

!	reference lisings of the custom draw data structures
!
!     TYPE T_NMLVCUSTOMDRAW
!     SEQUENCE
!       TYPE (T_NMCUSTOMDRAW) nmcd ! typedefs  NMCUSTOMDRAW 
!       integer(ULONG) clrText ! typedefs  COLORREF 
!       integer(ULONG) clrTextBk ! typedefs  COLORREF 
!       integer(SINT) iSubItem ! knowns  int 
!     END TYPE
!		TYPE T_NMCUSTOMDRAW
!		SEQUENCE
!		  TYPE (T_NMHDR) hdr ! typedefs  NMHDR 
!		  integer(DWORD) dwDrawStage ! knowns  DWORD 
!		  integer(HANDLE) hdc ! handles  HDC 
!		  TYPE (T_RECT) rc ! typedefs  RECT 
!		  integer(DWORD_PTR) dwItemSpec ! knowns  DWORD_PTR 
!		  integer(UINT) uItemState ! knowns  UINT 
!		  integer(LONG_PTR) lItemlParam ! knowns  LPARAM 
!		END TYPE

!			TYPE T_NMHDR
!			SEQUENCE
!			  integer(HANDLE) hwndFrom ! handles  HWND 
!			  integer(UINT) idFrom ! typedefs  UINT_PTR 
!			  integer(UINT) code ! knowns  UINT 
!			END TYPE


0 Kudos
ahasan
Beginner
1,117 Views

Paul, thanks for the reply.

I actually did it the way you indicated (below), and think that is the way to go. But also did it the way the SDK indicated above. Both methods seem to work. But, I am puzzeled at why the SDK method works in IVF. The lparam, above, is pointing at two different structures, so the addressappears to be the same for both structures? However, the addresses cannot be the same?

p_LVCD = lparam
if(LVCD%NMCD%hDr%hwndFrom == hWndList) then

if(LVCD%NMCD%hDR%code == NM_CUSTOMDRAW) then
select case(LVCD%NMCD%dwDrawStage)

case(CDDS_PREPAINT)
MainWndProc = CDRF_NOTIFYITEMDRAW
return

case(CDDS_ITEMPREPAINT)
hWndFocus = GetFocus()

! if the LV window does not have focus and the item/row is the
! HighLightedRow then shade row with gray
if(hWndFocus /= hWndList .AND. LVCD%NMCD%dwItemSpec == HighLightedRow) then
LVCD%clrTextBk = rgb(int1(220), int1(220), int1(220))
end if

MainWndProc = CDRF_NEWFONT
return

end select
end if
end if

Message Edited by halcyong@fcc.net on 03-11-2006 12:28 PM

Message Edited by halcyong@fcc.net on 03-12-2006 05:56 AM

0 Kudos
ahasan
Beginner
1,117 Views

After thinking about the double use of the lparam in my initial post, I believethe following is occurring:

1) the initial NM_LISTVIEW notification mesg. and the associated lparam point to the NMLISTVIEW struc. and defineNMLV%HDR%code

2) a second notification mesg. NM_CUSTOMDRAW is received emmediatelyafter, and this time thelparam points at the NMLVCUSTOMDRAW struc., however, there is no corresponding HDR member in this structure. Therefore, NMLV%HDR%code is still defined (on the stack?)). This allows the code to execute andassociatethe secondlparam with the NMLVCUSTOMDRAW (LVCD) struc.

If the above conjecture is someplace in the ball park, is it safe to assume that NMLV%HDR%code willalways be defined when the second notification mesg. arrivess?

Message Edited by halcyong@fcc.net on 03-12-2006 05:52 AM

Message Edited by halcyong@fcc.net on 03-12-2006 05:54 AM

0 Kudos
Paul_Curtis
Valued Contributor I
1,117 Views

The nested types listed in my earlier post indicate that only a single pointer is required. Here is the code for the actual processing for custom colors in a list:

Code:

CASE (WM_NOTIFY)
    controlId = wParam
    SELECT CASE (controlId)

    ! process CUSTOMDRAW messages to show each data column
    ! in its own color, matching the plot colors
    CASE (IDC_VLIST)
    IF (nmlvcd%nmcd%hdr%code == NM_CUSTOMDRAW) THEN
	SELECT CASE (nmlvcd%nmcd%dwDrawStage)
					
	CASE (CDDS_PREPAINT)
	    rval = SetWindowLong (hwnd, DWL_MSGRESULT, CDRF_NOTIFYITEMDRAW)
					
	CASE (IOR(CDDS_ITEM, CDDS_PREPAINT))
	    rval = SetWindowLong (hwnd, DWL_MSGRESULT, CDRF_NOTIFYSUBITEMDRAW)

	CASE (IOR(CDDS_ITEM, IOR(CDDS_PREPAINT, CDDS_SUBITEM)))
	    IF (nmlvcd%iSubItem > 0) THEN	
		nmlvcd%clrText = tcolor(nmlvcd%iSubItem) ! preloaded custom color
		rval = SetWindowLong (hwnd, DWL_MSGRESULT, CDRF_NEWFONT)
	    END IF

	CASE DEFAULT
            rval = SetWindowLong (hwnd, DWL_MSGRESULT, CDRF_DODEFAULT)
 	END SELECT
    END IF		 

! ... other message processing
END SELECT
res = 1



0 Kudos
ahasan
Beginner
1,117 Views
I seethe POINTER(lparam, nmlvcd) now. Thanks Paul.
0 Kudos
Reply