Click here to Skip to main content
13,552,630 members
Click here to Skip to main content

Stats

640.7K views
28.4K downloads
270 bookmarked
Posted 14 Sep 2010
Licenced CPOL

PVS.AVPlayer - MCI Audio and Video Library

, 16 Apr 2018
Windows Media Control Interface (MCI) library with many added features
PVS.AVPlayer
PVS.AVPlayer .NET 2.0
PVS.AVPlayer .NET 3.0
PVS.AVPlayer .NET 3.5
PVS.AVPlayer .NET 4.0
PVS.AVPlayer .NET 4.5
PVS.AVPlayer .NET 4.5.1
PVS.AVPlayer .NET 4.5.2
PVS.AVPlayer .NET 4.6
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.6.1
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.6.2
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.7
PVS.AVPlayer .NET 4.7.1
PVS.AVPlayer.dll
PVS.AVPlayer .NET 4.7.2
PVS.AVPlayer.dll
PVS.AVPlayer.dll
PVS.AVPlayer All Source Code
AVPlayerExample
AVPlayerExample
AVPlayerExample.csproj.user
bin
Debug
Release
Dialogs
Display Overlays
obj
Debug
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
WingDings3a.ttf
Voice Recorder
FolderView
FolderView
bin
Debug
Release
FolderView.csproj.user
obj
Release
x86
Debug
Release
Properties
Resources
Crystal Italic1.ttf
PVS.AVPlayer
AVPlayerExample.csproj.user
PVS.AVPlayer.dll
Custom Items
Native Methods
Bob.png
Crystal Italic1.ttf
Dial Green 2.png
Dial Green 4.png
Dial Green.png
Dial Red 2.png
Dial Red.png
media7.ico
media7a.ico
Media8.ico
Media8a.ico
VU Meter.png
WingDings3a.ttf
Sound Recorder
Various
About Dialog
PVS.AVPlayer.dll
Custom Items
FolderView.csproj.user
Bob.png
Crystal Italic1.ttf
media7a.ico
media7b.ico
Media8a.ico
Media8b.ico
Subtitles Overlay
Various
How To (C#)
PVSAVPlayerHowTo
bin
Debug
PVS.AVPlayer.dll
Release
Properties
How To (VB.NET)
PVSAVPlayerHowToVB
ApplicationEvents.v_b
bin
Debug
PVS.AVPlayer.dll
Release
Form1.Designer.v_b
Form1.v_b
My Project
app.manifest
Application.Designer.v_b
Application.myapp
AssemblyInfo.v_b
Resources.Designer.v_b
Settings.Designer.v_b
Overlay.Designer.v_b
Overlay.v_b
PVSAVPlayerHowTo.vbproj.user
PVS.AVPlayer Examples
AVPlayerExample.ex_
FolderView.ex_
AVPlayerExample.exe
FolderView.exe
PVS.AVPlayer.dll
--------------------------------
About PVS.AVPlayer versions:
--------------------------------

The PVS.AVPlayer libraries are compiled using different .NET Framework versions so you can use the library on any computer that has .NET Framework version 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6 or higher installed. Just pick the (lowest) version you need*. All library versions have exactly the same functionality.

* As .NET Framework is highly backwards compatible, you should be able to use the lower versions of the PVS.AVPlayer library also with the higher versions of .NET Framework. 

If you get the libraries mixed up, you can read the .NET Framework version number by right-clicking on a library file in Windows Explorer and select Properties: Details. The last number in the version number shows the .NET Framework version, e.g. 0.4.6.35 for .NET Framework version 3.5.

--------------------------------
Replacing a previous (or other .NET Framework version) library version:
--------------------------------

In your project please remove the reference to PVS.AVPlayer.dll and add a reference to the new PVS.AVPlayer.dll.

--------------------------------
Questions and Remarks
--------------------------------

Any questions, remarks, suggestions, comments and/or votes are very much welcome and appreciated at the PVS.AVPlayer article at www.codeproject.com.


--------------------------------
PVS.AVPlayer library versions:
--------------------------------

Version 0.46

- added .NET Framework 4.6 library.
- fixed 'ResizeFormRefresh' function.
- error reporting 'ScreenCopy', 'VideoZoom' and others fixed.
- ShuttleSlider Max/Min properties removed.
- DeviceID check added, reduced (= no) chances on duplicate device aliases (that would prevent creating a player/recorder).

- fixed a few minor issues in the example applications and added a few options.

--------------------------------
--------------------------------

Version 0.45

- fixed mp4 repeat issues: when repeating ('repeat one') an mp4-file (and maybe other types as well), playback could sometimes come to a halt at the end of the file instead of starting over again. This seems to occur only when a file is repeated from begin to end (and with minimized forms). This issue was addressed before but seems only to have been fully resolved now.

- improved mci notify handling. The internal mci notify handling is now more efficient and also no longer stops media playback with certain (user) mci commands (with Player.MciCommand/Request methods).

- fixed a few minor issues in the example applications and added a few options, like (Drag and) Drop files, Auto/Continue Play, Auto Overlay Selection (AVPlayerExample) and single instance application (FolderView).

--------------------------------
--------------------------------

Version 0.42

- fixed the positioning of a Display Overlay (with OverlayMode.Video) when a video image is partially (on the top or left) outside of the player's display and the display's position is changed - the Display Overlay would always be positioned as if the video image was both on the top and on the left outside of the display (i.e. in the top-left corner of the player's display).

----

- added property 'FormRestoreBounds' to get the 'original' size and position of a player's parent form when the player is in fullscreen* mode. These values can be used to save (to disk, preferences) and restore the form's bounds (* 'FormRestoreBounds' also gets the form's 'Bounds' (or 'RestoreBounds' if Maximized) if the player is not in fullscreen mode).

To save a fullscreen (or non-fullscreen) player and parent form settings you could use:

 Prefs.FullScreenMode = myPlayer1.FullScreenMode;              // save player setting
 Prefs.FullScreen = myPlayer1.FullScreen;                      // save player setting
 Prefs.Maximized = WindowState == FormWindowState.Maximized;   // save form setting
 Prefs.FormBounds = myPlayer1.FormRestoreBounds;               // save form setting
 (... save preferences)

To restore a fullscreen (or non-fullscreen) player and parent form settings you could use:

- in form constructor (VB.Net: Form.Load):
 (... load preferences)
 StartPosition = FormStartPosition.Manual;                     // restore form setting
 Bounds = Prefs.Bounds;                                        // restore form setting

- in form constructor or Form_Shown:
 if (Prefs.Maximized) WindowState = FormWindowState.Maximized; // restore form setting
 Player1.FullScreenMode = Prefs.FullScreenMode;                // restore player setting

- in Form_Shown:
 Player1.FullScreen = Prefs.Fullscreen;                        // restore player setting

----

- added 'preferences' to the example application as an example on how to save Player settings (including fullscreen preserving a player's parent Form size and position). The preferences settings are accessible from the display menu (right-click display) only.

--------------------------------
--------------------------------

Version 0.41

- all methodnames starting with MCI have been renamed to methodnames starting with Mci (partial lowercase) - sorry for any inconvenience;
- added events for display overlay mode setting change (MediaOverlayModeChanged) and overlay hold setting change (MediaOverlayHoldChanged);
- fixed slider (trackbar) managers (e.g. myPlayer1.AudioVolumeSlider): when a slider was changed the previous slider's (event) handlers were not properly removed;
- cleaned up all source code;
- fixed some minor other issues.

--------------------------------
--------------------------------

Version 0.4

- Fixed destructor (finalizer) bug: the destructor tries to restore a player's fullscreen display (among others), but if you're quiting the application the display/form may already have been removed (disposed);
- Cleaned up library source code and added a few comments.

--------------------------------
--------------------------------

Version 0.37

- Fixed playing audio (mp3) without a display.
- Full library source code now available.
- Fixed some minor bugs in the example application.

--------------------------------
--------------------------------

Version 0.36

Only a few changes/fixes, but just couldn't let them be:

- VideoEnabled fix - this option was 'damaged' in a previous update and has now been fixed. With this option you can switch on/off the display of video of a playing mediafile. However, when a file is started with VideoEnabled set to false there's a short 'display flash' as the video is still displayed for just a brief moment. Maybe this could be 'fixed' somehow, but it's not worth the trouble: if you want to hide the video of a mediafile just move the display (e.g. panel1) out of sight or move the video itself out of sight with something like myPlayer1.VideoBounds = new Rectangle(-50, -50, 40, 40).

- EndPositionMedia fixed - this option sets the playback end position of an already playing mediafile and could (before the fix) sort of freeze playback until another player transport command was used.

- OverlayHold fix - when changing playback from a movie to audio only media (that has not a display size, e.g. MP3) the size of a display Overlay was not changed if the option OverlayHold was active (the overlay now changes to full display size).

- Display Overlays are now updated (when resizing or moving a display) before the video of a mediafile is updated for an 'earlier/faster' redraw of the overlay.

--------------------------------
--------------------------------

Version 0.35

- Added SleepDisabled - with this option you can prevent the computer from going into 'sleep mode' (this option uses the Win32 native method 'SetThreadExecutionState').
You can use

    myPlayer1.SleepDisabled = true;

to prevent 'sleep mode' during the use of your application or just during the playback of one or more mediafiles.
The original (system) 'sleep mode' settings (Energy Saving/Power Options) are restored with

    myPlayer1.SleepDisabled = false;

but only if every player that has set SleepDisabled to true, also has reset (to false) this option.
This player property is also reset when a player is disposed or when the application is closed.

- When the OverlayCanFocus option is (re-) set to false, the overlay now also loses focus (if the overlay had focus, the display's owner Form is activated).

- Added GetTrackTimes and GetProgressTimes - two new methods that return two TimeSpan values containing the duration 'from the beginning' and 'to the end' of a playing mediafile. This is more efficient than two or more calls to GetMediaLength (you can still use GetMediaLength if you like), e.g. inside your MediaPositionChanged EventHandler (class field: TimeSpan[] trackTimes;):

    myPlayer1_MediaPositionChanged(object sender, EventArgs e)
    {
        trackTimes = myPlayer1.GetTrackTimes();

        // myTrackBar1.Value = trackTimes[0].TotalMilliseconds;
        positionLabel1.Text = trackTimes[0].ToString().Substring(0, 8);
        positionLabel2.Text = trackTimes[1].ToString().Substring(0, 8);
    }

- And a few other minor changes/improvements (among others: Finalize added and show Overlay z-order improved).

Example application:
- Applied SleepDisabled and GetTrackTimes/GetProgressTimes (as above).
- Subtitles Overlay added simple synchronize adjustment option.
- PlayList 'remove-item-when-mediafiles-are-playing bug' fixed.
- Overall text color (gold) made less bright.
- A few other minor changes/improvements.

--------------------------------
--------------------------------

Version 0.34

- Added .NET Framework 4.5.1 library.

- Repeat bug fix - if Repeat setting was turned on during media playback and playback position was passed the repeat endposition, playback position was set to endposition OK but halted (with x64 system).
- shuttle slider improved - shuttle slider and step function remain 'problematic' because media has to be playing (not paused) while performing 'frame step': the playing interferes with the frame stepping. Setting playback speed to 0 (zero) may help when using the step function.

- A few minor bug fixes in the example application, for instance in the 'Message' overlay a long lived bug with more than one space between words could crash the overlay, and application wide flashing buttons are now truly synchronized. Added "All Screens" example display overlay.

--------------------------------
--------------------------------

Version 0.33

- Speed Settings fix - setting was not handled properly with no media playing.
- Added easy access to display and sound control panels (for additional settings): ShowVideoSettingsPanel(), ShowAudioMixerPanel() and ShowAudioOutputPanel().
- Added WaveAudio Recorder Class.

A WaveAudio Recorder class has been added to the library, although the MCI recording options are rather limited.

Basically, you create a recorder, record sound with it and save it to a file.
Stopping a recording closes the recorder device and deletes the recording - you can save the recording by using the Pause method or using the RecorderSaveRequest event. The recorder remains available for new recordings until you delete it (with myRecorder1.Dispose();).

using PVS.AVPlayer;

// 1. create a recorder
Recorder myRecorder1 = new Recorder();

// 2. optional: change recorder settings - please see below

// 3. start recording
myRecorder1.Record();
if (myRecorder1.LastError) MessageBox.Show(myRecorder1.LastErrorString);

// 4. stop recording - fires the RecorderSaveRequest event that allows saving the recording
myRecorder1.Stop();

// (4.) or (if you don't want to use the Save event) you can pause the recording (before stopping) to save the recording:
myRecorder1.Pause();
if (myRecorder1.Length > 0) myRecorder1.Save(@"C:\MyRecordings\MyRecording.wav");
myRecorder1.Stop();

Recorder settings.

The options to change the input (microphone) settings for the MCI waveaudio device are rather limited. Besides setting the number of channels (mono (1) or stereo (2)), the number of bits per sample (8 or 16 bits) and the number of samples per second (11025, 22050 or 44100 samples) there seems not much else to be adjustable*, not even the input volume level. Using the system's sound control panel to select and adjust the input device (besides channels, bits, and samplerate) may come to rescue: you can open the control panel with: myRecorder1.ShowAudioInputPanel(this);

* There is, however, a way to select an input device directly: myRecorder1.InputDevice. You can get the number of available inputdevices with myRecorder1.InputDeviceCount and a description (max 31 chars) with myRecorder1.InputDeviceInfo:

int n = myRecorder1.InputDeviceCount;
if (n > 0)
{
    int old = myRecorder1.InputDevice; // save inputdevice #

    string inputList = "";
    for (int i = -1; i < n; i++) // -1 is (system) default input
    {
        myRecorder1.InputDevice = i;
        inputList += myRecorder1.InputDeviceInfo + "\r\n";
    }
    MessageBox.Show(inputList);

    myRecorder1.InputDevice = old; // set back inputdevice #
}
else MessageBox.Show("No input devices.");

If you set the inputdevice other than the system default (-1), you may also be able to get input peaklevel values with myRecorder1.Level (and the RecorderLevelChanged event).

--------------------------------
--------------------------------

Version 0.32

- Position Slider fix - the position slider (trackbar) handled by the player could exceed the maximum value resulting in an errormessage.
- Overlay Hold fix - setting the option Overlay Hold when the Form (the player's display is on) is not visible (e.g at startup time) would not show the overlay when the Form became visible.
- MCI.Sendstring fix - when using a return value you had to set the maximum capacity of the return buffer (StringBuilder).
Now you just can specify the preferred capacity, e.g. StringBuilder resultText = new Stringbuilder(256).
- Play movie without display fix - it was possible (second time try) to play movies (sound only) without a display. However that may be considered useful, it may cause problems (because an 'internal' display is being used as a 'true' display). If you want to only hear the sound of a movie, you can use the VideoEnabled option or hide the player's display ('panel1').
- Step (and Shuttle Slider) fix - the Step command triggered Resume events when playback was not paused.

- Main Example Application:
- Added Voice Recorder (accessible from display menu (right-click display) only) as an example on how to use the direct MCI access functions of the library to add functionality,
- Playback Speed input box,
- Quick access to system media settings (control panels display, sound and volume mixer),
- Mouse scrollwheel fix (with 'Stretch Video' and others) assuming value of 120
- and some other minor improvements.

--------------------------------
--------------------------------

Version 0.31

- Added library "MediaEndedNotice" event:
the "MediaEndedNotice" event is fired together with, but just before, the "MediaEnded" event - as a main application process may use the "MediaEnded" event to play new ("next") mediafiles, other "MediaEnded" event "listeners" (e.g. Display Overlays) may receive their "MediaEnded" event AFTER the main application already started a new mediafile. And that's where things might go wrong. Therefore you can use the "MediaEnded" event as normal (and play next mediafiles) and use the "MediaEndedNotice" event with secondary running processes (like a player driven dynamic overlay (like the "SubTitles" example overlay)) just to stop the process (or any action other than playing a new mediafile);

- Added library "MediaStoppedNotice" event:
the "MediaStoppedNotice" event is fired together with, but just before, the "MediaStopped" event - please see explanation above.

- Main Example Application:
- added Display Overlay "MP3 Karaoke",
- changed Display Overlay "Scribble" (preserve and scaling),
- re-installed non-transparent position slider (to minimize flicker),
- default playlist (and screencopy) now stored in user AppData folder,
- some minor other changes.

- Scheduled for next update:
- example apps m3u playlists;
- "Mini MP3 Player" example application.

--------------------------------
--------------------------------

Version 0.3

- Improved Display Overlay Handling;

- The main form does not get deactivated when a Display Overlay is activated (unless you choose to do so in the overlay's activation event code);

- Changing Display Overlays (e.g. when next media is played) on minimized forms sets the new overlay without (direct) activation. This prevents taskbar notifications and firing the VisibleChanged event;

- Synchronization of Display Overlays with the main form when restoring from a minimized windowstate is now a built-in PVS.AVPlayer option: OverlayDelay. When a form is restored from minimized, an overlay's visibility is delayed until the main form is visible. The OverlayDelay option is by default enabled (300 ms) but can be changed with:

    myPlayer1.OverlayDelay = ms; // set delay time (100-1000 ms)
    myPlayer1.OverlayDelay = 0;  // disable overlay delay

--------------------------------
--------------------------------

Version 0.28

- Improved support for newer codecs/filters.
- Some minor other improvements and fixes.
- Updated example applications, including easy skinning trackbar example (please see FolderView example sourcecode).

--------------------------------
--------------------------------

Version 0.27

- Added .NET Framework 4.5 library.

- The library is now compiled for 'Any CPU' and marked as (fully) CLS-compliant.
The use of 32-bit or 64-bit library code depends on your application's 'Solution Platform' setting and the used computer/Windows version.

- All library events now use .Net system generic eventhandlers.
In existing C# projects please remove anything directly in front of the word 'EventHandler', e.g. change:
myPlayer1.MediaEnded += new Player.MediaEndedEventHandler(myPlayer1_MediaEnded);
to:
myPlayer1.MediaEnded += new EventHandler(myPlayer1_MediaEnded);
You also can use:
myPlayer1.MediaEnded += myPlayer1_MediaEnded;

- Event MediaAudioChanged has been split into two events:
MediaAudioVolumeChanged - signals that (only) the player's audio volume has changed, and
MediaAudioBalanceChanged - signals that (only) the player's audio balance has changed;
You still can use the same eventhandler for both events if you like to.

- VideoBounds (DisplayMode.Manual) can be set/changed anytime when a player has a display (was: when a video is playing). If you want to use it in your application like before you can use: if (myPlayer1.VideoPresent) {...};

- Added methods 'PlayNext' and 'PlayPrevious' (and events 'MediaNextRequested' and 'MediaPreviousRequested') to play 'next' or 'previous' media (e.g. myPlayer1.PlayNext();). For convienience only, the methods just generate an event (if media is playing) to be handled by the main application.

- Applied some minor other changes.

--------------------------------
--------------------------------

Version 0.26

- the LastError property has been renamed to LastErrorCode:
the new LastError property now returns a boolean to indicate if there was a last error; to get the last error code please use the LastErrorCode property:
if (myPlayer1.LastError) handle error, or
if (myPlayer1.LastErrorCode != 0) handle error

- the default display (the videowindow if no display was specified while playing movies) is no longer available (this means you always have to specify a display (a Form or other Control) to play movies (not needed with audio only (music)).
You can use a Form in your project to create a 'standalone' display like the (former) default display (myPlayer1.Display = myForm2;).

- fixed AudioPresent (was changed by optimization and worked only after audio setting was changed).

- improved Display Overlay handling:
Display Overlays don't obscure overlapping child windows (like a MessageBox or OpenFileDialog) anymore when activated (shown/reshown/changed) and other improvements.

- the default display overlay mode has changed to OverlayMode.Video (was OverlayMode.Display).

- methods and properties no longer available (their functions may be realized otherwise):
PlayerStartInfo
DisplaySize
OverlayAutoScale
OverlayEnabled
OverlaySize
GetMediaFileLength
PositionSliderCustom
PositionSliderFocus
AudioVolumeSliderFocus
AudioBalanceSliderFocus
SpeedSliderFocus

- events added: MediaDisplayChanged, MediaOverlayChanged, MediaOverlayModeChanged, MediaVideoEnabledChanged, MediaAudioEnabledChanged, MediaRepeatChanged, MediaVideoBoundsChanged, MediaFullScreenChanged, MediaFullScreenModeChanged.

- properties renamed: DeviceID, DeviceType and DeviceName to MCIDeviceID, MCIDeviceType and MCIDeviceName.

--------------------------------
--------------------------------

Version 0.25

- Some errorcodes may differ from previous versions
- The Step method (and the shuttle slider) now also signals audio file positions (position events)
- Provides direct access to all MCI devices and functions both with and without the use of a PVS.AVPlayer Player (for special purposes only):

--------

Using the direct MCI access functions:

Note: It is not recommended to use these options unless you really need some special MCI functions not provided by the PVS.AVPlayer Player. You might also consider using 'external' functions instead of MCI to 'get the job done', like retrieving information directly from the playing mediafile with .NET methods.
Most of the MCI functions that are not available with the PVS.AVPlayer library are not supported by the mpegvideo type device.
For more information about MCI functions you can start at http://msdn.microsoft.com/en-us/library/dd743572%28v=VS.85%29.aspx

Some examples:

--------

1. Using direct MCI access functions without a PVS.AVPlayer Player:
You can use these functions at all times, even if you have not created a PVS.AVPlayer Player.

MCI.SendString("set CDAudio door open", null, IntPtr.Zero);
MCI.SendString("set CDAudio door closed", null, IntPtr.Zero);

----

string myMovie = @"C:\MyMovies\MyMovie.mpg";
StringBuilder resultText = new StringBuilder(512);

int errorCode = MCI.SendString("Open \"" + myMovie + "\" type mpegvideo alias MyPlayer", null, IntPtr.Zero);
if (errorCode == 0) errorCode = MCI.SendString("Play MyPlayer", null, IntPtr.Zero);
if (errorCode != 0)
{
    MCI.GetErrorString(errorCode, resultText);
    MessageBox.Show(resultText.ToString());
}

--------

2. Using direct MCI access functions with a PVS.AVPlayer Player:
You can only use these functions when a mediafile is playing (opened). If you're using functions that are also available with a PVS.AVPlayer Player (or some of the other functions) you may cause the Player to malfunction. Errorcodes are returned as with all other Player functions (also with myPlayer1.LastError(String)).

myPlayer1.MCICommand("pause"); // example, please use the player's pause command.

----

myPlayer1.MCICommand("setaudio", "stream to 1"); // example, no other streams are available with 'mpegvideo'.
if (myPlayer1.LastError != 0) MessageBox.Show(myPlayer1.LastErrorString);

----

string result;
myPlayer1.MCIRequest("status", "mode", out result);
MessageBox.Show(result);

--------------------------------
--------------------------------

Version 0.24

- The libraries are now signed (strong named, thanks Gernod (comments))
- Changing size of display overlays with video- to musicfiles fixed
- The example application now allows URLs to be added to the playlist (and a few other minor changes).

--------------------------------
--------------------------------

Version 0.23

- Fullscreen display on secondary screens has been fixed
- 'Smooth' activating (show) of display overlays has been improved
- Easy cancel (closing) of contextmenus on non-focusable display overlays has been fixed
- Plays one or two more types of mediafiles (thanks Marco (comments))
- The example application (version 3.3) now uses library version 0.23 and has also has been cleaned up a little bit.

--------------------------------
--------------------------------

Version 0.22

- Redraw of video with certain displaymodes when paused has been fixed
- Zooming video has changed (internally)
- An option (ResizeFormRefresh) has been added to redraw the main Form when the player's display is resized, because MCI sometimes 'spills' video on adjacent controls (to the right of the display) when doing so.

--------------------------------
--------------------------------

Version 0.21

This version cleans up the 'interface' (like some method names, parameters and intellisense text) a little bit more, fixes a few issues and comes compiled for different .NET versions.

- All time information (previously in milliseconds) now use the TimeSpan structure
- MediaEvent names have changed (a little bit), MediaEventArgs are replaced by (empty) EventArgs
- The Start- and EndPosition properties are now used for the next mediafile to play only and reset to 0 after media has started playing, the start- and/or end position of the playing media can be changed with the StartPositionMedia and/or EndPositionMedia properties
- Starting media (Play) with PlayerStartInfo no longer shows up with Visual Studio intellisense, but is still available.

--------------------------------

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)

Share

About the Author

Peter Vegter
United States United States
No Biography provided

You may also be interested in...

Permalink | Advertise | Privacy | Terms of Use | Mobile
Web02-2016 | 2.8.180515.1 | Last Updated 16 Apr 2018
Article Copyright 2010 by Peter Vegter
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid