Laden...
S
Spook myCSharp.de - Member
Fachinformatiker Esslingen a.N. Dabei seit 28.10.2008 250 Beiträge
Benutzerbeschreibung

Forenbeiträge von Spook Ingesamt 250 Beiträge

19.09.2024 - 12:48 Uhr

Hallo,

du hättest auch einfach den Enumerator der Liste zurückgeben können:

public IEnumerator<IClass> GetEnumerator()
{
   return Items.GetEnumerator();
}

Damit kannst du dir die Nachimplementierung sparen.

Grüße

10.09.2024 - 16:32 Uhr

Hallo Gene,

als erstes würde ich den Converter Code aufräumen, wie es Th69 bereits vorgeschlagen hat. Mit folgendem Snippet sollte dein gewünschtes Ergebnis herauskommen:

NumberFormatInfo info = new()
{
    CurrencySymbol = "€",
    CurrencyDecimalDigits = 2,
    CurrencyGroupSeparator = " ",
    CurrencyDecimalSeparator = ",",
    CurrencyPositivePattern = 3,
    CurrencyNegativePattern = 8
};
decimal value = 123_456_789_012_345.131516m;
string text = value.ToString("c", info); // 123 456 789 012 345,13 €

Zu dem Caret Problem:
Woher sollte die Textbox den Zusammenhang von dem eingegebenen Text und dem dahinterliegenden Converter kennen? Die verlinkte CurrencyTextBox wird mit Sicherheit eine interne Logik haben, die Eingabe und Caret Position speziell behandelt. Womöglich wirst du dies selbst machen müssen, da diese TB nur vorgegebene Formate unterstützt (laut Beschreibung).

17.07.2023 - 08:02 Uhr

Hallo nerkon,

ich sehe hier zwei mögliche Ursachen:

  1. long in C# ist immer 64bit während es dein C-Kompiler vermutlich als 32bit behandeln wird. Du solltest also in beiden am besten int verwenden.
  2. Response ist in C# als Klasse definiert und ich glaube mich zu erinnern, dass diese dann by default als Referenz gemarshallt werden, was mit der Signatur des C Exports (Callback) nicht zusammen passt. Ich würde in C# diese ebenfalls als struct definieren.
  3. (Das MarshalAs Attribut bei long ts ist glaube ich überflüssig - siehe Punkt 1)

Grüße
spooky

20.01.2023 - 09:16 Uhr

Hallo Oskar,

sobald strings gemarshallt werden, würde ich den verwendeten CharSet im DllImport angeben.

Grüße
spooky

23.07.2022 - 16:19 Uhr

Natürlich ist das wrappen des Streams hier nicht optimal gelöst, ich denke, ich muss noch ALLE methoden, die den Ursprungs-Stream benutzen und über das festgelegte offset und limit hinausgehen, "clampen", also die gewünschte Position auf den Bereich limitieren.

Ich denke du schießt gewaltig über das Ziel mit der Implementierung hinaus.
Das Einzige was du überschreiben musst sind die abstrakten Members von Stream - alle anderen kannst du genau so lassen wie sie sind. Ganz besonders macht es keinen Sinn Member zu überschreiben und dann den Basis-Member wieder eins zu eins aufzurufen...

.. der eine "View" über den _innerStream legt, dabei zu Beginn von Außen Offset := 0 und Länge := das Limit ist.
Intern kann das ja auf den _innerStream umgerechnet werden. Z.B. beim Setzen der Position halt den Offset berücksichtigen.

Wie schon gesagt wurde ... du muss lediglich Position, Length, Read und Seek so anpassen dass nur der gewünschte Bereich von außen sicht- und zugreifbar ist und der Rest verhält sich dann wie gewünscht.
Hier ein grober Ansatz, den du ausbauen kannst (Parameterprüfung von ctor, Position etc.):


public class StreamLimiter : Stream
{
    private readonly Stream _stream;
    private readonly long _offset;
    private readonly long _length;

