TC_SETDRIVE currently takes three boolean values encoded into wParam and an optional path in lParam. If lParam is NULL, it looks up the directory from FS_GETDIRECTORY.
Between original_plus and the first 10.0 release, a change was made in TC_SETDRIVE that will update the selection without a refresh if the value supplied in lParam can be found in the existing tree. In some cases, such as the View File Types dialog, TC_SETDRIVE is invoked with a NULLlParam, which causes a full refresh to occur. In others, including RefreshWindow, lParam is supplied as a directory, which has the effect of suppressing any refresh.
This change modifies RefreshWindow to not supply lParam as a way to cause the refresh to happen. The previous code was calling FS_GETDIRECTORY from RefreshWindow, then calling FS_CHANGEDRIVES, then calling TC_SETDRIVE. The code reads as though it expects FS_CHANGEDRIVES to invalidate the directory, so it must be saved first. However, I do not see FS_CHANGEDRIVES doing this, and have looked back to the oldest source I can find in Windows 3.1 (where FS_CHANGEDRIVES is very different) but still don't see it doing this. The "worst" case I can find or think of is if FS_CHANGEDRIVES decides that the drive owned by a window no longer exists, but in this case, the code was already setting lParam to NULL. I've tested this case and even with this change the program seems to behave correctly (it displays an error to the user about the drive being invalid before and after this change.)
That said, there are other options for a fix:
Note that RefreshWindow is called in a handful of places, not just in response to the refresh menu item. This change could be scoped to IDM_REFRESH by adding a new parameter to RefreshWindow.
Alternatively, TC_SETDRIVE could take a fourth boolean to suppress the optimization, so that RefreshWindow could still save and restore the directory, but tell TC_SETDRIVE to perform a real refresh. (This was my initial idea before noticing how lParam is affecting this in other paths.)
TC_SETDRIVE
currently takes three boolean values encoded intowParam
and an optional path inlParam
. IflParam
isNULL
, it looks up the directory fromFS_GETDIRECTORY
.Between
original_plus
and the first 10.0 release, a change was made inTC_SETDRIVE
that will update the selection without a refresh if the value supplied inlParam
can be found in the existing tree. In some cases, such as the View File Types dialog,TC_SETDRIVE
is invoked with aNULL
lParam
, which causes a full refresh to occur. In others, includingRefreshWindow
,lParam
is supplied as a directory, which has the effect of suppressing any refresh.This change modifies
RefreshWindow
to not supplylParam
as a way to cause the refresh to happen. The previous code was callingFS_GETDIRECTORY
fromRefreshWindow
, then callingFS_CHANGEDRIVES
, then callingTC_SETDRIVE
. The code reads as though it expectsFS_CHANGEDRIVES
to invalidate the directory, so it must be saved first. However, I do not seeFS_CHANGEDRIVES
doing this, and have looked back to the oldest source I can find in Windows 3.1 (whereFS_CHANGEDRIVES
is very different) but still don't see it doing this. The "worst" case I can find or think of is ifFS_CHANGEDRIVES
decides that the drive owned by a window no longer exists, but in this case, the code was already settinglParam
toNULL
. I've tested this case and even with this change the program seems to behave correctly (it displays an error to the user about the drive being invalid before and after this change.)That said, there are other options for a fix:
RefreshWindow
is called in a handful of places, not just in response to the refresh menu item. This change could be scoped toIDM_REFRESH
by adding a new parameter toRefreshWindow
.TC_SETDRIVE
could take a fourth boolean to suppress the optimization, so thatRefreshWindow
could still save and restore the directory, but tellTC_SETDRIVE
to perform a real refresh. (This was my initial idea before noticing howlParam
is affecting this in other paths.)