2010-01-18 62 views
0

我不確定是否有人可以幫助解決這個問題,但我沒有聽說過這段代碼,我不知道這個問題是什麼,也不熟悉WndProc方法。未運行的區域是「檢查自定義繪圖消息」部分。我需要它來運行ProcessListCustomDraw(m)方法,以便生成一些縮略圖。我相信原始應用程序對於.net 1.1來說是必須的,所以我可能是SOL。任何想法或想法將不勝感激。ListView CustomDraw不能在64位平臺上工作

<SecurityPermission(SecurityAction.LinkDemand, Flags:=SecurityPermissionFlag.UnmanagedCode)> _ 
    Protected Overrides Sub WndProc(ByRef m As Message) 
     Try 

      If m.Msg = Win32.Consts.WM_NCPAINT Then 
       ' always repaint background if get wm_ncpaint 
       _backgroundDirty = True 
      End If 

      If m.Msg = Win32.Consts.WM_ERASEBKGND Then 
       ' see if should repaint the background or not 
       If ProcessBackground() = False Then Return 
      End If 

      ' look for messages to owner draw the listview items 
      If m.Msg = Win32.Consts.OCM_NOTIFY Then 
       ' get the notification info 
       Dim notifyHeader As Win32.NMHDR = _ 
       CType(m.GetLParam(GetType(Win32.NMHDR)), Win32.NMHDR) 

       ' turn off background painting when get the item changed message 
       If notifyHeader.code = Win32.Consts.LVN_ITEMCHANGED Then 
        _paintBackground = False 
       End If 

       ' check for custom draw message 
       If notifyHeader.hwndFrom.Equals(Me.Handle) And _ 
       notifyHeader.code = Win32.Consts.NM_CUSTOMDRAW Then 
        _paintBackground = True 

        ' process the message, returns true if performed custom 
        ' drawing, otherwise false 
        If ProcessListCustomDraw(m) Then 
         Return 
        End If 
       End If 
      End If 

      MyBase.WndProc(m) 

     Catch ex As Exception 

      Log.WriteLog(Log.SZ_LOG_EXCEPTION & MethodBase.GetCurrentMethod().Name & " " & ex.Message) 

     End Try 

    End Sub 

' one step closer to detecting if a listview item should be drawn 
    ' return true if the listview item was drawn 
    Private Function ProcessListCustomDraw(ByRef m As Message) As Boolean 
     Try 
      ' return true if performed custom drawing 
      Dim drawSelf As Boolean = False 

      ' get custom draw information 
      Dim customDraw As Win32.NMCUSTOMDRAW = _ 
      CType(m.GetLParam(GetType(Win32.NMCUSTOMDRAW)), Win32.NMCUSTOMDRAW) 

      ' return different values in the message depending on the draw stage 
      Select Case customDraw.dwDrawStage 
       Case Win32.Consts.CDDS_PREPAINT 
        m.Result = New System.IntPtr(Win32.Consts.CDRF_NOTIFYITEMDRAW) 

       Case Win32.Consts.CDDS_ITEMPREPAINT 
        m.Result = New System.IntPtr(Win32.Consts.CDRF_SKIPDEFAULT) 

        If IsItemVisible(customDraw.dwItemSpec) Then 
         ' finally, draw the listview item 
         Dim g As Graphics = Graphics.FromHdc(customDraw.hdc) 
         Try 
          DrawItemEg(g, CInt(customDraw.dwItemSpec)) 
          drawSelf = True 
         Finally 
          g.Dispose() 
         End Try 
        Else 
         drawSelf = True 
        End If 

       Case Else 
        m.Result = New System.IntPtr(Win32.Consts.CDRF_DODEFAULT) 
      End Select 


      Return drawSelf 

     Catch ex As Exception 

      Log.WriteLog(Log.SZ_LOG_EXCEPTION & MethodBase.GetCurrentMethod().Name & " " & ex.Message) 

     End Try 

    End Function 

更新:這裏是Win32類:

' win32 values 
Private Class Win32 
    Public Enum Consts 
     ' messages 
     WM_NCPAINT = &H85 
     WM_ERASEBKGND = &H14 
     WM_NOTIFY = &H4E 
     OCM_BASE = &H2000 
     OCM_NOTIFY = OCM_BASE + WM_NOTIFY 
     NM_CUSTOMDRAW = -12 
     NM_SETFOCUS = -7 
     LVN_ITEMCHANGED = -101 

     ' custom draw return flags 
     CDRF_DODEFAULT = &H0 
     CDRF_SKIPDEFAULT = &H4 
     CDRF_NOTIFYITEMDRAW = &H20 

     ' custom draw state flags 
     CDDS_PREPAINT = &H1 
     CDDS_ITEM = &H10000 
     CDDS_ITEMPREPAINT = CDDS_ITEM Or CDDS_PREPAINT 
    End Enum 

    <StructLayout(LayoutKind.Sequential)> _ 
    Public Structure NMHDR 
     Public hwndFrom As IntPtr 
     Public idFrom As Integer 
     Public code As Integer 
    End Structure 

    <StructLayout(LayoutKind.Sequential)> _ 
    Public Structure RECT 
     Public left As Integer 
     Public top As Integer 
     Public right As Integer 
     Public bottom As Integer 
    End Structure 

    <StructLayout(LayoutKind.Sequential)> _ 
    Public Structure NMCUSTOMDRAW 
     Public hdr As NMHDR 
     Public dwDrawStage As Integer 
     Public hdc As IntPtr 
     Public rc As RECT 
     Public dwItemSpec As Integer 
     Public uItemState As Integer 
     Public lItemlParam As IntPtr 
    End Structure 
End Class 

回答

3

如果它工作在x86那麼你的的P/Invoke聲明可能錯了。使用Integer需要IntPtr,類似的東西。你沒有發佈他們,我不知道。訪問pinvoke.net以獲得正確的。


看到您的編輯後:是的,您的NMHDR聲明是錯誤的。它看起來像這樣:

<StructLayout(LayoutKind.Sequential)> _ 
Public Structure NMHDR 
    Public hwndFrom As IntPtr 
    Public idFrom As IntPtr    ' NOT INTEGER!!! 
    Public code As Integer 
End Structure 
+0

你是什麼意思?看到,ProcessListCustomDraw永遠不會被調用。行:「如果notifyHeader.hwndFrom.Equals(Me.Handle)和_ notifyHeader.code = Win32.Consts.NM_CUSTOMDRAW然後」.. notifyHeader.code始終爲0,而​​Win32.Consts.NM_CUSTOMDRAW爲-12。 – DDiVita 2010-01-19 02:51:52

+0

是的,您的NMHDR聲明可能是錯誤的。 idFrom字段是IntPtr,而不是整數。 – 2010-01-19 10:06:52

+0

我更新了文章,以便您可以看到Win32類。 – DDiVita 2010-01-19 15:13:17