    public StreamLimiter(Stream stream, long offset, long length)
    {
        _stream = stream;
        _offset = offset;
        _length = length;

        Position = 0;
    }

    public override bool CanRead => true;
    public override bool CanSeek => true;
    public override bool CanWrite => false;
    public override long Length => _length;

    public override long Position
    {
        get { return _stream.Position - _offset; }
        set { _stream.Position = _offset + value; }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        long remaining = Length - Position;
        if (remaining == 0)
            return 0;

        count = (int)Math.Min(count, remaining);
        return _stream.Read(buffer, offset, count);
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
        long position = origin switch
        {
            SeekOrigin.Begin => offset,
            SeekOrigin.Current => Position + offset,
            SeekOrigin.End => Length + offset,
            _ => throw new ArgumentException(nameof(origin))
        };

        if (position < 0 || position > Length)
            throw new ArgumentException(nameof(offset));

        Position = position;
        return position;
    }

    public override void Flush() => throw new NotSupportedException();
    public override void SetLength(long value) => throw new NotSupportedException();
    public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException();
}

Grüße
spooky

19.07.2022 - 08:58 Uhr

Hallo sandreas,

die Wrapper Klasse wäre vermutlich der einfachste Weg.
Jedoch solltest du nicht SetLength auf dem gewrappten (File)Stream aufrufen. Dadurch verkleinerst deine gewrappte Datei (schneidest Daten am Ende ab), was vermutlich nicht gewollt ist.

Grüße
spooky

17.03.2022 - 09:44 Uhr

Der verlinke Multimedia Timer ist leider für NET Core, ich hab hier noch .NET Framework.

Der Quellcode ist mit sehr sehr großer Wahrscheinlichkeit 1:1 .NET Framework kompatibel, da er fast identisch aussieht wie The Multimedia Timer for the .NET Framework.

15.03.2022 - 14:40 Uhr

Hallo Abt,

mir ist bewusst, dass man 0.5ms nicht zu 100% erreichen kann ... dies waren eben die ersten sinnvollen Google-Treffer wenn man nach der verwendeten Win-API Funktion gesucht hat. Es sollte lediglich den TE auf diese Option hinweisen.

Hallo ill_son,

vielleicht wäre es besser anstatt eines Sleep Ansatzs einen Timer zu verwenden.

Ich vermute einfach mal frech, dass du deinen Sensor immer im selben Takt abfragen möchtest. Da würde ein Timer, der in regelmäßigen Intervallen auslöst, vermutlich passen.
Da du eine hohe Präzision möchtest, würde ich dir den Multimedia-Timer empfehlen. (Es gibt auch andere Implementierungen im Netz, falls diese nicht zusagt). Dort kannst du die gewünschte Auflösung in ms angeben.
(Ja auch hier wirst du nicht auf die ns genau sein, aber besser als Sleeps oder Spin-Locks).

Grüße
spooky

10.03.2022 - 14:19 Uhr

Auch wenn du keine Echtzeit erreichen kannst, ist es trotzdem möglich die Auflösung der System-clock feiner einzustellen, siehe:
How to set timer resolution to 0.5ms
How to setup timer resolution to 0.5 ms?
Clockres

Grüße
spooky

01.12.2021 - 09:23 Uhr

Versuche mal bitte Urzas Vorschlag plus den Scrollviewer um das gesamte ItemsControl zu legen.
Ggf müsste dieser vielleicht sogar noch weitere Ebenen im XAML nach oben.

07.10.2021 - 08:19 Uhr

Hallo,

du solltest prüfen ob MainWindowHandle auch ein gültiges Handle oder IntPtr.Zero zurück gibt.
Das wird vermutlich das Problem sein.
Hier könntest du eine Lösung finden: Process.MainWindowHandle returns 0 for too many processes

Grüße

06.09.2021 - 15:51 Uhr

