Default Blue Green Red
Pages: [1] 2 3
 1 
 on: July 27, 2010, 03:48:40 AM 
Started by BC_Programming - Last post by BC_Programming
Since I've started working with C#/.NET I've noticed that the framework doesn't appear to have built in functionality for reading windows INI files. It is of course, rather simple to create a class akin to my previous cINIFile class in VB6 in C#, in fact, it's quite a lot easier in many ways.

Code: (csharp)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace BCStartup
{
    public class INIValue

    {
        public String Name { get; set; }
        public String Value { get; set; }
        public String Comment { get; set; }

        public INIValue(String pName, String pValue, String pComment)
        {
            Name = pName;
            Value = pValue;
            Comment = pComment;
        }

        public override string ToString()
        {
            return Name + "=" + Value;
        }
    }

    public class INISection
    {
        public String Name { get; set; }
        public String Comment { get; set; }
        public List<INIValue> Values { get; protected set; }


        public INIValue this[String index]
        {
            get {
                INIValue valueitem = Values.FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase));
                if(valueitem!=null) return valueitem;
                //otherwise, we add the new item...
                valueitem = new INIValue(index, "", "");
                Values.Add(valueitem);
                return valueitem;
                
            
            
            }
            set
            {
                Values = Values.Where((p, x) => p.Name != index).ToList();
                Values.Add(value);
            }
        }

        public override string ToString()
        {
            return "[" + Name + "] (" + Values.Count().ToString() + " Values)";
        }

        public INISection(String pName, String pComment)
        {
            Name = pName;
            Values = new List<INIValue>();
        }
    }

    public class CINIFile
    {
        public List<INISection> Sections;
        //indexer...
        public INISection this[String index]
        {
            get {
                INISection sectionitem = Sections.FirstOrDefault((w) => w.Name.Equals(index, StringComparison.OrdinalIgnoreCase));
                if (sectionitem != null) return sectionitem;
                //otherwise, we add the new item...
                sectionitem = new INISection(index, "");
                Sections.Add(sectionitem);
                return sectionitem;
            
            
            
            }
            set
            {
                Sections = Sections.Where((p, x) => p.Name != index).ToList();
                Sections.Add(value);
            }
        }
        public CINIFile()
        {
            Sections = new List<INISection>();
        }

        public CINIFile(String filename)
        {
            loadINI(filename);
        }

        public static String findcomment(String INIfilestring)
        {
            bool inquote = false;
            for (int i = 0; i < INIfilestring.Length; i++)
            {
                if (INIfilestring == '\"')
                    inquote = !inquote;

                if (INIfilestring == ';' && !inquote)
                {
                    return INIfilestring.Substring(i + 1);
                }
            }
            return "";
        }

        public static INIValue ParseINIValue(String lineparse)
        {
            String parsename, parsevalue, parsecomment;
            int firstequals;
            parsename = lineparse.Substring(0, firstequals = lineparse.IndexOf('='));
            //parsecomment = findcomment(lineparse);
            ///int firstequals= lineparse.IndexOf('=');
            parsevalue = lineparse.Substring(firstequals + 1);

            return new INIValue(parsename, parsevalue, "");
        }

        public void loadINI(String filename)
        {
            loadINI(filename, Encoding.ASCII);
        }

        public void loadINI(String filename, Encoding pEncoding)
        {
            StreamReader readstream = new StreamReader(File.OpenRead(filename), pEncoding);
            loadINI(readstream);
            readstream.Close();
        }


        public void loadINI(StreamReader readerstream)
        {
            INISection currsection = null;
            String currentline;
            Sections = new List<INISection>();
            currsection = new INISection("Global", "");
            Sections.Add(currsection);
            while ((currentline = readerstream.ReadLine()) != null)
            {
                currentline = currentline.Trim();
                if (!currentline.StartsWith(";"))
                {
                    String newsectionname = null;
                    if (currentline.StartsWith("["))
                    {
                        newsectionname = currentline.Substring(1, currentline.IndexOf("]") - 1);
                        currsection = new INISection(newsectionname, findcomment(currentline));
                        Sections.Add(currsection);
                    }
                    else
                    {
                        //otherwise, it's likely a value.
                        INIValue newvalue = ParseINIValue(currentline);

                        currsection.Values.Add(newvalue);
                    }
                }
                else
                {
                    //Sections.Add(new INISection("#Comment",currentline));
                    currsection.Values.Add(new INIValue("#Comment", "", currentline));
                }
            }
        }


        public void saveINI(String filename)
        {
            saveINI(filename, Encoding.ASCII);
        }

        public void saveINI(String filename, Encoding pEncoding)
        {
            StreamWriter writerstream = new StreamWriter(File.OpenWrite(filename), pEncoding);
            saveINI(writerstream);
            writerstream.Close();
        }

        public void saveINI(StreamWriter writerstream)
        {
            foreach (INISection currsection in Sections)
            {
                if (currsection.Name.Equals("#Comment"))
                    writerstream.WriteLine(currsection.Comment);
                else
                {
                    if (!currsection.Name.Equals("Global")) writerstream.WriteLine("[" + currsection.Name + "]");

                    
                    foreach (INIValue currvalue in currsection.Values)
                    {
                        if (currvalue.Name.Equals("#Comment"))
                            writerstream.WriteLine(currvalue.Comment);
                        else
                        {
                            writerstream.WriteLine(currvalue.ToString());
                        }
                    } //foreach
                } //if #comment...
            } //foreach
        }
    }
}



paste this into a new class file (ideally, name the file CINIData.cs, but hey, I'm not here to judge.

Then, using it is simple. you can pass a filename or a StreamReader to the Constructor, or, to create a new INI file, you can not pass a file at all:

Code: (csharp)

public createINIfile(String inifile)
{
CINIFile inifile = new CINIFile();
inifile["sectionname"]["valuename"].Value="This is a value";
inifile["yet another section"]["yet another val"].Value="yet one more value";
inifile.SaveINI(inifile);
}



Reading the values from an INI file is pretty similar:

Code: (csharp)

public void listitemsinmainsection(String filename)
{
CINIFile ifile = new CINIFile(filename);
foreach(INIValue valueloop in ifile["main"])
{
Debug.Print("value:" + valueloop.ToString());

}


}



 2 
 on: April 16, 2010, 11:30:19 PM 
Started by geek9pm - Last post by BC_Programming
OK, not really a programing issue
 Just an annoyance.
I have to use the magnifier and I don't like the way it docks to the top, sides or bottom, Sometimes I just need to move it out of the way, and BAM! it docks to the nearest edge. Very annoying for somewhat who needs it for a low vision problem.
Thanks for any help you can give.

First: this forum is <NOT> a general computer help forum. You appear to believe otherwise, for one reason or another. (actually I considered having it as both, but considering the fact that there are a LOT of already well-established sites for that purpose it felt a bit redundant).

Anyway, may as well help you with this one... have you given the other two "view" modes a try? you cannot really control the docking behaviour for the "docked" view, you would need to consciously keep it away from the sides of the screen. AFAIK there is no setting that shuts off the docking. the "Lens" view might work for you.

 3 
 on: April 16, 2010, 11:01:58 PM 
Started by geek9pm - Last post by geek9pm
OK, not really a programing issue
 Just an annoyance.
I have to use the magnifier and I don't like the way it docks to the top, sides or bottom, Sometimes I just need to move it out of the way, and BAM! it docks to the nearest edge. Very annoying for somewhat who needs it for a low vision problem.
Thanks for any help you can give.

 4 
 on: April 13, 2010, 12:36:22 AM 
Started by EEVIAC - Last post by EEVIAC
"groan" is funny..

Instead of being thanked, someone get an "Errrrrrrrrrrrrrrrrrrr ! "    Grin

 5 
 on: April 12, 2010, 04:11:08 PM 
Started by EEVIAC - Last post by BC_Programming
Did you consider making the "smite" feature as a separate count of its own?  If someone "thanks" you, the "thank" count will increase.  If someone "smites" you, the "smite" count will increase..  Just a thought
I would have to literally gut SMF to add that. as it is now there is a single count- "karma"- give thanks adds one; smite removes one from that count. that is- there is only one piece of data that is modified by both. I'm sure there is a mod I could install that would make all that work- I know  there are some for vbulletin, since GlitchPC (http://glitchpc.com) has "thanks" as well as "groans" which are separate entities. I just think it seems counter-productive to add a feature to the forum that basically acts as a derogation of the user, if you know what I mean.

Quote
I got that simplified C++ book I was talking about a while back... C++ Demystified.  It helps a lot to see the picture in a simplified way.  When I start writing practice programs again, which should be soon, I'll start posting in here more, to generate some programming discussion in the forums...  Smiley

But it's so busy here already!  Tongue

That's a good idea Smiley

 6 
 on: April 11, 2010, 04:02:11 AM 
Started by EEVIAC - Last post by EEVIAC
You and your possums...     Smiley


Did you consider making the "smite" feature as a separate count of its own?  If someone "thanks" you, the "thank" count will increase.  If someone "smites" you, the "smite" count will increase..  Just a thought

Then again... You could get spammers and other users taking advantage of it, so it might not be a good idea..


I got that simplified C++ book I was talking about a while back... C++ Demystified.  It helps a lot to see the picture in a simplified way.  When I start writing practice programs again, which should be soon, I'll start posting in here more, to generate some programming discussion in the forums...  Smiley

 7 
 on: April 07, 2010, 12:11:30 AM 
Started by geek9pm - Last post by BC_Programming
Using Windows 7 with Linux.
How do you do it best?
Why would it be useful?
Thanks.  Smiley


Actually, I don't use Ubuntu in any Dual boot configuration, personally. I've helped friends/colleagues setup Windows 7 and Ubuntu dual boots.

If you install Ubuntu First on the first partition and windows Vista/7 on the second partition, Ubuntu will replace the MBR on the system boot partition with it's own, which will load GRUB on startup. when you just have Linux, that is all that is in the GRUB boot loader.

Installing Windows Vista/7 has the effect that Windows detects the other operating system and creates an entry in the Boot Configuration for it (I almost said "boot.ini" but Windows Vista/7 have changed that mechanism). Windows Vista/7, as with other Windows Versions before them, save the boot sector code for Linux (well, it's not important what the OS is, it still does it with a DOS install too) in a special file. when you choose Linux from the boot menu, it executes that "boot sector" as if it was being booted from. This sort of behaviour can be seen when you install XP and Vista or 7; selecting "Previous version of windows" in effect loads the XP boot sector, which displays the XP boot menu- the XP boot menu has no knowledge of the Vista or 7 installations. Of course this requires that you have at least three OS's, XP, an OS that appears on XP's boot menu, and windows Vista or 7.

Installing in the other order is something I am less sure of. I'm not familiar enough with GRUB to know it's particulars as I am with the windows boot loader and boot files, however, my experience with dual booting XP and 2000 tells me that it's OS agnostic; it doesn't really matter what the other OS actually is.

In the case of Windows Vista and 7; they changed the boot method; now instead of NTLDR, it loads GRLDR, and the boot information is not loaded from boot.ini but from some other file. It still uses the same mechanisms to boot from the drive as always, they just changed the code behind them. Ubuntu, as far as I've seen, saves the previous MBR code just as windows does.

Personally if I had to do it I'd install Ubuntu first, mostly because I had some issues with larger hard drive partition locations and some older distro (6 or 7) as well as the fact that even though it is not the same as the XP boot setup Vista and 7's boot configuration options are still less foreign then those of GRUB or LILO.

Which reminds me, I've always preferred LILO over GRUB, for some reason. perhaps it's because I've preferred slackware as a Linux distribution.

 8 
 on: April 06, 2010, 12:17:02 PM 
Started by geek9pm - Last post by geek9pm
Using Windows 7 with Linux.
How do you do it best?
Why would it be useful?
Thanks.  Smiley

 9 
 on: March 31, 2010, 07:36:13 AM 
Started by BC_Programming - Last post by BC_Programming
Amazingly, C# doesn't give programmers the ability to hook such things as Control+C or Control Break, or when your console application is closed via log off, or whatever.

I'm rather Noobish to C# but it seemed like a doable challenge, and I've written similar features for VB6.

I'm proud to say it was a success! Here is the Class:

Code: (csharp)

using System;
using System.Runtime.InteropServices;
namespace ConsoleHook
{
    
    public enum ConsoleEventConstants
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT = 1,
        CTRL_CLOSE_EVENT = 2,
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT = 6

    }
    public delegate int HandlerRoutine(ConsoleEventConstants ConsoleEvent);
    public class CConsoleHook : IDisposable
    {


        private HandlerRoutine mHandler;
        [DllImport("kernel32.dll")]
        private static extern int SetConsoleCtrlHandler(Delegate HandlerRout, int Add);
        public CConsoleHook(HandlerRoutine handler)
        {
            mHandler = handler;
            //add it to the Control handler...
            SetConsoleCtrlHandler(new HandlerRoutine(innerhandler), 1);
        }
        ~CConsoleHook()
        {
            this.Dispose();
        }
        public void Dispose()
        {
            if (mHandler != null)
            {
                SetConsoleCtrlHandler(mHandler, 0);
            }
        }
        private int innerhandler(ConsoleEventConstants ConsoleEvent)
        {
            if (mHandler != null)
            {
                return mHandler(ConsoleEvent);
            }
            else
            {
                return 0;
            }
        }


    }
}


My original concept placed this in it's own ConsoleHook library (thus the namespace declaration) there is, of course, nothing stopping anybody from simply plopping it into the same project that they want to use it in. (Not sure how namespace directives get along in the same project, but it will probably work.

The test application was a simple C# Console program:

Code: (csharp)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ConsoleHook;
namespace testconhook
{
    class Program
    {
        private static CConsoleHook conhook;
        static void Main(string[] args)
        {
            conhook = new CConsoleHook(new HandlerRoutine(handler));

            while (true)
            {
                String s = System.Console.ReadLine();
            }
        }
        static int handler(ConsoleHook.ConsoleEventConstants param)
        {
            //System.Windows.Forms.MessageBox.Show("ConsoleEvent Constants called with:" + param);
            System.Console.WriteLine("ConsoleEvent Called :" + param);
            return 1;

        }
    }
}



This is a rather basic demonstration. Actually, it highlight a feature that I didn't know about but still think is awesome (and probably exists in VB.NET as well)... enumerated types are printed as their name, rather then just as their value.


EDIT: Almost forgot! I really have to give "props" to APIViewer 2004, which I have been using for as long as I remember for API declarations for Visual Basic 6. It can provide declarations in a number of languages, including C#, Delphi, powerBASIC, etc. Best of all it's free!

 10 
 on: March 28, 2010, 12:49:48 PM 
Started by EEVIAC - Last post by BC_Programming
hey bc, you have 5 stars, and I have none.  It's just not fair      Sad

I was going to turn all the starts into miniature possum heads eventually, heh.

Quote
edit:  heh, I like the "smite" feature      Lol

Actually, thanks for reminding me, that wasn't supposed to be there, since as it was it was subtracting from a persons "thank" count.

Pages: [1] 2 3