|
ZIP compression doesn't support streaming. Since the compression algorithm uses an index based on the contents of the ENTIRE stream it's compressing. It sounds like you're already using the best method for doing ZIP-type compression on a stream. I mean, break your stream into fragments, run the compression acrossed a single fragment, send the ZIP'd version of the fragment down the wire, then continue with this procedure on the next fragment. The receiving side will have to un-ZIP each fragment and recombine each piece into the original stream.
But, since a ZIP contains the bit stream substitution table used to compress the fragment, you'll be wasting bandwidth on sending this table for each fragment. This overhead will ultimately reduce the benefit your getting with compression.
Your best bet is to ZIP the entire file all at once, then send it using normal file transfer means. Using the fragmentation method you described, you're actually getting a smaller return for your coding investment.
|
|
|
|
|
|
I've found some examples here on putting icons in subitems of a listview. that works fine, but I don't want an icon/image in the first column, so the listview puts a gap there. Is there any way around this?
If I write code in my sleep, does that make me brilliant, or just a lazy programmer?
My articles
www.stillwaterexpress.com
BlackDice - the programmer formerly known as bdiamond
|
|
|
|
|
You may have better luck asking on the message board for one of the articles you found, the best probably being C# ListView v1.3[^] (also known as Glacial ListView).
Not only have they probably got a similar question before (and hopefully answered it), the authors of the better articles have worked extensively with the Common Controls APIs (since almost all the Windows Forms controls encapsulate the Common Controls in the BCL, and most List View variants start with the List-View common control). You could also try searching this forum as I know I've answered similar questions in the past (long ago). The article message boards are still your best bet, however.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Hi folks!
Can someone tell me how to access a GridItem of the PropertyGrid programmatically? I don't the value but the label. I want to change the background color of a single field in the PropertyGrid. Is this possible and if yes, how can I do that?
Cheers!
...Dan
|
|
|
|
|
Without reflection, your only way to get a specific GridItem is to use either the SelectedGridItem property or the SelectedGridItemChanged event which are documented on the PropertyGrid . If you read the documentation for the GridItem , however, you'll see no property to change the background color. It's risky anyway. Since GridItem s are created and destroyed constantly, you need to make sure that any references you have to it (like an event handler) are destroyed otherwise you'll consume memory that will never be released (if you have, for example, an event handler for a GridItem and the PropertyGrid would normally release that GridItem it won't be released since you have a reference to it; therefore, it will never be garbage collected).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
I'm trying to get printer info from the OS using the GetProfileStringA function in Kernel32.dll. I used this logic in VB.NET for a while now without any problems, but in C#, the return string buffer is not getting filled. Does anyone have any ideas what might causing this?
<br />
[DllImport("Kernel32.dll")]<br />
static extern int GetProfileStringA( string lpAppName, string lpKeyName, string lpDefault, string lpReturnedString, int nSize) ;<br />
<br />
public bool SetDefaultPrinter(string printerName) <br />
{<br />
bool success = true;<br />
<br />
string sBuffer = new string(' ',255);<br />
string sPrinterSetup = "";<br />
string[] sEle;<br />
string sDriver;<br />
string sPort;<br />
<br />
try<br />
{<br />
<br />
int i;<br />
<br />
i=GetProfileStringA("PrinterPorts", printerName, "", sBuffer, sBuffer.Length);<br />
<br />
if (sBuffer.Trim() != "")<br />
{<br />
sEle = sBuffer.Split(',');<br />
if (sEle.Length > 0)<br />
{<br />
sDriver = sEle[0];<br />
sPort = sEle[1];<br />
sPrinterSetup = printerName.Trim() + "," + sDriver + "," + sPort;<br />
WriteProfileStringA("windows", "Device", sPrinterSetup);<br />
SendMessageA(HWND_BROADCAST, WM_WININICHANGE, 0, "windows");<br />
System.Windows.Forms.Application.DoEvents();<br />
}<br />
}<br />
else<br />
{<br />
errorMessage = "Printer "+printerName+" not detected.";<br />
success = false;<br />
}<br />
<br />
}<br />
catch (Exception ex)<br />
{<br />
errorMessage = ex.Message;<br />
success = false;<br />
}<br />
<br />
return success;<br />
<br />
}<br />
|
|
|
|
|
First, never allocate a string buffer with spaces, use '\0' for null characters. This ensures that - so long as you don't have any buffer overrun - your string is null-terminated whether the API supports it or not. It's far better to use a StringBuilder however, which also helps ensure this and may increase performance since it is mutable, unlike string .
Because you're declaring GetProfileStringA , you must also specify the DllImportAttribute.ExactSpelling . While not necessary (the default CharSet is CharSet.Ansi , it may also be a good idea to specify CharSet=CharSet.Ansi for better readability, IMO.
This is all not only a waste of time, though, but also a security problem. Because you're P/Invoking to unmanaged code your code requires [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)] . There's already a property defined by the BCL (and the BCL assemblies, by default, already have the necessary security permissions to execute) that does this: PrinterSettings.InstallPrinters . This makes the necessary calls and returns you a nice string[] array. Even using WMI is a better alternative to P/Invoking.
Why? Because the BCL assemblies allow partially-trusted assemblies and, since the BCL assemblies have the necessary permissions (by default), actually make the calls that require that permission and your code doesn't need that permission (it would still need the PrintingPermission , however, which is granted, by default, to even the Internet zone in .NET 1.1 (nothing is granted to the Internet zone by default in 1.0).
This also makes for cleaner code. Instead of allocating buffers, parsing strings, and everything that's necessary - and it may work differently, depending on what you're doing, in Windows vs. Windows NT - you enumerating one simple property: PrinterSettings.InstallPrinters .
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks for your reply! Initializing the string with nulls made no difference by itself. However, adding DllImport attributes did help.
[DllImport("Kernel32.dll", CharSet=CharSet.Unicode,ExactSpelling=true)]<br />
As you can see, I decided to use Unicode, and instead of GetProfileStringA, declared GetProfileStringW.
I'm having a little trouble getting a StringBuilder in C#. StringBuilder is not showing up as a member of System.Text. All that does show up is RegularExpressions. Any ideas on that?
I do use PrinterSettings.InstalledPrinters to get the list of all printers installed. I'll look into using it to get the more detailed information for the specific printer I'm interested in. You'd think that PrinterSettings would have a method to set the system default printer without having to resort to API calls.
Thanks, again!
|
|
|
|
|
If you use Unicode, then it won't work on Win9x. Why not just declare it as:
[DllImport("kernel32.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.U4)]
static extern int GetProfileString(string appName, string keyName, string default,
[Out] string returnedstring, [MarshalAs(UnmanagedType.U4)] int size); That way, it works on both platforms?
If you're typing using System.Text only namespaces show up. The whole point of importing namespaces is so you don't have to qualify all your classes. If you import System.Text the StringBuilder will show up as a usable class (it's defined in mscorlib.dll, which is always referenced by default whether you see it in VS.NET or not).
BTW, I didn't say that initializing the string buffer to NULL characters would fix the problem, only that you should to make sure the string is initialized correctly by being "zero'd out". It's still a better idea to use PrinterSettings.InstalledPrinters . That's why a BCL exists: to common routines trivial (and, in .NET's case, to alliviate the burden of your code requiring extra permissions).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Unfortunately, PrinterSettings.InstalledPrinters only returns a collection of strings (not a string array) that contain the printer names. Other items (driver name and printer port) are required to set the default printer (via WriteProfileString) that InstalledPrinters does not provide.
The MS documentation on GetProfileString seemed to imply that GetProfileStringA/W should be used instead. Also, we don't have any computers running Windows 9x any more. Anyone that is needs to upgrade.
|
|
|
|
|
The Platform SDK documentation wouldn't say that (trust me). You should use GetProfileString , which is a macro definition for GetProfileStringA or GetProfileStringW depending on whether or not UNICODE is defined. Practically all Microsoft APIs that take a string as a parameter are defined this way (unless string parameters are explicitly always ANSI or always Unicode).
If you want to set the default printer and don't have to worry about Windows machines (i.e., 9X and Me) or Windows NT 4, then enumerate PrinterSettings.InstalledPrinters , find the printer, and call SetDefaultPrinter defined in winspool.dll. You can more easily use WMI on supported platforms (the platforms that .NET supports, but, IIRC, 98 and NT 4 will need the WMI redist installed) to abstract the differences away if you want to support older Windows platforms. As I wrote some time back in this forum:
using System;
using System.Management;
using System.Reflection;
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyKeyName("dev")]
class Printers
{
static void Main(string[] args)
{
EnumeratePrinters(args.Length > 0 ? args[0] : null);
}
static void EnumeratePrinters(string defaultName)
{
ManagementObject defaultPrinter = null;
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"select * from Win32_Printer");
foreach (ManagementObject printer in searcher.Get())
{
string name = printer["Name"].ToString();
Console.WriteLine("Printer: " + name);
if (defaultName != null &&
string.Compare(name, defaultName, true) == 0)
defaultPrinter = printer;
}
if (defaultPrinter != null)
{
Console.WriteLine("Setting default printer to \"{0}\"",
defaultPrinter["Name"]);
defaultPrinter.InvokeMethod("SetDefaultPrinter", null);
}
}
} WMI is a services that allows scripting and other COM clients to query and modify data on local and remote machines.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Wow. You don't know how much time has been spent by folks trying to figure out ways to set the system default printer. I've scoured the internet, Microsoft KB, etc., and the only references found specify using API calls.
Your example works great. You've used some things I'm not familiar with (e.g., ManagementObject), so I'll have to study this a bit. Thanks, Heath.
|
|
|
|
|
Never mind on that StringBuilder question - I had a senior moment.
|
|
|
|
|
Hi,
I have a Windows Service which uses a NotifyIcon. If the
computer is rebooted, and I log on, I see the icon appearing, everything
OK. If I log off and log on again, the icon is gone. What is happening over
here ? Also, if I manually stop/start the service the Icon appears after
starting the service, but is gone after logging off and on again.
|
|
|
|
|
Without any details or code snippets, it's almost impossible to tell you anything. However, it appears that you're assuming the service is stopped when you log off and started when you log on. That's not the case. Services were created to run before credentials are even required of an interactive user and have nothing to do with whether a user is logged on or off (even if you run the service as an interactive user, a separate window station is created in order to run the service; allowing the service to interact with the desktop interacts with the current interactive user account).
Your evidence also supports that: if you stop and restart the service your icon is back. If you log off and back on, it's not there. When you logged off the service wasn't stopped (it is run by the service control manager (SCM), not the Windows shell).
You should consider creating a separate control panel application that is started from HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run or the [All Users]\Start menu\Programs\Startup folder. This would interact with the service through .NET Remoting (recommended for .NET applications) or some other IPC. You can also send custom commands (see ServiceController.ExecuteCommand and ServiceBase.OnCustomCommand ) to communicate with your service, but you'll limited to a simple int , requiring that you create your own protocol for controlling your service (it is much easier than .NET Remoting or IPC, however, if all you need to do is send simple commands to perform some routine).
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Thanks for your reply,
I'll try to give some more details :
The service I have isn't stopped when I log off, it keeps running, like it should. I've added a NotifyIcon to the service, and it is displayed only once : Right after your start the service through 'Administrative Tools->Services', or the first time you log in. If you have the time, please try creating a simple service, add a NotifyIcon to it, register as a service and you should see the same.
I only see this with a service withc managed code, a service created with Visual Studio 6.0/ATL code will always show the icon.
|
|
|
|
|
Is there a method to calculate the count of minutes between two given datetime values ?
|
|
|
|
|
Sure. The DateTime and TimeSpan structures have lots of useful helper methods for doing stuff like this.
Here is my (very contrived) example of one way to do it (NOTE: there are several other ways to go about this):
DateTime time1 = DateTime.Now;<br />
DateTime time2 = DateTime.Now.Add(new TimeSpan(0,0,59,0,0));<br />
<br />
TimeSpan span = time2.Subtract(time1);<br />
int minutes = span.Minutes;
The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’
|
|
|
|
|
FYI, the - operator also returns a TimeSpan when subtracting two DateTime , and subtracting a TimeSpan from a DateTime yields another DateTime :
DateTime dt1 = DateTime.Now;
DateTime dt2 = dt1.AddDays(30);
TimeSpan span = dt2 - dt1; Certainly makes for cleaner code, IMO.
This posting is provided "AS IS" with no warranties, and confers no rights.
Software Design Engineer
Developer Division Sustained Engineering
Microsoft
[My Articles] [My Blog]
|
|
|
|
|
Agreed. My post was intentionally explicit. In practice I use the subtraction operator as well.
Thanks for the feedback.
The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’
|
|
|
|
|
There is:
DateTime a = new DateTime(2004, 11, 15, 12, 30, 15, 22);
DateTime b = new DateTime(2004, 11, 15, 13, 33, 15, 22);
double minutes = ((TimeSpan) (b - a)).TotalMinutes;
www.troschuetz.de
|
|
|
|
|
Hi,
I developed a User Control (B) that inherits from another User Control (A).
At first, the control worked fine. Thus, I continued development.
Currently, the control (B), that I initially dragged on the form in the test app, still works.
However, when I try to drag an additional instance of the same control to the same form, I get the error "Object reference not set to an instance of an object", showing on the form a picture saying "System.NullReference" with a red icon with a white cross.
When I try to drag the control to a new test project's form, I get this same error.
Still, the original instance I dragged on the form still works. When I step through that control, I can see that in the constructor all values are initialised to the intended values.
The user control (A), that the null-reference user control (B) inherits from, still works fine; I can still drag additional instance of that control (A) to my form without problems.
Both controls do not contain other controls; I just draw things on them and react on mouse actions.
I don't understand why this user control claims to be a null reference, when I drag a new instance on the form, while the initially created instance of the same control, referencing the same source code, still works.
Closing down the developer environment and restarting it, didn't help either.
Has anyone else experienced a problem like this?
Regards,
Jannigje
|
|
|
|
|
I've had cases like this as well. It sounds like there may be an issue with versioning. What happens if you remove the <@Register> tag and references for the control, then re-add them to your containing page?
It may be easier (during development) to add the controls manually by editing the HTML until the control is stable.
The most exciting phrase to hear in science, the one that heralds the most discoveries, is not 'Eureka!' ('I found it!') but 'That's funny...’
|
|
|
|
|
I had tried that, too, several times, without any effect.
After adding a try-catch in my OnPaint, I could run it without problems and it worked at run-time, but it still displayed with an error on my form in design mode.
Then, while, again, checking if all properties had been intialised - without doing any changes (as far as I know), the control suddenly displayed on the form in design mode, as it should.
I've got the feeling that it has something to do with the initialisation of some value. While the value is wrong, it cannot draw anything in design mode (and, apparently, gives a null reference), but at run time, the value is filled in and no problems occur. Still, all values seem to be properly initialised in the constructor.
Strange...
Jannigje
|
|
|
|
|