Hallo,

hier gibt es ein Projekt für globale Mouse- und Keyboard-Hooks:
Global-Low-Level-Key-Board-And-Mouse-Hook
Mit drei Zeilen Code hast du deinen Hook erstellt - Beispiel ist auch vorhanden.

Ansonsten suchst du die GetCursorPos function mit welcher du die Mausposition abrufen kannst.
Hier der P/Invoke dafür:
https://www.pinvoke.net/default.aspx/user32.getcursorpos

Grüße
spooky

26.08.2021 - 19:36 Uhr

Ist schon eine Weile her, aber ich vermute du prüfst die falsche Property.

So ist es.

Filter enthält alle Auswahlmöglichkeiten. Du musst die FilterIndex Property verwenden. (Der Startindex ist 1).

05.08.2021 - 12:59 Uhr

Hallo Programmierlaie,

du verwendest vermutlich .NET Core / .NET 5 - dein Beispiel ist jedoch für .NET Framework.
Du musst UseShellExecute verwenden und auf true setzen:


ProcessStartInfo processStartInfo = new ProcessStartInfo();
processStartInfo.FileName = "https://google.de";
processStartInfo.UseShellExecute = true;
Process.Start(processStartInfo);

Grüße
spooky

16.07.2021 - 17:15 Uhr

Hallo Tehral,

mit folgendem Code kannst du die Berechtigungen eines Ordners abrufen:


var info = new DirectoryInfo(path);
var accessControl = info.GetAccessControl();
var rules = accessControl.GetAccessRules(true, false, typeof(SecurityIdentifier));

foreach (FileSystemAccessRule rule in rules)
{
    NTAccount account = (NTAccount)rule.IdentityReference.Translate(typeof(NTAccount));
    ...
}

Du kannst über die DirectorySecurity.AddAccessRule(FileSystemAccessRule) Methode deine gewünschte Regel hinzufügen.
Dass diese nur für den Ordner alleine gilt müsstest du glaube ich PropagationFlags.NoPropagateInherit verwenden (nicht getestet).
Du könntest diese Methode als Grundlage für dein Vorhaben anpassen:


public static void SetDirectoryAccess(
    string path, string account, FileSystemRights access, AccessControlType controlType,
    InheritanceFlags inheritanceFlags = InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
    PropagationFlags propagationFlags = PropagationFlags.None)
{
    DirectoryInfo info = new DirectoryInfo(path);
    DirectorySecurity security = info.GetAccessControl();
    security.AddAccessRule(new FileSystemAccessRule(account, access, inheritanceFlags, propagationFlags, controlType));
    info.SetAccessControl(security);
}

Grüße
spooky

02.06.2021 - 11:24 Uhr

Hallo hypersurf

Woran liegt es, dass der Fehler nicht durch die Event-Handler für die Unhandled Exceptions gefangen wird? Ist ein Memorydump der einzige Weg die Ursache zu ermitteln?

Sollte es sich um eine SEHException handeln (müsstest du mal prüfen), dann kann diese ab .NET FW 4 nicht mehr (ohne Weiteres) über die von dir verwendeten Event-Handler gefangen werden.
CLR Inside Out - Handling Corrupted State Exceptions
Ich würde ebenfalls den von dir versuchten Weg gehen und einen Memory-Dump anfertigen.

Grüße
spooky

25.05.2021 - 14:24 Uhr

Hallo RPAutomation,

wir verwenden zum Teil diese Lib für den Zugriff auf OPC-Server:
h-opc

Die Logik zum Verbinden, Auslesen der Variablen(struktur), Aktualisieren der Werte und Oberfläche wirst du selbst machen müssen.

Grüße
spooky

21.05.2021 - 13:04 Uhr

Hallo pollito,

du kannst eine .NET 5 (oder .NET Core) Assembly in einem C++/cli Projekt verwenden.
Dafür musst du ggf. die Projektdatei entsprechend anpassen (geht auch über die Projekteingenschaften).

