Jump to content

Search the Community

Showing results for tags 'SHChangeNotification_Lock'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • General
    • Announcements and Site News
    • Administration
  • AutoIt v3
    • AutoIt Help and Support
    • AutoIt Technical Discussion
    • AutoIt Example Scripts
  • Scripting and Development
    • Developer General Discussion
    • Language Specific Discussion
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Categories

  • AutoIt Team
    • Beta
    • MVP
  • AutoIt
    • Automation
    • Databases and web connections
    • Data compression
    • Encryption and hash
    • Games
    • GUI Additions
    • Hardware
    • Information gathering
    • Internet protocol suite
    • Maths
    • Media
    • PDF
    • Security
    • Social Media and other Website API
    • Windows
  • Scripting and Development
  • IT Administration
    • Operating System Deployment
    • Windows Client
    • Windows Server
    • Office

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


Member Title


Location


WWW


Interests

Found 1 result

  1. HiHo Forum , I was playing around with the _WinAPI_ShellChangeNotifyRegister() function from (required for the example) and hit a wall, would be great if this one could be answered. Looking around the net, I found a definition on how to register the notifications for all filesystem objects and not just specified directories (see my adjusted _WinAPI_ShellChangeNotifyRegisterEx() below). This works fine (commented part in the WM_SHELLCHANGENOTIFY function below), but I wanted it to take a step further. I've found this article: http://koti.mbnet.fi/vaultec/files/miscellaneous/undocw95/notify.html [font="Times New Roman"][size="3"]This all seems simple enough, but on NT there is a bit of a problem. You can't just send a message to a window in a different process, and still expect the structure pointer contained in that message to be accessible. To get around this, NT actually dumps all the data into a memory-mapped file, and then sends the memory-map handle and a process id as the parameters to the message. In order to remain compatible with Windows 95, some- body obviously has to extract the information from that memory-map on the other side. The way this works is that NT creates a hidden 'proxy' window whenever you call SHChangeNotifyRegister. It is the proxy window that receives the notification message containing the memory- map. Its message handler then extracts all the information, before passing on the expected data structure to your win- dow. Of course, this is not exactly efficient, which is where the [size="-1"]SHCNF_NO_PROXY[/size] flag comes in. By specifying that flag, you are telling NT not to create the proxy window, so the memory-map handle gets passed directly to your win- dow. It's then up to you to extract the relevant information from the memory-map. Fortunately there are two functions that do all the work for you:[/size][/font] The SHCNF_NO_PROXY flag mentioned equals the SHCNRF_NEWDELIVERY flag in the MSDN documentation.... and there's my problem. According to the article the notification is sent via a memory mapped file, which can be accessed via a call to SHChangeNotification_Lock(), and this part currently fails for me, I don't get the pointer to the PIDL. #region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #endregion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <APIConstants.au3> #include <WinAPIEx.au3> #include <GUIConstantsEx.au3> HotKeySet("{ESC}", "_Exit") Global $hWnd, $iMsg, $ID ; http://koti.mbnet.fi/vaultec/files/miscellaneous/undocw95/notify.html $hWnd = GUICreate('') $iMsg = _WinAPI_RegisterWindowMessage('SHELLCHANGENOTIFY') GUIRegisterMsg($iMsg, 'WM_SHELLCHANGENOTIFY') $ID = _WinAPI_ShellChangeNotifyRegisterEx($hWnd, $iMsg, $SHCNE_ALLEVENTS, BitOR($SHCNRF_INTERRUPTLEVEL, $SHCNRF_SHELLLEVEL, $SHCNRF_RECURSIVEINTERRUPT, $SHCNRF_NEWDELIVERY), "", 1) If @error Then MsgBox(16, 'Error', 'Window does not registered.') Exit EndIf OnAutoItExitRegister('OnAutoItExit_ShellChangeNotifyRegister') While 1 Sleep(1000) WEnd Func _Exit() Exit EndFunc ;==>_Exit Func WM_SHELLCHANGENOTIFY($hWnd, $iMsg, $wParam, $lParam) #cs Local $Path = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate('dword Item1; dword Item2', $wParam), 'Item1')) If $Path Then ConsoleWrite(TimerInit() & @TAB & 'Event: 0x' & Hex($lParam) & ' | Path: ' & $Path & @CR) Else ConsoleWrite(TimerInit() & @TAB & 'Event: 0x' & Hex($lParam) & @CR) EndIf #ce ConsoleWrite("+ " & $hWnd & @TAB & $iMsg & @TAB & $wParam & @TAB & $lParam & @CRLF) Local $iRes = DllCall("shell32.dll", "handle", "SHChangeNotification_Lock", "handle", $wParam, "dword", $lParam, "ptr", "", "ulong", "") Local $PIDLIST_ABSOLUTE = $iRes[3] Local $plEvent = $iRes[4] ConsoleWrite("! 1: " & $iRes[0] & @TAB & "2: " & $PIDLIST_ABSOLUTE & @TAB & "3: " & $plEvent & @CRLF) Local $Path = _WinAPI_ShellGetPathFromIDList(DllStructGetData(DllStructCreate('dword Item1; dword Item2', $PIDLIST_ABSOLUTE), 'Item1')) ; Local $Path = _WinAPI_ShellGetPathFromIDList($PIDLIST_ABSOLUTE) ConsoleWrite("- Path: " & $Path & @CRLF) $iRes = DllCall("shell32.dll", "int", "SHChangeNotification_Unlock", "HANDLE", $iRes[0]) ConsoleWrite($iRes[0] & @CRLF & "============" & @CRLF & @CRLF) EndFunc ;==>WM_SHELLCHANGENOTIFY Func OnAutoItExit_ShellChangeNotifyRegister() _WinAPI_ShellChangeNotifyDeregister($ID) EndFunc ;==>OnAutoItExit_ShellChangeNotifyRegister Func _WinAPI_ShellChangeNotifyRegisterEx($hWnd, $iMsg, $iEvents, $iSources, $aPaths, $fRecursive = 0) Local $tEntry, $Path = $aPaths, $Struct = '', $iCount If $aPaths Then If IsArray($aPaths) Then If UBound($aPaths, 2) Then Return SetError(1, 0, 0) EndIf Else Dim $aPaths[1] = [$Path] EndIf For $i = 0 To UBound($aPaths) - 1 If Not _WinAPI_PathIsDirectory($aPaths[$i]) Then Return SetError(1, 0, 0) EndIf Next For $i = 0 To UBound($aPaths) - 1 $Struct &= 'ptr;int;' Next $tEntry = DllStructCreate($Struct) For $i = 0 To UBound($aPaths) - 1 $aPaths[$i] = _WinAPI_ShellILCreateFromPath(_WinAPI_PathSearchAndQualify($aPaths[$i])) DllStructSetData($tEntry, 2 * $i + 1, $aPaths[$i]) DllStructSetData($tEntry, 2 * $i + 2, $fRecursive) Next Local $Ret = DllCall('shell32.dll', 'ulong', 'SHChangeNotifyRegister', 'hwnd', $hWnd, 'int', $iSources, 'long', $iEvents, 'uint', $iMsg, 'int', UBound($aPaths), 'ptr', DllStructGetPtr($tEntry)) Else $tEntry = DllStructCreate('ptr;int;') DllStructSetData($tEntry, 1, "") DllStructSetData($tEntry, 2, 1) Local $Ret = DllCall('shell32.dll', 'ulong', 'SHChangeNotifyRegister', 'hwnd', $hWnd, 'int', $iSources, 'long', $iEvents, 'uint', $iMsg, 'int', 1, 'ptr', DllStructGetPtr($tEntry)) EndIf If (Not @error) And ($Ret[0]) Then $Ret = $Ret[0] Else $Ret = 0 EndIf For $i = 0 To UBound($aPaths) - 1 _WinAPI_CoTaskMemFree($aPaths[$i]) Next Return SetError(Number($Ret = 0), 0, $Ret) EndFunc ;==>_WinAPI_ShellChangeNotifyRegisterEx
×
×
  • Create New...