Click here to Skip to main content
15,892,674 members
Articles / Desktop Programming / WPF

Wrap Panel Virtualization

Rate me:
Please Sign up or sign in to vote.
4.95/5 (18 votes)
2 Jan 2012CPOL2 min read 53.6K   5.6K   41  
WrapPanel doesn't support virtualization. But we can improve the performance by simulating virtualization.
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace Dokan
{
    public class DokanOptions
    {
        public ushort Version;
        public ushort ThreadCount;
        public bool DebugMode;
        public bool UseStdErr;
        public bool UseAltStream;
        public bool UseKeepAlive;
        public bool NetworkDrive;
        public bool RemovableDrive;
        public string VolumeLabel;
        public string MountPoint;
    }


    // this struct must be the same layout as DOKAN_OPERATIONS
    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    struct DOKAN_OPERATIONS
    {
        public Proxy.CreateFileDelegate CreateFile;
        public Proxy.OpenDirectoryDelegate OpenDirectory;
        public Proxy.CreateDirectoryDelegate CreateDirectory;
        public Proxy.CleanupDelegate Cleanup;
        public Proxy.CloseFileDelegate CloseFile;
        public Proxy.ReadFileDelegate ReadFile;
        public Proxy.WriteFileDelegate WriteFile;
        public Proxy.FlushFileBuffersDelegate FlushFileBuffers;
        public Proxy.GetFileInformationDelegate GetFileInformation;
        public Proxy.FindFilesDelegate FindFiles;
        public IntPtr FindFilesWithPattern; // this is not used in DokanNet
        public Proxy.SetFileAttributesDelegate SetFileAttributes;
        public Proxy.SetFileTimeDelegate SetFileTime;
        public Proxy.DeleteFileDelegate DeleteFile;
        public Proxy.DeleteDirectoryDelegate DeleteDirectory;
        public Proxy.MoveFileDelegate MoveFile;
        public Proxy.SetEndOfFileDelegate SetEndOfFile;
        public Proxy.SetAllocationSizeDelegate SetAllocationSize;
        public Proxy.LockFileDelegate LockFile;
        public Proxy.UnlockFileDelegate UnlockFile;
        public Proxy.GetDiskFreeSpaceDelegate GetDiskFreeSpace;
        public Proxy.GetVolumeInformationDelegate GetVolumeInformation;
        public Proxy.UnmountDelegate Unmount;
        public Proxy.GetFileSecurityDelegate GetFileSecurity;
        public Proxy.SetFileSecurityDelegate SetFileSecurity;
    }

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 4)]
    struct DOKAN_OPTIONS
    {
        public ushort Version;
        public ushort ThreadCount; // number of threads to be used
        public uint Options;
        public ulong Dummy1;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string MountPoint;
    }


    class Dokan
    {
        [DllImport("dokan.dll")]
        public static extern int DokanMain(ref DOKAN_OPTIONS options, ref DOKAN_OPERATIONS operations);

        [DllImport("dokan.dll")]
        public static extern int DokanUnmount(int driveLetter);

        [DllImport("dokan.dll")]
        public static extern int DokanRemoveMountPoint(
            [MarshalAs(UnmanagedType.LPWStr)] string mountPoint);

        [DllImport("dokan.dll")]
        public static extern uint DokanVersion();

        [DllImport("dokan.dll")]
        public static extern uint DokanDriveVersion();

        [DllImport("dokan.dll")]
        public static extern bool DokanResetTimeout(uint timeout, ref DOKAN_FILE_INFO rawFileInfo);
    }


    public class DokanNet
    {
        public const int ERROR_FILE_NOT_FOUND       = 2;
        public const int ERROR_PATH_NOT_FOUND       = 3;
        public const int ERROR_ACCESS_DENIED        = 5;
        public const int ERROR_SHARING_VIOLATION    = 32;
        public const int ERROR_INVALID_NAME         = 123;
        public const int ERROR_FILE_EXISTS          = 80;
        public const int ERROR_ALREADY_EXISTS       = 183;

        public const int DOKAN_SUCCESS              = 0;
        public const int DOKAN_ERROR                = -1; // General Error
        public const int DOKAN_DRIVE_LETTER_ERROR   = -2; // Bad Drive letter
        public const int DOKAN_DRIVER_INSTALL_ERROR = -3; // Can't install driver
        public const int DOKAN_START_ERROR          = -4; // Driver something wrong
        public const int DOKAN_MOUNT_ERROR          = -5; // Can't assign drive letter

        public const int DOKAN_VERSION = 600; // ver 0.6.0

        private const uint DOKAN_OPTION_DEBUG = 1;
        private const uint DOKAN_OPTION_STDERR = 2;
        private const uint DOKAN_OPTION_ALT_STREAM = 4;
        private const uint DOKAN_OPTION_KEEP_ALIVE = 8;
        private const uint DOKAN_OPTION_NETWORK = 16;
        private const uint DOKAN_OPTION_REMOVABLE = 32;

        public static int DokanMain(DokanOptions options, DokanOperations operations)
        {
            if (options.VolumeLabel == null)
            {
                options.VolumeLabel = "DOKAN";
            }
            
            Proxy proxy = new Proxy(options, operations);

            DOKAN_OPTIONS dokanOptions = new DOKAN_OPTIONS();

            dokanOptions.Version = options.Version;
            if (dokanOptions.Version == 0)
            {
                dokanOptions.Version = DOKAN_VERSION;
            }
            dokanOptions.ThreadCount = options.ThreadCount;
            dokanOptions.Options |= options.DebugMode ? DOKAN_OPTION_DEBUG : 0;
            dokanOptions.Options |= options.UseStdErr ? DOKAN_OPTION_STDERR : 0;
            dokanOptions.Options |= options.UseAltStream ? DOKAN_OPTION_ALT_STREAM : 0;
            dokanOptions.Options |= options.UseKeepAlive ? DOKAN_OPTION_KEEP_ALIVE : 0;
            dokanOptions.Options |= options.NetworkDrive ? DOKAN_OPTION_NETWORK : 0;
            dokanOptions.Options |= options.RemovableDrive ? DOKAN_OPTION_REMOVABLE : 0;
            dokanOptions.MountPoint = options.MountPoint;

            DOKAN_OPERATIONS dokanOperations = new DOKAN_OPERATIONS();
            dokanOperations.CreateFile = proxy.CreateFileProxy;
            dokanOperations.OpenDirectory = proxy.OpenDirectoryProxy;
            dokanOperations.CreateDirectory = proxy.CreateDirectoryProxy;
            dokanOperations.Cleanup = proxy.CleanupProxy;
            dokanOperations.CloseFile = proxy.CloseFileProxy;
            dokanOperations.ReadFile = proxy.ReadFileProxy;
            dokanOperations.WriteFile = proxy.WriteFileProxy;
            dokanOperations.FlushFileBuffers = proxy.FlushFileBuffersProxy;
            dokanOperations.GetFileInformation = proxy.GetFileInformationProxy;
            dokanOperations.FindFiles = proxy.FindFilesProxy;
            dokanOperations.SetFileAttributes = proxy.SetFileAttributesProxy;
            dokanOperations.SetFileTime = proxy.SetFileTimeProxy;
            dokanOperations.DeleteFile = proxy.DeleteFileProxy;
            dokanOperations.DeleteDirectory = proxy.DeleteDirectoryProxy;
            dokanOperations.MoveFile = proxy.MoveFileProxy;
            dokanOperations.SetEndOfFile = proxy.SetEndOfFileProxy;
            dokanOperations.SetAllocationSize = proxy.SetAllocationSizeProxy;
            dokanOperations.LockFile = proxy.LockFileProxy;
            dokanOperations.UnlockFile = proxy.UnlockFileProxy;
            dokanOperations.GetDiskFreeSpace = proxy.GetDiskFreeSpaceProxy;           
            dokanOperations.GetVolumeInformation = proxy.GetVolumeInformationProxy;        
            dokanOperations.Unmount = proxy.UnmountProxy;

            return Dokan.DokanMain(ref dokanOptions, ref dokanOperations);
        }


        public static int DokanUnmount(char driveLetter)
        {
            return Dokan.DokanUnmount(driveLetter);
        }

        public static int DokanRemoveMountPoint(string mountPoint)
        {
            return Dokan.DokanRemoveMountPoint(mountPoint);
        }

        public static uint DokanVersion()
        {
            return Dokan.DokanVersion();
        }

        public static uint DokanDriverVersion()
        {
            return Dokan.DokanDriveVersion();
        }

        public static bool DokanResetTimeout(uint timeout, DokanFileInfo fileinfo)
        {
            DOKAN_FILE_INFO rawFileInfo = new DOKAN_FILE_INFO();
            rawFileInfo.DokanContext = fileinfo.DokanContext;
            return Dokan.DokanResetTimeout(timeout, ref rawFileInfo);
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) KAZ Software Limited
Bangladesh Bangladesh
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions