Disable Dragging In Windows 95

a) users can drag files in Windows 95.
   -this includes explorer windows, open/save dialogs,
    and the desktop.

a) should stop user from dragging icons.
b) must be controllable, as in turning on/off when I want.
c) must be in VB Source Code!
d) must be a complete solution to the problems presented above.

Thank you,
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

I can't provide a total answer, because I don't do much of this type of code myself, but maybe I can start you in the right direction by saying look into the SetWindowsHookEx API call.  That is the only way I can see that it can be done.

Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long

By passing WH_MOUSE as the first parameter, you can intercept any mouse movement before it is processed by the system.
This will be difficult but I suppose you know that...  I played with it for a couple of hours.

SetWindowsHookEx only lets you hook one hInstance (running application) at a time.  You could loop through, get the hInstances for each of the running apps and set hooks to them all.  You would also need to set a ShellProc hook to set MouseProc hooks on any processes that were started after you hooked the rest.

Problem is, you must have a separate hook procedure for each app, because when a MouseProc hook receives a message, it receives no hHook (hook handle) - and to enable the system to process messages of no interest, you must forward the message to CallNextHookEx which requires an hHook.  Therefore, a single generic MouseProc Hook won’t do because you’ll have no way of knowing which hHook to pass along with messages you don’t wish to intercept.

If AddressOf could be used to reference a procedure in a class, you’d be set - because you could just redim preserve an object array to add another hook object whenever you needed it... but VB doesn’t permit this... bummer.

This is a good one.  If I think of anything that may be helpful, I’ll pass it on.  Good luck.

On second thought, I doubt this approach would work anyway because whatever steps that would be taken to prevent the mouse from "dragging" an object, would probably prevent the user from moving windows, dragging window borders, etc... It would probably disable a good deal of everything.  I obviously never got that far.

One other idea I perused is the RevokeDragDrop API function.  It requires only an hWind.  Problem with it is, once you disable dropdrag, there's no way to turn it back on because the RegisterDragDrop function requires a pointer to the object's dragdrop interface.  Besides, a program could call the RegisterDragDrop function at anytime and you'd have no way of knowing when to control it.  Strike Two - I'm out!

Please offer the reason you would like to accomplish such a thing anyway.
The Ultimate Tool Kit for Technolgy Solution Provi

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy for valuable how-to assets including sample agreements, checklists, flowcharts, and more!

What about enumerating all windows and calling DragAcceptFiles?
My only comment is... I hope you have a really good reason for having one of your applications disable Windows functionality. As far as design goes what you are proposing to do here is a major no-no. The point of "windows gui" is that "ALL" programs look and feel the same, your app should be invisible to the user. Introducing something like you propose would do nothing more than really annoy the users.
I know this isn't an answer or solution but you should really reconsider your design if you must disable basic Windows functionality like the drag n drop.
StarFieldSoftwareAuthor Commented:
Well, first of all, I am making a security program for Windows 95.  It works great, but the ONLY hole in the security is through dragging files and deleting them, etc.
FoolProof Control (smartstuff software) does this, so I know it is possible.
Well, disabling drag'n'drop isn't necessarily the answer, as that would mean people couldn't move files on their desktops, for example. Also it would screw up many apps which use drag'n'drop inside their own system (not necesarilly for files)

I think a better solution is to prevent files from being deleted in the first place. You're probably better off looking for ways to prevent calls to delete files succeeding. And besides, what if a user right clicked a file and went to Delete, or just pressed the DEL key on the file? Removing drag/drop does nothing to prevent this!!!

StarFieldSoftwareAuthor Commented:
Well, you are right on the fact that this will not totally fill the security "hole", but it will help.  Providing the user with many options to secure their computer is helpful.  It will also let users set up the visual appearance of their desktop, and will prevent changes.

I looked into some other options on doing this.
1) I found something about ICopyHook.  This may help anyone trying to solve this question.  It stops users from changing Folders (and maybe files) locations or renaming them.

2) RevokeDragDrop might do what I want.  If it can disable dragging on the desktop window, and if possible Open/Save dialogs, but you have to restart your computer to unprotect it, it may work.  I just can't seem to make that call work.  Also, I would need the handle of the desktop window, which I can't seem to get.  I know how to get the desktop window's handle, but not the actual DESKTOP WINDOW displayed on your screen.  Afterall, you cannot hook the "desktop" window that controls the system.

3) another option might be to "hook" windows messages until you find a message something like "CreateDragImage".  But, I would need the desktop window's handle, and also the message number of the message, and also the syntax of the "hook" function.

You can get the Desktop DC for drawing and dragging purposes  by calling GetDC with no parameters.

Dim sDC As Long

sDC = GetDC()

That much I CAN help with.
OK, bizzare angle...

  Have you looked at the WH_CBT hook in conjunction with WH_JournalPlayback & WH_JournalRecord?  It looks like you should be able to filter DragNDrop Mouse functions, along with keyboard input.  

 I don't have the time right now to look into this, but it could be the direction you want to go.

StarFieldSoftwareAuthor Commented:
My expertise is not in the "hook" field of windows.  I have some understanding, but do not know where I would call these functions from, or where I might find reference info.  I also do not know how to do what you (chris lewis) said.  I looked it up in the MSDN CD but it is really confusing.

Some good news:
I will accept any solutions that prevents the user from modifying (renaming, deleting, moving, copying, etc) files and folders, even if it does not disable dragging.
If you disable dragging, users will still be able to rename, delte, move and copy with the keyboard. This will not stop anyone. They will just find strange and plainfully anoying that those efficient feature don't work on that particular system.

Disabling every single command for file managemant would a gagantist job filled with special case, non-standart hacks and buggy tricks. And still it will not be much secure since anyone could come out with another program that copy files around. Think about someone installing the SendTo powertool from Microsoft or installing a sinple FTP client like WS_FTP.

Then you need to restrict acces to file themselves. And not all of them since doing so would crash any program that tries to manage its own tempory files.

Doesn't this sound like a low level job? Doesn't this sound like what WinNT is about? Unless you are a kernel guru and you want to rewrite the file core of Windows...

Wouldn't it be sinpler to just disable acces to any program that can copy files? Let say users could only run allowed programs you know can't copy files. Take a look at the Policy editor. It is a small util on the Win95 cd that allow you to make more or less simple security restrictions, like this one.

This won't work for the whole system, but if there is a limited list of files, you can disable manupulations with them just using the Open command. The user won't be able to delete the files while they are opened
For dragging and dropping (the primary question) you can do this in the registry: set HKCU\Control Panel\Desktop\DragWidth=65535 and HKCU\Control Panel\Desktop\DragHeight=65535.
Note that you'll also disable window-dragging and dragging functionality in some applications with this setting. It doesn't affect the Ctrl-X and right-mouse menu capabilities of cutting and pasting. If you still want an implementation of this in VB without needing to restart the computer (so you can switch the setting) I'll be willing to post it here for you. But it doesn't apply to the other security issues you involved via the comments.

StarFieldSoftwareAuthor Commented:
Sounds like it might do what I want!  Could you send the source code to TSugarbaker@starfieldsw.com?  After I decide if it works for my needs, I will give the points.  Thanks!

Below you'll find fully working program code, which you can pass directly into VB. A small explanation can be helpful to edit it to your own purposes, so hear it goes:

The program code is for both Win95 and WinNT but on WinNT the DragY and DragX values can be higher. If the sample doesn't directly work on your computer, try decreasing the values of DragX and DragY (the values are in pixels), since a lower resolution might need lower values.

If you start a project in VB, remove the form and add a Module. Make a Sub Main() and paste the code. Compile and run. It will switch dragging and dropping on and off on your computer.

These functions get the current values for DragHeight and DragWidth (like in the registry)

1 = Kind of info you want and if you want to set or get it.
    SPI_SETDRAGHEIGHT and SPI_SETDRAGWIDTH set the values you want
2 = Value to set
3 = not applicable in this case
4 = SPIF_SENDCHANGE + SPIF_UPDATEINIFILE notify all the windows of the change and it updates the registry (this way you won't have to restart the computer)

If you would choose to edit the registry directly, it'll work, but only after a restart.
In the exaple I use 4 as default setting (normal drag 'n' drop) but you can change that to whatever setting you want.

I also have a small EXE-file for you which turns the setting on and off, made in C++ 5.0. This one doesn't need the load of the huge VB dll, it only loads 20k. If you want it I'll mail it to you with the sourcecode.

Is this what you wanted? It does enable/disable drag 'n' drop. If you want an email of my project- and source code file, or a compiled version, you name it and I'll send it to you (the source is the same as posted here...:)

Some things to think of:
-It enables/disables file and window drag 'n' drop in all common dialog boxes, listviews, listcontrols and a lot others, but most drag 'n' drop of text stays enabled (differs per application).
-Window dragging in still possible via Right mousebutton on the captionbar->move and arrowkeys.

Succes with it, hope it does the job.



'Place this in the declaration section of a module
Declare Function SystemParametersInfo Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Long, ByVal uParam As Long, ByVal lpvParam As Long, ByVal fuWinIni As Long) As Long
Declare Function GetSystemMetrics Lib "user32" (ByVal nIndex As Long) As Long
Public Const SPI_SETDRAGWIDTH = 76
Public Const SPIF_SENDCHANGE = &H2
Public Const SM_CXDRAG = 68
Public Const SM_CYDRAG = 69

'Place this in place of a sub
Sub Main()
Dim DragX As Integer, DragY As Integer