Einen Ausschnitt aus einem Projekt, dass .NET 5 verwendet:


  <ItemGroup Label="ProjectConfigurations">
    <FrameworkReference Include="Microsoft.WindowsDesktop.App" />
	...
  </ItemGroup>
  <PropertyGroup Label="Globals">
	...
    <TargetFramework>net5.0</TargetFramework>
    <CLRSupport>NetCore</CLRSupport>
    <Keyword>ManagedCProj</Keyword>
	...
  </PropertyGroup>

Portieren eines C++/CLI-Projekts zu .NET Core

Ich denke nicht, dass du eine .NET 5 Assembly aus einer beliebigen .NET Framework Version referenzieren oder verwenden kannst.

Grüße spooky

09.04.2021 - 08:18 Uhr

Hallo EyeTrackJack,

Raw Input könnte die Lösung sein. Wenn man weiter zu Mauseingaben geht, gibt es relative Bewegungsinformationen. Allerdings weis ich nicht, ob diese von Windows am Bildschirmrand auch abgeschnitten werden. Das müsste man noch evaluieren.

In welcher Art von Umgebung benötigst du diese Information? 3D (Spiel)?

Grüße
spooky

24.02.2021 - 13:39 Uhr

Bitte genauer sagen, was Du ausdrücken magst, als nur "falsch".

Gerne.

Ich hätte erwartet, dass wenn ich das Icon für "Neue Beiträge!" (Text des Icons) sehe, dass dann dieses Forum auch wirklich Threads enthält die ungelesen sind.
Wir sind uns einig, dass dies aktuell nicht der Fall sein muss, wenn ich über "Aktive Themen" gehe.

Meine Meinung:
Aus Benutzer-Sicht ist dies nicht konsistent und verwirrend.
Nehen wir an es gibt seit meinem letzten Besuch 10 neue Posts in 10 verschiedenen Foren. Nun besuche ich 5 dieser Threads über "Aktive Themen" und gehe danach auf die Forenübersicht. Nun sind hier immer noch 10 Foren mit "Neuen Beiträgen!" markiert. In 5 Fällen gehe ich in ein Forum und sehe, dass ich den Thread schon gelesen hatte.

Ich würde, als stink normaler Benutzer, implizieren, dass das Icon eine Aggregation aus den einzelnen Threads ist. Enthält ein Thread im jeweiligen Forum einen ungelesenen Beitrag ist das Forum als ungelesen zu markieren, und nicht, dass ich manuell in das Forum navigieren muss um dieses als gelesen zu markieren.

Grüße

24.02.2021 - 10:02 Uhr

Einen kleinen Bug scheint es mit der Anzeige ungelesener Beiträge zu geben, wenn man nicht das Forum, das den Thread enthält, direkt besucht, sondern nur über "Aktive Themen" geht:

  • Ich gehe auf die Foren-Übersicht und es wird mir in Forum X angezeigt dass es neue Beiträge gibt (orangenes Icon)
  • Ich gehe auf Aktive Themen (nicht direkt in das Forum) und sehe nun Thread Y ist ungelesen
  • Ich klicke auf den Thread um ihn zu lesen
  • Ich gehe eine Seite im Browser zurück (aktive Themen), refreshe die Seite und der Thread ist als gelesen markiert => korrekt
  • Ich gehe eine weitere Seite im Browser zurück, refreshe die Seite (Forenübersicht) und das Forum, das den Thread enthielt, ist immer noch markiert mit ungelesenen Threads => falsch
  • Ich klicke auf das Forum und es enthält keine ungelesenen Threads (Thread gerade gelesen)
  • Ich gehe wieder zurück auf die Forenübersicht, refreshe die Seite und nun ist auch dort die Markierung (oragenes Icon) weg

Grüße

19.02.2021 - 15:29 Uhr

Ich fand diese Funktion auch sehr nützlich, da ich dies als Standardansicht für die Navigation im Forum verwendet habe.
Bin klar für eine Wiedereinführung 😉

02.02.2021 - 15:25 Uhr

Hier weiß ich nicht, was gemeint ist.

Mein Post sah wie folgt aus:

Text
Url-Tag
Text

Vor dem Posten hatte ich die "Vorschaufunktion" benutzt und der komplette Text hinter dem URL-Tag wurde in der Vorschau gelöscht. Dann habe ich den Text wiederhergestellt und gepostet und der Text war wieder gelöscht.
Ich kann den Fehler aktuell auch nicht mehr reproduzieren ... aber auch mit einem nicht korrekt geschlossenem Tag passiert nichts ungewöhnliches. Merkwürdig.

Beim Versuch den Fehler zu reproduzieren habe ich Folgendes gefunden:
Beim Erstellen eines neuen Threads ohne Eingabe einer Überschrift => Vorschau => Error500

02.02.2021 - 08:22 Uhr

Vielen Dank für die Mühen und die investierte Zeit. Das ist nicht selbstverständlich. 👍
Dem Team und allen Anderen alles Gute und bleibt gesund.

02.02.2021 - 08:19 Uhr

Nachtrag:
Das URL Tag scheint alles dahinter geschriebene sowohl in der Vorschau als auch im finalen Post zu entfernen.

Was ich noch zur Seitenauswahl geschrieben hatte:
Dort ist [1] 2 2 zu finden. Klickt man auch eine der 2en dann kommt 1 1 [2].

Liebe Grüße
spooky

02.02.2021 - 08:17 Uhr

Hallo zusammen,

bei Themen dir mehrere Seiten an Posts haben funktioniert die Seitenauswahl links unten nicht korrekt.

27.01.2021 - 11:43 Uhr

Also ehrlich gesagt, verstehe ich nicht, warum du eine WpfApplicaton als Konsolenanwendung missbrauchst.

Weil dann ein Konsolenfenster verfügbar ist, um schnell Debug-Messages, auf einem nicht-Entwicklungsrechner, auszugeben. Siehe Init-Methode. Darauf nun rumzureiten, obwohl es null mit der Ursache oder Lösung des Problems zu tun hat bringt doch garnix.

Ich denke aber, daß der Fehler von einer nativen Komponente verursacht wird (z.B. direkt von der .NET-Laufzeitumgebung).

Dies sollte klar sein, dass die Laufzeit, Treiber oder sonstige Komponente ein Problem hat und nicht die Anwendung selber. Im Notfall die Runtime neu installieren, System auf Fehler prüfen oder Windows komplett zurückzusetzen.

Hier findest du eine Anleitung zum Reparieren von Systemdateien:
Verwenden des Systemdatei-Überprüfungsprogramms (SFC.exe) zur Problembehandlung bei fehlenden oder beschädigten Systemdateien

27.01.2021 - 08:44 Uhr

Hallo Qt21580,

ich habe mal deine kompilierte Variante probiert. Diese startet.
Dann habe ich den Code mit und ohne einkommentiertem TextBlock in Debug und Release getestet. Alle vier Kominationen starten ohne Probleme.

26.01.2021 - 17:17 Uhr

Wenn es eine unbehandelte Ausnahme gibt, wird das entsprechende Ereignis ausgelöst.

AccessViolationExceptions (genauer gesagt alle SEHExceptions) können seit .NET 4 nicht mehr einfach gefangen werden. Der Prozess wird beendet und ein Eintrag in das Ereignisprotokoll geschrieben.

In version 4 and later, the CLR exception system will not deliver CSEs to managed code unless the code has expressly indicated that it can handle process corrupted state exceptions.

Was du versuchen könntest wäre einen Crash-Dump zu erzeugen und diesen dann zu debuggen.
Am einfachsten kannst du dies machen in dem du Procdump verwendest. Stürzt ein Prozess ab wird automatisch ein Memory-Dump erzeugt.

Mit folgendem Batch-Skript kannst du die automatische CrashDump Erstellung aktivieren:

cd %~dp0
md c:\procdumps
procdump -accepteula -ma -i c:\procdumps

Und mit folgendem wieder deaktivieren:

cd %~dp0
procdump -u

(Beide Skripte benötigen Adminrechte zur Ausführung. Beide Skripte zur Procdump-Exe kopieren vor der Ausführung.)

Den Crashdump (aus C:\procdumps) solltest du dann einfach via Drag&Drop in VS ziehen und debuggen können.

27.10.2020 - 09:25 Uhr

Hallo BerndFfm,

handelt es sich um WPF oder um Forms?

Grüße

17.09.2020 - 09:45 Uhr

Hallo ma_fo,

du wirst wohl nicht darum herumkommen die Argumentliste von neuen Instanzen an die laufende zu übertragen. Th69 hat dazu ja bereits eine mögliche Lösung gepostet (Stichwort IPC).
Ich würde in der primären Instanz eine Queue anlegen und dort die eigenen Einträge einfügen und diese in einer Schleife abarbeiten. Weitere Instanzen übertragen ihre Argumentliste an die primäre Instance, die ebenfalls in die Queue eingefügt werden. Ist die Queue leer beendet sich das Programm.

Grüße
spooky

16.09.2020 - 10:33 Uhr

Leider kann man in dem Screenshot nicht sehen, was um die Zuweisungen, die du ja nun schon mehrmals gepostet hast, passiert. Poste bitte die komplette Schleife, inklusive der Anzeige, wo das Programm sich gerade befindet (gelber Pfeil links). Und am noch den (wenn nötig gekürzten) Inhalt von Liste_Messung_Filter_Daten.

16.09.2020 - 08:50 Uhr

Liste_Messung_Filter_Daten[MovingSegment].Scale_Lst = 1.29949236
scale = 0.76953125
scale_temp = 1
Liste_Messung_Filter_Daten[MovingSegment].Start_Point_X = 243
Liste_Messung_Filter_Daten[MovingSegment].Start_Point_Y = 228
Startpunkt_alt_X = 243
Startpunkt_alt_Y = 226

Wie hast du diese Werte ermittelt?

Vorschlag:
Trage alle diese Werte beim Debuggen in das "Überwachen" Fenster ein. Halte das Programm hinter der letzten Zuweisung an und mach einen Screenshot von VS in dem man das Überwachen-Fenster, den relevanten Code mit Breakpoint sehen kann.

15.09.2020 - 13:54 Uhr

Ich rate einfach mal:
MovingSegment ist ein Index einer Schleife. Du inkrementierst diesen und vergleichst dann die Werte aus dem letzten mit denen aus dem aktuellen Durchlauf.

08.09.2020 - 10:40 Uhr

Oder, falls gewünscht global, mit diesem Code (siehe auch verlinkter Post):

            FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(
                    XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

Kannst du z.B. im Ctor/OnStartup deiner Application-Klasse aufrufen.

Grüße

08.09.2020 - 07:17 Uhr

Hallo,

siehe Hinweise von Binding.ConverterCulture Eigenschaft.

Edit:
Du hast fast die gleiche Frage schonmal gestellt und eine Antwort bekommen, wie man diese umstellt.
Vielleicht sollte man mit klarem Kopf und ausgeschlafen an die Sache rangehen 😉

Grüße spooky

31.07.2020 - 12:50 Uhr

Hallo matrix4you,

was spricht gegen das Erstellen einer Wrapper DLL wie bereits vorgeschlagen wurde?
Ich würde dies als sinnvollen und umsetzbaren Lösungsweg ansehen.
Das gelinkte Beispiel macht 1 zu 1 was du brauchst.

Hast du von der verwendeten DLL die .h und die .lib Dateien?
Was hast du schon in die Richtung versucht?

PS: Wenn die DLL eine native C/C++ DLL ist, dann macht es wenig Sinn diese als Verweis hinzuzufügen.

Grüße
spooky

edit: Typo

31.07.2020 - 11:38 Uhr

Wo hatte ich das nur wieder her ? Environment.GetCommandLineArgs gibt dir den Pfad der Anwendung als erstes Argument.

14.07.2020 - 07:07 Uhr

in DBB10 steht die länge des Strings (254).
ab DBB12 bekomme ich immer eine Null.

In DB2000.DBB11 steht eine "0".

Die Daten sind konsistent:
[254][0][0]
Maximale Länge: 254
Tatsächliche/Benutzte Länge: 0
Erstes Byte: 0

Also ist der String leer.
Vermutlich steht einfach nichts drinnen. Das solltest du prüfen.

10.07.2020 - 12:33 Uhr

Hallo Goofigoofi,

wenn ich das richtig sehe, hast du einen String mit als Längen-Information.
Das erste Byte stellt die maximale Länge des Strings in Bytes dar.
Das zweite Byte die tatsächliche Länge des Strings in Bytes.
Danach folgen die N Bytes des Strings (nicht verwendete Bytes sollten mit 0x00 gefüllt sein).

Du solltest schauen, was in DBB11 steht.

(Alternativ scheint es dafür schon eine Hilfsmethode in der von dir verwendeten Lib zu geben: StringEx.FromByteArray. Hier müsstest du alle Bytes, inklusive Header, in ein Byte-Array kopieren und dann die Methode aufrufen.)

Grüße spooky

02.07.2020 - 12:34 Uhr

Das Problem ist, dass der Code hier vermutlich extrem ausgedünnt und dabei noch diverse Fehler enthält:


IntPtr pAeusere;
getData(pAeusere);

Alleine das kann schon nicht kompilieren.


Aeusere aeusere = (Aeusere) Marshal.PtrToStructure(pAeusere, typeof(emxArray));

Das wird zur Laufzeit krachen, außer Aeusere ist ein Alias für emxArray.

Was du machen möchtest ist relativ simpel zu lösen. Aber bitte zeige uns den richtigen Code und nicht etwas völlig verfälschtes.

01.07.2020 - 16:01 Uhr

Hallo mifi261,

die Definitionen der structs im C# entspricht nicht denen aus dem C++ Code.

             IntPtr pElement = new IntPtr(aeusere.data.ToInt32() + Marshal.SizeOf(typeof(Innere)) * i);

Einen Pointer nach Int32 umzuwandeln ist keine gute Idee. Sollte dein Programm unter 64Bit laufen wirst du eine Exception bekommen. Verwende stattdessen besser den + Operator von IntPtr.

Aeusere aeusere = (Aeusere) Marshal.PtrToStructure(pAeusere, typeof(emxArray));

Wo ist emxArray definiert? Mir scheint hier, dass dies a) nicht kompiliert und b) zusammengewürfelte Teile sind.

Wenn du ein Array of structs übertragen willst, kannst du dies sehr viel einfacher machen indem du im C# direkt ein Array deiner Struct als Parameter angibst. Im C++ kopierst du dann einfach die Daten via memcpy in das Array.
Da du das Array natürlich im C# vorallokieren musst, und in C++ keine Länge da ist würde ich einen weiteren in/out Parameter für die Array-Länge anlegen:


        struct Innere
        {
            int iValue1;
            int iValue2;
            double dValue;
        };

        [DllImport(DLLPfad, CallingConvention = CallingConvention.Cdecl)]
        private static extern void GetData(Innere[] data, ref int size);

                int size = 0;
                Innere[] data = null;
                GetData(data, ref size); // Länge abrufen
                data = new Innere[size]; // Array allokieren
                GetData(data, ref size); // Werte direkt ins Array schreiben

C++


        DLL_EXPORT void GetData(Innere* array, int& size)
        {
            if (array == nullptr)
            {
                size = ...;//
            }
            else
            {
                memcpy(array, ..., sizeof(Innere) * size);
            }
        }

Damit kannst du dir die äußere Struct sparen und die Daten werden direkt kopiert also auch kein Marshalling nötig.

Grüße
spooky

26.05.2020 - 07:54 Uhr

Komplexer machen es nur die Kombinationen aus mehreren Buchstaben.
Täusche ich mich?

Wenn ich beim Überfliegen der Texte richtig verstanden habe, können/müssten Buchstabenkombinationen wie 'sch' oder 'ch' und Zahlen, da A-J auch 1-0 sind, separat behandelt werden. Also wird einfaches Ersetzen eines chars mit einem anderen nicht klappen.

Mit diesen zwei Spezialfällen sollte trotzdem eine recht übersichtliche Lösung zu finden sein:

  • Kommt eine Zahl => 'Zahl folgt' + alle Zeichen der Zahl (hier ist die Frage wie z.B. 1,23 umgesetzt werden - ich vermute dass kein zweites 'Zahl folgt' verwendet wird)
  • Kommen Zeichen, die in einer Kombination zusammengefasst sind => Kombinations-char
  • Ansonsten einzelnes Zeichen mappen

Grüße

25.05.2020 - 07:52 Uhr

Hallo Sebrahi,

du kannst den Code der an einer anderen Stelle ausgeführt werden soll in eine Methode schreiben und diese dann über die Verwendung von Delegates an einer anderen Stelle ausführen:

	public static void vier_mal_wiederholen()
	{
		for(int i=1;i<=4;i++)
		{
			// hier soll der Code rein der viermal wiederholt werden soll
		}
	}
	
	public static void drei_mal_wiederholen()
	{
		for(int i=1;i<=3;i++)
		{
			// hier soll der Code rein der dreimal wiederholt werden soll
		}
	}
	
	public static void Test(Action action)
	{
		action();
		MessageBox.Show("hi");
	}
	
	public static void Main()
	{
		Action action = vier_mal_wiederholen;
		Test(action);
		
		Test(drei_mal_wiederholen);
	}

Grüße
spooy

13.03.2020 - 11:50 Uhr

Hallo,

ich habe die Vermutung, dass der Schatten des Fensters bei der Berechnung der Größe mitgezählt wird, da dieser bei FormBorderStyles.None nicht gerendert wird und hier das Fenster die erwartete Größe hat.

Grüße

31.01.2020 - 07:19 Uhr

Über die Windows API:
Creating a Window

Hier die Verwendung in Windows Forms:
NativeWindow

Die anderen Aufrufe sind über die Suche leicht zu finden.

Grüße

10.01.2020 - 10:59 Uhr

... steht etwas von KernelBase.Dll, was aber völlig unverständlich ist.

Wieso postest du die Meldung denn nicht einfach? Vielleicht kann hier jemand damit etwas anfangen.

05.12.2019 - 12:36 Uhr

Ich meine, dass ich genau dieses Wunschverhalten schon viele viele Male gelesen habe, das in der Form aufgrund des Fernsterverhaltens des Betriebssystem jedoch leider gar nicht möglich ist; weil eben das Window Management hier den Fokus wechselt und Du dies nicht aktiv beeinflussen kannst.

Diese stehen in der Remarks Section von SetForgroundWindow.

Grüße

31.10.2019 - 07:29 Uhr

Versuch diese Änderung:

        public Form1()
        {
            InitializeComponent();
            GetData();
        }

Grüße

27.09.2019 - 10:26 Uhr

Das Löschen des Cookie Caches scheint das Problem bei mir gelöst zu haben. Bin seit gestern Nachmittag immer noch eingeloggt und bleibe es anscheinend auch nach mehreren Pausen und Reboot des Rechners.