-
Sep 23rd, 2020, 10:27 PM
#1
SHChangeNotify messages causing weird asych behavior
My code is set up to respond to messages from the shell. I'm receiving a duplicate message immediately after the other, and it's causing bizarre asynchronous behavior.
I've got a sub that handles messages, which calls a sub that responds to a particular message.
MessageHandler
If msg Call Function1
Function1
Line1
Line2
Line3
The execution order becomes
MessageHandler for first instance of msg
Line1(msg1)
Line2(msg1)
MessageHandler for duplicate of msg
Line1(msg2)
Line2(msg2)
Line3(msg1)
Line3(msg2)
There's no DoEvents statement anywhere in Function1, or anywhere in the entire control. The project is not multithreaded.
I have absolutely no idea how it's running 2 instances at the same time, but it is, and the function not finishing before it gets called again is causing problems.
How can I ensure Function1 completes before the first half of it runs again? Because I need it to exit at Line2 if Line3 has already run.
I tried setting a module-level variable, but apparently it's suspending execution of the first run-through when the 2nd message comes in, even if DoEvents is called, so the flag never clears.
Last edited by fafalone; Sep 23rd, 2020 at 10:49 PM.
-
Sep 24th, 2020, 01:39 AM
#2
Re: SHChangeNotify messages causing weird asych behavior
Line2 may be calling something that calls something (MessageHandler?) that calls Function1.
-
Sep 24th, 2020, 03:51 AM
#3
Re: SHChangeNotify messages causing weird asych behavior
MessageHandler for first instance of msg
Line1(msg1)
Line2(msg1)
MessageHandler for duplicate of msg
Line1(msg2)
Line2(msg2)
Line3(msg1) <-------- break here
Line3(msg2)
Look at the call-stack from the breakpoint. Usually there is a hidden message pump (DoEvents) lurking.
cheers,
</wqw>
-
Sep 25th, 2020, 06:56 PM
#4
Re: SHChangeNotify messages causing weird asych behavior
There's no DoEvents or PeekMessage call anywhere in the entire project.
The issue involves whether a module-level usertype already contains the file path.
Code:
Private Sub TVAddItem(siChild As oleexp.IShellItem, hitemParent As Long, Optional bForceEnable As Boolean = False)
On Error GoTo e0
(Dim statements omitted)
siChild.GetDisplayName SIGDN_DESKTOPABSOLUTEPARSING, lpFull
sFPP = LPWSTRtoStr(lpFull)
DebugAppend "TVAddItem " & sFPP
For i = 0 To UBound(TVEntries)
If TVEntries(i).sFullPath = sFPP Then Exit Sub
End If
lpName = 0&: sName = "": lpFull = 0&: sFull = "": lpIcon = 0&: lpIconOvr = 0&: lAtr = 0&: bFolder = False: bZip = False: fDisable = 0&
siChild.GetAttributes SFGAO_CAPABILITYMASK Or SFGAO_CONTENTSMASK Or SFGAO_PKEYSFGAOMASK Or SFGAO_STORAGECAPMASK Or SFGAO_COMPRESSED Or SFGAO_ENCRYPTED Or SFGAO_SHARE, lAtr
If ((lAtr And SFGAO_FOLDER) = SFGAO_FOLDER) Or (mShowFiles = True) Or (bFav = True) Then
If (((mShowFiles = False) And ((mExpandZip = False) And (lAtr And SFGAO_STREAM) = 0&) Or (mExpandZip = True))) Or (bFav = True) Or (mShowFiles = True) Then 'exlude .zip/.cab
siChild.GetDisplayName SIGDN_PARENTRELATIVEPARSING, lpNameFull
sNameFull = LPWSTRtoStr(lpNameFull)
If (lAtr And SFGAO_FOLDER) = SFGAO_FOLDER Then
bFolder = True
If (lAtr And SFGAO_STREAM) = SFGAO_STREAM Then
bZip = True
End If
End If
If (mFilter <> "*.*") And (mFilter <> "") Then
If bFolder Then
If mFilterFilesOnly = False Then
If InStr(mFilter, ";") Then
If PathMatchSpecExW(StrPtr(sNameFull), StrPtr(mFilter), PMSF_MULTIPLE) = 0& Then Exit Sub
Else
If PathMatchSpecW(StrPtr(sNameFull), StrPtr(mFilter)) = 0& Then Exit Sub
End If
End If
Else
If InStr(mFilter, ";") Then
If PathMatchSpecExW(StrPtr(sNameFull), StrPtr(mFilter), PMSF_MULTIPLE) = 0& Then Exit Sub
Else
If PathMatchSpecW(StrPtr(sNameFull), StrPtr(mFilter)) = 0& Then Exit Sub
End If
End If
End If
nCur = nCur + 1
ReDim Preserve TVEntries(nCur)
fSubFolder = 1
tVI.Mask = TVIF_TEXT Or TVIF_IMAGE Or TVIF_SELECTEDIMAGE Or TVIF_PARAM Or TVIF_STATEEX 'Or TVIF_STATE
If fDisable = 0& Then
If (lAtr And SFGAO_HASSUBFOLDER) = SFGAO_HASSUBFOLDER Then
If (TVEntries(nCur).bZip = False) Or ((TVEntries(nCur).bZip = True) And (mExpandZip = True)) Then
tVI.cChildren = 1
tVI.Mask = tVI.Mask Or TVIF_CHILDREN
End If
Else
If (mShowFiles = True) Then
If bFolder = True Then
If FolderIsEmpty(siChild) = False Then
tVI.cChildren = 1
tVI.Mask = tVI.Mask Or TVIF_CHILDREN
End If
End If
End If
End If
End If
siChild.GetDisplayName SIGDN_NORMALDISPLAY, lpName
sName = LPWSTRtoStr(lpName)
TVEntries(nCur).sFullPath = sFPP
Once it executes up to that line, the check at the start will exit the sub. But it's finding no match.
I'm not sure where either a message pump, or a call to HandleShellNotify (which is only called in the WndProc in response to the notification), could be coming in.
-
Sep 26th, 2020, 03:26 AM
#5
Re: SHChangeNotify messages causing weird asych behavior
The message pump is not in your code per se. If you really want to figure out what’s going on you have to instrument your code with a separate line where you can put a breakpoint that is hit on re-entrancy only (just an If statement w/ a dummy single-line body).
Then compile with no optimizations and create symbolic info on (PDB) then start the executable and attach the debugger to it in VS2015+, open the VB6 source file there and put a breakpoint with F9. Once it’s hit show Debug-> Call-stack window and double click on addresses there.
There is no shortcut to learning from exotic problems when even VBForums can’t help :))
Last edited by wqweto; Sep 26th, 2020 at 06:40 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|