DragX = GetSystemMetrics(SM_CXDRAG)
DragY = GetSystemMetrics(SM_CYDRAG)
DragX = IIf(DragX = 32000, 4, 32000)
DragY = IIf(DragY = 32000, 4, 32000)

    MsgBox "Could not edit SystemParametersInfo", vbOKOnly, "Swich Drag and Drop on and off"
End If
    MsgBox "Could not edit WIDTH-parameter of SystemParametersInfo", vbOKOnly, SPIF_SENDCHANGE + SPIF_UPDATEINIFILE
End If

End Sub


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial

The last MsgBox is not correct, should - of course - be:
MsgBox "Could not edit WIDTH-parameter of SystemParametersInfo", "Swich Drag and Drop on and off"
StarFieldSoftwareAuthor Commented:
This looks ok, and does what I want with the exception of the window dragging lockout.  However, I will give you the points since I said that I wanted to disable icon dragging, which you did.  But, if you ever figure out how to do this without locking window dragging, please tell me!

Look at this function (CopyCallback). It can do exactly what you want, but only on folders, you already stated it talking about ICopyHook. The only problem is, I have no idea how to implement that in VB. If you're able of doing that in C++, it's fairly easy. Maybe it gets you going in (another) right direction. The solution you can get by using this function can be much more beautiful then the one I provided before. I hope you can do something with it. Good luck.
The only problem is that it only applies to folders. I read in VC++ 2nd Ed. (Viktor Toth, Sams Publishing) that it also works on files, but looking at this documentation I don't think so. But you'll find out soon enough.


Either allows the shell to move, copy, delete, or rename a folder or printer object, or disallows the shell from carrying out the operation. The shell calls each copy hook handler registered (see Comments below) for a folder or printer object until either all the handlers have been called or one of them returns IDCANCEL.

UINT CopyCallback(
HWND hwnd,                    //Handle of the parent window for displaying UI objects
UINT wFunc,                     //Operation to perform.
UINT wFlags,                    //Flags that control the operation
LPCSTR pszSrcFile,       //Pointer to the source file
DWORD dwSrcAttribs,    //Source file attributes
LPCSTR pszDestFile,     //Pointer to the destination file
DWORD dwDestAttribs   //Destination file attributes


Handle of the window that the copy hook handler should use as the parent window for any user interface elements the handler may need to display. If FOF_SILENT is specified, the method should ignore this parameter.

Operation to perform. This parameter can be one of the following values:

Copies the file specified by pszSrcFile to the location specified by pszDestFile.

Deletes the file specified by pszSrcFile.

Moves the file specified by pszSrcFile to the location specified by pszDestFile.

Renames the file specified by pszSrcFile.

Deletes the printer specified by pszSrcFile.

Changes the printer port. The pszSrcFile and pszDestFile parameters contain double null-terminated lists of strings. Each list contains the printer name followed by the port name. The port name in pszSrcFile is the current printer port, and the port name in pszDestFile is the new printer port.

Renames the printer specified by pszSrcFile.

Combination of PO_RENAME and PO_PORTCHANGE.

Flags that control the operation. This parameter can be a combination of the following values:

Preserves undo information (when possible).

Not implemented.

Not implemented. The shell calls a copy hook handler only for folder objects, not files.

The SHFileOperation function specified multiple destination files (one for each source file) rather than one directory where all the source files are to be deposited. A copy hook handler typically ignores this value.

Responds with “yes to all” for any dialog box that is displayed.

Does not confirm the creation of any needed directories if the operation requires a new directory to be created.

Gives the file being operated on a new name, such as, “Copy #1 of ...”, in a copy, move, or rename operation when a file with the target name already exists.

Displays no progress dialog box.

Displays a progress dialog box, but the dialog box does not show the names of the files.

Pointer to a string that contains the name of the source file.

Attributes of the source file. This parameter can be a combination of any of the file attribute flags (FILE_ATTRIBUTE_*) defined in the Windows header files.

Pointer to a string that contains the name of the destination file.

Attributes of the destination file. This parameter can be a combination of any of the file attribute flags (FILE_ATTRIBUTE_*) defined in the Windows header files.

Returns an integer value that indicates whether or not the shell should perform the operation. It can be one of the following:

Allows the operation.

Prevents the operation on this file, but continues with any other operations (for example, a batch copy operation).

Prevents the current operation and cancels any pending operations.

You need to register your copyhook handler. For example, …\directory copyhook handlers are registered under HKEY_CLASSES_ROOT\directory\shellex\CopyHookHandlers\your_copyhook\{copyhook CLSID value}. Other registry keys associated with shell extensions are: *, Folder, Drives, Printers, Unknown, and AudioCD.

The shell initializes the ICopyHook interface directly, when ICopyHook::CopyCallback is called, without using an IShellExtInit or IPersistFile interface first.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic Classic

From novice to tech pro — start learning today.