Laden...
Avatar #avatar-1768.jpg
dr4g0n76 myCSharp.de - Experte
Software-Entwickler, momentan als Software Test Engineer tätig Deutschland Dabei seit 07.07.2005 2.921 Beiträge

Forenbeiträge von dr4g0n76 Ingesamt 2.921 Beiträge

14.01.2016 - 14:48 Uhr

Neuere Version

13.01.2016 - 19:17 Uhr

@Th69: Jupp stimmt.
Ich hatte zuerst gedacht, ich mache noch was anderes und das darum in Strings umgewandelt.

Hier der vorerst fertige Parser:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Drawing;

namespace WindowsFormsApplication3
{
    public class Parser
    {
        private List<Point> m_Tokens = new List<Point>();


        public string[] Tokens(string variable, string text)
        {
            List<string> tokens = new List<string>();

            Point point = Parse(variable, text, 0);
            m_Tokens.Add(point);
            while (point.X != -1 && point.Y != -1)
            {
                point = Parse(variable, text, point.X + 1);

                if (point.X != -1 && point.Y != -1)
                    m_Tokens.Add(point);
            }

            string gapText = string.Empty;
            if (m_Tokens[0].X > 0)
            {
                gapText = text.Substring(0, m_Tokens[0].X);
                tokens.Add(gapText);
            }

            string gapTexts = string.Empty;

            //if (m_Tokens[0].X > 0)
            //{
            //    gapTexts = text.Substring(0, m_Tokens[0].X);
            //    tokens.Add(gapTexts);
            //}
            for (int i = 0; i < m_Tokens.Count - 1; i++)
            {
                tokens.Add(text.Substring(m_Tokens[i].X, m_Tokens[i].Y));
                gapTexts = text.Substring(m_Tokens[i].X + m_Tokens[i].Y, m_Tokens[i + 1].X - m_Tokens[i].X - m_Tokens[i].Y);
                tokens.Add(gapTexts);
            }

            int nLastToken = m_Tokens.Count - 1;
            tokens.Add(text.Substring(m_Tokens[nLastToken].X, m_Tokens[nLastToken].Y));
            gapTexts = text.Substring(m_Tokens[nLastToken].X + m_Tokens[nLastToken].Y, text.Length - m_Tokens[nLastToken].X - m_Tokens[nLastToken].Y);
            tokens.Add(gapTexts);
            return tokens.ToArray();
        }

        public Point Parse(string variable, string text, int nStartIndex = 0)
        {
            string sVar = variable;
            int nRowIndex = text.IndexOf(sVar, nStartIndex);

            Dictionary<string, int> bracketCounter = new Dictionary<string, int>();
            string sCharacter = string.Empty;

            bracketCounter.Add("(", 0);
            bracketCounter.Add("{", 0);
            bracketCounter.Add("[", 0);

            int nPos = -1;
            bool bBracketStartFound = false;
            if (nRowIndex > -1)
            {
                nPos = nRowIndex - 1;
                while (nPos++ < text.Length - 1)
                {
                    sCharacter = text[nPos].ToString();
                    if (bracketCounter.ContainsKey(sCharacter))
                    {
                        bracketCounter[sCharacter]++;
                        bBracketStartFound = true;
                    }

                    if (sCharacter == ")") bracketCounter["("]--;
                    if (sCharacter == "]") bracketCounter["["]--;
                    if (sCharacter == "}") bracketCounter["{"]--;

                    //only to debug. not needed 
                    if (nPos <= text.Length - sVar.Length)
                    {
                        string sCheck = text.Substring(nPos, sVar.Length);
                        if (nPos + sVar.Length == text.Length)
                        {
                            if (sCheck == sVar)
                            {
                                return new Point(nPos, sVar.Length);
                            }
                        }
                    }

                    if (nPos < (text.Length - sVar.Length - 1))
                    {
                        if (text.Substring(nPos, sVar.Length + 1) == sVar + " ")
                        {
                            nPos = nPos + sVar.Length - 1;
                            break;
                        }
                    }
                    //no " " at the end.

                    if (bracketCounter["("] == 0 && bracketCounter["["] == 0 && bracketCounter["{"] == 0 && bBracketStartFound)
                    {
                        if (nPos < text.Length - 1 && text[nPos + 1] == '.')
                        {
                            bBracketStartFound = false;
                            continue;
                        }
                        break;
                    }

                }
            }

            return new Point(nRowIndex, nPos - nRowIndex + 1);
            //return text.Substring(nRowIndex, nPos - nRowIndex + 1);
        }
    }
}

13.01.2016 - 17:50 Uhr

Korrigierte Version, weil jetzt es hat zwar für alle Fälle mit Klammern, Punkt und was weiss ich alles funktioniert aber nicht mehr für nur

$row


     private string Parse(string text)
        {
            string sVar = "$row";
            int nRowIndex = text.IndexOf(sVar);

            Dictionary<string, int> bracketCounter = new Dictionary<string, int>();
            string sCharacter = string.Empty;

            bracketCounter.Add("(", 0);
            bracketCounter.Add("{", 0);
            bracketCounter.Add("[", 0);

            int nPos = -1;
            bool bBracketStartFound = false;
            if (nRowIndex > -1)
            {
                nPos = nRowIndex - 1;
                while (nPos++ < text.Length - 1)
                {
                    sCharacter = text[nPos].ToString();
                    if (bracketCounter.ContainsKey(sCharacter))
                    {
                        bracketCounter[sCharacter]++;
                        bBracketStartFound = true;
                    }

                    if (sCharacter == ")") bracketCounter["("]--;
                    if (sCharacter == "]") bracketCounter["["]--;
                    if (sCharacter == "}") bracketCounter["{"]--;

                    string sCheck = text.Substring(nPos, sVar.Length);

                    if (nPos < (text.Length - sVar.Length - 1))
                    {
                        if (text.Substring(nPos, sVar.Length + 1) == sVar + " ")
                        {
                            nPos = nPos + sVar.Length - 1;
                            break;
                        }
                    }

                    if (bracketCounter["("] == 0 && bracketCounter["["] == 0 && bracketCounter["{"] == 0 && bBracketStartFound)
                    {
                        if (nPos < text.Length - 1 && text[nPos + 1] == '.')
                        {
                            bBracketStartFound = false;
                            continue;
                        }
                        break;
                    }

                }
            }
            return text.Substring(nRowIndex, nPos - nRowIndex + 1);
        }

13.01.2016 - 17:15 Uhr

Mein erster Versuch wäre dieser:


       private string Parse(string text)
       {
            int nRowIndex = text.IndexOf("$row");

            Dictionary<string, int> bracketCounter = new Dictionary<string, int>();
            string sCharacter = string.Empty;

            bracketCounter.Add("(", 0);
            bracketCounter.Add("{", 0);
            bracketCounter.Add("[", 0);

            int nPos = -1;
            bool bBracketStartFound = false;
            if (nRowIndex > -1)
            {
                nPos = nRowIndex - 1;
                while (nPos++ < text.Length - 1)
                {
                    sCharacter = text[nPos].ToString();
                    if (bracketCounter.ContainsKey(sCharacter))
                    {
                        bracketCounter[sCharacter]++;
                        bBracketStartFound = true;
                    }

                    if (sCharacter == ")") bracketCounter["("]--;
                    if (sCharacter == "]") bracketCounter["["]--;
                    if (sCharacter == "}") bracketCounter["{"]--;

                    if (bracketCounter["("] == 0 && bracketCounter["["] == 0 && bracketCounter["{"] == 0 && bBracketStartFound)
                    {
                        if (nPos < text.Length - 1 && text[nPos + 1] == '.')
                        {
                            bBracketStartFound = false;
                            continue;
                        }
                        break;
                    }
                }
            }
            return text.Substring(nRowIndex, nPos - nRowIndex + 1);
        }

Mein Teststring folgende(r):

1.) Hallo Ingo, wie geht es Dir? $row.Substring[0].ToString().Substring(0, 2) Was machst Du heute noch?

2.) Hallo Ingo, wie geht es Dir? $row.Substring[0].ToString().Substring(0, 2)

3.) $row.Substring[0].ToString().Substring(0, 2) Was machst Du heute noch?

Funktioniert für mich fürs erste zuverlässig genug.

Der String:

row.Substring[0].ToString().Substring(0, 2) wird jedesmal gefunden.

13.01.2016 - 16:38 Uhr

Genau auf das Problem mit den Leerzeichen bin ich eben dabei auch gestoßen.
Außerdem müssten IMHO zwei Arten von Klammern beachtet werden.
Also [ und (. wenn noch irgendwo anonyme delegates usw. zum Tragen kommen sollten,
dann natürlich auch noch {.

Hmmm.....

Da muss ich mir mal noch n paar Gedanken dazu machen.

13.01.2016 - 15:55 Uhr

Ich bin dabei dem Tool

Search & Replace Tool

wieder ein paar Grund-Zusatzfunktionalitäten zu spendieren und zwar geht es mir nur um den Text parsen im Filter Feld.

Ich habe eine Variable eingeführt namens

$row.

Folgende Ausgangsdaten im oberen Textfeld:
**:::

Jetzt kann z.B.

**"Hallo $row.Substring(2, $row.Length - 2) , wie gehts?" **

eingegeben werden (ohne die Anführungszeichen).

Das Programm soll automatisch erkennen, dass nur der Teil von $row kompiliert werden soll

so dass folgendes Ergebnis herauskommt:

**:::

Es geht also darum die Anweisung vom restlichen Text zu unterscheiden.
Komme ich da irgendwie um einen komplexen Parser herum?

Anders ausgedrückt im genannten Beispiel geht es darum den eingegebenen Filter Text mit der Variable folgendermassen aufzusplitten:

"Hallo "
"$row.Substring(2, $row.Length-2)"
" , wie gehts?"

So dass ich auf jeden Fall die Anweisung mit dem $row String in einer einzelnen Zeile erhalte.

Würde der Text so aussehen:

"1 mal $row, 2 mal $row, 3 mal $row.Reverse()"**

Sollte durch das filtern herauskommen:
"1 mal "
"$row"
", 2 mal "
"$row"
", 3 mal "
"$row.Reverse()"

so dass wieder die Anweisungen mit Row jeweils in einer Ergebniszeile dastehen.

Dann würde das Programm als Ergebnis:

**:::

Ich hoffe das ist verständlich.

Es geht hier also nur darum den orange-roten Text so zu parsen, dass jeweils das Array in schwarz fettgedruckt herauskommt.


Eine andere Idee ist:

Einfach den $row Teil mit etwas zusätzlichem kennzeichen, finde ich aber für den Benutzer umständlich:

z.B.:

**"Hallo << $row.Substring(2, $row.Length - 2) >> , wie gehts?" **

Dann ist klar,

dann muss nur nach << und >> gesucht werden, um das gewünschte Ergebnis zu erhalten.

Wie würdet ihr das machen?

12.01.2016 - 15:30 Uhr

Ich zitiere mal mich selbst:

Ist hier nur ein Proof of Concept und vorerst kein besonders sauberer Code.

Siehe weiter oben.

12.01.2016 - 13:52 Uhr

Ich wollte schon immer die Technik erweitern, meine EventHandler per Namensangabe quasi zur Laufzeit registrieren zu können.

Ist hier nur ein Proof of Concept und vorerst kein besonders sauberer Code.
So geht das:

Warum will ich das tun können?

Weil dann zur Laufzeit EventHandler so an Controls geknüpft werden können, dass sie verschiedene Aktionen ausführen.

Um das machen zu können, befindet sich hier alles schon im Forum.

Benutzen kann man dazu die Klasse aus dem Beitrag:

EventLogger / EventSpy

und z.B. diese Klasse "GuiHelper":


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;

namespace EventHandlerTest
{
    public interface IParameter
    {
        object Value { get; set; }
    }

    public interface ICommand
    {
        void Run(object sender, EventArgs e);

        string CommandName { get; }

        string Description { get; set; }

        object Owner { get; set; }

        List<IParameter> Parameters { get; set; }

        object Result { get; }
    }

    public static class GuiHelper
    {
        private static CEventLogger2 eventLogger2 = new CEventLogger2();

        public static bool m_bOpenNewChildOnAction = true;
        public static bool m_bUseStandardFileDialog = true;
        public static string m_sFileName = string.Empty;

        public static event ExecutedCommandHandler handler;

        static GuiHelper()
        {

        }

        public static void ExecuteAction(object sender, object eventArgs)
        {
            ICommand command = sender.GetType().GetProperty("Tag").GetValue(sender) as ICommand;
            ExecuteAction(command, (EventArgs)eventArgs);
        }

        public static  void ExecuteAction(object sender, EventArgs e)
        {
            object obj2 = sender;
            ICommand command = sender as ICommand;
            if (command != null)
            {
                Stopwatch stopwatch = new Stopwatch();
                stopwatch.Start();
                Debug.Write(string.Format("Executing command {0}", command.Description));
                Debug.WriteLine(string.Format("Execution time: {0}", stopwatch.ElapsedTicks));
                command.Run(sender, e);
                OnExecutedCommand(command);
                stopwatch.Stop();
            }
        }

        public static void OnExecutedCommand(ICommand _icommand)
        {
            if (handler != null)
            {
                handler(typeof(GuiHelper), _icommand);
            }
        }

        private static void SetAction(ToolStripItem _item, ICommand _icommand)
        {
            _item.Tag = _icommand;
            _item.Enabled = true;
            _item.Click += (sender, e) => ExecuteAction(_item.Tag, EventArgs.Empty);
        }

        public static void SetEventHandler(Control _control, ICommand _icommand)
        {
            _control.Tag = _icommand;
            _control.Enabled = true;
            _control.Click += (sender, e) => ExecuteAction(_control.Tag, EventArgs.Empty);
        }

        public static void SetEventHandler(ToolStripItem _item, string eventHandlerName, ICommand _icommand)
        {
            _item.Tag = _icommand;
            _item.Enabled = true;
            string[] eventName = eventLogger2.GetEventNames(_item);
            if (!eventName.Contains(eventHandlerName)) return;
            //Diese Zeile wurde hier zusätzlich eingebaut
            eventLogger2.AttachEventHandler(_item, eventHandlerName);
        }

        public static void SetEventHandler(Control _control, string eventHandlerName, ICommand _icommand)
        {
            _control.Tag = _icommand;
            _control.Enabled = true;
            string[] eventName = eventLogger2.GetEventNames(_control);
            if (!eventName.Contains(eventHandlerName)) return;

            //Diese Zeile wurde hier zusätzlich eingebaut
            eventLogger2.AttachEventHandler(_control, eventHandlerName);
        }   

        public static void SetEventHandler(ToolStripItem _item, ICommand _icommand)
        {
            SetAction(_item, _icommand);
        }

        public delegate void ExecutedCommandHandler(object _sender, ICommand _icommand);
    }
}

In der Klasse CEventLogger2 habe ich den EventDump-Befehl so modifiziert:


        /// <summary>
        /// Dumps the event.
        /// </summary>
        /// <param name="_sEvent">The _s event.</param>
        /// <param name="_objectSource">The _object source.</param>
        /// <param name="_eventArgs">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        public static void EventDump(string _sEvent, object _objectSource, EventArgs _eventArgs)
        {
            if (!bStaticEventDumpIsActive) return;

            Control control = _objectSource as Control;
            ToolStrip toolStrip = _objectSource as ToolStrip;
            if (control != null || toolStrip != null)
            {
                GuiHelper.ExecuteAction(_objectSource, (object)_eventArgs);
            }
        }

Ausserdem habe ich ein Form mit 2 CheckBoxen.

Jetzt kann ich durch folgende Aufrufe:


GuiHelper.SetEventHandler(this.checkBox1, "MouseDown", new ActionMessageBox1());
GuiHelper.SetEventHandler(this.checkBox2, "MouseUp", new ActionMessageBox2());

die MessageBox-Actions mit dem Event der checkBox verknüpfen.

Jetzt habe ich die Möglichkeit Actions mit Control-Events verknüpfen.

Ich hänge noch ein Beispiel-Projekt an.

08.01.2016 - 17:42 Uhr

Und so sieht das Programm jetzt aus:

08.01.2016 - 17:32 Uhr

Diese Version habe ich noch nicht ausgiebig getestet. Nur in den Grundzügen, folgendes ist jetzt möglich:

Wenn ihr im Textfeld folgende Daten habt:

**:::

und im Filter:

foreach line "&quot;" + sInput + "&quot;"**

dann wird daraus:
**:::

Das war mir aber immer zu umständlich mit der Zeit, vor allem musste man sich immer die Variable sInput merken.

Jetzt könnt ihr auch folgendes machen:

**:::

und im Filter:

Beginn >> $row << Ende.**

dann wird daraus:
**:::

Also einfach die Variable row benutzen. Das geht auch mit den ganzen .net-Kommandos,
da ich aber bisher nur nach den leerzeichen parse, dürft ihr in dem String kein Leerzeichen benutzen. Werde ich aber in der nächsten Version beheben.

Ihr könnt also auch folgendes machen:

**:::

und im Filter:

Hallo: $row.Substring(0,2)**

dann wird daraus:
**:::

So und jetzt noch das beste neue Feature (IMHO):

**:::

und im Filter:

$0 ist $3 geboren.**

dann wird daraus:
**:::

Der Text wird also behandelt wie Spalten aus einer Datenbank.

Damit solltet ihr immer wiederkehrende Aufgaben die mit Text zu tun haben ziemlich vermindern können.

**:::

und im Filter:

Insert into Info (Place, Surname, Company) Values('$0', '$1', '$2')**

dann wird daraus:
**:::

Und schon habt ihr Datenbank statements generiert. Usw.

07.01.2016 - 15:02 Uhr

mit dieser Version können die Module jetzt in Unterverzeichnisse kopiert werden.
Entweder mit Unterverzeichnissen oder ohne. Gemischt ist gerade nicht möglich.

Der Button Re-Input war unter die anderen Controls verrutscht und ist wieder nutzbar.

Es werden mehr Typen erkannt (auch von generischen Typen sollten jetzt die Ergebnisse aufgelistet werden.)

Die Einstellungen:

Grösse der Form
Position der Form
Position der Splitter
Re-Input
Execute Immediately im Modul Menu
Topmost

sollten in einer config.ini

abgespeichert und wieder neu geladen werden.

Ich habe einige Module kommentiert, damit ist dann doch verständlicher was damit anzustellen ist.

05.01.2016 - 10:54 Uhr

[EDIT 29.03.2016: Umgeändert]

Hier kommt evtl. ein anderer Text rein, sonst kann dieser Beitrag später gelöscht werden.

09.09.2015 - 16:05 Uhr

Vielleicht hilft das noch als zusätzliche Antwort,

hier ging es darum, warum plötzlich eine Float-Zahl scheinbar nicht mehr richtig dargestellt werden konnte.

[?FAQ?] Double und Float: Fehler beim Vergleich und Rundungsfehler

Vielleicht hilft Dir auch noch das weiter:

http://www.codeproject.com/Articles/192735/Rounding-Floating-Point-Numbers-Up-or-Down-in-NET

Ausserdem können einige Zahlen in Float nicht repräsentiert werden wie LaTino u.a. schon erwähnt hat.

HTH

09.09.2015 - 11:30 Uhr

Also fürs erste habe ich folgenden Workaround, der absolut ausreichend funktioniert:

Wenn der user eine ComboBox geöffnet hat (bzw. aktiviert hat), dann kann genau das durchgeführt werden, was ich tun wollte. Falls jemand das ganze selbst auch mal braucht, hier die bisherige "Lösung":

Dazu hatte ich mir folgende Klasse gemacht:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using RemoteScriptingLibrary.Microsoft.Win32;

namespace FindAllControlsOnForm
{
    public class Win32ComboBoxHelper
    {
        public static uint CB_GETLBTEXT = 0x0148;
        public static uint CB_SETCURSEL = 0x014E;
        public static uint CB_GETCOUNT = 0x0146;
        public static uint CB_SHOWDROPDOWN = 0x014f;

        // constants for searching the ComboBox
        public static uint CB_FINDSTRINGEXACT = 344;
        public static uint CB_FINDSTRING = 332;
        // constants for searching the ListBox
        public static uint LB_FINDSTRINGEXACT = 418;
        public static uint LB_FINDSTRING = 399;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "SendMessage")]
        public static extern IntPtr SendRefMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

        //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        //public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern long SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

        public static int Count(IntPtr hwnd)
        {
            return SendMessage(hwnd, CB_GETCOUNT, 0, 0);
        }

        public static string GetComboItem(IntPtr hwnd, int index)
        {
            StringBuilder ssb = new StringBuilder(256, 256);
            SendRefMessage(hwnd, CB_GETLBTEXT, index, ssb);
            return ssb.ToString();
        }

        public static void SetComboItem(IntPtr hwnd, int index)
        {
            SendMessage(hwnd, CB_SETCURSEL, index, "0");
        }


        private const int TRUE = 1;
        private const int FALSE = 0;

        public static void DropDown(IntPtr hwnd)
        {
            SendMessage(hwnd, CB_SHOWDROPDOWN, TRUE, 0);
        }

        /// <summary>
        /// function to get find an item in the ComboBox
        /// Does not work yet.
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="SearchKey"></param>
        /// <param name="FindExactMatch"></param>
        /// <returns></returns>
        public static long GetComboBoxIndex(IntPtr hWnd, string SearchKey, bool FindExactMatch = true)
        {
            // Parameters:
            // Warning!!! Optional parameters not supported
            //     hWnd - the handle to the ComboBox control.  Usage:  Combo1.hWnd
            //     SearchKey - item that you would like to search for.  Can be any string - case doesn't matter when searching
            //     Optional FindExactMatch - Default is True.  Pass False to find a partial match
            // Return:
            //     Returns the index of the found match.  If the match is not found, -1 is returned
            // Usage:
            //     Combo1.ListIndex = GetComboBoxIndex(Combo1.hWnd, "Test Item")
            //     Combo1.ListIndex = GetComboBoxIndex(Combo1.hWnd, "Test Item", False)
            if (FindExactMatch)
            {
                return SendMessage(hWnd, CB_FINDSTRINGEXACT, -1, SearchKey);
            }
            else
            {
                return SendMessage(hWnd, CB_FINDSTRING, -1, SearchKey);
            }
        }

        /// <summary>
        /// Does not work yet
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="SearchKey"></param>
        /// <param name="FindExactMatch"></param>
        /// <returns></returns>
        public static long GetListBoxIndex(IntPtr hWnd, string SearchKey, bool FindExactMatch = true)
        {
            // Parameters:
            // Warning!!! Optional parameters not supported
            //     hWnd - the handle to the ListBox control.  Usage:  List1.hWnd
            //     SearchKey - item that you would like to search for.  Can be any string - case doesn't matter when searching
            //     Optional FindExactMatch - Default is True.  Pass False to find a partial match
            // Return:
            //     Returns the index of the found match.  If the match is not found, -1 is returned
            // Usage:
            //     Combo1.ListIndex = GetComboBoxIndex(List1.hWnd, "Test Item")
            //     Combo1.ListIndex = GetComboBoxIndex(List1.hWnd, "Test Item", False)
            if (FindExactMatch)
            {
                return SendMessage(hWnd, LB_FINDSTRINGEXACT, -1, SearchKey);
            }
            else
            {
                return SendMessage(hWnd, LB_FINDSTRING, -1, SearchKey);
            }
        }
    }
}

Die Fenster-Handles werden hier ermittelt:


        private void cbPrepare_Click(object sender, EventArgs e)
        {
            IntPtr ptrSkriptWindow = Helper.GetWindowFromPartialCaption("Skript Handling");
            var test = Helper.EnumAllWindows(ptrSkriptWindow, "WindowsForms10.COMBOBOX.app.0.2bf8098_r11_ad1").ToArray();

            if (test.Count() == 0)
            {
                MessageBox.Show("Activate combobox in Skript Window");
                return;
            }
            ptrComboBox = test[0];
            int count = Win32ComboBoxHelper.Count(ptrComboBox);
            for (int i = 0; i < count; i++)
            {
                string text = Win32ComboBoxHelper.GetComboItem(ptrComboBox, i);
                comboBoxItems.Add(new ComboBoxItemAM(i, text));
            }

            listBox1.Items.AddRange(comboBoxItems.ToArray());

            Win32.SetParent(this.Handle, ptrSkriptWindow);
            this.Location = new Point(0, 500);

            this.cbPrepare.Visible = false;

            Win32.RECT rect = new Win32.RECT();
            Win32.GetWindowRect(ptrSkriptWindow, out rect);
        }

Die Funktion, um die Fenster-Handles zu finden, sieht so aus (bisher):


   public static IEnumerable<IntPtr> EnumAllWindows(IntPtr hwnd, string childClassName)
        {
            List<IntPtr> children = GetChildWindows(hwnd);
            if (children == null)
                yield break;
            foreach (IntPtr child in children)
            {
                if (GetWinClass(child) == childClassName)
                    yield return child;
                foreach (var childchild in EnumAllWindows(child, childClassName))
                    yield return childchild;
            }
        }

GetChildWindows sieht so aus:


      /// <summary>
        /// Returns a list of child windows
        /// </summary>
        /// <param name="parent">Parent of the windows to return</param>
        /// <returns>List of child windows</returns>
        public static List<IntPtr> GetChildWindows(IntPtr parent)
        {
            List<IntPtr> result = new List<IntPtr>();
            GCHandle listHandle = GCHandle.Alloc(result);
            try
            {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
                EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
            }
            finally
            {
                if (listHandle.IsAllocated)
                    listHandle.Free();
            }
            return result;
        }

EnumWindow:



        /// <summary>
        /// Delegate for the EnumChildWindows method
        /// </summary>
        /// <param name="hWnd">Window handle</param>
        /// <param name="parameter">Caller-defined variable; we use it for a pointer to our list</param>
        /// <returns>True to continue enumerating, false to bail.</returns>
        public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);

   /// <summary>
        /// Callback method to be used when enumerating windows.
        /// </summary>
        /// <param name="handle">Handle of the next window</param>
        /// <param name="pointer">Pointer to a GCHandle that holds a reference to the list to fill</param>
        /// <returns>True to continue the enumeration, false to bail</returns>
        private static bool EnumWindow(IntPtr handle, IntPtr pointer)
        {
            GCHandle gch = GCHandle.FromIntPtr(pointer);
            List<IntPtr> list = gch.Target as List<IntPtr>;
            if (list == null)
            {
                throw new InvalidCastException("GCHandle Target could not be cast as List<IntPtr>");
            }


02.09.2015 - 10:30 Uhr

Um die Frage noch einmal anders zu stellen,

weiss jemand wie man mittels Windows-API an die einzelnen Window-Handles der eingebetteten Controls kommt?

Das muss auch irgendwie möglich sein.

Im Moment komme ich gerade nicht damit weiter.

Vielleicht hat ja noch jemand eine Idee.

21.08.2015 - 12:22 Uhr

Danke für den Hinweis Inflames2k.

Es mag sein, dass das jemand schreibt und der Inspector zeigt sie eben an.

Ausserdem habe ich gerade was herausgefunden, mein altes Programm von hier:

Window Handles hierarchisch auslesen.

zeigt sie ebenfalls an, auch als ComboLBox, auch wenn gerade nicht editiert wird.
Sie sind also eindeutig auffindbar, egal ob gerade editiert wird oder nicht.
Zumindest in diesem Fall.

Allerdings finde ich die Nodes nur, wenn ich von CWindowNode(Win32.GetDesktopWindow())
ausgehe. Also alle Handles durchlaufe bisher. Das möchte ich natürlich nicht.
Und liegt auch irgendwo an meinem Programm vom anderen Thread.

Gehen muss es. Da bin ich mir sicher. Und dass ich die Lösung (irgendwann) finde auch. 😉

EDIT:

Falls es damit gehen sollte, den ListBox Teil (was anscheinend ComboLBox bedeutet) auszulesen,
kann das mit:



[...]
       List<string> listBoxContent = GetListBoxContents(this.listBox1.Handle);
[...]

        private List<string> GetListBoxContents(IntPtr listBoxHwnd)
        {
            int cnt = (int)Win32.SendMessage(listBoxHwnd, (int)Win32.LB.LB_GETCOUNT, IntPtr.Zero, null);
            List<string> listBoxContent = new List<string>();
            for (int i = 0; i < cnt; i++)
            {
                StringBuilder sb = new StringBuilder(256);
                IntPtr getText = Win32.SendMessage(listBoxHwnd, (int)Win32.LB.LB_GETTEXT, (IntPtr)i, sb);
                listBoxContent.Add(sb.ToString());
            }
            return listBoxContent;
        }

gemacht werden. Funktioniert.

Fehlt aber immer noch der Teil an die die ComboLBox oder ComboBox oder wie auch immer das wie eine ComboBox aussehende Control in der DataGridView unter Windows ist, heranzukommen. 😉

21.08.2015 - 11:28 Uhr

Mit dem Inspector kann man hier schön sehen, wie die Control heisst, auf die ich zugreifen möchte usw., nur wie er in letzter Instanz an die Controls rankommt ist mir (noch) etwas schleierhaft.

Per Windows API finde ich bisher nur das GridViewControl-Handle. Aber wie von dort aus weiter navigieren, so dass ich auch wie im Inspector die einzelnen Zeilen oder das Fenster, das die Zeilen hostet (falls es denn so sein sollte) und darüber dann alles weitere finde?

Ich versuche das inzwischen weiter, sollte ich eine Lösung haben, werde ich sie natürlich hier posten.

Wer hat solange eine Idee?

21.08.2015 - 11:23 Uhr

Hallo Community.

Ich habe ein DatagridView einer anderen Anwendung, auf die ich nur per Win32-Api Zugriff habe.
Jetzt soll eine ComboBox des DataGridViews angesteuert werden.

Hintergrund ist der:

Der Auswahlmechanismus des Programmes ist beschränkt und es kann nicht nach "Funktionen", die in den ComboBoxen per Namen aufgelistet sind, gesucht werden.

Ich will bzw. soll die Suche von aussen implementieren.


Um das auszuprobieren, habe ich einfach zuerst einmal versucht eine eigene ComboBox aus eigenem Projekt anzusteuern. Ebenfalls externe Anwendung, falls jemand dazu den Code braucht, hier bitteschön:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using RemoteScriptingLibrary.Microsoft.Win32;

namespace WindowsFormsApplication2
{
    public class Win32ComboBoxHelper
    {
        public static uint CB_GETLBTEXT = 0x0148;
        public static uint CB_SETCURSEL = 0x014E;
        public static uint CB_GETCOUNT = 0x0146;
        public static uint CB_SHOWDROPDOWN = 0x014f;

        // constants for searching the ComboBox
        public static uint CB_FINDSTRINGEXACT = 344;
        public static uint CB_FINDSTRING = 332;
        // constants for searching the ListBox
        public static uint LB_FINDSTRINGEXACT = 418;
        public static uint LB_FINDSTRING = 399;

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false, EntryPoint = "SendMessage")]
        public static extern IntPtr SendRefMessage(IntPtr hWnd, uint Msg, int wParam, StringBuilder lParam);

        //[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        //public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern long SendMessage(IntPtr hWnd, uint Msg, int wParam, string lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, uint wParam, uint lParam);

        public static int Count(IntPtr hwnd)
        {
            return SendMessage(hwnd, CB_GETCOUNT, 0, 0);
        }

        public static string GetComboItem(IntPtr hwnd, int index)
        {
            StringBuilder ssb = new StringBuilder(256, 256);
            SendRefMessage(hwnd, CB_GETLBTEXT, index, ssb);
            return ssb.ToString();
        }

        public static void SetComboItem(IntPtr hwnd, int index)
        {
            SendMessage(hwnd, CB_SETCURSEL, index, "0");
        }


        private const int TRUE = 1;
        private const int FALSE = 0;

        public static void DropDown(IntPtr hwnd)
        {
            SendMessage(hwnd, CB_SHOWDROPDOWN, TRUE, 0);
        }

        /// <summary>
        /// function to get find an item in the ComboBox
        /// Does not work yet.
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="SearchKey"></param>
        /// <param name="FindExactMatch"></param>
        /// <returns></returns>
        public static long GetComboBoxIndex(IntPtr hWnd, string SearchKey, bool FindExactMatch = true)
        {
            // Parameters:
            // Warning!!! Optional parameters not supported
            //     hWnd - the handle to the ComboBox control.  Usage:  Combo1.hWnd
            //     SearchKey - item that you would like to search for.  Can be any string - case doesn't matter when searching
            //     Optional FindExactMatch - Default is True.  Pass False to find a partial match
            // Return:
            //     Returns the index of the found match.  If the match is not found, -1 is returned
            // Usage:
            //     Combo1.ListIndex = GetComboBoxIndex(Combo1.hWnd, "Test Item")
            //     Combo1.ListIndex = GetComboBoxIndex(Combo1.hWnd, "Test Item", False)
            if (FindExactMatch)
            {
                return SendMessage(hWnd, CB_FINDSTRINGEXACT, -1, SearchKey);
            }
            else
            {
                return SendMessage(hWnd, CB_FINDSTRING, -1, SearchKey);
            }
        }

        /// <summary>
        /// Does not work yet
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="SearchKey"></param>
        /// <param name="FindExactMatch"></param>
        /// <returns></returns>
        public static long GetListBoxIndex(IntPtr hWnd, string SearchKey, bool FindExactMatch = true)
        {
            // Parameters:
            // Warning!!! Optional parameters not supported
            //     hWnd - the handle to the ListBox control.  Usage:  List1.hWnd
            //     SearchKey - item that you would like to search for.  Can be any string - case doesn't matter when searching
            //     Optional FindExactMatch - Default is True.  Pass False to find a partial match
            // Return:
            //     Returns the index of the found match.  If the match is not found, -1 is returned
            // Usage:
            //     Combo1.ListIndex = GetComboBoxIndex(List1.hWnd, "Test Item")
            //     Combo1.ListIndex = GetComboBoxIndex(List1.hWnd, "Test Item", False)
            if (FindExactMatch)
            {
                return SendMessage(hWnd, LB_FINDSTRINGEXACT, -1, SearchKey);
            }
            else
            {
                return SendMessage(hWnd, LB_FINDSTRING, -1, SearchKey);
            }
        }
    }
}

Für eine normale ComboBox habe ich das also hinbekommen.
Ich kann auch wenn sie sich in einer anderen Anwendung befindet, sie suchen, finden, komplett auslesen oder einen bestimmten Eintrag selektieren.

Beim DatagridView ist es ja so, dass es aus mehreren Komponenten bestehen kann.
Ich habe hierzu ein Bild angehängt.

Jetzt geht es darum, wie finde ich die ComboBoxen (die vom Typ ComboLBox sind, man beachte das "L") per Windows API im DatagridView?

04.08.2015 - 14:03 Uhr

Hallo Community.

Gibt es irgendwie eine Möglichkeit, diese drei Dinge zusammenzufassen,
am liebsten mit einer gemeinsamen Schnittstelle, die überall SelectedObjects enthält.

Controls abzuleiten oder umzuändern funktioniert hier leider nicht.
Will derjenige der den Code braucht nicht.

ListBox und ComboBox haben zumindest den Typ ListControl gemeinsam. Aber zusammen mit der ListView funktioniert das nicht mehr.

Eine gemeinsame Schnittstelle, die bei allen dreien SelectedItem enthält, habe ich nicht gefunden.


                if (comboBox != null)
                {
                    foreach (string item in comboBox.Items)
                    {
                        if (item.StartsWith(inputSearch, StringComparison.CurrentCultureIgnoreCase))
                        {
                            comboBox.SelectedItem = item;
                            break;
                        }
                    }
                }
                else if (listBox != null)
                {
                    foreach (string item in listBox.Items)
                    {
                        if (item.StartsWith(inputSearch, StringComparison.CurrentCultureIgnoreCase))
                        {
                            listBox.SelectedItem = item;
                            break;
                        }
                    }
                }
                else if (listView != null)
                {
                    foreach (string item in listView.Items)
                    {
                        if (item.StartsWith(inputSearch, StringComparison.CurrentCultureIgnoreCase))
                        {
                            listBox.SelectedItem = item;
                            break;
                        }
                    }
                }

Mir ist dazu bisher die Lösung eingefallen zu verwenden, die ich selbst einmal hier gepostet habe:

Interface zur Laufzeit zu einer Klasse hinzufügen (Lösung)

Bin mir aber sicher es gibt bessere, oder?

20.07.2015 - 16:06 Uhr

Da es auch teilweise wohl im neuesten VS 2013 ähnliche Probleme geben kann, Abhilfe gibts hier:

https://support.microsoft.com/en-us/kb/2877623

16.07.2015 - 11:20 Uhr

@Mr. Sparkle:

Genau darauf wollte ich ja raus und dann habe ich es wohl nicht offensichtlich genug erklärt.

Neulich hatten ein paar Leute das selbe Problem und meinten, die verstehen das nicht.

Also habe ich den Code als Beispiel genommen, zur Anmerkung:

@Fzelle:
Die Klassen sind nicht mein Code. Ich kann den gar nicht ändern.
Mein Code ist nur der Aufruf von oben mit dem Find.

Wenn jetzt diese beiden Objekte in einer Liste zusammengeführt werden,
existiert z.B. in Driver

"DriverProviderName" als Key.
Aber in InstalledUpdate nicht.
Dafür existiert aber z.B. in InstalledUpdate "DisplayName",
dafür aber in Driver nicht.

Allerdings habe ich das hier doch beschrieben.

15.07.2015 - 11:55 Uhr

Falls jemand den Find-Befehl einer generischen Liste benutzt und den Fehler bekommt:

Fehlermeldung:
KeyNotFoundException key does not exist,

kann es daran liegen, dass der Key tatsächlich nicht vorhanden ist, oder in einem Indexer
ein Objekt aufgerufen wird, dass selbst ein Dictionary oder etwas ähnliches ist und eben diesen Key nicht enthält.

Klar, denen die schon länger programmieren ist das sowieso klar.

Dieser Code hat das Problem ausgelöst:


            Dictionary<string, InstalledEntity> installedEntities = null;
            installedEntities = ReadDrivers();         

            List<InstalledEntity> allInstalledEntities = CommonTools.GetInstalledUpdates();
            allInstalledEntities.AddRange(installedEntities.Values.ToArray());

            object o = allInstalledEntities.Find(x => x["DisplayName"] == "KB97440");
            o = allInstalledEntities.Find(
                x => x.ColumnsToRead != null 
                    && x.ColumnsToRead.Contains("DriverProviderName") 
                    && x["DriverProviderName"] == "Microsoft3");

Wobei diese Zeile evtl. sogar funktionieren kann, wenn denn der Wert KB97440 gefunden werden würde, wird er nicht gefunden, tritt ziemlich sicher oben benannter Fehler auf

object o = allInstalledEntities.Find(x => x["DisplayName"] == "KB97440");

Nur...warum?

Die Basis-Klasse von InstalledEntity sieht so aus:


public abstract class InstalledEntity
{
      protected Dictionary<string, string> installedValues = new Dictionary<string, string>();
      protected List<string> columnsToRead = null;
      public InstalledEntity(params string[] allowedEntityNames)
      {

      }

      public virtual string this[string valueName]
      {
          get { return installedValues[valueName]; }
          set { installedValues[valueName] = value; }
      }

       public abstract List<string> ColumnsToRead { get; }
}

Hier ist schon mal wichtig den Indexer zu beachten.

InstalledUpdate sieht so aus:


  public class InstalledUpdate : InstalledEntity
    {
        public InstalledUpdate()
        {
            //Define columns to read from registry
            columnsToRead = new List<string>() {
                "DisplayName",
                "DisplayVersion",
                "Publisher"
            };
        }

        public override List<string> ColumnsToRead
        {
            get { return columnsToRead; }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Update: ");
            sb.Append(installedValues["DisplayName"]);
            sb.Append(" - ");
            sb.Append(installedValues["DisplayVersion"]);
            sb.Append(" - ");
            sb.Append(installedValues["Publisher"]);
            return sb.ToString();
        }
    }

und

Driver so:


  public class Driver : InstalledEntity
    {
        protected ManagementObject managementObject = null;
        
        public Driver(ManagementObject obManagementObject)
        {
            managementObject = obManagementObject;

            //Define columns to read from registry
            columnsToRead = new List<string>() {
                "DeviceName",
                "DriverVersion",
                "DriverProviderName"
            };
        }

        public override string this[String key]
        {
            get
            {
                try
                {
                    [...] //Auslassungszeichen
                    return managementObject[key] as string;
                }
                catch (ManagementException ex)
                {
                    return string.Empty;
                }
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("Driver: ");
            sb.Append(managementObject["DeviceName"]);
            sb.Append(" - ");
            sb.Append(managementObject["DriverVersion"]);
            sb.Append("-");
            sb.Append(managementObject["DriverProviderName"]);
            return sb.ToString();
        }

        public override List<string> ColumnsToRead
        {
            get { return columnsToRead; }
        }
    }

Wenn jetzt diese beiden Objekte in einer Liste zusammengeführt werden,
existiert z.B. in Driver

"DriverProviderName" als Key.
Aber in InstalledUpdate nicht.
Dafür existiert aber z.B. in InstalledUpdate "DisplayName",
dafür aber in Driver nicht.

Find sucht im ineffektivsten Fall alle Entities durch.
Wurden jetzt z.B. zuerst die Driver hinzugefügt und dann die Updates zur Liste hinzuaddiert,
dann passiert erst mal nichts schlimmes, wenn die Suche passt und der entsprechende Driver gefunden wird.

Sollte aber der Key nicht passen, wird einfach weitergesucht und dann landen wir irgendwann bei den Updates.


object o = allInstalledEntities.Find(x => x["DriverProviderName"] == "Microsoft2"); //key der garantiert nicht gefunden wird.

Jetzt wird also bei den Updates der Indexer aufgerufen, also dieser Teil:


        public override string this[String key]
        {
            get
            {
                try
                {
                    [...] //Auslassungszeichen
                    return managementObject[key] as string;
                }
                catch (ManagementException ex)
                {
                    return string.Empty;
                }
            }
        }

und dann wenn eben

managementObject[key]

nicht existiert, bekommt ihr eben diesen Fehler.

Jetzt könnt ihr entweder eure Klassen so anpassen, dass die Keys immer gleich heissen (Achtung: Es ist natürlich wichtig darüber nachzudenken, ob das einen Sinn hat)

oder ihr müsst die Abfrage sicherer machen:


            o = allInstalledEntities.Find(
                x => x.ColumnsToRead != null 
                    && x.ColumnsToRead.Contains("DriverProviderName") 
                    && x["DriverProviderName"] == "Microsoft3");

Ich hoffe ich konnte das sinnvoll rüberbringen und hilft.

P.S.: Wie gesagt, für den der genug Programmiererfahrung hat, ist das offensichtlich.

09.07.2015 - 15:37 Uhr

Hmmm, hat hier schon immer der Dateianhang bzw. Verweis auf einen Link gefehlt?

Aber für alle denen das zu kompliziert ist, gibts auch das Ganze nochmal hier:

Windows Remote Scripting

Falls der obere Link nicht funktioniert, bitte hier herauskopieren:

https://app.box.com/s/0ja09ku9ijr6v4mcwxxdltdxn1meh5bo
EDIT: Ah gerade gesehen

29.06.2015 - 13:25 Uhr

Genau dazu habe ich eine Ergänzung.

Habe heute festgestellt, dass das Snippet bei mir unter Windows 7 mit .NET 4.5 wundervoll funktioniert. Mit .NET 4.0 kommen allerdings mit dem exakt identischen Code (identisch geschrieben in Visual Studio, also einfach nur Framework Version umgestellt) andere Ergebnisse heraus.

Ich habe dann festgestellt, dass unter 4.5 automatisch der RegistryKey der hier hinzugefügt wurde


SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall

mit ausgelesen wird. Warum auch immer.

Anmerkung:

Aufgefallen ist mir dies deshalb, weil ich eine Applikation im VS offen hatte mit 4.5 und eine andere mit 4.0 und mich gewundert habe, warum auf dem gleichen Rechner eine unterschiedliche Zahl von installierten Programmen/Hotfixes/Updates und Security Fixes installiert sein soll.


       public static List<InstalledEntity> GetInstalled()
        {
            List<InstalledEntity> allPrograms = new List<InstalledEntity>();
            string[] registryKeyPaths = new string[]
            {
                @"Software\Microsoft\Windows\CurrentVersion\Uninstall",
                @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
            };

            foreach (string registryKeyPath in registryKeyPaths)
            {
                RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(registryKeyPath);

                if (registryKey != null)
                {
                    string[] subKeyNames = registryKey.GetSubKeyNames();

                    for (int i = 0; i < subKeyNames.Length; i++)
                    {
                        RegistryKey subKey = registryKey.OpenSubKey(subKeyNames[i]);

                        string displayName = (string) subKey.GetValue("DisplayName");
                        if (displayName == null)
                        {
                            displayName = (string) subKey.GetValue("QuitDisplayName");
                        }

                        //Pattern example: Update for Microsoft Office 2010 (KB2589386) 32-Bit Edition

                        if (displayName != null)
                        {
                            InstalledEntity installedEntity = null;
                            if (Regex.Match(displayName, @"\(KB[0-9]{7}\)").Success)
                            {
                                installedEntity = new InstalledUpdate();
                            }
                            else
                            {
                                installedEntity = new InstalledProgram();
                            }
                            foreach (string columnName in installedEntity.ColumnsToRead)
                            {
                                installedEntity[columnName] = (string) subKey.GetValue(columnName);
                            }
                            allPrograms.Add(installedEntity);
                        }
                        else
                        {

                        }
                    }
                }
                //else
                //{
                //    throw new Exception("Registry-Key: "
                //                        + Registry.LocalMachine.Name
                //                        + "\\" + registryKeyPath
                //                        + " not found");
                //}
            }
            return allPrograms;
        }

20.05.2015 - 09:13 Uhr

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

namespace PTC_FDA_Report_GUI
{
    public delegate void VerifyEventHandler(object sender, VerifyEventArgs e);

    public class VerifyEventArgs : EventArgs
    {
        private string m_sText = string.Empty;

        public VerifyEventArgs(string _sOutput)
        {
            m_sText = _sOutput;
        }

        public string Text
        {
            get { return m_sText; }
            private set { m_sText = value; }
        }
    }

    public class Verify
    {   
        public event VerifyEventHandler VerifyEvent;

        public bool IsValidFileName(string _sFileName)
        {
            //Check Path
            string sPath = string.Empty;

            bool bResult = true;
            try
            {
                char[] chInvalidPathChars = Path.GetInvalidPathChars();
                sPath = Path.GetDirectoryName(_sFileName);
                if (sPath == null)
                {
                    bResult &= false;
                }
                else if (sPath.IndexOfAny(chInvalidPathChars) > 0)
                {
                    bResult &= false;
                }
                else
                {
                    bResult &= true;
                }
                if (!Directory.Exists(sPath))
                {
                    OnVerify(new VerifyEventArgs(string.Format("Path {0} does not exist", sPath)));
                    bResult &= false;
                }
            }
            catch(ArgumentException ex)
            {
                OnVerify(new VerifyEventArgs(ex.Message));
                bResult &= false;
            }
            catch(Exception ex)
            {
                OnVerify(new VerifyEventArgs(ex.Message));
                bResult &= false;
            }

            //Check Filename
            string sFileName = string.Empty;

            try
            {
                char[] chInvalidFileNameChars = Path.GetInvalidFileNameChars();
                sFileName = Path.GetFileName(_sFileName);

                chInvalidFileNameChars = Path.GetInvalidFileNameChars();
                if (sFileName.IndexOfAny(chInvalidFileNameChars) > 0) bResult &= false;
                bResult &= true;
            }
            catch(Exception ex)
            {
                OnVerify(new VerifyEventArgs(ex.Message));
                bResult &= false;
            }
            return bResult;
        }
      
        public bool IsValidFilter()
        {
            return false;
        }

        public bool IsValidConfig()
        {
            return false;
        }

        protected void OnVerify(VerifyEventArgs e)
        {
            if (this.VerifyEvent != null)
            {
                this.VerifyEvent(this, e);
            }
        }
    }
}

28.04.2015 - 11:22 Uhr

Im oberen verwiesenen Thread geht es ja nur darum, wie man das @ für Strings benutzen kann.

Du aber meinst @Runshak ob das sinnvoll ist:


string @string = "";

oder z.B.


string @class = "";

richtig?

Ich weiss zwar, dass das geht, aber kann mich nicht erinnern das in meinen Programmen zu benutzen.

Benutze es also nicht. Keine Ahnung ob andere das benutzen

17.04.2015 - 11:57 Uhr

Jetzt sieht die Oberfläche z.B. so aus:

17.04.2015 - 11:45 Uhr

Exe bei denen die Splitter jetzt variabler sind, d.h. die Textboxen werden entsprechend ohne Limits mitvergrössert.

13.04.2015 - 09:25 Uhr

Möglicherweise bietet auch WMI mit Events eine Möglichkeit.
Ich nenne hier nur die Stichworte wie das genau gemacht wird, weiss ich momentan auch nicht.

02.04.2015 - 07:49 Uhr

Anmerkung:

Mit dieser Version solltet ihr alles ausprobieren können, was ich beschrieben habe.
"vorherige Endversion" bedeutet bevor mir wieder neue Dinge einfallen, die ich einbauen könnte.

Vorabversion zum Testen
EDIT: Vorabversion deshalb, weil sie alles enthält, was die vorherige "Endversion" können sollte.
Aber ich möchte alles so testen, dass alles gut und ohne grössere Probleme funktioniert.
Auch das GUI.

Bisher entdeckte Issues:

  • Die Splitter-Positionen werden immer noch nicht richtig reinitialisiert, wenn diese verschoben
    wurde. Die Textboxen vergrössern sich auch noch nicht richtig entsprechend
  • das Delegate wird nicht aufgerufen oder korrekt erstellt.
  • Die Expression Results werden nur angezeigt bevor "->" benutzt wird
01.04.2015 - 15:23 Uhr

Beispiele:

(++Quasi dynamischen Text aus anderem Text erstellen:[/u][/color]
Mit Results arbeiten.

Eingabe:

Mit 5 Results arbeiten ist einfacher als 5 mal denselben langen Ausdruck einzugeben.

Filter:


Regex.Split(sInput, " ") -> string.Format("{3}: {0} + {1} = {2}", ra[1], ra[7], int.Parse(ra[1])+int.Parse(ra[7]), ra[2])

Ausgabe:

Results: 5 + 5 = 10

Das schöne ist an diesem Beispiel, wir können die Zahlen austauschen. Die Formel wird immer noch richtig berechnet.

(Anmerkung: Wäre das eigentlich eine Idee für Texte?)

(++Rtf Text in zwei Spalten Excel:[/u][/color]

Ich möchte einen Text in eine Excel-Tabelle übernehmen (CSV).
Warum? Ich habe Englische Wörter gelernt und einfach in ein rtf notiert.

Dabei habe ich immer durch ein "=" Englisch und Deutsch voneinander getrennt.

In echt kamen hier ca. 3000 Wörter mit der Zeit zusammen.
Irgendwann fand ich dann Excel einfach praktischer.

Der Text wurde folgendermassen notiert:

verbatim = wörtlich

honed = feingeschliffen

attainment = erwerbung / erlangung

instill = einimpfen / einflössen / anerziehen(

epigram - sinngedicht

conducive = dienlich / förderlich

conceive = geistig erfassen / begreifen

stray = herumirren

relish = geniessen

diligently = sorgfältig / fleissig
[...]

Das einfachste Script das mir dazu einfällt ist:


foreach line sInput.Replace("=", "\t")

und schon erhalte ich im Output

verbatim wörtlich
honed feingeschliffen
attainment erwerbung / erlangung
instill einimpfen / einflössen / anerziehen
epigram sinngedicht
conducive dienlich / förderlich
conceive geistig erfassen / begreifen
stray herumirren
relish geniessen
diligently sorgfältig / fleissig
[...]

und kann direkt ins Excel kopieren.
Der Text wird in 2 Spalten kopiert.

Von Hand hätte das eine Weile gedauert.
Und ich muss mich auch nicht mit den Excel-Import/Export-Funktionen auskennen.
Auch wenn das da auch nicht kompliziert ist. 😃

(++Klasse erstellen bzw. Snippets[/u][/color]

Irgendwann wollte ich für mein Projekt ImageRecognition2 weitere Klassen erstellen.
Ich hatte aber keine Lust mit irgendeinem Snippet-Editor Templates zu erstellen.
Da fiel mir ein, hey, das müsste doch auch mit meinem Tool gehen.

Hier der Filter dazu:


string.Format(
@"
using System.Drawing;
using LowLevelGraphics.Filter;
using System.Drawing.Imaging;

public class {0} : BaseImageFilter
{1}
	public {0}
	{1}
	{2}

	internal {0}({0} _{0})
	{1}
	{2}

      	public override UnsafeBitmap Execute(UnsafeBitmap bitmapSource)
        	{1}
		throw new Exception(""Implement code!!!"");
	{2}
  
	public override object Clone()
	{1}
		return new {0}(this);
	{2}
{2}

",
sInput,"{","}")

Die Eingabe:

AutoHDR

und das Ergebnis:



using System.Drawing;
using LowLevelGraphics.Filter;
using System.Drawing.Imaging;

public class AutoHDR : BaseImageFilter
{
	public AutoHDR
	{
	}

	internal AutoHDR(AutoHDR _AutoHDR)
	{
	}

      	public override UnsafeBitmap Execute(UnsafeBitmap bitmapSource)
        {
		throw new Exception("Implement code!!!");
	}
  
	public override object Clone()
	{
		return new AutoHDR(this);
	}
}

24.03.2015 - 12:57 Uhr

Ausblick auf die nächste Version:

Erweiterungen:

1.)
Inzwischen können auch Results benutzt werden,
d.h. wenn z.B.


Regex.Split(sInput.Substring(0,3).Reverse(), " ")

70 Ergebnisse liefert und ich diese weiterverarbeiten will, möchte ich nicht jedesmal schreiben müssen:

Regex.Split(sInput.Substring(0,3).Reverse(), " ")[0] + Regex.Split(sInput.Substring(0,3).Reverse(), " ")[3]

usw.

Hier unten ein Beispiel, wo es noch keine Results gibt, dann muss z.B. so geschrieben werden:


(int.Parse(Regex.Split(sInput, " ")[1]) - int.Parse(Regex.Split(sInput, " ")[0])) /  int.Parse(Regex.Split(sInput, " ")[2])
+ Environment.NewLine +
(int.Parse(Regex.Split(sInput, " ")[4]) - int.Parse(Regex.Split(sInput, " ")[3])) /  int.Parse(Regex.Split(sInput, " ")[5])
+ Environment.NewLine +
(int.Parse(Regex.Split(sInput, " ")[7]) - int.Parse(Regex.Split(sInput, " ")[6])) /  int.Parse(Regex.Split(sInput, " ")[8])
+ Environment.NewLine +
"========" 
+ Environment.NewLine +
((int.Parse(Regex.Split(sInput, " ")[1]) - int.Parse(Regex.Split(sInput, " ")[0])) /  int.Parse(Regex.Split(sInput, " ")[2])
+(int.Parse(Regex.Split(sInput, " ")[4]) - int.Parse(Regex.Split(sInput, " ")[3])) /  int.Parse(Regex.Split(sInput, " ")[5])
+(int.Parse(Regex.Split(sInput, " ")[7]) - int.Parse(Regex.Split(sInput, " ")[6])) /  int.Parse(Regex.Split(sInput, " ")[8]))

Mit Results kann ich jetzt schreiben:


(Result[1] - Result[0]) / Result[2]
+ Environment.NewLine +
(Result[4] - Result[3]) /  Result[5]
+ Environment.NewLine +
(Result[7] - Result[6]) /  Result[8]
+ Environment.NewLine +
"========" 
+ Environment.NewLine +
(Result[1]) - Result[0]) /  Result[2])
+ (Result[4]) - Result[3]) /  Result[5])
+ (Result[7]) - Result[6]) /  Result[8]))

Für diese können auch Aliases festgelegt werden.

Jetzt ist es egal, wie lange die Formel ist bzw. Formeln sind, um diese Werte zu ermitteln.

2.) Ausserdem wurden die Anzahl der Klicks, die benötigt wurden, um z.B. von Wordpad aus automatisch ersetzen zu lassen, reduziert.

3.) Die Splitterpositionen werden jetzt richtig abgespeichert.

4.) Die übersetzte Funktion wird durch ein Delegate intern ersetzt, so dass z.B. in Schleifen (foreach line...) nicht jedesmal neu übersetzt wird, was viel Zeit kostet.

5.) Rechts ist ein Tab in dem man die Results sehen kann.
Diese können durch Doppelklick in den Text übernommen werden.

6.) Die Zeilenumbrüche werden jetzt im Output angezeigt.

7.) Ergebnisse (Results) werden jetzt auf einem Tab rechts - zusätzlich zu den Compiler-Meldungen - angezeigt.

8.) Die "hässlichen" Buttons oben und unten sind verschwunden und wurden durch sinnvollere Controls ersetzt.

17.03.2015 - 15:16 Uhr

Fürs erste habe ich eine noch einfachere Lösung gefunden:

wenn die Grenzen gut genug eingezeichnet sind,
so dass ich ein FloodFill mit einem Zeichenprogramm verwenden kann,
reicht das völlig aus.

Dann muss ich nur wissen wo das Land sich befindet. 😃

Zum Beispiel von hier:

16.03.2015 - 15:33 Uhr

Ich suche eine Webseite oder ein Programm mit denen ich einzelne Länder der Landkarten einfärben kann (Floodfill). Z.B.

Wenn ich Deutschland auswähle und Frankreich sollten diese beiden Länder jeweils in der von mir ausgewählten Farbe eingefärbt werden.

Sollte die Webseite oder das Programm nur max. zehn Farben bieten, ist das völlig ausreichend.
Ich möchte mir nämlich bestimmte Zustände merken. Das ist hier nur manuell gedacht.
Also reicht mir im Idealfall eine Webseite völlig aus.

Bsp.:

Ich möchte mir z.B. markieren:

  • Land bereist
  • möchte das Land bereisen
  • möchte das Land nicht bereisen

Es kommt also vor, dass mehrere Länder jeweils in der gleichen Farbe markiert werden.

Hat mir jemand einen Tipp?

Sollte sich nichts finden, werde ich mir .NET selbst so was erstellen, dann kommt natürlich wieder die Frage auf: woher die Kartendaten bekommen?


Falls jemand nur eine Farbe braucht, dafür habe ich schon genügend Webseiten gefunden, z.B. diese:

http://landkartenindex.blogspot.de/2008/02/erstelle-deine-eigene-weltkarte-deiner.html
http://www.amcharts.com/visited_states/

12.03.2015 - 12:49 Uhr

Vorneweg: unten ist eine Beispielmail enthalten, die man in so einem Fall üblicherweise erhält.

1.) Ist das eine Abzockfalle - NEIN! Die E-Mail ist echt und nicht zu ignorieren.

Falls jemand von euch eine Mail erhält, wie unten zitiert,
das ist in diesem Falle keine Abzockfalle, sondern real und legitim.

2.) Was ist zu tun?

Erstmal anrufen und nachfragen, um welche Domains es geht und bis wann bezahlt werden sollte.
Es ist vor Ablauf der Mahnungsfrist oder allgemeiner Frist, falls eine angegeben wurde,
eine E-Mail (mit eingescannter Unterschrift ist legitim und gültigt - habe ich extra nachgefragt), Brief oder Fax zu schicken.

Darin sollte enthalten sein, dass ihr die Domains nicht mehr braucht und gelöscht werden können. Natürlich nur, wenn ihr die Domains wirklich nicht mehr benötigt.

Dann muss weder eine Rechnung bezahlt werden noch ist die Mahnung länger gültig.
Ihr habt also gar keine Kosten, wenn ihr euch rechtzeitig bis bevor der Ablauffrist darum kümmert.

3.) Woher kommt das ganze und ist es legitim/legal von der Denic?

Es ist legal.

Beispiel:

Die DENIC ist der Registrar für .de Domains. Wenn du deine www.jommodore.de bei Strato oder so holst, lässt Strato die .de bei der DENIC registrieren und zahlt die anfallenden Gebühren.
So als Beispiel.

Fällt dieser Anbieter weg, z.B. von freien Domainanbietern, bei denen keine Gebühren zu entrichten sind, müssen die Verwaltungskosten bei der Denic entrichtet, d.h. gezahlt werden.

Sehr geehrte Damen und Herren,

Sie sind bei uns als administrativer Ansprechpartner (Admin-C) der folgenden Domain(s) eingetragen:

codxxxxxxs.de, dexxxxxxxrt.de

Unsere Rechnung für die Verwaltung dieser Domain(s) wurde postalisch an folgende Anschrift versandt:

Blablablabl bla
Blablablastrasse 4
12555 Blablahausen
DEUTSCHLAND

Leider wurde die Rechnung bisher nicht oder nur unvollständig beglichen.

Wenn Sie selbst nicht der Rechnungsempfänger sind, bitten wir Sie, sich mit diesem in Verbindung zu setzen,
um die Zahlung zu veranlassen. Wird/Werden die Domain(s) nicht mehr benötigt, kann/können diese mit Hilfe der
in der Rechnung genannten Zugangsdaten online gelöscht werden. Wünschen Sie den Fortbestand der Domain(s),
können Sie dort auch ein Providerwechsel-Passwort (AuthInfo) festlegen, um sie zu einem Provider Ihrer Wahl
zu transferieren.

Sollten wir bis zum 18. März 2015 keine vollständige Zahlung erhalten, werden wir den Domainvertrag für
die genannte(n) Domain(s) nach § 7 Abs. 2 der DENIC-Domainbedingungen fristlos kündigen. Die Domain(s)
wird/werden danach gelöscht.

Mit freundlichen Grüßen Ihre DENIC eG

Direct Services

DENIC eG
Kaiserstraße 75-77
60329 Frankfurt am Main
GERMANY

E-Mail:
>

Fon: +49 69 27235-273
Fax: +49 69 27235-238

>

Angaben nach § 25a Absatz 1 GenG:
DENIC eG (Sitz: Frankfurt am Main)
Vorstand: Helga Krüger, Andreas Musielak, Carsten Schiefner, Dr. Jörg Schweiger
Vorsitzender des Aufsichtsrats: Thomas Keller
Eingetragen unter Nr. 770 im Genossenschaftsregister, Amtsgericht Frankfurt am Main

Noch Fragen?

04.03.2015 - 16:10 Uhr

Wenn Du für etwas bestimmtes den Code nicht weisst,
Klick auf Macro->Start (Developer Tab), dann bau das ein was Du tun möchtest.
Klicke auf Stop und dann beim Macro auf Edit. Dann solltest Du den generierten Code sehen, den Du "nur noch" in C# umsetzen musst.

Soweit verstanden?

04.03.2015 - 16:07 Uhr

foreach (System.IO.FileInfo f in ParentDirectory.GetFiles())
{
        Console.WriteLine("Datei: " + f.Name);
        // Open the file to read from.
        string readText = File.ReadAllText(f.Name);
        Console.WriteLine(readText);
}

Reicht Dir das als Info?
Mi File.ReadAllText("Dateiname") kannst Du den Inhalt in einen string einlesen.
Console.WriteLine(readText) gibt den Text aus.

Wenn Du nur eine Ausgabe brauchst geht auch:


Console.WriteLine(File.ReadAllText(f.Name));

04.03.2015 - 15:56 Uhr

@Carfly:

Hi. Was Du zuerst machen solltest, ist die zu zeichnenden Rechtecke als Objekte definieren.
Z.B. wie in [Tutorial] Gezeichnete Objekte mit der Maus verschieben (dort heissen die glaub ich MyGraphobject)

Ein Rechteck wäre also ein Objekt á la:


public class MovingRectangle : MyGraphObject
{
}

Mit der Funktion Move kannst Du dann die Rechtecke bewegen, ggf. müssen die Methoden überschrieben und/oder angepasst werden.


/// <summary>
    /// Bewegt das Objekt um deltaX in x-Richtung und deltaY in y-Richtung.
    /// </summary>
    public virtual void Move(int deltaX, int deltaY) {
        Matrix mat = new Matrix();
        mat.Translate(deltaX, deltaY);
        _path.Transform(mat);
    }

Dann bleibt nur noch die Abfrage wann etwas kollidiert.

Gezeichnet werden die Rechtecke im Paint-Event. Nirgends sonst.
Ein Invalidate zeichnet neu, was neu gezeichnet werden muss.


 protected override void OnPaint(PaintEventArgs e) {
        base.OnPaint(e);
        e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
        // Der Bereich, der neugezeichnet werden soll, wird auf die Zeichenfläche
        // beschränkt, damit Objekte, die darüber hinausschauen abgeschnitten werden.
        Region clip = new Region(_canvas);
        clip.Intersect(e.Graphics.Clip);
        e.Graphics.Clip = clip;
        e.Graphics.Clear(Color.White);
        foreach (MyGraphicObject go in _graphicObjects) {
            go.Draw(e.Graphics);
        }
    }

Ob die Rechtecke sich treffen ist ja nicht schwierig abzufragen, dazu gibt es viele Möglichkeiten,
1.) entweder händisch
2.) Von Rectangle kannst Du zusammen mit

Contains(Point) Bestimmt, ob der angegebene Punkt in dieser Rectangle-Struktur enthalten ist.
Contains(Rectangle) Bestimmt, ob der von rect dargestellte rechteckige Bereich vollständig in dieser Rectangle-Struktur enthalten ist.
Contains(Int32, Int32) Bestimmt, ob der angegebene Punkt in dieser Rectangle-Struktur enthalten ist.

3.) GraphicsPath:

IsVisible(Point) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(PointF) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(Int32, Int32) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(Point, Graphics) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(PointF, Graphics) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(Single, Single) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist.
Öffentliche Methode
IsVisible(Int32, Int32, Graphics) Gibt an, dass der angegebene Punkt in diesem GraphicsPath enthalten ist und dass dabei das angegebene Graphics-Objekt verwendet wird.
Öffentliche Methode
IsVisible(Single, Single, Graphics) Gibt an, ob der angegebene Punkt in diesem GraphicsPath im sichtbaren Clipbereich des angegebenen Graphics-Objekts enthalten ist.

usw.

P.S.: Fast alle Code-Stücke sind aus dem entsprechenden Tutorial entnommen.

04.03.2015 - 12:53 Uhr

Auch von mir vielen Dank für Dein Engagement und Deine immer sehr wertvollen Beiträge.
Es gibt nicht viele Leute, denen ich einiges verdanke was mein Wissen zu .NET und vor allem C# angeht. Du bist einer davon.

Dein Wissen hat mich immer beeindruckt 😃

Ebenso wie Deine Fähigkeit alles auf einen Nenner zu bringen. Egal wie komplex das Thema ist.

Danke. 😃

02.03.2015 - 14:53 Uhr

@Serun:

Klingt für mich als versuchst Du Dich an:

Hintergrund eines Spieles - unendliches Bewegen des Hintergrundes und betreffende

20.02.2015 - 11:42 Uhr

Ich frage mich ob es ausser den erhältlichen

  • Visual Studio Versionen von Microsoft
  • SharpDevelop
  • MonoDevelop

noch weitere IDEs gibt, die möglicherweise IDEs gibt, mit denen komplette .SLNs verwaltbar sind.
Wisst ihr welche?

Das einzige was ich noch entdeckt habe bisher heisst "Storm" und gehört zu einer IDE namens "Moonlite" von Vestras.

Davon gibt es auch einen Screenshot.
(link dazu: http://www.codeproject.com/Articles/42799/Storm-the-world-s-best-IDE-framework-for-NET)

Wer kennt noch weitere?
Oder arbeitet jemand von euch an einer weiteren? 😃

19.02.2015 - 12:28 Uhr

Auch schön:


	private void Timer1Tick(object sender, System.EventArgs e)
		{
			this._nTimerZaehler1++;
			Application.DoEvents();
		}
		private void Timer2Tick(object sender, System.EventArgs e)
		{
			this._nTimerZaehler2++;
			Application.DoEvents();
		}
		private void NamegändertTick(object sender, System.EventArgs e)
		{
			this._nNamegändertTick++;
			if (this._nNamegändertTick == 1)
			{
				if (this._oNamegändertTick != null)
				{
					this._oNamegändertTick.DisconnectAll();
					this._tRelaisTimer.Stop();
					this._tRelaisTimer.Enabled = false;
				}
			}
			Application.DoEvents();
		}

18.02.2015 - 11:49 Uhr

Auch wenn dieser Thread hier noch so alt ist:

gibt es eine c#-(GDI+)Demo-Szene?
Das wäre IMHO sehr interessant.

10.02.2015 - 11:43 Uhr

Hahaha Trib. An den dachte ich ehrlich gesagt dabei auch. 😄

06.02.2015 - 12:16 Uhr

Vielleicht hilft dieses Framework, um damit etwas anzustellen (nicht evaluiert ob kostenlos oder nicht bisher, aber anscheinend schon: fork on github):

http://accord-framework.net/

Auszug:

Machine learning made in a minute

The Accord.NET Framework is a .NET machine learning framework combined with audio and image processing libraries completely written in C#. It is a complete framework for building production-grade computer vision, computer audition, signal processing and statistics applications even for commercial use. A comprehensive set of sample applications provide a fast start to get up and running quickly, and an extensive online documentation helps fill in the details.

Klingt sehr gut. Sobald ich Zeit habe will ich damit unbedingt mal herumspielen.
Jetzt brauche ich nur noch ähs. ^^ 😉

05.02.2015 - 15:12 Uhr

Hallo iceget.

ich denke, wenn Du mit WPF das ganze machst erübrigt sich das mit den Skins.
Denn dann kannst Du das alles selbst hinterher jederzeit machen.

Wenn Du eine Windows-Forms Anwendung machen solltest,
dann empefehle ich Dir unter anderem hier nachzusehen:

Und da gibt es natürlich auch wieder mehrere Möglichkeiten:

Kommerziell und nicht kommerziell.
Und davon nochmal zwei Möglichkeiten:

Entweder ein Framework das alle Komponenten skinned oder geskinnte Controls, die eben schon entsprechend gezeichnet sind.

Am flexibelsten ist IMHO:

benutze ein nichtkommerzielles OpenSource Projekt das Dir die Controls zur Laufzeit skinned.

Nicht kommerziell:
Skins

(ein altes Projekt, das ich allerdings bisher nicht mehr weiterverfolgt habe, in diesem Falle evtl. PN an mich)

Kommerziell:

Geskinnte einzelne Controls:

z.B. DevExpress
https://visualstudiogallery.msdn.microsoft.com/7937dfc6-b216-421a-97e8-6483c5727914

Skinframework:

(momentan finde ich die Links nicht mehr, wird evtl. angepasst)

03.02.2015 - 12:15 Uhr

Auch wenn der Beitrag jetzt sieben Jahre alt ist, gibt es denn inzwischen so ein Programm das so was kann? Weiss da jemand was? Ausser dem untenstehenden Link habe ich dazu bisher nichts konkretes gefunden.

Möglicherweise ist es ja auch damit möglich:

Microsoft Patent: "Automatische Audio Sprachdaten Zensur"

03.02.2015 - 09:48 Uhr

Ich habe diesen Code dazu im Internet gefunden, aber nicht ausprobiert:

EDIT: Ich weiss aber nicht mehr wo. Vielleicht reicht das ja schon aus?


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace StringCollectionEditorTest
{
    /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor"]/*">
    /// <devdoc>
    ///      The StringCollectionEditor is a collection editor that is specifically
    ///      designed to edit collections containing strings.  The collection can be
    ///      of any type that can accept a string value; we just present a string-centric
    ///      dialog for the user.
    /// </devdoc>
    public class StringCollectionEditor : CollectionEditor
    {

        public StringCollectionEditor(Type type)
            : base(type)
        {
        }

        /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.CreateCollectionForm"]/*">
        /// <devdoc>
        ///      Creates a new form to show the current collection.  You may inherit
        ///      from CollectionForm to provide your own form.
        /// </devdoc>
        protected override CollectionForm CreateCollectionForm()
        {
            return new StringCollectionForm(this);
        }

        /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.HelpTopic"]/*">
        /// <devdoc>
        ///    <para>Gets the help topic to display for the dialog help button or pressing F1. Override to
        ///          display a different help topic.</para>
        /// </devdoc>
        protected override string HelpTopic
        {
            get
            {
                return "net.ComponentModel.StringCollectionEditor";
            }
        }

        /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.StringCollectionForm"]/*">
        /// <devdoc>
        ///     StringCollectionForm allows visible editing of a string array. Each line in
        ///     the edit box is an array entry.
        /// </devdoc>
        protected class StringCollectionForm : CollectionForm
        {

            private Label instruction;
            private TextBox textEntry;
            private Button okButton;
            private Button cancelButton;
            private TableLayoutPanel okCancelTableLayoutPanel;

            private StringCollectionEditor editor = null;

            /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.StringCollectionForm.StringCollectionForm"]/*">
            /// <devdoc>
            ///     Constructs a StringCollectionForm.
            /// </devdoc>
            public StringCollectionForm(CollectionEditor editor)
                : base(editor)
            {
                this.editor = (StringCollectionEditor)editor;
                InitializeComponent();
                HookEvents();
            }

            private void Edit1_keyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Escape)
                {
                    cancelButton.PerformClick();
                    e.Handled = true;
                }
            }

            private void StringCollectionEditor_HelpButtonClicked(object sender, CancelEventArgs e)
            {
                e.Cancel = true;
                editor.ShowHelp();
            }

            private void Form_HelpRequested(object sender, HelpEventArgs e)
            {
                editor.ShowHelp();
            }

            private void HookEvents()
            {
                this.textEntry.KeyDown += new KeyEventHandler(this.Edit1_keyDown);
                this.okButton.Click += new EventHandler(this.OKButton_click);
                this.HelpButtonClicked += new System.ComponentModel.CancelEventHandler(this.StringCollectionEditor_HelpButtonClicked);
            }

            /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.StringCollectionForm.InitializeComponent"]/*">
            /// <devdoc>
            ///     NOTE: The following code is required by the form
            ///     designer.  It can be modified using the form editor.  Do not
            ///     modify it using the code editor.
            /// </devdoc>
            private void InitializeComponent()
            {
                System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(StringCollectionEditor));
                this.instruction = new System.Windows.Forms.Label();
                this.textEntry = new System.Windows.Forms.TextBox();
                this.okButton = new System.Windows.Forms.Button();
                this.cancelButton = new System.Windows.Forms.Button();
                this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
                this.okCancelTableLayoutPanel.SuspendLayout();
                this.SuspendLayout();
                //
                // instruction
                //
                //resources.ApplyResources(this.instruction, "instruction");
                this.instruction.Margin = new System.Windows.Forms.Padding(3, 1, 3, 0);
                this.instruction.Name = "instruction";
                //
                // textEntry
                //
                this.textEntry.AcceptsTab = true;
                this.textEntry.AcceptsReturn = true;
                //resources.ApplyResources(this.textEntry, "textEntry");
                this.textEntry.Name = "textEntry";
                //
                // okButton
                //
                //resources.ApplyResources(this.okButton, "okButton");
                this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
                this.okButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
                this.okButton.Name = "okButton";
                //
                // cancelButton
                //
                //resources.ApplyResources(this.cancelButton, "cancelButton");
                this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
                this.cancelButton.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
                this.cancelButton.Name = "cancelButton";
                //
                // okCancelTableLayoutPanel
                //
                //resources.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel");
                this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
                this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
                this.okCancelTableLayoutPanel.Controls.Add(this.okButton, 0, 0);
                this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0);
                this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel";
                this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
                //
                // StringCollectionEditor
                //
                //resources.ApplyResources(this, "$this");
                this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
                this.Controls.Add(this.okCancelTableLayoutPanel);
                this.Controls.Add(this.instruction);
                this.Controls.Add(this.textEntry);
                this.HelpButton = true;
                this.MaximizeBox = false;
                this.MinimizeBox = false;
                this.Name = "StringCollectionEditor";
                this.ShowIcon = false;
                this.ShowInTaskbar = false;
                this.okCancelTableLayoutPanel.ResumeLayout(false);
                this.okCancelTableLayoutPanel.PerformLayout();
                this.HelpRequested += new HelpEventHandler(this.Form_HelpRequested);
                this.ResumeLayout(false);
                this.PerformLayout();
            }

            /// <include file="doc\StringCollectionEditor.uex" path="docs/doc[@for="StringCollectionEditor.StringCollectionForm.OKButton_click"]/*">
            /// <devdoc>
            ///      Commits the changes to the editor.
            /// </devdoc>
            private void OKButton_click(object sender, EventArgs e)
            {
                char[] delims = new char[] { '\n' };
                char[] trims = new char[] { '\r' };

                string[] strings = textEntry.Text.Split(delims);
                object[] curItems = Items;

                int nItems = strings.Length;
                for (int i = 0; i < nItems; i++)
                {
                    strings[i] = strings[i].Trim(trims);
                }

                bool dirty = true;
                if (nItems == curItems.Length)
                {
                    int i;
                    for (i = 0; i < nItems; ++i)
                    {
                        if (!strings[i].Equals((string)curItems[i]))
                        {
                            break;
                        }
                    }

                    if (i == nItems)
                        dirty = false;
                }

                if (!dirty)
                {
                    DialogResult = DialogResult.Cancel;
                    return;
                }

                // ASURT #57372
                // If the final line is blank, we don't want to create an item from it
                //
                if (strings.Length > 0 && strings[strings.Length - 1].Length == 0)
                {
                    nItems--;
                }

                object[] values = new object[nItems];
                for (int i = 0; i < nItems; i++)
                {
                    values[i] = strings[i];
                }

                Items = values;
            }

            // <summary>
            //      This is called when the value property in the CollectionForm has changed.
            //      In it you should update your user interface to reflect the current value.
            // </summary>
            //
            protected override void OnEditValueChanged()
            {
                object[] items = Items;
                string text = string.Empty;

                for (int i = 0; i < items.Length; i++)
                {
                    if (items[i] is string)
                    {
                        text += (string)items[i];
                        if (i != items.Length - 1)
                        {
                            text += "\r\n";
                        }
                    }
                }

                textEntry.Text = text;
            }
        }
    }
}

dr4g0n76

02.02.2015 - 14:13 Uhr

Hier in CodeProject benutzt das jemand, zumindest für OpenType.

Auszug von dort für die Steps:

The GDI+ API used by the .NET platform does not support OpenType fonts well, but the system wide API, GDI (without the plus sign, but does more here), supports OpenType much better. We can use Platform Invoke to call functions exposed by the GDI and render texts with OpenType fonts.

The procedure is listed below. The major functions to use are the CreateFont function and the DrawText function.

Get the device context (DC) from the graphics.
Call the CreateFont function and create the GDI font.
Use the font in the DC by calling SelectObject.
Call the DrawText function and draw the text onto the specific region of the DC.
Release the resources by calling DeleteObject.