How to use the API:SHChangeNotify?

The MSDN says:

Notifies the system of an event that an application has performed. An application should use this function if it performs an action that may affect the Shell.

VOID SHChangeNotify(
    LONG wEventId,
    UINT uFlags,
    LPCVOID dwItem1,
    LPCVOID dwItem2

Describes the event that has occurred. Typically, only one event is specified at a time. If more than one event is specified, the values contained in the dwItem1 and dwItem2 parameters must be the same, respectively, for all specified events. This parameter can be one or more of the following values: SHCNE_ALLEVENTS  All events have occurred.  

But who can give me a example?
I want to Notify the system systemimage updated,but I don't know what can we set the value of dwItem1 and dwItem2.
Who is Participating?

Improve company productivity with a Business Account.Sign Up

MonkeyLinAuthor Commented:
Thank you,hes.
I have seen the example before,but I still can't understand it.
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Richie_SimonettiIT OperationsCommented:
In vb, that function looks so:

Declare Sub SHChangeNotify Lib "shell32" _
                        (ByVal wEventId As SHCN_EventIDs, _
                        ByVal uFlags As , _
                        ByVal dwItem1 As Long, _
                        ByVal dwItem2 As Long)

You need two structs (types for us) to pass the first two parameters:
Public Enum SHCN_EventIDs
  SHCNE_RENAMEITEM = &H1      ' (D) A nonfolder item has been renamed.
  SHCNE_CREATE = &H2                ' (D) A nonfolder item has been created.
  SHCNE_DELETE = &H4                ' (D) A nonfolder item has been deleted.
  SHCNE_MKDIR = &H8                  ' (D) A folder item has been created.
  SHCNE_RMDIR = &H10                ' (D) A folder item has been removed.
  SHCNE_MEDIAINSERTED = &H20     ' (G) Storage media has been inserted into a drive.
  SHCNE_MEDIAREMOVED = &H40      ' (G) Storage media has been removed from a drive.
  SHCNE_DRIVEREMOVED = &H80      ' (G) A drive has been removed.
  SHCNE_DRIVEADD = &H100              ' (G) A drive has been added.
  SHCNE_NETSHARE = &H200             ' A folder on the local computer is being shared via the network.
  SHCNE_NETUNSHARE = &H400        ' A folder on the local computer is no longer being shared via the network.
  SHCNE_ATTRIBUTES = &H800           ' (D) The attributes of an item or folder have changed.
  SHCNE_UPDATEDIR = &H1000          ' (D) The contents of an existing folder have changed, but the folder still exists and has not been renamed.
  SHCNE_UPDATEITEM = &H2000                  ' (D) An existing nonfolder item has changed, but the item still exists and has not been renamed.
  SHCNE_SERVERDISCONNECT = &H4000   ' The computer has disconnected from a server.
  SHCNE_UPDATEIMAGE = &H8000&              ' (G) An image in the system image list has changed.
  SHCNE_DRIVEADDGUI = &H10000               ' (G) A drive has been added and the shell should create a new window for the drive.
  SHCNE_RENAMEFOLDER = &H20000          ' (D) The name of a folder has changed.
  SHCNE_FREESPACE = &H40000                   ' (G) The amount of free space on a drive has changed.

#If (WIN32_IE >= &H400) Then
  ' (G) SHCNE_EXTENDED_EVENT:  the extended event is identified in dwItem1,
  ' packed in LPITEMIDLIST format (same as SHCNF_DWORD packing).
  ' Unlike the standard events, the extended events are ORDINALs, so we
  ' don't run out of bits.  Extended events follow the SHCNEE_* naming
  ' convention.
  ' The dwItem2 parameter varies according to the extended event.
#End If     ' WIN32_IE >= &H0400

  SHCNE_ASSOCCHANGED = &H8000000       ' (G) A file type association has changed.

  SHCNE_DISKEVENTS = &H2381F                  ' Specifies a combination of all of the disk event identifiers. (D)
  SHCNE_GLOBALEVENTS = &HC0581E0        ' Specifies a combination of all of the global event identifiers. (G)
  SHCNE_INTERRUPT = &H80000000              ' The specified event occurred as a result of a system interrupt.
                                                                            ' It is stripped out before the clients of SHCNNotify_ see it.
End Enum

' Notification flags

' uFlags & SHCNF_TYPE is an ID which indicates what dwItem1 and dwItem2 mean
Public Enum SHCN_ItemFlags
  SHCNF_IDLIST = &H0                ' LPITEMIDLIST
  SHCNF_PATHA = &H1               ' path name
  SHCNF_PRINTERA = &H2         ' printer friendly name
  SHCNF_DWORD = &H3             ' DWORD
  SHCNF_PATHW = &H5              ' path name
  SHCNF_PRINTERW = &H6        ' printer friendly name
  ' Flushes the system event buffer. The function does not return until the system is
  ' finished processing the given event.
  SHCNF_FLUSH = &H1000
  ' Flushes the system event buffer. The function returns immediately regardless of
  ' whether the system is finished processing the given event.

#End If

End Enum

The code was extracted from as hes commented.
Richie_SimonettiIT OperationsCommented:
By the way, it the zip file that comes with that article there is usage and explanation of this function.
Good Luck.
MonkeyLinAuthor Commented:
I want to know, in this case what is the value of dwItem1 and dwItem2:SHChangeNotify SHCNE_UPDATEDIR,SHCNF_PATH(the path is "d:\1"),...
MonkeyLinAuthor Commented:
Is that right?Thank you!
Richie_SimonettiIT OperationsCommented:
It could be, i didn't have the time to read and understand that article.
Anyway, i think that using vbNull instead of Null would be better for VB runtime
Roy LowCommented:
Urgent Comment

I am trying to use SHChangeNotify to refresh a custom folder icon programmatically after I have made the necessary changes to desktop.ini. The alternative is:
"Select folder in Explorer and press F5" which works but is inconvenient and inelegant.

I have tried Richie Simonetti's answer without success.

Can anyone help me, I have lots of points!!!

The code for PCMag's "folders" utility which works brilliantly in doing this is written in Pascal and the three lines which are crucial are:

SHChangeNotify(SHCNE_UPDATEIMAGE, SHCNF_DWORD, Pointer(SFI.iIcon), nil);

The variable pszpath seems to be a pointer to a null terminated string and is a Long.
I think I need to use a "PIDL" value for this which indicates my folder such as the value returned by:
Unfortunately, there does not appear to be an equivalent for "Non-Special" folders.

The variable Pointer(SFI.iIcon) looks to be the same as psfib.iIcon obtained from a call such as
    Finfo = SHGetFileInfo(MyFolder, dwFileAttributes, psfib, cbFileInfo, uFlags) where psfib is declared As SHFILEINFOBYTE

The third line seems ok after replacing "nil" with 0.
MonkeyLinAuthor Commented:
I think you could try this to refresh the custom folder icon :
Private Const WM_WININICHANGE = &H1A
Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Long, ByVal wMsg
As Long, ByVal wParam As Long, lParam As Any) As Long
  whwnd = FindWindow("progMan", "program manager")
  SendMessage whwnd, WM_SETTINGCHANGE, 0, 0

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.