Re: System tray balloon tips

Tech-Archive recommends: Fix windows errors by optimizing your registry

From: MikeD (nobody_at_nowhere.edu)
Date: 06/18/04


Date: Thu, 17 Jun 2004 20:15:14 -0400


"Lindsay" <lindsay@home.com> wrote in message
news:_UTzc.15727$NK4.2580905@stones.force9.net...
> I'm using the shell_notifyicon API in VB6:
>
> Private Type NOTIFYICONDATA
> cbSize As Long
> hwnd As Long
> uID As Long
> uFlags As Long
> uCallbackMessage As Long
> hIcon As Long
> szTip As String * 128
> dwState As Long
> dwStateMask As Long
> szInfo As String * 256
> uTimeOutOrVersion As Long
> szInfoTitle As String * 64
> dwInfoFlags As Long
> guidItem As GUID
> End Type
>
> ...but have 2 questions.
> 1- How does the uTimeOutOrVersion work? I would like the tooltip to
> disappear after a while.
>

I'm guessing your confusion comes from that fact that in the C definition of
the structure, uTimeOutOrVersion is actually a union of two unsigned
integers. VB doesn't support unions so these two unsigned integers must be
combined into a Long. However, I don't think there could ever be a time when
you'd need (or even could) specify both. Therefore, it's really not an
issue. You would only specify a Version value when you send the NIM_VERSION
message for Shell_NotifyIcon. You would only specify a TimeOut value when
sending a NIM_MODIFY or NIM_ADD message to Shell_NotifyIcon. IOW, the two
are mutually exclusive. To specify the timout value, just assign the number
of milliseconds to uTimeOutOrVersion (and set value for other members of
this structure as appropriate) and then call Shell_NotifyIcon (sending
NIM_MODIFY or NIM_ADD).

> 2. Using this structure, will it work on versions of Windows prior to XP?
I
> understand there is one version that works on ME or better.

Different versions of Windows support different versions of this structure.
This is why one of the members of this structure is its size. You can define
the structure once and use that UDT for all versions of Windows. But you
need to determine the version of Windows under which the app is running in
order to specify the correct value for the cbSize member of the structure.
Unfortunately, this has gotten a little complicated because the structure
has changed a couple times with different versions of Windows. dwState to
dwInfoFlags are only supported under Windows 2000 and later (actually,
version 5 or later of shell32.dll). guidItem is only supported under
Windows XP (and it's reserved, meaning it's not even currently used under
WinXP; one can only guess that a future version of Windows after XP [or an
SP to WinXP] will use it). Also, under Win2000 and greater, szTip can be
128 bytes (or characters). Under Win95/98, szTip can only be 64 bytes. MS
really made this structure a little confusing.

Anyway, as I said, you need to determine the version of Windows and then
specify the proper structure size. Here's some multiple fragments of code to
get you started on that.

Public Type NOTIFYICONDATA
    cbSize As Long
    hWnd As Long
    uID As Long
    uFlags As Long
    uCallbackMessage As Long
    hIcon As Long
    szTip As String * 128
    dwState As Long
    dwStateMask As Long
    szInfo As String * 256
    'We have to take some liberties because VB doesn't support unions.
    'We must therefore combine uTimeOut and uVersion into one element
    'of the structure. This will work out fine, however, because the
    'only time uVersion would be assigned is when sending the NIM_SETVERSION
    'message, and for that message, you would not assign a value for
uTimeOut.
    'IOW, uTimeOut and uVersion are used exclusively of one another.
    uTimeOutAndVersion As Long
    szInfoTitle As String * 64
    dwInfoFlags As Long
    guidItem As GUID 'WinXP only
End Type

Public Const NOTIFYICONDATA_V1_SIZE As Long = 88 'this includes elements
thru szTip with that being 64 chars
Public Const NOTIFYICONDATA_V2_SIZE As Long = 488 'this includes all
elements except guidItem.

