Hallo,
meinst du das Arbeiten im visuellen Designer oder zur Laufzeit?
Ich verstehe jedoch nicht, was du mit dem MenuStrip
meinst? Über ein Menü kannst du die verschiedenen Bereiche zur Auswahl stellen, so daß der Anwender zwischen diesen wechseln kann - das Anzeigen und Verstecken mußt du jedoch selber ausprogrammieren.
Ich würde vorschlagen, du erzeugst je Bereich ein eigenes UserControl
(diese kannst du auch im Designer erstellen und bearbeiten). Und dann hältst du die einzelnen UserControls
in einer Liste und merkst dir jeweils die gerade Aktive in einer Eigenschaft.
Das sind die Debug-Infos, welche beim Kompilieren mitgegeben werden.
Wenn du diese nicht benötigst, dann erstelle deine Applikation als Release und liefere keine ".pdb"-Dateien aus.
Hallo,
schau auch mal in Interprocess Communications (der deutsch übersetzte Artikel ist leider nicht zu verstehen).
OK, schön, daß ersteres schon auf dem Wege ist.
Wenn ich Dateien aus dem Internet herunterlade, möchte ich schon direkt den passenden (angezeigten) Dateinamen haben, anstatt jedesmal diesen wieder ändern zu müssen (denn wenn alle Dateien nachher nur "attachments-..." heißen, bringt mir das nicht viel). Vllt. hilft hier Change the name of your file with – HTML5 “Download” attribute?
Sollte der Forenbereich "FAQ" (und evtl. auch "Artikel") für normale Benutzer nicht besser schreibgeschützt sein (da gerade dort ein Thema fälschlicherweise eröffnet wurde)?
Außerdem ist mir noch eine andere Sache aufgefallen:
Beim Herunterladen von Anhängen wird nicht der angezeigte Dateiname genommen, sondern "attachment-...", so daß man selber den Dateinamen beim Abspeichern wieder ändern muß.
Bei einem GUI-Programm kann man Process.CloseMainWindow (sowie anschließend Process.Close) aufrufen. Das startende Programm muß sich also dessen Process
-Instanz merken.
Ja, du benötigst dazu einen HTTP Server.
Gefunden habe ich noch folgende Links:
Weitere Stichworte zum Nachlesen: HTTP/Web/REST API, z.B. Einfache REST-API mittels PHP
Soll deine App denn nur bei dir im lokalen Netzwerk funktionieren oder willst du Zugriff auch über das Mobilfunknetz auf die Datenbank haben?
Es gab neulich erst folgendes Thema: XAMARIN MySQL Datenbankverbindung wirft Exception - beachte besonders die Hinweise von Abt.
Möchtest du gleichzeitig die PDF-Datei lesen und beschreiben? Das wird wohl so nicht direkt funktionieren - gib mal als 2. Parameter für PdfStamper
einen eigenen Output-FileStream
an, s.a. C# (CSharp) iTextSharp.text.pdf PdfStamper Beispiele.
Dann sollte auch das File.Copy
überflüssig sein.
In welcher Zeile genau erhältst du denn die Exception?
Durch die using
-Anweisung in Zeile 20 sollte pdfStamper.Close()
überflüssig sein (aber es sollte trotzdem keine Exception geworfen werden).
Analog solltest du beim Zugriff auf PdfReader pdfReader
besser ebenfalls eine using
-Anweisung benutzen.
Einfach das NuGet-Package ShellFileDialogs zu deinem Projekt hinzufügen und dann dessen ShellFileDialogs.FolderBrowserDialog
benutzen.
Falls du noch nie vorher mit NuGet gearbeitet hast, dann lies Schnellstart: Installieren und Verwenden eines Pakets in Visual Studio (nur Windows) (s. "Hinzufügen des NuGet-Pakets „Newtonsoft.Json“", nur daß du dort dann das andere Paket suchst und auswählst).
Schau mal in Unterstützung hoher DPI-Werte in Windows Forms, ob dir die Einstellungen dort helfen.
Hallo,
dazu kannst du das "Windows API Code Pack" benutzen (gibt es in zwei Versionen, einmal für .NET Framework und einmal für .NET [Core]).
Eine abgespeckte Version, nur die Dialoge betreffend, gibt es unter ShellFileDialogs.
Puh 😉
Schön, daß es jetzt funktioniert und danke für die positive Rückmeldung.
Du meinst .NET Framework 4.8? Ich wollte nur wissen, ob es nicht doch das neuere .NET 5 / 6 oder 7 ist.
Ich habe sowohl per Code, d.h. Paste
als auch manuell über "Strg+V" das im Clipboard gespeicherte BMP-Bild in die RichTextBox
einfügen können.
Kannst du es denn zur Laufzeit manuell über "Strg+V" bzw. das Kontextmenü "Einfügen" hinzufügen (oder ist es ausgegraut)?
Hast du es mal mit einer anderen BMP-Datei probiert (evtl. ist deine "NeoPixel.bmp" in einem nicht-kompatiblen Format)?
Welche .NET Version verwendest du?
In einem Testprojekt mit .NET Framework 4 kann ich problemlos eine BMP-Datei in eine RichTextBox
einfügen.
Dein Ansatz mit der PictureBox
, wie du schon erkannt hast, kann so nicht funktionieren, da das RTF-Control so nichts über dieses Control weiß und somit den Text auch nicht herumfließen lassen kann.
Ich meinte, daß du ersteinmal unter Windows testest, ob der Code funktioniert. Und wenn das klappt, dann baust du den Code nach und nach um, so daß es dann bei deiner anderen Umgebung kompiliert und funktioniert.
Benutzt du das neueste VS? Seit der letzten C#-Version 11 gibt es Raw string literal, d.h. du kannst den gesamten Aufruf direkt in deinen Code einbauen (ohne explizit Zeichen 'escapen' zu müssen).
Auf welcher Hardware dein eigentlicher Code läuft spielt ja für den Aufruf ersteinmal keine Rolle.
Du mußt schauen, daß du ersteinmal einen funktionierenden Aufruf mit CURL hinbekommst (egal, ob von Windows, Linux oder einem anderen System).
Hallo Abt,
jetzt wollte ich es doch mal genauer wissen und habe im Source-Code nachgeschaut. Das eigentliche Parsen des Formats findet in der Methode DateTimeParse.ParseByFormat
statt, für "z"
in Zeile 4122 ff.
Dort wird erst mittels GetRepeatCount()
die maximale Anzahl des gleichen Formatspezifizierers (hier also z
) ermittelt und dann die Methode ParseTimeZoneOffset aufgerufen.
Und dort ist das Entscheidende der switch
über die Anzahl: bei Werten ungleich von 1
und 2
wird dann der default
Code ausgeführt und dort ist dann der entscheidende Hinweis als Kommentar
// ':' is optional.
if (str.Match(":"))
// ...
Zusammengefaßt also:
"z"
und "zz"
werden getrennt geparst"zzz"
sowie alle weiteren Wiederholungen von z
werden gleich behandelt. Was in der Doku fehlt, ist der Hinweis auf das optionale :
Zeichen bei dem Zeitzonenoffset!Ich habe jetzt auch mal den Code selber kompiliert und ausgeführt (nur mit "zzz"
und -1230
als Zeitzonenoffset):
string date = "Sun Dec 13 03:52:21 -1230 2009";
string format = "ddd MMM dd hh:mm:ss zzz yyyy";
CultureInfo provider = new CultureInfo("en-US");
CultureInfo provider2 = new CultureInfo("de-DE");
if(DateTime.TryParseExact(date, format, provider, DateTimeStyles.None, out DateTime dt))
{
Console.WriteLine(dt.ToString("o"));
Console.WriteLine(dt.ToString("G", provider2));
}
Richtige Ausgabe:
2009-12-13T16:22:21.0000000+00:00
13.12.2009 16:22:21
(also die Zeit um 12 Stunden und 30 Minuten verschoben)
Das selbe Ergebnis gibt es auch bei -12:30
als Zeitzonenoffset.
qed.
Dein letzter Code sieht schon ganz gut aus, jedoch sehe ich keine Millisekunden (daher solltest du fff
löschen).
Und +0000
ist wohl der Zeitzonenoffset, jedoch erwartet zzz
diesen im Format +00:00
(s.a. Formatspezifizierer „z“ für das Offset) - das müßtest du also mal näher evaluieren.
Desweiteren solltest du daher auch DateTimeOffset
verwenden.
@Abt: Als Nachfrage zu deinem Code: Woher hast du den vierstelligen zzzz
als Format? Dies ist, soweit ich gelesen habe, nirgendwo dokumentiert.
Was hast du denn genau versucht?
Auf Anhieb sehe ich, daß die Query falsch ist (es ist ja JSON-Format):
string query = "{ \"query\" : /*...*/ }"; // Doppelpunkt außerhalb der Hochkommata
Am besten, du testest es direkt in der Eingabeaufforderung mit curl
(setze einen Haltepunkt und kopiere dann den Inhalt der Variablen url
).
PS: Hat dir meine Antwort in deinem anderen Thema bzgl. WebRequest
weitergeholfen?
Bei DisplayMemberPath
muss eine Eigenschaft verwendet werden, kein reines Feld, also
public string SSID { get; set; } = "NONE";
(am besten auch die anderen Felder zu Eigenschaften umwandeln)
Du solltest bisher auch im VS-Ausgabefenster eine Binding-Warnung sehen (ansonsten in den Optionen höher einstellen).
Sorry, aber dein C++-Code ist fehlerhaft:
Zum einen kopierst du in SetStr
das Nullendezeichen ('\0'
) nicht mit und zum anderen erzeugt GetStrCA
undefiniertes Verhalten (UB), da myData
nur einen Leerstring als String-Literal darstellt und kein beschreibbares String-Array.
Wie schon geschrieben, benutze zum Kopieren eines C-Strings strcpy
(bzw. strncpy
mit Angabe der max. Länge).
Und hast du bei STRLENGTH
auch dieses Nullendezeichen beachtet, d.h. dieser Wert sollte mindestens 5
sein?
Warum benötigst du denn noch das Array strArrMC
(und wenn, dann sollte es nicht im Shared Memory Bereich liegen!)?
Hier mein (aus dem Texteditor) geschriebener Code dazu:
bool __stdcall SetStr(int gvId, const char* gvStr)
{
if (gvId >= 0)
{
strArrMC[gvId] = gvStr;
//FÜR CA
std::strcpy(strArrCA[gvId], gvStr);
// bzw.
// std::strncpy(strArrCA[gvId], gvStr, MAXELNGTH); gvStr[MAXLENGTH-1] = `\0';
return true;
}
return false;
}
const char* __stdcall GetStrCA(int gvId)
{
if (gvId >= 0)
{
return strArrCA[gvId];
}
else
return "Null";
}
(gvStr
ist dasselbe wie &gvStr[0]
, jedoch kürzer und üblicher so zu schreiben)
PS: Irgendwie erzeugt der Browser aus >``=
immer ein Zeichen ≥
- das mußt du dann wieder ändern.
Mir ist gerade aufgefallen, daß man mittels Zeiger keine Daten in verschiedenen Prozessen nutzen kann, s.a. How do I share data in my DLL with an application or with other DLLs?:
Each process gets its own address space. It is very important that pointers are never stored in a variable contained in a shared data segment. A pointer might be perfectly valid in one application but not in another.
Du müsstest also so etwas wie
char strArr[MAXSYSTEM][MAXLENGTH]
verwenden (also ein fixes 2D-Array). Und dann von C++ aus mittels str(n)cpy
o.ä. die Texte reinkopieren.
Hast du denn auch IAdresseRepository
mit der Klasse AdresseRepository
registriert?
Das ist ja schon mal ein kleiner Fortschritt. Und jetzt gibt es wohl auch keinen Speicherzugriffsfehler mehr?
Das was mich jedoch wundert, ist, daß du für 1
einen Leerstring (""
) und nicht null
zurückerhältst - denn
const char* strArr[MAXSYSTEM] = { "" };
initialisiert ja nur den ersten Wert (Index 0) mit dem Leerstring, alle weiteren Werten werden auf NULL
(bzw. nullptr
) gesetzt.
Hat die C++ Anwendung auch nur einen Leerstring geschrieben? Und mit welcher Speicheranforderungsfunktion wird denn der String (const char*
) erzeugt?
Was passiert denn, wenn du testweise mal das Array so initialisierst:
const char* strArr[MAXSYSTEM] = { "0", "1", "2" };
?
Ansonsten könntest du auch mal probieren, 2 C++ Anwendungen dazu zu erstellen (eine schreibt, die andere liest).
Ruf nun mal deine Methode IntPtrToStr
mit den Werten -1
, 0
und 1
auf?
Welchen Wert hat dann jeweils ptr
sowie results
?
WebRequest ist eine abstrakte Klasse, nur die davon abgeleitete Klasse HttpWebRequest verfügt über die Eigenschaft CookieContainer: sieh dir das Beispiel dort an, du mußt also entsprechend casten.
Dann schau dir mal Ausführen von Left Outer Joins an.
Oder wenn du das Original SQL-Statement hast, dann kannst du mal Linqer (SQL to LINQ converter) ausprobieren.
Ich glaube, du verstehst nicht, wie DLLs in Anwendungen (Prozesse) eingebunden sind. Wenn mehrere Anwendungen auf dieselben Daten zugreifen wollen, dann benötigt man dafür Inter-Process-Communication (IPC) oder aber eine externe Datenhaltung (wie z.B. eine Datenbank). Oder ist das Array explizit als "shared data section" deklariert (s.a. Dynamic-link library: Memory management)?
Probiere mal
[DllImport("C:\\Windows\\SysWOW64\\Alert.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GetStr(int system); // Rückgabetyp ändern
Und lass dir mal den zurückgegebenen Wert ausgeben (bzw. debuggen).
Wenn aber auch der Zugriff auf das String-Literal "0"
nicht funktioniert, dann liegt evtl. noch ein anderes Problem vor.
Da du ja auf "SysWOW64" zugreifst, ist denn dein C#-Projekt explizit als "x86" (bzw. 32bit) eingestellt?
Edit: Bzgl. DLLs + Shared Memory habe ich noch folgenden Artikel Windows Libraries I: Weitere Informationen zu DLL's ... (Code s. "Shared Memory") gefunden.
Vergleiche noch mal genau deinen und meinen Code...
Edit:
Ist bei GetStr(i)
auch ein Wert vorhanden oder ist dieser null
?
Und kommt der Fehler auch bei GetStr(-1)
oder nur, wenn auf das String-Array zugegriffen wird?
das Schreiben des Strings übernimmt ausschließlich die andere Anwendung
Was genau meinst du damit? Hast du eine andere Anwendung, welche auch diese DLL nutzt? Dann hat aber jede Anwendung ihre eigenen Daten.
Hallo,
benutzt du das DGV nur als X*Y Raster? Oder haben die einzelnen Zeilen eine anwendungsbezogene Bedeutung?
Ansonsten schau dir mal die Komponente FlowLayoutPanel (bzw. TableLayoutPanel) an.
Du könntest auch noch zusätzlich
[return: MarshalAs(UnmanagedType.LPStr)]
angeben.
Schön, daß es dir geholfen hat - habe aber auch nur die Internet-Suche benutzt. 😉
Wieso jetzt denn "mp4" (also eine Video-Datei)? Du kannst nicht erwarten, daß jedes Format die Tags unterstützt, s.a. ExifTool Tag Names
Mit dem "WindowsAPICodePack" habe ich auch nicht viel Erfahrung.
Hast du denn nach dem Speichern die Datei wieder neu eingeladen bevor du file.Properties.System.Title
aufgerufen hast?
.heic
-Dateien sind (noch) kein Standard im .NET-Umfeld.
Es gibt eine proprietäre Lösung: Manage XMP and EXIF Data of HEIF/HEIC Images using C#
Oder aber du benutzt das Kommandozeilentool ExifTool (es gibt wohl auch .NET Wrapper dafür, s. unter Additional Documentation and Resources/Related Utilities/Programming).
PS: Bei der ExifLibrary gibt es bisher nur ein offenes Issue: Reading and writing HEIF image format metadata
Hast du schon ExifLibrary ausprobiert? Das Beispiel sieht doch sehr einfach zu verwenden aus (s.a. Properties).
Hallo,
Contains
ist wohl die falsche Methode, um Namen und Passwort abzufragen...
Du solltest auf exakte Gleichheit abfragen (beim Namen kannst du evtl. Groß-/Kleinschreibung ignorieren).
Gibt es denn jeweils unterschiedliche Layouts je Frage oder sollen mehrere Fragen gleichzeitig angezeigt werden? Ansonsten reicht ja ein statisches Layout und du tauschst jeweils nur die Fragen und Antworten aus (am besten per DataBinding).
Einfach den ganzen Code in eine eigene neue Datei deines Projektes kopieren (evtl. noch Namensbereich und/oder Klassenname anpassen).
OK, ich wusste nicht, daß dort eine andere ListBox
als die Standard-DropDown-ListBox verwendet wird.
Nach intensiver Suche habe ich dann noch C# – Combo box drop down width on suggest gefunden (du müßtest also dann den Code bei dir übernehmen, kompilieren und dann ComboBoxEx
als Komponente [aus der Toolbox] verwenden und kannst dann die beiden Eigenschaften AutoCompleteDropDownWidth
und AutoCompleteDropDownHeight
entsprechend setzen).
Sorry, das geht ja viel einfacher, da es dafür direkte Eigenschaften gibt:
Nur als Hinweis noch zu meiner ersten Antwort:
Die ComboBox
ist ein WinAPI-Control und daher muß man dann tiefer in die Trickkiste greifen, um an die untergeordneten Controls zu kommen.
Als Anfänger wirst du das wahrscheinlich nicht direkt verstehen können, aber ich habe mal ein paar Links herausgesucht (wenn auch alle in englisch sind):
Hallo und willkommen,
schau dir mal die Eigenschaft Controls
(im Debugger) an, dort müßten die TextBox
als auch die ListBox
enthalten sein.
Ich kann dir aber so nicht sagen, ob es reicht die Größe einmalig anzupassen oder aber ob du jedesmal beim Anzeigen der ListBox
diese wieder neu setzen mußt (s. DropDown-Ereignis).
Das mit abhängigen Komponenten ist ein generelles Problem der Software-Architektur (bei längerfristigen Projekten weiß man ja nie, wie lange externe Komponenten noch verwendet werden können oder ob man sie dann nicht doch eines Tages durch etwas anderes ersetzen möchte).
Sauber läßt sich das nur lösen, wenn man diese Abhängigkeit so lokal wie möglich hält (also nur ein paar [kleine] Klassen hat, welche diese externe Komponente verwendet).
Idealerweise erstellt man sich eine eigene Schnittstelle (interface
) und erzeugt dann dazu eine Implementationsklasse, welche alle Funktionalitäten auf die externe Komponente weiterleitet (auch Wrapper-Klasse genannt). Und im eigenen Code wird dann nur diese Schnittstelle verwendet, so daß dieser Code dann unabhängig von der externen Komponente [per Mocking] getestet werden kann.
Die beiden Methoden PowerManagementNativeMethods.PowerGetActiveSchem und CoreNativeMethods.LocalFree sind einfach nur P/Invoke-Deklarationen, welche du einfach in deinen Code übernehmen kannst (und einen eigenen Klassennamen dafür nimmst).
internal static class MyNativeMethods
{
[DllImport("powrprof.dll")]
internal static extern int PowerGetActiveScheme( // <- hier schon den Rückgabetyp auf int (bzw. uint) geändert
IntPtr rootPowerKey,
[MarshalAs(UnmanagedType.LPStruct)]
out Guid activePolicy);
[DllImport("Kernel32.dll", EntryPoint = "LocalFree")]
internal static extern IntPtr LocalFree(ref Guid guid);
}
(die Sichtbarkeit public
oder internal
kannst du selber festlegen)
Und dann nur die Eigenschaft in eine eigene Klasse übernehmen (und den möglichen Fehler abfangen):
public static PowerPersonality PowerPersonality
{
get
{
Guid guid;
var error = MyNativeMethods.PowerGetActiveScheme(IntPtr.Zero, out guid);
try
{
return PowerPersonalityGuids.GuidToEnum(guid);
}
finally
{
if (error == 0)
MyNativeMethods.LocalFree(ref guid);
}
}
Leider mußt du auch noch die (kleine) Klasse PowerPersonalityGuids in deinen Code übernehmen, da diese ebenfalls internal
ist - auch hier dann, damit keine Konflikte entstehen, einen eigenen Klassennamen (bzw. Namespace) dafür benutzen.
Und dann kannst du ja testen, ob es keinen Speicherfehler mehr gibt und welchen Wert error
hat.
Ja, das Auslagern in eine eigene Klasse ist quasi Pflicht, denn es ist ja die Logik (s.a. [Artikel] Drei-Schichten-Architektur) deines Programms, also unabhängig von der UI.
Ich habe einen String und einen State den ich an C# übermittle
Du meinst "an den SerialPort übermittle"!?
Wenn dies jeweils unterschiedliche Strings und State-Werte sind, dann sind dies die Zustände der State Machine und je nach zuletzt geschickten Werten (requests) würdest du dann die Antworten empfangen und entsprechend auswerten. Wenn du mit Werten (gemessene Grade) Zahlen im Textformat meinst, dann reicht wahrscheinlich eine der TryParse
-Methoden (z.B. für Double
).
Nur falls die Daten im Binärformat verschickt werden, bräuchtest du BinaryReader.
Je nach Umfang deines Protokolls kannst du auch eine externe Komponente für die State Machine benutzen, z.B. Stateless - ist aber wahrscheinlich erst mal zu viel für dein Projekt.
Generell fällt das unter dem Begriff "Protokoll".
Wenn du unterschiedliche Daten empfängst, dann benötigst du eine entsprechende Auswertung dieser Daten (üblicherweise wird dazu ein Parser eingesetzt).
Wenn auch noch unterschiedliche Anfragen (requests) gesendet werden, dann benutzt man häufig eine/n Endlicher Automat/Zustandsmaschine (state machine).
Fürs Zeit messen kannst du die Klasse Stopwatch benutzen.
Abt und ich haben eine andere Vorstellung bzgl. Testbarkeit von statischen Methoden, s.a. Dependency Injected DbContext in Statischer Klasse für Hilfsmethoden nutzen legitim? ff.