欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

重写Notification有感~~

发布时间:2025/6/17 编程问答 44 豆豆
生活随笔 收集整理的这篇文章主要介绍了 重写Notification有感~~ 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
为了给程序添加一个Balloon Notification又不使用opennetcf,就花了几个小时功夫把opennetcf里面有关Notification类的c#程序提取出来整理了,最终翻译成了VB.net,感触颇深。本人才疏学浅,就写写自己的一些感受吧~~
1、vb.net与c#之间还是有一定的差异,对于大段的程序用c# to vb.net Convertor程序反而起不到好大的效果,却会使程序变得混乱。建议小段程序使用Convertor,自己整理代码。
2、vb.net里面直接声明public event eventName(byval Param1 as object,...) 这样比用c#的委托那样搞过去搞过来写一大堆代码方便。我就郁闷c#里面没有看到过类似的用法呢?是不是c#不支持这样的语法哦~~声明:我对c#不是很熟悉哈~~~
3、Platform Invoke看起来比较复杂,但是做起来还是简单。只要理解了如何把各个变量的指针找到很多事情就好办了。Opennetcf里面又很多关于P/Invoke的例子,可以借鉴学习。
例如关于如何提取图标的例子(vb.net):
 
Private Declare Function ExtractIconEx()Function ExtractIconEx Lib "coredll.dll" (ByVal fileName As StringByVal index As IntegerByVal hIconLarge As IntegerByRef hIconSmall As IntPtr, ByVal nIcons As IntegerAs IntPtr
private mIcon as Intptr

ExtractIconEx(fullname, 
00, mIcon, 1)
4、Opennetcf太大了,直接用不太好。如果需要其中很小一块功能而给客户安装一个新的类库有些浪费了,可以通过代码重写来达到要求。有些东西可以找替换的。比如在.net cf没有guid.newGuid方法,虽然opennetcf里面有GuidEx类,但如果层层深入翻译成vb.net代码会遇到很多问题。最为严重的就是c#里面的移位操作所带来的麻烦。这是,变通一下,找到了微软的MSDN里面的PocketGuid解决了这个问题(见下)
介绍文章请见:http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/PPCGuidGen.asp
Imports System.Runtime.InteropServices

'
'
 Generate GUIDs on  the  .NET Compact Framework.
'
Public Class PocketGuidClass PocketGuid

    
' guid variant types
    Private Enum GuidVariantEnum GuidVariant
        ReservedNCS 
= &H0
        Standard 
= &H2
        ReservedMicrosoft 
= &H6
        ReservedFuture 
= &H7
    
End Enum


    
' guid version types
    Private Enum GuidVersionEnum GuidVersion
        TimeBased 
= &H1
        Reserved 
= &H2
        NameBased 
= &H3
        Random 
= &H4
    
End Enum


    
' constants  that are used in the class
    Private Class ConstValuesClass ConstValues
        
' number of  bytes in guid
        Public Const ByteArraySize As Integer = 16

        
' multiplex  variant  info
        Public Const VariantByte As Integer = 8
        
Public Const VariantByteMask As Integer = &H3F
        
Public Const VariantByteShift As Integer = 6

        
' multiplex  version  info
        Public Const VersionByte As Integer = 7
        
Public Const VersionByteMask As Integer = &HF
        
Public Const VersionByteShift As Integer = 4
    
End Class


    
' imports for the crypto api functions
    Private Class WinApiClass WinApi
        
Public Const PROV_RSA_FULL As Integer = 1
        
Public Const CRYPT_VERIFYCONTEXT As Integer = &HF0000000

        
<DllImport("coredll.dll")> _
        
Public Shared Function CryptAcquireContext()Function CryptAcquireContext( _
           
ByRef phProv As IntPtr, ByVal pszContainer As String, _
           
ByVal pszProvider As StringByVal dwProvType As Integer, _
           
ByVal dwFlags As IntegerAs Boolean
        
End Function


        
<DllImport("coredll.dll")> _
        
Public Shared Function CryptReleaseContext()Function CryptReleaseContext( _
           
ByVal hProv As IntPtr, ByVal dwFlags As IntegerAs Boolean
        
End Function


        
<DllImport("coredll.dll")> _
        
Public Shared Function CryptGenRandom()Function CryptGenRandom( _
           
ByVal hProv As IntPtr, ByVal dwLen As Integer, _
           
ByVal pbBuffer() As ByteAs Boolean
        
End Function

    
End Class


    
' all static methods
    Private Sub New()Sub New()
    
End Sub


    
' Return a new System.Guid object.
    Public Shared Function NewGuid()Function NewGuid() As Guid
        
Dim hCryptProv As IntPtr = IntPtr.Zero
        
Dim guid As Guid = guid.Empty

        
Try
            
' holds  random bits  for  guid
            Dim bits(ConstValues.ByteArraySize - 1As Byte

            
' get crypto provider handle
            If Not WinApi.CryptAcquireContext(hCryptProv, NothingNothing, _
               WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT) 
Then
                
Throw New SystemException( _
                   
"Failed  to acquire cryptography  handle.")
            
End If

            
' generate a 128 bit (16 byte) cryptographically random  number
            If Not WinApi.CryptGenRandom(hCryptProv, bits.Length, bits) Then
                
Throw New SystemException( _
                   
"Failed  to generate  cryptography random  bytes.")
            
End If

            
' set the variant
            bits(ConstValues.VariantByte) = bits(ConstValues.VariantByte) And _
               
CByte(ConstValues.VariantByteMask)
            bits(ConstValues.VariantByte) 
= bits(ConstValues.VariantByte) Or _
               
CByte(GuidVariant.Standard << ConstValues.VariantByteShift)

            
' set the version
            bits(ConstValues.VersionByte) = bits(ConstValues.VersionByte) And _
               
CByte(ConstValues.VersionByteMask)
            bits(ConstValues.VersionByte) 
= bits(ConstValues.VersionByte) Or _
               
CByte(GuidVersion.Random << ConstValues.VersionByteShift)

            
' create the new System.Guid object
            guid = New Guid(bits)
        
Finally
            
' release the crypto provider handle
            If Not hCryptProv.Equals(IntPtr.Zero) Then
                WinApi.CryptReleaseContext(hCryptProv, 
0)
            
End If
        
End Try

        
Return guid
    
End Function

End Class


如果想直接应用opennetcf里面的guidex类的话vb.net会花费很大的功夫来改写,具体可以看看opennetcf的源代码。
6、最后一个:想得到,就做得到!

好了,睡觉了~~~很晚了,最后把我翻译的代码贴在这里供大家参考评价,有些c#的我不太明确的都已用#######注释标明。
Imports System.Runtime.InteropServices
Namespace PocketBallonNamespace PocketBallon
    
Public Class NotificationClass Notification
        
Private WithEvents msgwnd As NotificationMessageWindow
        
Private Shared notifications As Hashtable
        
Private Shared id As Integer
        
Private Shared clsid As Guid = PocketGuid.NewGuid

        
Private m_data As SHNOTIFICATIONDATA
        
Private Structure SHNOTIFICATIONDATAStructure SHNOTIFICATIONDATA
            
Public cbStruct As Integer
            
Public dwId As Integer
            
Public npPriority As SHNP
            
Public Enum SHNPEnum SHNP As Integer
                INFORM 
= &H1B1
                ICONIC 
= 0
            
End Enum

            
Public csDuration As Integer
            
Public hicon As IntPtr
            
Public grfFlags As SHNF
            
Public Enum SHNFEnum SHNF As Integer
                STRAIGHTTOTRAY 
= &H1
                CRITICAL 
= &H2
                FORCEMESSAGE 
= &H8
                DISPLAYON 
= &H10
                SILENT 
= &H20
            
End Enum

            
Public clsid As Guid
            
Public hwndSink As IntPtr
            
Public pszHTML As IntPtr
            
Public pszTitle As IntPtr
            
Public lParam As Integer
        
End Structure


        
Private mIcon As IntPtr
        
Private mDuration As Integer = 10
        
Private mText As String = String.Empty
        
Private mCaption As String = String.Empty
        
Private mCritical As Boolean = False
        
Private mVisible As Boolean = False

Properties#Region "Properties"
        
Public Property Caption()Property Caption() As String
            
Get
                
Return mCaption
            
End Get
            
Set(ByVal value As String)
                mCaption 
= value
            
End Set
        
End Property


        
Public Property Critical()Property Critical() As Boolean
            
Get
                
Return mCritical
            
End Get
            
Set(ByVal value As Boolean)
                mCritical 
= value
            
End Set
        
End Property


        
Public Property IconHandle()Property IconHandle() As IntPtr
            
Get
                
Return mIcon
            
End Get
            
Set(ByVal value As IntPtr)
                mIcon 
= value
            
End Set
        
End Property


        
Public Property InitialDuration()Property InitialDuration() As Integer
            
Get
                
Return mDuration
            
End Get
            
Set(ByVal value As Integer)
                mDuration 
= value
            
End Set
        
End Property


        
Public Property Text()Property Text() As String
            
Get
                
Return mText
            
End Get
            
Set(ByVal value As String)
                mText 
= value
            
End Set
        
End Property


        
Public Property Visiable()Property Visiable() As Boolean
            
Get
                
Return mVisible
            
End Get
            
Set(ByVal value As Boolean)
                mVisible 
= value
                
If value = True Then
                    Show()
                
Else
                    Remove()
                
End If
            
End Set
        
End Property

#End Region


        
'#Region "events"
        '        'Code here are probably not be well written.

        
'        Public Event BalloonChanged As BalloonChangedEventHandler
        '        Public Delegate Sub BalloonChangedEventHandler(ByVal sender As Object, ByVal balevent As BalloonChangedEventArgs)
        '        Public Class BalloonChangedEventArgs
        '            Inherits EventArgs
        '            Private m_visible As Boolean

        
'            Public Sub New(ByVal visible As Boolean)
        '                m_visible = visible
        '            End Sub

        
'            Public ReadOnly Property Visible() As Boolean
        '                Get
        '                    Return m_visible
        '                End Get
        '            End Property
        '        End Class
        '        Friend Sub OnBalloonChanged(ByVal e As BalloonChangedEventArgs)
        '            mVisible = e.Visible
        '            '#####################################
        '            'C# code:
        '            '            if(this.BalloonChanged!=null)
        '            '    {
        '            '        this.BalloonChanged(this, e);
        '            '    }
        '            '#####################################
        '            RaiseEvent BalloonChanged(Me, e)
        '        End Sub

        
'        Public Class ResponseSubmittedEventArgs
        '            Inherits EventArgs
        '            Private m_response As String
        '            Public Sub New(ByVal response As String)
        '                m_response = response
        '            End Sub
        '            Public ReadOnly Property Response() As String
        '                Get
        '                    Return m_response
        '                End Get
        '            End Property
        '        End Class
        '        Public Delegate Sub ResponseSubmittedEventHandler(ByVal sender As Object, ByVal respevent As ResponseSubmittedEventArgs)
        '        Public Event ResponseSubmitted As ResponseSubmittedEventHandler
        '        Friend Sub OnResponseSubmitted(ByVal e As ResponseSubmittedEventArgs)
        '            RaiseEvent ResponseSubmitted(Me, e)
        '        End Sub

        
'        Public Class CmdClickedEventArgs
        '            Inherits EventArgs
        '            Private m_response As String
        '            Private m_ID As Integer
        '            Public Sub New(ByVal m_ID As Integer, ByVal cmd As String)
        '                m_response = cmd
        '            End Sub
        '            Public ReadOnly Property Cmd() As String
        '                Get
        '                    Return m_response
        '                End Get
        '            End Property

        
'            Public ReadOnly Property ID() As Integer
        '                Get
        '                    Return m_ID
        '                End Get
        '            End Property
        '        End Class
        '        Public Delegate Sub CmdClickedEventHandler(ByVal sender As Object, ByVal respevent As CmdClickedEventArgs)
        '        Public Event CmdClicked As CmdClickedEventHandler
        '        Friend Sub OnCmdClicked(ByVal e As CmdClickedEventArgs)
        '            RaiseEvent CmdClicked(Me, e)
        '        End Sub

        
'#End Region
        Public Event CmdClicked(ByVal cmd As Integer)
        
Public Event LinkClicked(ByVal link As String)
        
Private Sub OnClicked()Sub OnClicked(ByVal cmd As IntegerHandles msgwnd.CmdClicked
            
RaiseEvent CmdClicked(cmd)
        
End Sub

        
Private Sub OnLinkClicked()Sub OnLinkClicked(ByVal link As StringHandles msgwnd.LinkClicked
            
RaiseEvent LinkClicked(link)
        
End Sub


        
Public Sub New()Sub New()
            notifications 
= New Hashtable()
            msgwnd 
= New NotificationMessageWindow(notifications)
            
Dim fullname As String = System.Reflection.Assembly.GetCallingAssembly.GetModules()(0).FullyQualifiedName
            ExtractIconEx(fullname, 
00, mIcon, 1)

            m_data 
= New SHNOTIFICATIONDATA
            
With m_data
                .clsid 
= clsid
                .hwndSink 
= msgwnd.Hwnd
                .dwId 
= id
                .cbStruct 
= Marshal.SizeOf(m_data)
            
End With
            notifications.Add(id, 
Me)
            id 
+= 1
        
End Sub


        
Protected Sub Dispose()Sub Dispose(ByVal disposing As Boolean)
            Visiable 
= False
            notifications.Remove(m_data.dwId)
        
End Sub


        
Private Sub Show()Sub Show()
            
With m_data
                .pszHTML 
= StringToHGlobalUni(mText)
                .pszTitle 
= StringToHGlobalUni(mCaption)
                .hicon 
= mIcon
                .csDuration 
= mDuration
                
If mDuration = 0 Then
                    .npPriority 
= SHNOTIFICATIONDATA.SHNP.ICONIC
                
Else
                    .npPriority 
= SHNOTIFICATIONDATA.SHNP.INFORM
                
End If

                
'C# code here !!!!!!!!!
                '##########################################
                '            if(mCritical)
                '{
                '    m_data.grfFlags |= SHNF.CRITICAL;
                '}
                'else
                '{
                '    m_data.grfFlags ^= (m_data.grfFlags & SHNF.CRITICAL);
                '}
                '###########################################

                
If mCritical Then
                    .grfFlags 
= .grfFlags Or SHNOTIFICATIONDATA.SHNF.CRITICAL
                
Else
                    .grfFlags 
= .grfFlags Or (.grfFlags And SHNOTIFICATIONDATA.SHNF.CRITICAL)
                
End If

                
Dim hresult As Integer = SHNotificationAdd(m_data)
                
If (.pszTitle.ToInt32 <> IntPtr.Zero.ToInt32) Then
                    LocalFree(.pszTitle)
                    .pszTitle 
= IntPtr.Zero
                
End If
                
If (.pszHTML.ToInt32 <> IntPtr.Zero.ToInt32) Then
                    LocalFree(.pszHTML)
                    .pszHTML 
= IntPtr.Zero
                
End If
            
End With
        
End Sub


        
Private Sub Remove()Sub Remove()
            
Dim hresult As Integer = SHNotificationRemove(clsid, m_data.dwId)
        
End Sub


        
Private Function StringToHGlobalUni()Function StringToHGlobalUni(ByVal s As StringAs IntPtr
            
Dim LPTR As Integer = &H0 Or &H40
            
If s Is Nothing Then Return IntPtr.Zero
            
Dim i As Integer = (s.Length + 1* System.Text.UnicodeEncoding.CharSize
            
Dim ptr As IntPtr = LocalAlloc(LPTR, i)
            
'Dim ptr As IntPtr = LocalAlloc(CUInt(LPTR), CUInt(i))
            Dim data As Byte() = System.Text.Encoding.Unicode.GetBytes(s)
            Marshal.Copy(data, 
0, ptr, data.Length)
            
Return ptr
        
End Function


        
Private Declare Function ExtractIconEx()Function ExtractIconEx Lib "coredll.dll" (ByVal fileName As StringByVal index As IntegerByVal hIconLarge As IntegerByRef hIconSmall As IntPtr, ByVal nIcons As IntegerAs IntPtr
        
Private Declare Function LocalAlloc()Function LocalAlloc Lib "coredll.dll" (ByVal uFlags As IntegerByVal Bytes As IntegerAs IntPtr
        
Private Declare Function LocalFree()Function LocalFree Lib "coredll.dll" (ByVal hMem As IntPtr) As IntPtr
        
<DllImport("aygshell.dll", EntryPoint:="#155", SetLastError:=True)> _
        
Private Shared Function SHNotificationAdd()Function SHNotificationAdd(ByRef shinfo As SHNOTIFICATIONDATA) As Integer
        
End Function


        
<DllImport("aygshell.dll", EntryPoint:="#157", SetLastError:=True)> _
        
Private Shared Function SHNotificationRemove()Function SHNotificationRemove(ByRef clsid As Guid, ByVal dwID As IntegerAs Integer
        
End Function

    
End Class

End Namespace

Imports System.Runtime.InteropServices
Imports Microsoft.WindowsCE
Namespace PocketBallonNamespace PocketBallon
    
Friend Class NotificationMessageWindowClass NotificationMessageWindow
        
Inherits Microsoft.WindowsCE.Forms.MessageWindow
        
Private m_notifications As Hashtable
        
Public Event BallonChanged(ByVal visible As Boolean)
        
Public Event CmdClicked(ByVal cmd As Integer)
        
Public Event LinkClicked(ByVal link As String)

        
Sub New()Sub New(ByVal notifications As Hashtable)
            m_notifications 
= notifications
        
End Sub

        
Protected Overrides Sub WndProc()Sub WndProc(ByRef m As Message)
            
Select Case m.Msg
                
Case 78
                    
Dim nm As NMSHN = CType(Marshal.PtrToStructure(m.LParam, GetType(NMSHN)), NMSHN)
                    
Dim n As Notification = CType(m_notifications(nm.idFrom), Notification)
                    
Select Case nm.code
                        
Case NMSHN.SHNN.DISMISS
                            
RaiseEvent BallonChanged(True)
                            
'n.OnBalloonChanged(New PocketBallon.Notification.BalloonChangedEventArgs(False))
                        Case NMSHN.SHNN.SHOW
                            
RaiseEvent BallonChanged(False)
                            
'n.OnBalloonChanged(New PocketBallon.Notification.BalloonChangedEventArgs(True))
                        Case NMSHN.SHNN.LINKSEL
                            
Dim link As String = Marshal.PtrToStringUni(New IntPtr(nm.union1))
                            
RaiseEvent LinkClicked(link)
                            
'n.OnResponseSubmitted(New PocketBallon.Notification.ResponseSubmittedEventArgs(link))
                    End Select
                
Case &H111
                    
'Dim nm As NMSHN = CType(Marshal.PtrToStructure(lastLParam, GetType(NMSHN)), NMSHN)
                    'Dim n As Notification = CType(m_notifications(nm.idFrom), Notification)
                    'n.OnCmdClicked(New PocketBallon.Notification.CmdClickedEventArgs(1, "1"))
                    RaiseEvent CmdClicked(m.WParam.ToInt32)
            
End Select
            
MyBase.WndProc(m)
        
End Sub


        
Private Structure NMSHNStructure NMSHN
            
Public hwndFrom As IntPtr
            
Public idFrom As Integer
            
Public code As SHNN
            
Public Enum SHNNEnum SHNN As Integer
                LINKSEL 
= -1000
                DISMISS 
= -1001
                SHOW 
= -1002
            
End Enum

            
Public lParam As Integer
            
Public dwReturn As Integer
            
Public union1 As Integer
            
Public union2 As Integer
        
End Structure



    
End Class

End Namespace

转载于:https://www.cnblogs.com/hesicong/archive/2005/08/08/209605.html

《新程序员》:云原生和全面数字化实践50位技术专家共同创作,文字、视频、音频交互阅读

总结

以上是生活随笔为你收集整理的重写Notification有感~~的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。