|
Go to the ASP.NET [^] forum and try asking there.
|
|
|
|
|
I'm working on a managed MIDI wrapper. Because the only valid devies are those that ae installed, the wrapper exposes a static public property that is an array of devices that are instances of the Input or Output classes (it is not possible for them to create their own instances of these classes).
It's extremely important that any devices used are stopped and closed etc correctly before the program closes.
To do this, I've made the Devices[] property getter return a singleton's static property that is the array, and put the necessary logic in the singleton's destructor.
Is this the best approach?
public class Output
{
private class Singleton
{
static Singleton()
{
Output[] result = new Output[GetNumberOfDevices()];
if (result.Length > 0)
{
for (UInt32 u = 0; u < result.Length; u++)
{
result[u] = new Output(u);
result[u].SetDeviceCapabilities();
}
}
Devices = result;
}
internal static Output[] Devices { get; private set; }
~Singleton()
{
Output.CloseAll();
}
}
internal Output(UInt32 id)
{
}
public static Output[] Devices
{
get { return Singleton.Devices; }
}
public new static void CloseAll()
{
foreach (Output device in Devices)
device.Close();
}
public override void Close()
{
}
internal static UInt32 GetNumberOfDevices()
{
return InteropFunctions.midiOutGetNumDevs();
}
internal void SetDeviceCapabilities()
{
}
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
modified on Thursday, May 28, 2009 4:54 PM
|
|
|
|
|
This is a good example of where you should use the Dispose pattern. You can find a bit about the Dispose pattern at http://msdn.microsoft.com/en-us/library/b1yfkh5e.aspx[^] on MSDN.
Here's a bit of a template example of the class members I would add to implemented it in your case:
private object syncRoot = new object();
private bool isDisposed = false;
~Output()
{
Dispose(false);
}
public override void Close()
{
Dispose();
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
lock(syncRoot)
{
if(!isDisposed)
{
if(disposing)
{
}
}
isDisposed = true;
}
}
I would also consider having some separate class, like a MIDIDeviceManager to control the life cycle of our Output objects and provide system information like the GetNumberOfDevices() method. In my opinion it would be a bit cleaner than having it all in the Output class. It could also allow you to only create the Output device instances the user needs, rather than an array of all of them.
|
|
|
|
|
I was avoiding Dispose as calling my Close automatically frees unmanaged resources - but on reflection, it makes sense.
By the way, the 'real' classes derive from an abstract base class, so I've implemented the Dispose in there.
I've experimented with a 'manager' class, and this is what I have as a basic outline. Opinions welcome!
public static class MIDIDeviceManager
{
private static List<MIDIOutput> activeOutputs = new List<MIDIOutput>();
private static List<MIDIInput> activeInputs = new List<MIDIInput>();
private static UInt32 availableMidiOutputCount;
private static UInt32 availableMidiInputCount;
public static UInt32 AvailableMIDIOutputCount
{
get
{
if (availableMidiOutputCount == 0)
availableMidiOutputCount = InteropFunctions.midiOutGetNumDevs();
return availableMidiOutputCount;
}
}
public static UInt32 AvailableMIDIInputCount
{
get
{
if (availableMidiInputCount == 0)
availableMidiInputCount = InteropFunctions.midiInGetNumDevs();
return availableMidiInputCount;
}
}
public static IList<MIDIOutput> ActiveOutputs
{
get { return activeOutputs.AsReadOnly(); }
}
public static IList<MIDIInput> ActiveInputs
{
get { return activeInputs.AsReadOnly(); }
}
public static MIDIOutput GetMIDIOutput(UInt32 id)
{
if (id < availableMidiOutputCount)
{
MIDIOutput result = null;
foreach (MIDIOutput midiOutput in activeOutputs)
{
if (midiOutput.ID == id)
{
result = midiOutput;
break;
}
}
if (result == null)
{
result = new MIDIOutput(id);
activeOutputs.Add(result);
}
return result;
}
throw new ArgumentOutOfRangeException(
"id", "ID out of range. Check MIDIOutputCount for available range.");
}
public static MIDIInput GetMIDIInput(UInt32 id)
{
if (id < availableMidiInputCount)
{
MIDIInput result = null;
foreach (MIDIInput midiInput in activeInputs)
{
if (midiInput.ID == id)
{
result = midiInput;
break;
}
}
if (result == null)
{
result = new MIDIInput(id);
activeInputs.Add(result);
}
return result;
}
throw new ArgumentOutOfRangeException(
"id", "ID out of range. Check MIDIInputCount for available range.");
}
internal static void RemoveDevice(MIDIDevice device)
{
switch (device.DeviceType)
{
case DeviceTypes.Input:
activeInputs.Remove((MIDIInput)device);
break;
default:
activeOutputs.Remove((MIDIOutput)device);
break;
}
}
}
public abstract class MIDIDevice : IDisposable
{
private object syncRoot = new object();
private bool isDisposed = false;
public MIDIDevice(UInt32 id)
{
ID = id;
}
~MIDIDevice()
{
Dispose(false);
}
public UInt32 ID { get; private set; }
public string Name { get; internal set; }
public abstract DeviceTypes DeviceType { get; }
public void Close()
{
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
lock (syncRoot)
{
if (!isDisposed)
{
if (disposing)
{
Close();
MIDIDeviceManager.RemoveDevice(this);
}
}
isDisposed = true;
}
}
}
public class MIDIOutput : MIDIDevice
{
internal MIDIOutput(UInt32 id) : base(id) { }
public override DeviceTypes DeviceType
{
get { return DeviceTypes.Output; }
}
}
public class MIDIInput : MIDIDevice
{
internal MIDIInput(UInt32 id) : base(id) { }
public override DeviceTypes DeviceType
{
get { return DeviceTypes.Input; }
}
}
public enum DeviceTypes
{
Output = 0,
Input = 1,
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Good people,
Using Windows Installer I am creating a .msi file. How do I make the application run immediately after installation? Also, how do I give the user a choice about whether it should run after install? I know about the dialog boxes but I just wasn't sure how to make it run after-wards.
Thanks for any help or information you can provide.
Blitz
|
|
|
|
|
hi
i want to read bmp image and then save that by RLE(run length encoding) algorithm and return rle file to bmp file.
this is my first project about image. i am inexperienced.
please tell me your recommands for do this project.
|
|
|
|
|
First look here: http://en.wikipedia.org/wiki/Run-length_encoding[^]
But then observe that it will only work well for pictures with many pixels of the same colour in a row.
A better idea (not very advanced, but a nice hobby project perhaps) would be to estimate the colour of every pixel based on only preceding pixels (often predicted as a weighted average of the pixel left, above, left-above and right-above) and then calculate the difference between the expected colour and the actual colour. Then apply RLE to that (now it will also compress gradients) and then Huffman encode it.
It wouldn't really work on photo's, but it's ok for screenshots and diagrams.
edit: note that applying Huffman coding means that you can use a new symbol for the RLE marker thing, instead of having to do crazy hacks with "escape sequences" and such. For extra winnage you can put the length symbols in a different alphabet and Huffman compress them separately (or just output them as raw bytes) - best not encode them in the same way as the actual data since that would mess up the symbol frequencies.
|
|
|
|
|
|
I have used LINQ in the past to call stored procedures, but this is my first time using LINQ to SQL instead of ADO.Net and stored procedures.
So far I really like it. My only issue with it is that if a table changes you have to delete the table from the model and re-add the table. Is there no way to have the dbml class scan the database for changes?
Also, the System.Xml.Linq classes are incredible. I have to process a bunch of XML in this application and I can't believe how easy it is.
I didn't get any requirements for the signature
|
|
|
|
|
I just use ADO.net; it's simple, I'm in control, I don't have to worry about what it's doing in the background.
|
|
|
|
|
Same as PIEBALDconsult, at the moment. I'm looking into the other two options at the moment (very early stages).
You are absolutely correct about LINQ to XML though. IMNSHO it is the best of the XML access technologies in .NET.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|
|
|
I have a windows form that can be moved around by clicking and dragging on any portion of the form. I used the method of overriding WndProc, and setting the result of the NCHITTEST function to be HTCAPTION, in order to fool the form into thinking I clicked the caption - so it enables dragging.
The code for this works great, and is below:
protected override void WndProc(ref Message msg)<br />
{<br />
if (msg.Msg == (int)WinAPI.NCHITTEST)<br />
{<br />
DefWndProc(ref msg);<br />
if ((int)msg.Result == (int)MousePositionCodes.HTCLIENT)<br />
{<br />
msg.Result = (IntPtr)MousePositionCodes.HTCAPTION;<br />
return;<br />
}<br />
}<br />
}<br />
base.WndProc(ref msg);<br />
}
The problem occurs when I dock a ToolStripPanel into the form (this is acting as a draggable toolbar). I need any portion of the ToolStripPanel that is not covered by a ToolStrip to pass up the messages necessary to cause the whole form to enter drag mode.
I have created my own ToolStripContainer class to override the WndProc function and have tried using the same function as above, but it causes the ToolStripContainer to enter drag mode *within* the form, which is not the desired functionality.
I have also tried passing up NCHITTEST messages to the parent, as well as constructing a new message with the current mouse coordinates and sending it to the parent using the WinAPI and the parent's window handle.
I have to be missing something simple here... Anyone have any ideas?
|
|
|
|
|
Hello,
I use SortedList as follows:
sortedlist sr=new sortedlist();
sr.add("abc","def");
How can i retrieve the value according the key? I mean if the key is "abc" and the value is "def"?
I mean when i write sr.getkey it can receive only integer , i mean sr.getkey(int) but i need string as key.
Also when i use :
sortedlist<string,string> sr=net sortedlist();
sr.add("abc","def");
and i do :
string k=sr["abc"];
it says : The given key was not present in the dictionary
Also i tried SortedDictionary but it's the same with it
|
|
|
|
|
Try the Generic Version, it seems to work fine for me with similar code to yours.
|
|
|
|
|
What does it mean Generic Version?
|
|
|
|
|
use System.Collections.Generics.SortedList instead of System.Collections.SortedList. If you are using 2005, Visual Studio defaults to the wrong namespace when creating your class files for you.
|
|
|
|
|
SortedList<string, string> sr = new SortedList<string, string>();
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia) Why are you using VB6? Do you hate yourself? (Christian Graus)
|
|
|
|
|
Hi,
your code does not compile at all. There isn't a single line without errors.
If you fix all the typos you would get one compile-time error (cannot implicitly convert...).
So you have to add an explicit string casting (or replace the old SortedList by a generic one).
If you want to ever become a successful programmer you need to become meticulous right away.
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
I used the system.collection.generic but it doesn't help as well.
|
|
|
|
|
Visual Studio 2005 is fine for .NET 2.0 (the first version offering generics).
You have another typo. Read the documentation and follow it to the letter.
[EDIT] In the previous version of your reply, the one containing:
Ok thanks,
But there is a problem- I use VS2005.
I wrote :
using System.Collections.Generics;
(i wrote using system.collection too).
But I get error saying that the type or namespace Generics does not exist in namespace system.collection
you had another typo.
[/EDIT]
Luc Pattyn [Forum Guidelines] [My Articles]
The quality and detail of your question reflects on the effectiveness of the help you are likely to get.
Show formatted code inside PRE tags, and give clear symptoms when describing a problem.
|
|
|
|
|
Does this code even compiles?
Following works perfectly fine for me:
SortedList<string,string> sr=new SortedList<string,string>();
sr.Add("abc","def");
string k=sr["abc"];
To be on the safer side, you can use TryGetValue method.
जय हिंद
|
|
|
|
|
Here is a snippet from my code:
SortedList <string, string=""> focus_URLS = new SortedList <string, string="">();
focus_URLS.Add("AR Coater","ARC+Lab&MachineName=AR+Coater&TypeID=2&StationID=1&datatype=0");
string focus_url_end = focus_URLS["AR Coater"];
but i receive error saying the key wasn't found
|
|
|
|
|
Does anyone know the problem?
|
|
|
|
|
Earlier today I had this exact error.
In my case it was because the key had been added with a preceding space. i.e. key = " abc", search = dict["abc"] <== error
So ensure that there are are no extraneous spaces in either the key, when added to the list, or your literal in the lookup.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
|
|
|
|