Private m_nid As NOTIFYICONDATA

    With m_nid
        'We need to determine which "version" of the NOTIFYICONDATA
        'structure to use. This depends on the version of Shell32.dll
        Select Case g_lShell32Ver
            Case Is < 500
                .cbSize = NOTIFYICONDATA_V1_SIZE
                .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP ' Or NIF_INFO
Or NIF_STATE Or NIF_GUID
            Case Is < 600
                .cbSize = NOTIFYICONDATA_V2_SIZE
                .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP Or NIF_INFO Or
NIF_STATE 'Or NIF_GUID
            Case Is >= 600
                .cbSize = Len(m_nid)
                .uFlags = NIF_MESSAGE Or NIF_ICON Or NIF_TIP Or NIF_INFO Or
NIF_STATE Or NIF_GUID
        End Select
        .uCallbackMessage = WM_NOTIFYICON

    End With

Private Type DLLVERSIONINFO
    cbSize As Long
    dwMajor As Long
    dwMinor As Long
    dwBuildNumber As Long
    dwPlatformID As Long
End Type

Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA"
(ByVal lpLibFileName As String) As Long
Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As
Long) As Long
Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As
Long, ByVal lpProcName As String) As Long
Private Declare Function DllGetVersion Lib "Shell32" (pdvi As
DLLVERSIONINFO) As Long

Public Function GetShell32Version() As Long

    Dim hModule As Long
    Dim lDllGetVersionAddress As Long
    Dim dvi As DLLVERSIONINFO
    Dim lRet As Long

    hModule = LoadLibrary("shell32.dll")

    If hModule Then
        'See if the DllGetVersion function is exported by shell32.dll
        lDllGetVersionAddress = GetProcAddress(hModule, "DllGetVersion")
        If lDllGetVersionAddress = 0 Then
            'The function is not exported which means the version
            'of shell32.dll is earlier than 4.71
            GetShell32Version = 400
        Else
            'It is, so let's get the version of it
            With dvi
                .cbSize = Len(dvi)
                lRet = DllGetVersion(dvi)
                If lRet = 0 Then
                    GetShell32Version = (.dwMajor * 100) + (.dwMinor)
                End If
            End With
        End If

        'Make sure we free the library
        FreeLibrary hModule

    End If

End Function

    g_lShell32Ver = GetShell32Version

REMEMBER, the above code is bits and pieces. I mentioned determining the
version of Windows. It's really better to determine the version of
shell32.dll. What the above fragments of code actually do is determine the
version of shell32.dll and then asssigns a value to cbSize based on the
version of shell32.dll. The version of shell32.dll can usually be
associated to a particular version of Windows, but that's not always the
case, so it's better to check the version of shell32.dll. More work is
involved, but it's safer.

Mike



Relevant Pages

  • Re: How to stop Stephen Bullens CFormChanger from minimizing as an MDI title bar?
    ... always minimizes to a little title bar in the L.R. corner of the ... screen *above* the Windows Taskbar ... Private Declare Function GetWindowLong Lib "user32" Alias _ ...
    (microsoft.public.excel.programming)
  • Re: Problem adding win2k client to SBS domain
    ... deselecting the 'mark private' check mark. ... On the client computer, quit the Windows Small Business Server Network ... files in the temporary folder of the affected user's profile. ...
    (microsoft.public.windows.server.sbs)
  • Re: Getting Notification of Moving of Form
    ... LocationChanged event of the parent form. ... Find great Windows Forms articles in Windows Forms Tips and Tricks ... private System.Windows.Forms.Label label1; ... Control topControl=this.Parent; ...
    (microsoft.public.dotnet.framework.windowsforms)
  • Memory Leak Issue
    ... MFC, COM dll, COM ocx, COM server, Windows static lib and windows dynamic ... It is also showing some of the memory leak in the MFC dlls. ... We are measuring the Private bytes for the application using Sysinternals ...
    (microsoft.public.vc.debugger)
  • Memory Leak issue
    ... MFC, COM dll, COM ocx, COM server, Windows static lib and windows dynamic ... It is also showing some of the memory leak in the MFC dlls. ... We are measuring the Private bytes for the application using Sysinternals ...
    (microsoft.public.vc.mfc)