|
code
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Subclass Help WM_NOTIFYCan somone suggest why I don't receive a WM_NOTIFY message from a control on a subclassed form. I am trying to follow up from alpine's suggestion that I use NM_CUSTOMDRAW. The code is an altered WindowProc is attached (long). Can somone please suggest on what is going wrong here: Public Function WindowProc(ByVal hWnd As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Dim i As Integer Dim hCurrFont As Long Dim lf As LOGFONT Dim lColour As Long Dim hOldFont As Long Dim tMessage As NMHDR Dim tTVMessage As NMTVCUSTOMDRAW Dim lCode As Long Dim tItem As TV_ITEM Dim lRet As Long Form1.Label1.Caption = "HERE" Select Case msg Case WM_NOTIFY CopyMemory tMessage, ByVal lParam, Len(tMessage) lCode = tMessage.code Select Case lCode Case NM_CUSTOMDRAW If tMessage.hwndFrom <> TreeView1.hWnd Then WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End If CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then Result = CDRF_NOTIFYITEMDRAW Exit Function End If If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then CopyMemory tItem, ByVal tTVMessage.nmcmd.lItemLParam, Len(tItem) hCurrFont = GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) lRet = GetObjectAPI(hCurrFont, Len(lf), lf) If lRet > 0 Then lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, FW_NORMAL) lf.lfItalic = (CInt(Rnd(1) * 10) < 5) lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' False lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) 'False lRet = DeleteObject(mlHeaderFont) mlHeaderFont = CreateFontIndirect(lf) hOldFont = SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) End If lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * 255) tTVMessage.clrText = lColour CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) Result = CDRF_NEWFONT Exit Function End If Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) End Select End Function I have not added all the constants and Types but I can if somone thinks that it will help. The sub routine is being called but it never receives a WM_NOTIFY message. Thanks... Alastair MacFarlane You omitted the code where the WindowProc is attached to a hWnd. Maybe
you've got the wrong hWnd? Robert Show quoteHide quote "Alastair MacFarlane" <AlastairMacFarl***@discussions.microsoft.com> wrote tTVMessage.nmcmd.lItemLParam,in message news:E096BEEB-69A7-49E4-A20F-E21F6DA4DFC0@microsoft.com... > Dear All, > > Can somone suggest why I don't receive a WM_NOTIFY message from a control on > a subclassed form. I am trying to follow up from alpine's suggestion that I > use NM_CUSTOMDRAW. The code is an altered WindowProc is attached (long). Can > somone please suggest on what is going wrong here: > > Public Function WindowProc(ByVal hWnd As Long, _ > ByVal uMsg As Long, _ > ByVal wParam As Long, _ > ByVal lParam As Long) As Long > Dim i As Integer > Dim hCurrFont As Long > Dim lf As LOGFONT > Dim lColour As Long > Dim hOldFont As Long > Dim tMessage As NMHDR > Dim tTVMessage As NMTVCUSTOMDRAW > Dim lCode As Long > Dim tItem As TV_ITEM > Dim lRet As Long > Form1.Label1.Caption = "HERE" > Select Case msg > Case WM_NOTIFY > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > Case NM_CUSTOMDRAW > If tMessage.hwndFrom <> TreeView1.hWnd Then > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, > uMsg, wParam, lParam) > Exit Function > End If > CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) > If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then > Result = CDRF_NOTIFYITEMDRAW > Exit Function > End If > If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then > CopyMemory tItem, ByVal Show quoteHide quote > Len(tItem) SelectObject(tTVMessage.nmcmd.hdc,> hCurrFont = > GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) > lRet = GetObjectAPI(hCurrFont, Len(lf), lf) > If lRet > 0 Then > lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, > FW_NORMAL) > lf.lfItalic = (CInt(Rnd(1) * 10) < 5) > lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' > False > lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) 'False > lRet = DeleteObject(mlHeaderFont) > mlHeaderFont = CreateFontIndirect(lf) > hOldFont = Show quoteHide quote > mlHeaderFont) > End If > lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * 255) > tTVMessage.clrText = lColour > CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) > Result = CDRF_NEWFONT > Exit Function > End If > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, > wParam, lParam) > Exit Function > End Select > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) > End Select > End Function > > I have not added all the constants and Types but I can if somone thinks that > it will help. The sub routine is being called but it never receives a > WM_NOTIFY message. > > Thanks... > > Alastair MacFarlane "Alastair MacFarlane" <AlastairMacFarl***@discussions.microsoft.com> wrote What are you subclassing? Is it the control or the control's parent? in message news:E096BEEB-69A7-49E4-A20F-E21F6DA4DFC0@microsoft.com... > Dear All, > > Can somone suggest why I don't receive a WM_NOTIFY message from a control > on > a subclassed form. I am trying to follow up from alpine's suggestion that > I > use NM_CUSTOMDRAW. The code is an altered WindowProc is attached (long). > Can > somone please suggest on what is going wrong here: WM_NOTIFY messages are sent *by* the control *to* its parent. Therefore, you need to subclass the control's parent (i.e. the form the control is on). -- Mike Microsoft MVP Visual Basic Are you subclassing the treeview's parent window?
HTH, Bryan _______________________________ Bryan Stafford New Vision Software newvision_don'tspam@mvps.org On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" <AlastairMacFarl***@discussions.microsoft.com> wrote: Show quoteHide quote >Dear All, > >Can somone suggest why I don't receive a WM_NOTIFY message from a control on >a subclassed form. I am trying to follow up from alpine's suggestion that I >use NM_CUSTOMDRAW. The code is an altered WindowProc is attached (long). Can >somone please suggest on what is going wrong here: > >Public Function WindowProc(ByVal hWnd As Long, _ > ByVal uMsg As Long, _ > ByVal wParam As Long, _ > ByVal lParam As Long) As Long > Dim i As Integer > Dim hCurrFont As Long > Dim lf As LOGFONT > Dim lColour As Long > Dim hOldFont As Long > Dim tMessage As NMHDR > Dim tTVMessage As NMTVCUSTOMDRAW > Dim lCode As Long > Dim tItem As TV_ITEM > Dim lRet As Long > Form1.Label1.Caption = "HERE" > Select Case msg > Case WM_NOTIFY > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > Case NM_CUSTOMDRAW > If tMessage.hwndFrom <> TreeView1.hWnd Then > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, >uMsg, wParam, lParam) > Exit Function > End If > CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) > If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then > Result = CDRF_NOTIFYITEMDRAW > Exit Function > End If > If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then > CopyMemory tItem, ByVal tTVMessage.nmcmd.lItemLParam, >Len(tItem) > hCurrFont = >GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) > lRet = GetObjectAPI(hCurrFont, Len(lf), lf) > If lRet > 0 Then > lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, >FW_NORMAL) > lf.lfItalic = (CInt(Rnd(1) * 10) < 5) > lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' >False > lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) 'False > lRet = DeleteObject(mlHeaderFont) > mlHeaderFont = CreateFontIndirect(lf) > hOldFont = SelectObject(tTVMessage.nmcmd.hdc, >mlHeaderFont) > End If > lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * 255) > tTVMessage.clrText = lColour > CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) > Result = CDRF_NEWFONT > Exit Function > End If > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, >wParam, lParam) > Exit Function > End Select > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) > End Select >End Function > >I have not added all the constants and Types but I can if somone thinks that >it will help. The sub routine is being called but it never receives a >WM_NOTIFY message. > >Thanks... > >Alastair MacFarlane Thanks all for your reply. I am running the subclass from the form as follows:
lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf WindowProc) therefore I presume I am subclassing the treeview control itself. The full code on the form is as follows: Option Explicit Private Const GWL_WNDPROC As Long = (-4&) Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd&, _ ByVal nIndex&, ByVal dwNewLong&) As Long Private Sub Form_Load() Dim lCount As Long With TreeView1.Nodes .Add , , "ROOT", "ROOT" For lCount = 1 To 25 .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item Number " & lCount Next End With lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf WindowProc) End Sub Private Sub Form_Unload(Cancel As Integer) Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) End Sub Thanks again for your support? Alastair Show quoteHide quote "alpine" wrote: > Are you subclassing the treeview's parent window? > > HTH, > Bryan > _______________________________ > Bryan Stafford > New Vision Software > newvision_don'tspam@mvps.org > > > On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" > <AlastairMacFarl***@discussions.microsoft.com> wrote: > > >Dear All, > > > >Can somone suggest why I don't receive a WM_NOTIFY message from a control on You'll need to subclass the treeview's parent window. Have a look at
the WM_NOTIFY topic in the MSDN for further info on this message. HTH, Bryan _______________________________ Bryan Stafford New Vision Software newvision_don'tspam@mvps.org On Tue, 18 Oct 2005 07:39:05 -0700, "Alastair MacFarlane" <AlastairMacFarl***@discussions.microsoft.com> wrote: Show quoteHide quote >Thanks all for your reply. I am running the subclass from the form as follows: > > lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >WindowProc) > >therefore I presume I am subclassing the treeview control itself. > >The full code on the form is as follows: > >Option Explicit > >Private Const GWL_WNDPROC As Long = (-4&) >Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" >(ByVal hWnd&, _ > ByVal nIndex&, ByVal dwNewLong&) As Long > >Private Sub Form_Load() > Dim lCount As Long > With TreeView1.Nodes > .Add , , "ROOT", "ROOT" > For lCount = 1 To 25 > .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item Number >" & lCount > Next > End With > lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >WindowProc) >End Sub > >Private Sub Form_Unload(Cancel As Integer) > Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) >End Sub > >Thanks again for your support? > >Alastair > >"alpine" wrote: > >> Are you subclassing the treeview's parent window? >> >> HTH, >> Bryan >> _______________________________ >> Bryan Stafford >> New Vision Software >> newvision_don'tspam@mvps.org >> >> >> On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" >> <AlastairMacFarl***@discussions.microsoft.com> wrote: >> >> >Dear All, >> > >> >Can somone suggest why I don't receive a WM_NOTIFY message from a control on Alpine,
Once again thanks for the reply. I have now changed the code to subclass the control parent instead as per your and msdn's advice, BUT the WM_NOTIFY message does not get raised. I have declared the messgage handler as on the Form_Load: lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) and WM_NOTIFY is declared as in the module: Public Const WM_NOTIFY = &H4E Is there any property of the form (Form1) that could interfere with the message queue. When I add a breakpoint at the line below the "Case WM_NOTIFY" (which I know you shouldn't), the line "CopyMemory tMessage, ByVal lParam, Len(tMessage)" is never called. Select Case msg Case WM_NOTIFY CopyMemory tMessage, ByVal lParam, Len(tMessage) lCode = tMessage.code Select Case lCode My aim (as discussed in a previous post) is to change the size of specific node fonts. Thanks again for your continued support and I apologise if I seem somewhat dense. Alastair MacFarlane Show quoteHide quote "alpine" <alpine_don'tsendspam@mvps.org> wrote in message news:905al1587bgtet142qpocpign5e0bh9i2h@4ax.com... > You'll need to subclass the treeview's parent window. Have a look at > the WM_NOTIFY topic in the MSDN for further info on this message. > > HTH, > Bryan > _______________________________ > Bryan Stafford > New Vision Software > newvision_don'tspam@mvps.org > > > On Tue, 18 Oct 2005 07:39:05 -0700, "Alastair MacFarlane" > <AlastairMacFarl***@discussions.microsoft.com> wrote: > >>Thanks all for your reply. I am running the subclass from the form as >>follows: >> >> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>WindowProc) >> >>therefore I presume I am subclassing the treeview control itself. >> >>The full code on the form is as follows: >> >>Option Explicit >> >>Private Const GWL_WNDPROC As Long = (-4&) >>Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" >>(ByVal hWnd&, _ >> ByVal nIndex&, ByVal dwNewLong&) As Long >> >>Private Sub Form_Load() >> Dim lCount As Long >> With TreeView1.Nodes >> .Add , , "ROOT", "ROOT" >> For lCount = 1 To 25 >> .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item >> Number >>" & lCount >> Next >> End With >> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>WindowProc) >>End Sub >> >>Private Sub Form_Unload(Cancel As Integer) >> Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) >>End Sub >> >>Thanks again for your support? >> >>Alastair >> >>"alpine" wrote: >> >>> Are you subclassing the treeview's parent window? >>> >>> HTH, >>> Bryan >>> _______________________________ >>> Bryan Stafford >>> New Vision Software >>> newvision_don'tspam@mvps.org >>> >>> >>> On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" >>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>> >>> >Dear All, >>> > >>> >Can somone suggest why I don't receive a WM_NOTIFY message from a >>> >control on > I just ran a test here in both VB5 & 6 and the WM_NOTIFY messages come
through just fine for the treeview. Are you getting *any* messages coming through your windowproc? HTH, Bryan _______________________________ Bryan Stafford New Vision Software newvision_don'tspam@mvps.org On Tue, 18 Oct 2005 19:14:32 +0100, "Alastair MacFarlane" <anonym***@microsoft.com> wrote: Show quoteHide quote >Alpine, > >Once again thanks for the reply. I have now changed the code to subclass the >control parent instead as per your and msdn's advice, BUT the WM_NOTIFY >message does not get raised. I have declared the messgage handler as on the >Form_Load: > >lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) > >and WM_NOTIFY is declared as in the module: > >Public Const WM_NOTIFY = &H4E > >Is there any property of the form (Form1) that could interfere with the >message queue. When I add a breakpoint at the line below the "Case >WM_NOTIFY" (which I know you shouldn't), the line "CopyMemory tMessage, >ByVal lParam, Len(tMessage)" is never called. > > Select Case msg > Case WM_NOTIFY > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > >My aim (as discussed in a previous post) is to change the size of specific >node fonts. > >Thanks again for your continued support and I apologise if I seem somewhat >dense. > >Alastair MacFarlane > > >"alpine" <alpine_don'tsendspam@mvps.org> wrote in message >news:905al1587bgtet142qpocpign5e0bh9i2h@4ax.com... >> You'll need to subclass the treeview's parent window. Have a look at >> the WM_NOTIFY topic in the MSDN for further info on this message. >> >> HTH, >> Bryan >> _______________________________ >> Bryan Stafford >> New Vision Software >> newvision_don'tspam@mvps.org >> >> >> On Tue, 18 Oct 2005 07:39:05 -0700, "Alastair MacFarlane" >> <AlastairMacFarl***@discussions.microsoft.com> wrote: >> >>>Thanks all for your reply. I am running the subclass from the form as >>>follows: >>> >>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>WindowProc) >>> >>>therefore I presume I am subclassing the treeview control itself. >>> >>>The full code on the form is as follows: >>> >>>Option Explicit >>> >>>Private Const GWL_WNDPROC As Long = (-4&) >>>Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" >>>(ByVal hWnd&, _ >>> ByVal nIndex&, ByVal dwNewLong&) As Long >>> >>>Private Sub Form_Load() >>> Dim lCount As Long >>> With TreeView1.Nodes >>> .Add , , "ROOT", "ROOT" >>> For lCount = 1 To 25 >>> .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item >>> Number >>>" & lCount >>> Next >>> End With >>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>WindowProc) >>>End Sub >>> >>>Private Sub Form_Unload(Cancel As Integer) >>> Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) >>>End Sub >>> >>>Thanks again for your support? >>> >>>Alastair >>> >>>"alpine" wrote: >>> >>>> Are you subclassing the treeview's parent window? >>>> >>>> HTH, >>>> Bryan >>>> _______________________________ >>>> Bryan Stafford >>>> New Vision Software >>>> newvision_don'tspam@mvps.org >>>> >>>> >>>> On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" >>>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>>> >>>> >Dear All, >>>> > >>>> >Can somone suggest why I don't receive a WM_NOTIFY message from a >>>> >control on >> > Alpine
Thanks again. The handler is getting some messages but no WM_NOTIFY messages. I have attached the full form and module code and I would appreciate your comments. Alastair MacFarlane '****Start Form Header Info **** 'Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX" '****End Form Header Info **** '****Start Form Code**** Option Explicit Private Const GWL_WNDPROC As Long = (-4&) Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd&, _ ByVal nIndex&, ByVal dwNewLong&) As Long Private Sub Form_Load() Dim lCount As Long With TreeView1.Nodes .Add , , "ROOT", "ROOT" For lCount = 1 To 25 .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item Number " & lCount Next End With lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) End Sub Private Sub Form_Unload(Cancel As Integer) Call SetWindowLong(hWnd, GWL_WNDPROC, lpPrevWndProc) End Sub '****End Form Code**** '****Start Module Code**** Public Type RECT Left As Long Top As Long Right As Long Bottom As Long End Type ' WinAPI Notification Structure Public Type NMHDR hwndFrom As Long idFrom As Long code As Long End Type ' Custom Draw Structure Public Type NMCUSTOMDRAWINFO hdr As NMHDR dwDrawStage As Long hdc As Long rc As RECT dwItemSpec As Long iItemState As Long lItemLParam As Long End Type ' Custom Draw Structure Associated with the TreeView Public Type NMTVCUSTOMDRAW nmcmd As NMCUSTOMDRAWINFO clrText As Long clrTextBk As Long iLevel As Integer End Type ' Font Constants Public Const LF_FACESIZE = 32 Public Const FW_NORMAL = 400 Public Const OBJ_FONT = 6 ' WinAPI LogFont Structure Public Type LOGFONT lfHeight As Long lfWidth As Long lfEscapement As Long lfOrientation As Long lfWeight As Long lfItalic As Byte lfUnderline As Byte lfStrikeOut As Byte lfCharSet As Byte lfOutPrecision As Byte lfClipPrecision As Byte lfQuality As Byte lfPitchAndFamily As Byte lfFaceName(LF_FACESIZE) As Byte End Type ' WinAPI TreeView Item Structure Public Type TV_ITEM mask As Long hitem As Long state As Long stateMask As Long pszText As Long ' pointer cchTextMax As Long iImage As Long iSelectedImage As Long cChildren As Long lParam As Long End Type ' Windows messages Public Const NM_CUSTOMDRAW = (0 - 12) Public Const WM_NOTIFY = &H4E ' Custom Draw Messages Public Const CDDS_PREPAINT& = &H1 Public Const CDDS_POSTPAINT& = &H2 Public Const CDDS_PREERASE& = &H3 Public Const CDDS_POSTERASE& = &H4 Public Const CDDS_ITEM& = &H10000 Public Const CDDS_ITEMPREPAINT& = CDDS_ITEM Or CDDS_PREPAINT Public Const CDDS_ITEMPOSTPAINT& = CDDS_ITEM Or CDDS_POSTPAINT Public Const CDDS_ITEMPREERASE& = CDDS_ITEM Or CDDS_PREERASE Public Const CDDS_ITEMPOSTERASE& = CDDS_ITEM Or CDDS_POSTERASE Public Const CDDS_SUBITEM& = &H20000 Public Const CDRF_DODEFAULT& = &H0 Public Const CDRF_NEWFONT& = &H2 Public Const CDRF_SKIPDEFAULT& = &H4 Public Const CDRF_NOTIFYPOSTPAINT& = &H10 Public Const CDRF_NOTIFYITEMDRAW& = &H20 Public Const CDRF_NOTIFYSUBITEMDRAW = &H20 'flags are the same, we can distinguish by context Public Const CDRF_NOTIFYPOSTERASE& = &H40 Public Const CDRF_NOTIFYITEMERASE& = &H80 Public mlHeaderFont As Long Public Declare Function GetCurrentObject Lib "gdi32" _ (ByVal hdc As Long, ByVal uObjectType As Long) As Long Public Declare Sub CopyMemory Lib "kernel32" Alias _ "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long) Public Declare Function DeleteObject Lib "gdi32" _ (ByVal hObject As Long) As Long Public Declare Function CreateFontIndirect Lib "gdi32" _ Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long Public Declare Function SelectObject Lib "gdi32" _ (ByVal hdc As Long, ByVal hObject As Long) As Long Public Declare Function GetObjectAPI Lib "gdi32" Alias _ "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _ (ByVal lpPrevWndFunc As Long, _ ByVal hWnd As Long, _ ByVal msg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Public lpPrevWndProc As Long Public Function WindowProc(ByVal hWnd As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, _ ByVal lParam As Long) As Long Dim i As Integer Dim hCurrFont As Long Dim lf As LOGFONT Dim lColour As Long Dim hOldFont As Long Dim tMessage As NMHDR Dim tTVMessage As NMTVCUSTOMDRAW Dim lCode As Long Dim tItem As TV_ITEM Dim lRet As Long Form1.Label1.Caption = "HERE" Select Case msg Case WM_NOTIFY CopyMemory tMessage, ByVal lParam, Len(tMessage) lCode = tMessage.code Select Case lCode Case NM_CUSTOMDRAW If tMessage.hwndFrom <> TreeView1.hWnd Then WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End If CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then Result = CDRF_NOTIFYITEMDRAW Exit Function End If If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then CopyMemory tItem, ByVal tTVMessage.nmcmd.lItemLParam, Len(tItem) hCurrFont = GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) lRet = GetObjectAPI(hCurrFont, Len(lf), lf) If lRet > 0 Then lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, FW_NORMAL) lf.lfItalic = (CInt(Rnd(1) * 10) < 5) lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' False lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) 'False lRet = DeleteObject(mlHeaderFont) mlHeaderFont = CreateFontIndirect(lf) hOldFont = SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) End If lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * 255) tTVMessage.clrText = lColour CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) Result = CDRF_NEWFONT Exit Function End If Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) End Select End Function '****End Module Code**** Show quoteHide quote "alpine" <alpine_don'tsendspam@mvps.org> wrote in message news:qnial15i1rlnph00veel2p8h6jne1uijel@4ax.com... >I just ran a test here in both VB5 & 6 and the WM_NOTIFY messages come > through just fine for the treeview. Are you getting *any* messages > coming through your windowproc? > > HTH, > Bryan > _______________________________ > Bryan Stafford > New Vision Software > newvision_don'tspam@mvps.org > > > On Tue, 18 Oct 2005 19:14:32 +0100, "Alastair MacFarlane" > <anonym***@microsoft.com> wrote: > >>Alpine, >> >>Once again thanks for the reply. I have now changed the code to subclass >>the >>control parent instead as per your and msdn's advice, BUT the WM_NOTIFY >>message does not get raised. I have declared the messgage handler as on >>the >>Form_Load: >> >>lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) >> >>and WM_NOTIFY is declared as in the module: >> >>Public Const WM_NOTIFY = &H4E >> >>Is there any property of the form (Form1) that could interfere with the >>message queue. When I add a breakpoint at the line below the "Case >>WM_NOTIFY" (which I know you shouldn't), the line "CopyMemory tMessage, >>ByVal lParam, Len(tMessage)" is never called. >> >> Select Case msg >> Case WM_NOTIFY >> CopyMemory tMessage, ByVal lParam, Len(tMessage) >> lCode = tMessage.code >> Select Case lCode >> >>My aim (as discussed in a previous post) is to change the size of specific >>node fonts. >> >>Thanks again for your continued support and I apologise if I seem somewhat >>dense. >> >>Alastair MacFarlane >> >> >>"alpine" <alpine_don'tsendspam@mvps.org> wrote in message >>news:905al1587bgtet142qpocpign5e0bh9i2h@4ax.com... >>> You'll need to subclass the treeview's parent window. Have a look at >>> the WM_NOTIFY topic in the MSDN for further info on this message. >>> >>> HTH, >>> Bryan >>> _______________________________ >>> Bryan Stafford >>> New Vision Software >>> newvision_don'tspam@mvps.org >>> >>> >>> On Tue, 18 Oct 2005 07:39:05 -0700, "Alastair MacFarlane" >>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>> >>>>Thanks all for your reply. I am running the subclass from the form as >>>>follows: >>>> >>>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>>WindowProc) >>>> >>>>therefore I presume I am subclassing the treeview control itself. >>>> >>>>The full code on the form is as follows: >>>> >>>>Option Explicit >>>> >>>>Private Const GWL_WNDPROC As Long = (-4&) >>>>Private Declare Function SetWindowLong Lib "user32" Alias >>>>"SetWindowLongA" >>>>(ByVal hWnd&, _ >>>> ByVal nIndex&, ByVal dwNewLong&) As Long >>>> >>>>Private Sub Form_Load() >>>> Dim lCount As Long >>>> With TreeView1.Nodes >>>> .Add , , "ROOT", "ROOT" >>>> For lCount = 1 To 25 >>>> .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item >>>> Number >>>>" & lCount >>>> Next >>>> End With >>>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>>WindowProc) >>>>End Sub >>>> >>>>Private Sub Form_Unload(Cancel As Integer) >>>> Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) >>>>End Sub >>>> >>>>Thanks again for your support? >>>> >>>>Alastair >>>> >>>>"alpine" wrote: >>>> >>>>> Are you subclassing the treeview's parent window? >>>>> >>>>> HTH, >>>>> Bryan >>>>> _______________________________ >>>>> Bryan Stafford >>>>> New Vision Software >>>>> newvision_don'tspam@mvps.org >>>>> >>>>> >>>>> On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" >>>>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>>>> >>>>> >Dear All, >>>>> > >>>>> >Can somone suggest why I don't receive a WM_NOTIFY message from a >>>>> >control on >>> >> >
Show quote
Hide quote
"Alastair MacFarlane" <anonym***@microsoft.com> wrote in message You *sure* about that code? There are problems with it as posted. For one, news:uKW5G2B1FHA.2312@TK2MSFTNGP14.phx.gbl... > Alpine > > Thanks again. The handler is getting some messages but no WM_NOTIFY > messages. I have attached the full form and module code and I would > appreciate your comments. > Public Function WindowProc(ByVal hWnd As Long, _ > ByVal uMsg As Long, _ > ByVal wParam As Long, _ > ByVal lParam As Long) As Long > Dim i As Integer > Dim hCurrFont As Long > Dim lf As LOGFONT > Dim lColour As Long > Dim hOldFont As Long > Dim tMessage As NMHDR > Dim tTVMessage As NMTVCUSTOMDRAW > Dim lCode As Long > Dim tItem As TV_ITEM > Dim lRet As Long > Form1.Label1.Caption = "HERE" > Select Case msg > Case WM_NOTIFY > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > Case NM_CUSTOMDRAW > If tMessage.hwndFrom <> TreeView1.hWnd Then > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, > uMsg, wParam, lParam) > Exit Function > End If > CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) > If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then > Result = CDRF_NOTIFYITEMDRAW > Exit Function > End If > If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then > CopyMemory tItem, ByVal > tTVMessage.nmcmd.lItemLParam, Len(tItem) > hCurrFont = > GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) > lRet = GetObjectAPI(hCurrFont, Len(lf), lf) > If lRet > 0 Then > lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), > 700, FW_NORMAL) > lf.lfItalic = (CInt(Rnd(1) * 10) < 5) > lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' > False > lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) > 'False > lRet = DeleteObject(mlHeaderFont) > mlHeaderFont = CreateFontIndirect(lf) > hOldFont = > SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) > End If > lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * > 255) > tTVMessage.clrText = lColour > CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) > Result = CDRF_NEWFONT > Exit Function > End If > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, > wParam, lParam) > Exit Function > End Select > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, > lParam) > End Select > End Function in your Select Case, you've got the variable as 'msg' but it should be 'uMsg' (per your procedure header). Also, you need to preface the reference to TreeView1 with the form's name (or other reference to the form). Furthermore, there's no declaration for your 'Result' variable. Maybe that's declared elsewhere, but I also noticed there was no Option Explicit for this module. However, once I corrected these problems, your code at least ran and handled the WM_NOTIFY message. I don't know that it did what it was supposed to do, but it at least ran. Here's what I changed your WindowProc to: -----BEGIN CODE Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long Dim i As Integer Dim hCurrFont As Long Dim lf As LOGFONT Dim lColour As Long Dim hOldFont As Long Dim tMessage As NMHDR Dim tTVMessage As NMTVCUSTOMDRAW Dim lCode As Long Dim tItem As TV_ITEM Dim lRet As Long Dim Result As Long Form1.Label1.Caption = "HERE" Select Case uMsg Case WM_NOTIFY Debug.Print "WM_NOTIFY" CopyMemory tMessage, ByVal lParam, Len(tMessage) lCode = tMessage.code Select Case lCode Case NM_CUSTOMDRAW If tMessage.hwndFrom <> Form1.TreeView1.hWnd Then WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End If CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then Result = CDRF_NOTIFYITEMDRAW Exit Function End If If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then CopyMemory tItem, ByVal tTVMessage.nmcmd.lItemLParam, Len(tItem) hCurrFont = GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) lRet = GetObjectAPI(hCurrFont, Len(lf), lf) If lRet > 0 Then lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, FW_NORMAL) lf.lfItalic = (CInt(Rnd(1) * 10) < 5) lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) 'False lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) 'False lRet = DeleteObject(mlHeaderFont) mlHeaderFont = CreateFontIndirect(lf) hOldFont = SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) End If lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * 255) tTVMessage.clrText = lColour CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) Result = CDRF_NEWFONT Exit Function End If Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End Select Case Else WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) End Select End Function -----END CODE Also, make sure the module contains Option Explicit. -- Mike Microsoft MVP Visual Basic Mike & Alpine,
It does seem to work (with your revised sub) and the problem is in the NM_CUSTOMDRAW message handling code which I will need to look at tomorrow (UK bed-time). I appreciate both your help but at a quick glance the code looks beyond my ability to fix at the moment because I don't truly understand the use of CopyMemory and the different Type structures mentioned. This one will probably just leave me beat. I will look at it tomorrow and thanks again for your help. Any thoughts on the revision of the code would be appreciated but not expected. Alastair MacFarlane p.s. Good night from the UK. It always seems to exit the sub about here, therefore tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT (but what does this mean?): If tMessage.hwndFrom <> Form1.TreeView1.hWnd Then WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, lParam) Exit Function End If CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then Result = CDRF_NOTIFYITEMDRAW **********************HERE****************** Exit Function End If Show quoteHide quote "MikeD" <nob***@nowhere.edu> wrote in message news:%23oO25RC1FHA.904@tk2msftngp13.phx.gbl... > > "Alastair MacFarlane" <anonym***@microsoft.com> wrote in message > news:uKW5G2B1FHA.2312@TK2MSFTNGP14.phx.gbl... >> Alpine >> >> Thanks again. The handler is getting some messages but no WM_NOTIFY >> messages. I have attached the full form and module code and I would >> appreciate your comments. >> Public Function WindowProc(ByVal hWnd As Long, _ >> ByVal uMsg As Long, _ >> ByVal wParam As Long, _ >> ByVal lParam As Long) As Long >> Dim i As Integer >> Dim hCurrFont As Long >> Dim lf As LOGFONT >> Dim lColour As Long >> Dim hOldFont As Long >> Dim tMessage As NMHDR >> Dim tTVMessage As NMTVCUSTOMDRAW >> Dim lCode As Long >> Dim tItem As TV_ITEM >> Dim lRet As Long >> Form1.Label1.Caption = "HERE" >> Select Case msg >> Case WM_NOTIFY >> CopyMemory tMessage, ByVal lParam, Len(tMessage) >> lCode = tMessage.code >> Select Case lCode >> Case NM_CUSTOMDRAW >> If tMessage.hwndFrom <> TreeView1.hWnd Then >> WindowProc = CallWindowProc(lpPrevWndProc, hWnd, >> uMsg, wParam, lParam) >> Exit Function >> End If >> CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) >> If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then >> Result = CDRF_NOTIFYITEMDRAW >> Exit Function >> End If >> If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT >> Then >> CopyMemory tItem, ByVal >> tTVMessage.nmcmd.lItemLParam, Len(tItem) >> hCurrFont = >> GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) >> lRet = GetObjectAPI(hCurrFont, Len(lf), lf) >> If lRet > 0 Then >> lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), >> 700, FW_NORMAL) >> lf.lfItalic = (CInt(Rnd(1) * 10) < 5) >> lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' >> False >> lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) >> 'False >> lRet = DeleteObject(mlHeaderFont) >> mlHeaderFont = CreateFontIndirect(lf) >> hOldFont = >> SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) >> End If >> lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * >> 255) >> tTVMessage.clrText = lColour >> CopyMemory ByVal lParam, tTVMessage, >> Len(tTVMessage) >> Result = CDRF_NEWFONT >> Exit Function >> End If >> Case Else >> WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, >> wParam, lParam) >> Exit Function >> End Select >> Case Else >> WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, >> lParam) >> End Select >> End Function > > > You *sure* about that code? There are problems with it as posted. For > one, in your Select Case, you've got the variable as 'msg' but it should > be 'uMsg' (per your procedure header). Also, you need to preface the > reference to TreeView1 with the form's name (or other reference to the > form). Furthermore, there's no declaration for your 'Result' variable. > Maybe that's declared elsewhere, but I also noticed there was no Option > Explicit for this module. > > However, once I corrected these problems, your code at least ran and > handled the WM_NOTIFY message. I don't know that it did what it was > supposed to do, but it at least ran. > > Here's what I changed your WindowProc to: > > -----BEGIN CODE > Public Function WindowProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal > wParam As Long, ByVal lParam As Long) As Long > > Dim i As Integer > Dim hCurrFont As Long > Dim lf As LOGFONT > Dim lColour As Long > Dim hOldFont As Long > Dim tMessage As NMHDR > Dim tTVMessage As NMTVCUSTOMDRAW > Dim lCode As Long > Dim tItem As TV_ITEM > Dim lRet As Long > > Dim Result As Long > > Form1.Label1.Caption = "HERE" > Select Case uMsg > Case WM_NOTIFY > Debug.Print "WM_NOTIFY" > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > Case NM_CUSTOMDRAW > If tMessage.hwndFrom <> Form1.TreeView1.hWnd Then > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, > uMsg, wParam, lParam) > Exit Function > End If > CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) > If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then > Result = CDRF_NOTIFYITEMDRAW > Exit Function > End If > If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then > CopyMemory tItem, ByVal > tTVMessage.nmcmd.lItemLParam, Len(tItem) > hCurrFont = > GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) > lRet = GetObjectAPI(hCurrFont, Len(lf), lf) > If lRet > 0 Then > lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), > 700, FW_NORMAL) > lf.lfItalic = (CInt(Rnd(1) * 10) < 5) > lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) > 'False > lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) > 'False > lRet = DeleteObject(mlHeaderFont) > mlHeaderFont = CreateFontIndirect(lf) > hOldFont = > SelectObject(tTVMessage.nmcmd.hdc, mlHeaderFont) > End If > lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * > 255) > tTVMessage.clrText = lColour > CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) > Result = CDRF_NEWFONT > Exit Function > End If > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, > wParam, lParam) > Exit Function > End Select > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, > lParam) > End Select > End Function > -----END CODE > > Also, make sure the module contains Option Explicit. > > > -- > Mike > Microsoft MVP Visual Basic > > > Try placing an Option Explicit at the top of your BAS module. ;-)
HTH, Bryan _______________________________ Bryan Stafford New Vision Software newvision_don'tspam@mvps.org On Tue, 18 Oct 2005 20:52:29 +0100, "Alastair MacFarlane" <anonym***@microsoft.com> wrote: Show quoteHide quote >Alpine > >Thanks again. The handler is getting some messages but no WM_NOTIFY >messages. I have attached the full form and module code and I would >appreciate your comments. > >Alastair MacFarlane > >'****Start Form Header Info **** >'Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "MSCOMCTL.OCX" >'****End Form Header Info **** > > >'****Start Form Code**** >Option Explicit >Private Const GWL_WNDPROC As Long = (-4&) >Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" >(ByVal hWnd&, _ > ByVal nIndex&, ByVal dwNewLong&) As Long > >Private Sub Form_Load() > Dim lCount As Long > With TreeView1.Nodes > .Add , , "ROOT", "ROOT" > For lCount = 1 To 25 > .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item Number >" & lCount > Next > End With > lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) >End Sub > >Private Sub Form_Unload(Cancel As Integer) > Call SetWindowLong(hWnd, GWL_WNDPROC, lpPrevWndProc) >End Sub >'****End Form Code**** > >'****Start Module Code**** > >Public Type RECT > Left As Long > Top As Long > Right As Long > Bottom As Long >End Type > >' WinAPI Notification Structure >Public Type NMHDR > hwndFrom As Long > idFrom As Long > code As Long >End Type > >' Custom Draw Structure >Public Type NMCUSTOMDRAWINFO > hdr As NMHDR > dwDrawStage As Long > hdc As Long > rc As RECT > dwItemSpec As Long > iItemState As Long > lItemLParam As Long >End Type > >' Custom Draw Structure Associated with the TreeView >Public Type NMTVCUSTOMDRAW > nmcmd As NMCUSTOMDRAWINFO > clrText As Long > clrTextBk As Long > iLevel As Integer >End Type > >' Font Constants >Public Const LF_FACESIZE = 32 >Public Const FW_NORMAL = 400 >Public Const OBJ_FONT = 6 > >' WinAPI LogFont Structure >Public Type LOGFONT > lfHeight As Long > lfWidth As Long > lfEscapement As Long > lfOrientation As Long > lfWeight As Long > lfItalic As Byte > lfUnderline As Byte > lfStrikeOut As Byte > lfCharSet As Byte > lfOutPrecision As Byte > lfClipPrecision As Byte > lfQuality As Byte > lfPitchAndFamily As Byte > lfFaceName(LF_FACESIZE) As Byte >End Type > >' WinAPI TreeView Item Structure >Public Type TV_ITEM > mask As Long > hitem As Long > state As Long > stateMask As Long > pszText As Long ' pointer > cchTextMax As Long > iImage As Long > iSelectedImage As Long > cChildren As Long > lParam As Long >End Type > >' Windows messages >Public Const NM_CUSTOMDRAW = (0 - 12) >Public Const WM_NOTIFY = &H4E > >' Custom Draw Messages >Public Const CDDS_PREPAINT& = &H1 >Public Const CDDS_POSTPAINT& = &H2 >Public Const CDDS_PREERASE& = &H3 >Public Const CDDS_POSTERASE& = &H4 >Public Const CDDS_ITEM& = &H10000 >Public Const CDDS_ITEMPREPAINT& = CDDS_ITEM Or CDDS_PREPAINT >Public Const CDDS_ITEMPOSTPAINT& = CDDS_ITEM Or CDDS_POSTPAINT >Public Const CDDS_ITEMPREERASE& = CDDS_ITEM Or CDDS_PREERASE >Public Const CDDS_ITEMPOSTERASE& = CDDS_ITEM Or CDDS_POSTERASE >Public Const CDDS_SUBITEM& = &H20000 > >Public Const CDRF_DODEFAULT& = &H0 >Public Const CDRF_NEWFONT& = &H2 >Public Const CDRF_SKIPDEFAULT& = &H4 >Public Const CDRF_NOTIFYPOSTPAINT& = &H10 >Public Const CDRF_NOTIFYITEMDRAW& = &H20 >Public Const CDRF_NOTIFYSUBITEMDRAW = &H20 'flags are the same, we can >distinguish by context >Public Const CDRF_NOTIFYPOSTERASE& = &H40 >Public Const CDRF_NOTIFYITEMERASE& = &H80 > >Public mlHeaderFont As Long > >Public Declare Function GetCurrentObject Lib "gdi32" _ > (ByVal hdc As Long, ByVal uObjectType As Long) As Long >Public Declare Sub CopyMemory Lib "kernel32" Alias _ > "RtlMoveMemory" (pDest As Any, pSource As Any, ByVal dwLength As Long) >Public Declare Function DeleteObject Lib "gdi32" _ > (ByVal hObject As Long) As Long >Public Declare Function CreateFontIndirect Lib "gdi32" _ > Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long >Public Declare Function SelectObject Lib "gdi32" _ > (ByVal hdc As Long, ByVal hObject As Long) As Long > >Public Declare Function GetObjectAPI Lib "gdi32" Alias _ > "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As >Any) As Long >Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" >_ > (ByVal lpPrevWndFunc As Long, _ > ByVal hWnd As Long, _ > ByVal msg As Long, _ > ByVal wParam As Long, _ > ByVal lParam As Long) As Long > >Public lpPrevWndProc As Long > >Public Function WindowProc(ByVal hWnd As Long, _ > ByVal uMsg As Long, _ > ByVal wParam As Long, _ > ByVal lParam As Long) As Long > Dim i As Integer > Dim hCurrFont As Long > Dim lf As LOGFONT > Dim lColour As Long > Dim hOldFont As Long > Dim tMessage As NMHDR > Dim tTVMessage As NMTVCUSTOMDRAW > Dim lCode As Long > Dim tItem As TV_ITEM > Dim lRet As Long > Form1.Label1.Caption = "HERE" > Select Case msg > Case WM_NOTIFY > CopyMemory tMessage, ByVal lParam, Len(tMessage) > lCode = tMessage.code > Select Case lCode > Case NM_CUSTOMDRAW > If tMessage.hwndFrom <> TreeView1.hWnd Then > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, >uMsg, wParam, lParam) > Exit Function > End If > CopyMemory tTVMessage, ByVal lParam, Len(tTVMessage) > If tTVMessage.nmcmd.dwDrawStage = CDDS_PREPAINT Then > Result = CDRF_NOTIFYITEMDRAW > Exit Function > End If > If tTVMessage.nmcmd.dwDrawStage = CDDS_ITEMPREPAINT Then > CopyMemory tItem, ByVal tTVMessage.nmcmd.lItemLParam, >Len(tItem) > hCurrFont = >GetCurrentObject(tTVMessage.nmcmd.hdc, OBJ_FONT) > lRet = GetObjectAPI(hCurrFont, Len(lf), lf) > If lRet > 0 Then > lf.lfWeight = IIf(CInt(Rnd(1) * 10 < 5), 700, >FW_NORMAL) > lf.lfItalic = (CInt(Rnd(1) * 10) < 5) > lf.lfUnderline = (CInt(Rnd(1) * 10) < 5) ' >False > lf.lfStrikeOut = (CInt(Rnd(1) * 10) < 2) >'False > lRet = DeleteObject(mlHeaderFont) > mlHeaderFont = CreateFontIndirect(lf) > hOldFont = SelectObject(tTVMessage.nmcmd.hdc, >mlHeaderFont) > End If > lColour = RGB(Rnd(1) * 255, Rnd(1) * 255, Rnd(1) * >255) > tTVMessage.clrText = lColour > CopyMemory ByVal lParam, tTVMessage, Len(tTVMessage) > Result = CDRF_NEWFONT > Exit Function > End If > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, >wParam, lParam) > Exit Function > End Select > Case Else > WindowProc = CallWindowProc(lpPrevWndProc, hWnd, uMsg, wParam, >lParam) > End Select >End Function >'****End Module Code**** > > > > > > > > >"alpine" <alpine_don'tsendspam@mvps.org> wrote in message >news:qnial15i1rlnph00veel2p8h6jne1uijel@4ax.com... >>I just ran a test here in both VB5 & 6 and the WM_NOTIFY messages come >> through just fine for the treeview. Are you getting *any* messages >> coming through your windowproc? >> >> HTH, >> Bryan >> _______________________________ >> Bryan Stafford >> New Vision Software >> newvision_don'tspam@mvps.org >> >> >> On Tue, 18 Oct 2005 19:14:32 +0100, "Alastair MacFarlane" >> <anonym***@microsoft.com> wrote: >> >>>Alpine, >>> >>>Once again thanks for the reply. I have now changed the code to subclass >>>the >>>control parent instead as per your and msdn's advice, BUT the WM_NOTIFY >>>message does not get raised. I have declared the messgage handler as on >>>the >>>Form_Load: >>> >>>lpPrevWndProc = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf WindowProc) >>> >>>and WM_NOTIFY is declared as in the module: >>> >>>Public Const WM_NOTIFY = &H4E >>> >>>Is there any property of the form (Form1) that could interfere with the >>>message queue. When I add a breakpoint at the line below the "Case >>>WM_NOTIFY" (which I know you shouldn't), the line "CopyMemory tMessage, >>>ByVal lParam, Len(tMessage)" is never called. >>> >>> Select Case msg >>> Case WM_NOTIFY >>> CopyMemory tMessage, ByVal lParam, Len(tMessage) >>> lCode = tMessage.code >>> Select Case lCode >>> >>>My aim (as discussed in a previous post) is to change the size of specific >>>node fonts. >>> >>>Thanks again for your continued support and I apologise if I seem somewhat >>>dense. >>> >>>Alastair MacFarlane >>> >>> >>>"alpine" <alpine_don'tsendspam@mvps.org> wrote in message >>>news:905al1587bgtet142qpocpign5e0bh9i2h@4ax.com... >>>> You'll need to subclass the treeview's parent window. Have a look at >>>> the WM_NOTIFY topic in the MSDN for further info on this message. >>>> >>>> HTH, >>>> Bryan >>>> _______________________________ >>>> Bryan Stafford >>>> New Vision Software >>>> newvision_don'tspam@mvps.org >>>> >>>> >>>> On Tue, 18 Oct 2005 07:39:05 -0700, "Alastair MacFarlane" >>>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>>> >>>>>Thanks all for your reply. I am running the subclass from the form as >>>>>follows: >>>>> >>>>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>>>WindowProc) >>>>> >>>>>therefore I presume I am subclassing the treeview control itself. >>>>> >>>>>The full code on the form is as follows: >>>>> >>>>>Option Explicit >>>>> >>>>>Private Const GWL_WNDPROC As Long = (-4&) >>>>>Private Declare Function SetWindowLong Lib "user32" Alias >>>>>"SetWindowLongA" >>>>>(ByVal hWnd&, _ >>>>> ByVal nIndex&, ByVal dwNewLong&) As Long >>>>> >>>>>Private Sub Form_Load() >>>>> Dim lCount As Long >>>>> With TreeView1.Nodes >>>>> .Add , , "ROOT", "ROOT" >>>>> For lCount = 1 To 25 >>>>> .Add "ROOT", tvwChild, "C\" & lCount, "Child treeview item >>>>> Number >>>>>" & lCount >>>>> Next >>>>> End With >>>>> lpPrevWndProc = SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, AddressOf >>>>>WindowProc) >>>>>End Sub >>>>> >>>>>Private Sub Form_Unload(Cancel As Integer) >>>>> Call SetWindowLong(TreeView1.hWnd, GWL_WNDPROC, lpPrevWndProc) >>>>>End Sub >>>>> >>>>>Thanks again for your support? >>>>> >>>>>Alastair >>>>> >>>>>"alpine" wrote: >>>>> >>>>>> Are you subclassing the treeview's parent window? >>>>>> >>>>>> HTH, >>>>>> Bryan >>>>>> _______________________________ >>>>>> Bryan Stafford >>>>>> New Vision Software >>>>>> newvision_don'tspam@mvps.org >>>>>> >>>>>> >>>>>> On Tue, 18 Oct 2005 06:29:04 -0700, "Alastair MacFarlane" >>>>>> <AlastairMacFarl***@discussions.microsoft.com> wrote: >>>>>> >>>>>> >Dear All, >>>>>> > >>>>>> >Can somone suggest why I don't receive a WM_NOTIFY message from a >>>>>> >control on >>>> >>> >> > "alpine" <alpine_don'tsendspam@mvps.org> wrote in message ....and every other VB file you create from here on!news:ijnal1pijkp2vllf4ofj08n4l1gpnr6vt9@4ax.com... > Try placing an Option Explicit at the top of your BAS module. ;-) Tools | Options | Editor tab | Require Variable Declaration --> Check it! |
|||||||||||||||||||||||