VirtualKeyboard erstellt und verwendet bei Login und NeuerAuftrag.

This commit is contained in:
Kilian Wirl 2026-04-29 17:13:24 +02:00
parent 2f65984f0f
commit 25233a57e6
29 changed files with 1255 additions and 83 deletions

View File

@ -28,12 +28,114 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.textBoxText = new System.Windows.Forms.TextBox();
this.labelFrage = new System.Windows.Forms.Label();
this.labelEingabe = new System.Windows.Forms.Label();
this.buttonAbbrechen = new System.Windows.Forms.Button();
this.buttonOK = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBoxText
//
this.textBoxText.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxText.Font = new System.Drawing.Font("Microsoft Sans Serif", 16.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.textBoxText.Location = new System.Drawing.Point(29, 105);
this.textBoxText.Margin = new System.Windows.Forms.Padding(20);
this.textBoxText.Name = "textBoxText";
this.textBoxText.Size = new System.Drawing.Size(409, 38);
this.textBoxText.TabIndex = 1;
this.textBoxText.Click += new System.EventHandler(this.TextBoxText_Click);
this.textBoxText.Enter += new System.EventHandler(this.TextBoxText_Enter);
this.textBoxText.Validating += new System.ComponentModel.CancelEventHandler(this.TextBoxText_Validating);
//
// labelFrage
//
this.labelFrage.AutoSize = true;
this.labelFrage.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelFrage.Location = new System.Drawing.Point(29, 19);
this.labelFrage.Margin = new System.Windows.Forms.Padding(20, 10, 20, 20);
this.labelFrage.Name = "labelFrage";
this.labelFrage.Size = new System.Drawing.Size(134, 20);
this.labelFrage.TabIndex = 4;
this.labelFrage.Text = "Deine Frage hier";
//
// labelEingabe
//
this.labelEingabe.AutoSize = true;
this.labelEingabe.Font = new System.Drawing.Font("Microsoft Sans Serif", 10.2F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelEingabe.Location = new System.Drawing.Point(29, 79);
this.labelEingabe.Margin = new System.Windows.Forms.Padding(20, 20, 20, 0);
this.labelEingabe.Name = "labelEingabe";
this.labelEingabe.Size = new System.Drawing.Size(65, 20);
this.labelEingabe.TabIndex = 5;
this.labelEingabe.Text = "Anzahl:";
//
// buttonAbbrechen
//
this.buttonAbbrechen.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonAbbrechen.BackColor = System.Drawing.Color.Red;
this.buttonAbbrechen.CausesValidation = false;
this.buttonAbbrechen.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonAbbrechen.FlatAppearance.BorderColor = System.Drawing.Color.Red;
this.buttonAbbrechen.FlatAppearance.BorderSize = 0;
this.buttonAbbrechen.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.buttonAbbrechen.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonAbbrechen.ForeColor = System.Drawing.Color.White;
this.buttonAbbrechen.Location = new System.Drawing.Point(238, 167);
this.buttonAbbrechen.Margin = new System.Windows.Forms.Padding(4, 4, 20, 4);
this.buttonAbbrechen.Name = "buttonAbbrechen";
this.buttonAbbrechen.Size = new System.Drawing.Size(200, 50);
this.buttonAbbrechen.TabIndex = 3;
this.buttonAbbrechen.Text = "Abbrechen";
this.buttonAbbrechen.UseVisualStyleBackColor = false;
this.buttonAbbrechen.Click += new System.EventHandler(this.ButtonAbbrechen_Click);
//
// buttonOK
//
this.buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.buttonOK.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
this.buttonOK.FlatAppearance.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(192)))), ((int)(((byte)(0)))));
this.buttonOK.FlatAppearance.BorderSize = 0;
this.buttonOK.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.buttonOK.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.buttonOK.ForeColor = System.Drawing.Color.White;
this.buttonOK.Location = new System.Drawing.Point(30, 167);
this.buttonOK.Margin = new System.Windows.Forms.Padding(20, 4, 4, 4);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Padding = new System.Windows.Forms.Padding(3, 2, 3, 2);
this.buttonOK.Size = new System.Drawing.Size(200, 50);
this.buttonOK.TabIndex = 2;
this.buttonOK.Text = "OK";
this.buttonOK.UseVisualStyleBackColor = false;
this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);
//
// CustomMessageBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(467, 230);
this.Controls.Add(this.buttonAbbrechen);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.labelEingabe);
this.Controls.Add(this.labelFrage);
this.Controls.Add(this.textBoxText);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Name = "CustomMessageBox";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "CustomMessageBox";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TextBox textBoxText;
private System.Windows.Forms.Label labelFrage;
private System.Windows.Forms.Label labelEingabe;
private System.Windows.Forms.Button buttonAbbrechen;
private System.Windows.Forms.Button buttonOK;
}
}

View File

@ -7,14 +7,98 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using VirtualKeyboard;
namespace Deckungsbeitrag.AA_Forms
{
public partial class CustomMessageBox : Form
{
private QwertzKeyboard keyboard;
private readonly bool isNumeric;
private readonly string frage;
private readonly string title;
private readonly string eingabe;
public string text;
public CustomMessageBox()
{
InitializeComponent();
}
public CustomMessageBox(string Frage, string Title, string Eingabe, string numeric) : this()
{
if (numeric == "isNumeric") this.isNumeric = true;
this.labelFrage.Text = Frage;
this.labelEingabe.Text = Eingabe + ":";
this.Text = Title;
if (isNumeric) this.textBoxText.Text = "1";
else this.textBoxText.Text = string.Empty;
}
private void TextBoxText_Click(object sender, EventArgs e)
{
this.textBoxText.Clear();
if (TouchHelper.IsTouchDeviceReady())
{
if (keyboard == null || keyboard.IsDisposed)
{
keyboard = new QwertzKeyboard(textBoxText, "isNumeric");
keyboard.Show();
}
else
{
keyboard.Close();
keyboard = new QwertzKeyboard(textBoxText, "isNumeric");
keyboard.Show();
}
}
}
private void TextBoxText_Enter(object sender, EventArgs e)
{
this.textBoxText.SelectAll();
//if (TouchHelper.IsTouchDeviceReady())
//{
// if (keyboard == null || keyboard.IsDisposed)
// {
// keyboard = new QwertzKeyboard(textBoxText, "isNumeric");
// keyboard.Show();
// }
// else
// {
// keyboard.Close();
// keyboard = new QwertzKeyboard(textBoxText, "isNumeric");
// keyboard.Show();
// }
//}
}
private void ButtonAbbrechen_Click(object sender, EventArgs e)
{
if (keyboard != null) keyboard.Close();
this.DialogResult = DialogResult.Cancel;
this.Close();
}
private void ButtonOK_Click(object sender, EventArgs e)
{
if (keyboard != null) keyboard.Close();
this.DialogResult = DialogResult.OK;
this.Close();
}
private void TextBoxText_Validating(object sender, CancelEventArgs e)
{
if (buttonAbbrechen.Focused)
return;
if (isNumeric)
{
if (int.TryParse(textBoxText.Text, out int value)) this.text = textBoxText.Text;
else
{
MessageBox.Show("Bitte nur ganze Zahlen eingeben.", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
e.Cancel = true;
this.textBoxText.SelectAll();
}
}
}
}
}

View File

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -1103,7 +1103,7 @@ namespace Deckungsbeitrag
if (liste == null || liste == ListenArt.Auftragliste) listAuftragToday = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Vorbereitet, minStatusFilter: AuftragStatus.Gewaschen);
if (liste == null || liste == ListenArt.Geschäftliste) listAuftragGeschaeft = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Fertig, minStatusFilter: AuftragStatus.Abgeholt, typFilter: AuftragTyp.Geschäft);
if (liste == null || liste == ListenArt.Vorbereitetliste) listVorbereitet = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Vorbereitet, minTypFilter: AuftragTyp.Geschäft);
if (liste == null || liste == ListenArt.Sonderliste) listSonderAuftrag = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Fertig, minStatusFilter: AuftragStatus.Herrichten, typFilter: AuftragTyp.Laufzettel, minTypFilter: AuftragTyp.Inventur);
if (liste == null || liste == ListenArt.Sonderliste) listSonderAuftrag = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Fertig, minStatusFilter: AuftragStatus.Herrichten, minTypFilter: AuftragTyp.Inventur);
if (liste == null || liste == ListenArt.Rampenliste) listRampe = await View_Auftrag_Expedit.GetAuftragExpeditAsync(statusFilter: AuftragStatus.Abgeholt, typFilter: AuftragTyp.Standart);
}
else

View File

@ -537,7 +537,7 @@ namespace Deckungsbeitrag
};
}
if ((userid != null && userid.Contains("reklamation")) || (this.benutzer != null && this.benutzer.Rolle == BenutzerRolle.Expedit)) { kndart.Reklamation++; artnw.Reklamation++; }
if ((userid != null && userid.Contains("reklamation")) || (this.benutzer != null && this.benutzer.Rolle == BenutzerRolle.Expedit) || (this.benutzer != null && this.benutzer.Rolle == BenutzerRolle.Frottee)) { kndart.Reklamation++; artnw.Reklamation++; }
else { kndart.Fehlmenge++; artnw.Nachwaesche++; }
// Wenn speichern nicht möglich, wird darauf hingewiesen.

View File

@ -1,4 +1,5 @@
using DatenDB;
using Deckungsbeitrag.AA_Forms;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
@ -13,13 +14,14 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using VirtualKeyboard;
namespace Deckungsbeitrag
{
public partial class FormLogin : Form
{
string progFiles = @"C:\Program Files\Common Files\Microsoft Shared\ink";
string keyboardPath;
QwertzKeyboard keyboard;
private OnboardingSchritt onBoardingArt;
public Benutzer Person { get; set; }
@ -83,6 +85,7 @@ namespace Deckungsbeitrag
}
}
private void buttonAbbrechen_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
@ -109,12 +112,12 @@ namespace Deckungsbeitrag
this.textBoxPwdWh.Visible = false;
this.buttonRegistrieren.Visible = false;
this.textBoxPasswort.Text = this.textBoxPwdWh.Text = string.Empty;
if (MessageBox.Show($"Benutzer {this.textBoxBenutzer.Text} wurde erfolgreich angelegt.\n\nMöchtest du einen eigenen Benutzername angeben?\n\n[JA] -> Neuen Benutzername anlegen\n[NEIN] -> Alten Benutzername behalten", "Hinweis", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
{
string eingabe = Interaction.InputBox("Welchen Benutzername möchtest du verwenden?\n\nBenutzername:", "Neuer Benutzername", "");
if (!string.IsNullOrWhiteSpace(eingabe)) person.BenutzerName = eingabe;
if (person.Save() != 1) MessageBox.Show("Benutzername konnte nicht gespeichert werden. Melde dich bei deinem Vorgesetzten.", "SPEICHERFEHLER", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
//if (MessageBox.Show($"Benutzer {this.textBoxBenutzer.Text} wurde erfolgreich angelegt.\n\nMöchtest du einen eigenen Benutzername angeben?\n\n[JA] -> Neuen Benutzername anlegen\n[NEIN] -> Alten Benutzername behalten", "Hinweis", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.Yes)
//{
// string eingabe = Interaction.InputBox("Welchen Benutzername möchtest du verwenden?\n\nBenutzername:", "Neuer Benutzername", "");
// if (!string.IsNullOrWhiteSpace(eingabe)) person.BenutzerName = eingabe;
// if (person.Save() != 1) MessageBox.Show("Benutzername konnte nicht gespeichert werden. Melde dich bei deinem Vorgesetzten.", "SPEICHERFEHLER", MessageBoxButtons.OK, MessageBoxIcon.Information);
//}
this.textBoxBenutzer.Focus();
this.buttonAnmelden.Enabled = true;
}
@ -129,8 +132,6 @@ namespace Deckungsbeitrag
this.textBoxBenutzer.Text = this.textBoxBenutzer.Text.Substring(0, this.textBoxBenutzer.Text.IndexOf(";"));
}
}
private void FormLogin_Load(object sender, EventArgs e)
{
this.groupBox1.Height = 110;
@ -138,8 +139,6 @@ namespace Deckungsbeitrag
this.textBoxPwdWh.Visible = false;
this.buttonRegistrieren.Visible = false;
this.textBoxBenutzer.Focus();
WindowState = FormWindowState.Normal;
StartPosition = FormStartPosition.CenterScreen;
}
@ -153,22 +152,42 @@ namespace Deckungsbeitrag
{
this.textBoxBenutzer.SelectAll();
//// Pfad zur Touch-Tastatur
//keyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
if (TouchHelper.IsTouchDeviceReady())
{
if (keyboard == null || keyboard.IsDisposed)
{
keyboard = new QwertzKeyboard(textBoxBenutzer, "isAlpha");
if (keyboard.ShowDialog() == DialogResult.OK) this.ActiveControl.Focus();
}
else
{
keyboard.Close();
keyboard = new QwertzKeyboard(textBoxBenutzer, "isAlpha");
if (keyboard.ShowDialog() == DialogResult.OK) this.ActiveControl.Focus();
}
}
//// Bildschirmtastatur starten
//Process.Start(keyboardPath);
}
private void textBoxPasswort_Enter(object sender, EventArgs e)
{
//// Pfad zur Touch-Tastatur
//keyboardPath = System.IO.Path.Combine(progFiles, "TabTip.exe");
if (TouchHelper.IsTouchDeviceReady())
{
if (keyboard == null || keyboard.IsDisposed)
{
keyboard = new QwertzKeyboard(textBoxPasswort, "isNumeric");
keyboard.Show();
}
else
{
keyboard.Close();
keyboard = new QwertzKeyboard(textBoxPasswort, "isNumeric");
keyboard.Show();
}
}
//// Bildschirmtastatur starten
//Process.Start(keyboardPath);
}
private void textBox_Leave(object sender, EventArgs e)
private void textBox_Leave(object sender, EventArgs e)
{
this.buttonAnmelden.Focus();
}

View File

@ -61,7 +61,6 @@ namespace Deckungsbeitrag
{
InitializeComponent();
this.panelMain.AllowDrop = true;
this.toolStripMenu.Size = new Size(toolStripButton1.Size.Width + 20, this.Height);
_fixedSize = screen.WorkingArea.Size;
}
@ -84,7 +83,7 @@ namespace Deckungsbeitrag
{
this.SuspendLayout();
this.Cursor = Cursors.WaitCursor;
this.ActiveControl = this.panelMain;
formloading = true;
_settings.Load();
@ -312,20 +311,8 @@ namespace Deckungsbeitrag
}
private void TSBScannTest_Click(object sender, EventArgs e)
{
if (open)
{
this.groupBoxScannTest.Visible = false;
this.textBoxScannTest.Visible = this.labelScannTest.Visible = this.buttonScannTest.Visible = this.pictureBoxScannTest.Visible = false;
open = false;
}
else
{
this.groupBoxScannTest.Visible = true;
this.textBoxScannTest.Visible = this.labelScannTest.Visible = this.buttonScannTest.Visible = this.pictureBoxScannTest.Visible = true;
this.pictureBoxScannTest.Image = Image.FromFile("C:\\Users\\KilianWirl\\OneDrive - gehgassi GmbH\\Wäscherei Wirl\\Programme\\Deckungsbeitrag\\static-qr-code-ca1aa53ab47cd115bc1ad29afb0e5f22.png");
this.textBoxScannTest.Focus();
open = true;
}
CustomMessageBox messageBox = new CustomMessageBox("Nenne mir eine Zahl und tippe sie unten ein", "TEST", "Anzahl", "isNumeric");
messageBox.Show();
}
private void TSBArtikelVW_Click(object sender, EventArgs e)
{
@ -1057,22 +1044,22 @@ namespace Deckungsbeitrag
#endregion
private void GetNeueInventur()
{
onBoardingArt = OnboardingSchritt.NeueInventur;
ZeigeOnboarding();
Kunde kunde = null;
FormListe liste = new FormListe(null, (int)Listentyp.Reklamationliste, "Miete");
if (liste.ShowDialog() == DialogResult.OK)
if (this.kunde == null)
{
kunde = liste.kunde;
uCInventur = new UCInventur(kunde, this.benutzer);
uCInventur.UCInventur_Update += () => { this.GetInventuren(); };
uCInventur.UCInventur_Delete += Do_UCInventur_Delete;
this.panelMain.Controls.Add(uCInventur);
uCInventur.Location = new Point(100, 100);
uCInventur.BringToFront();
RegisterDragEvents(uCInventur);
FormListe liste = new FormListe(null, (int)Listentyp.Reklamationliste, "Miete");
if (liste.ShowDialog() == DialogResult.OK)
{
this.kunde = liste.kunde;
}
}
uCInventur = new UCInventur(this.kunde, this.benutzer);
uCInventur.UCInventur_Update += () => { this.GetInventuren(); };
uCInventur.UCInventur_Delete += Do_UCInventur_Delete;
this.panelMain.Controls.Add(uCInventur);
uCInventur.Location = new Point(100, 100);
uCInventur.BringToFront();
RegisterDragEvents(uCInventur);
}
private async void GetInventuren()
{
@ -1236,7 +1223,7 @@ namespace Deckungsbeitrag
btn.Enabled = btn.Name.Contains("Hilfe");
break;
case BenutzerRolle.Master:
btn.Enabled = true;
btn.Enabled = btn.Visible = true;
break;
case BenutzerRolle.Expedit:
btn.Enabled = btn.Name.Contains("Hilfe");

View File

@ -112,7 +112,11 @@ namespace Deckungsbeitrag
if (!GetKunde(kndService)) { CloseForm(DialogResult.Cancel); return; }
// Containeranzahl laden
if (int.TryParse(Interaction.InputBox($"Wieviel Container hast du beim Kunde {kundeName} abgeholt?", "CONTAINERANZAHL", "1"), out int i)) this.textBoxCont.Text = i.ToString();
CustomMessageBox messageBox = new CustomMessageBox($"Wieviel Container hast du beim Kunde {kundeName} abgeholt?", "CONTAINERANZAHL", "Containeranzahl", "isNumeric");
if (messageBox.ShowDialog() == DialogResult.OK)
{
this.textBoxCont.Text = messageBox.text.ToString();
}
else { CloseForm(DialogResult.Cancel); return; }
// NextLiefertag laden
@ -351,7 +355,7 @@ namespace Deckungsbeitrag
{
ComboBox cb = sender as ComboBox;
if (cb.SelectedIndex == -1) return;
if (cb.SelectedItem is Tour selected && selected.TourID == tour.TourID) return;
if (tour != null && (cb.SelectedItem is Tour selected && selected.TourID == tour.TourID)) return;
if (this.benutzer.Rolle == BenutzerRolle.Verwaltung || this.benutzer.Rolle == BenutzerRolle.Admin || this.benutzer.Rolle == BenutzerRolle.Expedit) return;
if (meldung.GetFrage(this, "Möchtest du den Auftrag wirklich einer anderen Tour zuteilen?", false) == DialogResult.No) { ((ComboBox)sender).SelectedIndex = -1; e.Cancel = true; }
else

View File

@ -49,7 +49,6 @@
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormShowUserControl_FormClosing);
this.Load += new System.EventHandler(this.FormShowUserControl_Load);
this.Shown += new System.EventHandler(this.FormShowUserControl_Shown);
this.ChangeUICues += new System.Windows.Forms.UICuesEventHandler(this.FormShowUserControl_ChangeUICues);
this.ResumeLayout(false);
}

View File

@ -21,6 +21,7 @@ namespace Deckungsbeitrag.AA_Forms
private string gb;
private bool toclose = false;
public (DateTime datum, string text, string[] touren) lieferDaten;
private Screen screen = Screen.PrimaryScreen;
public bool _toclose
{
@ -101,6 +102,7 @@ namespace Deckungsbeitrag.AA_Forms
{
this.ClientSize = new Size(uc.Width, uc.Height);
this.CenterToScreen();
this.Location = new Point((screen.WorkingArea.Width - this.Width) / 2, (screen.WorkingArea.Height - this.Height) / 2);
}
private void FormShowUserControl_FormClosing(object sender, FormClosingEventArgs e)
@ -114,9 +116,5 @@ namespace Deckungsbeitrag.AA_Forms
}
private void FormShowUserControl_ChangeUICues(object sender, UICuesEventArgs e)
{
if (e.ShowKeyboard == false) this.CenterToScreen();
}
}
}

View File

@ -1094,7 +1094,7 @@ namespace Deckungsbeitrag
Graphics g = Graphics.FromImage(bitmap);
Font font1 = new Font("Arial", 15, FontStyle.Bold);
Font font2 = new Font("Arial", 30, FontStyle.Bold);
Font font3 = new Font("Arial", 30, FontStyle.Regular);
Font font3 = new Font("Arial", 20, FontStyle.Regular);
Font font4 = new Font("Arial", 150, FontStyle.Bold);
float height_font1 = g.MeasureString($"{kunde.Suchtext}", font1).Height;
float height_font2 = g.MeasureString($"{kunde.PLZ} {kunde.Ort})", font2).Height;
@ -1113,8 +1113,10 @@ namespace Deckungsbeitrag
nextposition += (int)height_font2;
g.DrawString($"{auftrag.Liefertag.Date.ToString("dd.MM.yyyy")}", font2, Brushes.Black, einzug, nextposition);
nextposition += (int)height_font2;
g.DrawString("Artikel Rekl/NW/Stand/Inv", font1, Brushes.Black, einzug, nextposition + 20);
g.DrawString("Artikel", font2, Brushes.Black, einzug, nextposition + 20);
nextposition += 20 + (int)height_font1;
g.DrawString("Rekl/NW/Stand/Inv", font3, Brushes.Black, bitmap.Width - g.MeasureString("Rekl/NW/Stand/Inv", font3).Width, nextposition + 10);
nextposition += (int)height_font2;
foreach (var kvp in dictionary)
{
@ -1123,10 +1125,10 @@ namespace Deckungsbeitrag
string artikelKey = _artikel.Bezeichnung; // z.B. "ART1"
int[] artbestand = kvp.Value; // z.B. [3, 0, 5]
string shortName = _artikel.Short;
float bestandWidth = g.MeasureString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font1).Width;
g.DrawString($"{shortName}", font1, Brushes.Black, einzug, nextposition);
if (artbestand[2] < 0) g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font1, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition);
else g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/{artbestand[2].ToString()}/{artbestand[3].ToString()}", font1, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition);
float bestandWidth = g.MeasureString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font3).Width;
g.DrawString($"{shortName}", font3, Brushes.Black, einzug, nextposition);
if (artbestand[2] < 0) g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/({artbestand[2].ToString()})/{artbestand[3].ToString()}", font3, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition);
else g.DrawString($"{artbestand[0].ToString()}/{artbestand[1].ToString()}/{artbestand[2].ToString()}/{artbestand[3].ToString()}", font3, Brushes.Black, bitmap.Width - bestandWidth - 10, nextposition);
nextposition += (int)height_font1;
}

View File

@ -6,7 +6,7 @@
</sectionGroup>
</configSections>
<appSettings>
<add key="ConnectionString" value="user id=postgres;password=Ki985941Wi;host=10.10.10.1;port=5432;database=Wirl_DB_17012023;Timeout=15" />
<add key="ConnectionString" value="user id=postgres;password=Ki985941Wi;host=10.10.10.1;port=5432;database=Test_Wirl;Timeout=15" />
<add key="SortimentPfad" value="N:\\TECHNIK\\Software\\Wirl-Verwaltung\\Listen\\Kundensortiment.txt" />
<add key="InventurPfad" value="N:\BÜRO\KUNDEN\INVENTUREN\Verwaltung" />
<add key="BildPfad" value="C:\\Users\\KilianWirl\\OneDrive - gehgassi GmbH\\Wäscherei Wirl\\Programme\\Deckungsbeitrag\\Deckungsbeitrag\\Star.png" />

View File

@ -36,7 +36,79 @@ namespace Deckungsbeitrag
Fourth = 4,
Fifth = 5
}
// Globale Touch-Info (static für alle Forms)
public static class TouchHelper
{
[DllImport("user32.dll")]
private static extern int GetSystemMetrics(int nIndex);
private const int SM_DIGITIZER = 94;
private const int SM_MAXIMUMTOUCHES = 95;
private const int SM_CONVERTIBLESLATEMODE = 125;
public static readonly bool HasTouchHardware = (GetSystemMetrics(SM_DIGITIZER) & 0x80) != 0;
public static readonly int TouchPoints = GetSystemMetrics(SM_MAXIMUMTOUCHES);
public static readonly bool IsTabletMode = GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 1;
/// <summary>
/// **Hauptmethode**: Touch FUNKTIONIERT (Hardware + aktiviert)
/// </summary>
public static bool IsTouchActive()
{
// 1. Registry: TouchGate = 0 → deaktiviert
if (IsRegistryDisabled()) return false;
// 2. TouchPoints > 0 UND System sagt "Touch ready"
if (TouchPoints <= 0) return false;
// 3. Windows Touch-Session aktiv? (SM_DIGITIZER bits)
int digitizer = GetSystemMetrics(SM_DIGITIZER);
bool touchReady = (digitizer & 0x00000001) != 0; // Integrated touch?
bool penReady = (digitizer & 0x00000002) != 0;
return touchReady || penReady;
}
/// <summary>
/// Vollständig einsatzbereit
/// </summary>
public static bool IsTouchDeviceReady() => HasTouchHardware && IsTouchActive();
/// <summary>
/// Registry-Status
/// </summary>
private static bool IsRegistryDisabled()
{
RegistryKey key = null;
try
{
key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Wisp\TouchGate");
if (key != null)
{
object value = key.GetValue("TouchGate");
if (value != null && Convert.ToInt32(value) == 0)
return true;
}
return false;
}
catch
{
return false;
}
finally
{
if (key != null) key.Close();
}
}
/// <summary>
/// Debug-Status
/// </summary>
public static string GetStatus()
{
int digitizer = GetSystemMetrics(SM_DIGITIZER);
return $"Hardware: {HasTouchHardware}, Active: {IsTouchActive()}, Points: {TouchPoints}, RegistryDisabled: {IsRegistryDisabled()}, Digitizer: 0x{digitizer:X}";
}
}
static class Program
{
public static Color Wirlblau = Settings.Default.Wirlblau;
@ -70,8 +142,8 @@ namespace Deckungsbeitrag
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Screen[] screens = Screen.AllScreens;
Cursor.Current = Cursors.WaitCursor;
// Check, Install und Update wenn Update vorhanden.
if (CheckAndInstallUpdate())
{
@ -190,6 +262,11 @@ namespace Deckungsbeitrag
}
#region private-Funktionen
private static void TouchAppConfig()
{
// Globale Touch-Optimierungen
// z.B. größere Buttons, Auto-Tastatur, etc.
}
private static void Open_ReadMe()
{
string readmePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Verwaltung_ReadMe.txt");

View File

@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
//
// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
// indem Sie "*" wie unten gezeigt eingeben:
[assembly: AssemblyVersion("1.0.9.9")]
[assembly: AssemblyFileVersion("1.0.9.9")]
[assembly: AssemblyVersion("1.1.0.7")]
[assembly: AssemblyFileVersion("1.1.0.7")]

View File

@ -255,6 +255,12 @@
}
"Entry"
{
"MsmKey" = "8:_848FCB2438E4DBC274C4D124CEB9562C"
"OwnerKey" = "8:_AD2C2F4AADC342899908C708EB4F4A72"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_8A953E0634B8757038749C9F77062056"
"OwnerKey" = "8:_C2D67A4770D262B66069252CF1E903CF"
"MsmSig" = "8:_UNDEFINED"
@ -460,6 +466,12 @@
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_848FCB2438E4DBC274C4D124CEB9562C"
"MsmSig" = "8:_UNDEFINED"
}
"Entry"
{
"MsmKey" = "8:_UNDEFINED"
"OwnerKey" = "8:_16723AF5DFDEF26FC6A07BEB7D389737"
"MsmSig" = "8:_UNDEFINED"
}
@ -1219,6 +1231,37 @@
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_848FCB2438E4DBC274C4D124CEB9562C"
{
"AssemblyRegister" = "3:1"
"AssemblyIsInGAC" = "11:FALSE"
"AssemblyAsmDisplayName" = "8:VirtualKeyboard, Version=1.0.1.0, Culture=neutral, processorArchitecture=MSIL"
"ScatterAssemblies"
{
"_848FCB2438E4DBC274C4D124CEB9562C"
{
"Name" = "8:VirtualKeyboard.exe"
"Attributes" = "3:512"
}
}
"SourcePath" = "8:VirtualKeyboard.exe"
"TargetName" = "8:"
"Tag" = "8:"
"Folder" = "8:_C848DFB5E4D140A7A7F5E1F129613626"
"Condition" = "8:"
"Transitive" = "11:FALSE"
"Vital" = "11:TRUE"
"ReadOnly" = "11:FALSE"
"Hidden" = "11:FALSE"
"System" = "11:FALSE"
"Permanent" = "11:FALSE"
"SharedLegacy" = "11:FALSE"
"PackageAs" = "3:1"
"Register" = "3:1"
"Exclude" = "11:FALSE"
"IsDependency" = "11:TRUE"
"IsolateTo" = "8:"
}
"{9F6F8455-1EF1-4B85-886A-4223BCC8E7F7}:_8A953E0634B8757038749C9F77062056"
{
"AssemblyRegister" = "3:1"
@ -1647,15 +1690,15 @@
{
"Name" = "8:Microsoft Visual Studio"
"ProductName" = "8:SetupVerwaltung"
"ProductCode" = "8:{EAA37164-29A8-4196-8D42-9F687DA3442F}"
"PackageCode" = "8:{5F45C29D-025D-47D5-A4F4-8DDE65C8B7D2}"
"ProductCode" = "8:{6D13C83E-FAD0-4B29-BBEC-E1ABCEAAFB03}"
"PackageCode" = "8:{32CA7B7D-CFC8-41EA-A986-11D890FE499A}"
"UpgradeCode" = "8:{2DC7CE56-8D1C-42EB-B326-2E887EBB7F5A}"
"AspNetVersion" = "8:"
"RestartWWWService" = "11:FALSE"
"RemovePreviousVersions" = "11:TRUE"
"DetectNewerInstalledVersion" = "11:TRUE"
"InstallAllUsers" = "11:FALSE"
"ProductVersion" = "8:1.0.99"
"ProductVersion" = "8:1.1.07"
"Manufacturer" = "8:Kilian Wirl GmbH"
"ARPHELPTELEPHONE" = "8:"
"ARPHELPLINK" = "8:"

View File

@ -261,7 +261,6 @@ namespace Deckungsbeitrag.UserControls
/// <param name="sender"></param>
private void GetInventurCSV(object sender, int? auftragID)
{
Button btn = (Button)sender;
Kunde _knd = this.kunde;
Benutzer _user = this.user;
List<KundeArtikel> _artikelliste = this.artikelListe;
@ -271,7 +270,7 @@ namespace Deckungsbeitrag.UserControls
// Inventur Status Warten wenn noch Zahlen fehlen und Herrichten wenn alle vorhanden.
if (btn.Text.ToString() == "Speichern") status = "Warten";
if (sender.ToString() == "Speichern") status = "Warten";
else
{
status = "Herrichten";

View File

@ -434,6 +434,9 @@
<DependentUpon>UCTourenplan.cs</DependentUpon>
</Compile>
<Compile Include="UserSettingsManager.cs" />
<EmbeddedResource Include="AA-Forms\CustomMessageBox.resx">
<DependentUpon>CustomMessageBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="AA-Forms\FehlmengeChart.resx">
<DependentUpon>FehlmengeChart.cs</DependentUpon>
</EmbeddedResource>
@ -617,6 +620,12 @@
<ItemGroup>
<Folder Include="Old-Forms\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="VirtualKeyboard\VirtualKeyboard.csproj">
<Project>{d5d68e54-f738-45e5-82fd-da987f2e0589}</Project>
<Name>VirtualKeyboard</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\build\Microsoft.Extensions.Logging.Abstractions.targets" Condition="Exists('packages\Microsoft.Extensions.Logging.Abstractions.6.0.0\build\Microsoft.Extensions.Logging.Abstractions.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@ -1,12 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.3.32922.545
# Visual Studio Version 18
VisualStudioVersion = 18.4.11626.88 stable
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Verwaltung", "Verwaltung.csproj", "{1CDFBC6A-240A-4D59-9F9E-35041D9ACCC6}"
EndProject
Project("{54435603-DBB4-11D2-8724-00A0C9A8B90C}") = "SetupVerwaltung", "SetupVerwaltung\SetupVerwaltung.vdproj", "{B95F7799-8515-9D54-0B5E-9F12DF88B85D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualKeyboard", "VirtualKeyboard\VirtualKeyboard.csproj", "{D5D68E54-F738-45E5-82FD-DA987F2E0589}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -19,6 +21,10 @@ Global
{1CDFBC6A-240A-4D59-9F9E-35041D9ACCC6}.Release|Any CPU.Build.0 = Release|Any CPU
{B95F7799-8515-9D54-0B5E-9F12DF88B85D}.Debug|Any CPU.ActiveCfg = Debug
{B95F7799-8515-9D54-0B5E-9F12DF88B85D}.Release|Any CPU.ActiveCfg = Release
{D5D68E54-F738-45E5-82FD-DA987F2E0589}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D5D68E54-F738-45E5-82FD-DA987F2E0589}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D5D68E54-F738-45E5-82FD-DA987F2E0589}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D5D68E54-F738-45E5-82FD-DA987F2E0589}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,5 +1,5 @@
=====================================
NEUIGKEITEN - Version 1.0.9.9
NEUIGKEITEN - Version 1.1.0.7
=====================================
Build-Info:
@ -7,9 +7,9 @@ Build-Info:
- Erledigte TODOs: 6
- Offene TODOs: 24
- Install-Reminders: 1
- Changes: 28
- Changes: 29
=== ✨ CHANGES (28) ===
=== ✨ CHANGES (29) ===
## ArtikelVW.cs ##
- ✨ Reklamation als Spalte hinzugefügt und Anzeigen implementiert. Sowohl bei KundeArtikel als auch bei NW_Artikel.
@ -43,6 +43,10 @@ Build-Info:
- ✨ DropDownWidth wird an das größte Item angepasst.
- ✨ Es kann ab jetzt Morgen als Liefertag gewählt werden.
## Settings.Designer.cs ##
- ✨ to this file may cause incorrect behavior and will be lost if
## Tourenplanung.cs ##
- ✨ Es kann nach der Kontrolle der Lieferrhythmus geändert werden. Dazu muss auch die Anzahl der Liefertage gewählt werden.
@ -66,5 +70,5 @@ Build-Info:
=== ⚙️ INSTALL-REMINDER (1) ===
- ⚙️ DB anpassen. (Priority in Auftrag etc.) [Auftrag.cs]
Installation: 28.04.2026 09:16
Installation: 29.04.2026 17:06
=====================================

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8" />
</startup>
</configuration>

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace VirtualKeyboard
{
internal static class Program
{
/// <summary>
/// Der Haupteinstiegspunkt für die Anwendung.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new QwertzKeyboard());
}
}
}

View File

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Allgemeine Informationen über eine Assembly werden über die folgenden
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
// die einer Assembly zugeordnet sind.
[assembly: AssemblyTitle("VirtualKeyboard")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("VirtualKeyboard")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
[assembly: ComVisible(false)]
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
[assembly: Guid("d5d68e54-f738-45e5-82fd-da987f2e0589")]
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
//
// Hauptversion
// Nebenversion
// Buildnummer
// Revision
//
[assembly: AssemblyVersion("1.0.1.2")]
[assembly: AssemblyFileVersion("1.0.1.2")]

View File

@ -0,0 +1,71 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion: 4.0.30319.42000
//
// Änderungen an dieser Datei können fehlerhaftes Verhalten verursachen und gehen verloren, wenn
// der Code neu generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace VirtualKeyboard.Properties
{
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder-Klasse
// über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der Option /str erneut aus, oder erstellen Sie Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VirtualKeyboard.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenlookups, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}

View File

@ -0,0 +1,117 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@ -0,0 +1,30 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace VirtualKeyboard.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}

View File

@ -0,0 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>

View File

@ -0,0 +1,40 @@
namespace VirtualKeyboard
{
partial class QwertzKeyboard
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Windows Form-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
}
#endregion
}
}

View File

@ -0,0 +1,310 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
namespace VirtualKeyboard
{
public partial class QwertzKeyboard : Form
{
private TextBox targetTextBox;
private Button okBtn;
private bool isNumeric = false;
private bool isCalc = false;
private bool isShift = false;
private Screen screen = Screen.PrimaryScreen;
// Erweiterte keys auf mehr Buttons (z.B. 14 pro Reihe)
private Button[][] keys = new Button[5][] {
new Button[14], new Button[14], new Button[14], new Button[14], new Button[8]};
// **Echtes QWERTZ-Layout** (5 Reihen + Funktion/Steuerung)
private string[] qwertzRows = {
" 1234567890ß⌫↵", // Ziffernreihe
"↔qwertzuiopü+", // Hauptbuchstaben 1 (versetzt)
" asdfghjklöä#", // Hauptbuchstaben 2 (versetzt)
"⇧<yxcvbnm,.-⇧", // Hauptbuchstaben 3 (Y statt Z, versetzt)
" _ " // Untere Reihe: Shift (breit), Enter (hoch), Space (sehr breit)
};
// NumPad-Positionen: Standard-Rechner-Layout
// Zeile 1: 7 8 9 /
// Zeile 2: 4 5 6 *
// Zeile 3: 1 2 3 -
// Zeile 4: 0 00 , +
// Rechts: OK
//string[] numpadLayout = {
// "⌫/*-",
// "789+",
// "456",
// "123↵",
// "0," // 0 breit, Komma, Plus
// };
// Numeric-Reihen
private string[] numpadLayout;
public QwertzKeyboard(TextBox target, string numeric)
{
if (numeric == "isNumeric")
{
isNumeric = true;
numpadLayout = new string[] { "789", "456", "123", "⌫0↵" };
}
if (numeric == "isCalc")
{
isCalc = true;
numpadLayout = new string[] {"⌫/*-","789+","456","123↵","0,"};
}
if (numeric == "isAlpha") isNumeric = isCalc = false;
targetTextBox = target;
InitializeKeyboard();
this.FormBorderStyle = FormBorderStyle.None;
this.BackColor = Color.FromArgb(1,53,101);
this.StartPosition = FormStartPosition.Manual;
this.TopMost = true;
this.ShowInTaskbar = false;
this.targetTextBox.Focus();
}
private void InitializeKeyboard()
{
//int[] rowWidths = { 800, 800, 800, 800, 800 }; // Versetzte Reihenbreiten
int btnHeight = 60, spacing = 4;
int startY = 10;
for (int row = 0; row < qwertzRows.Length; row++)
{
string rowText = qwertzRows[row];
int rowLength = rowText.Length;
keys[row] = new Button[rowLength];
int x = 10;
for (int col = 0; col < rowLength; col++)
{
int btnWidth = 0; // Breiten anpassen
char ch = rowText[col];
string sch = ch.ToString();
int btnH = (ch == '↵' ? (btnHeight + spacing) * 5 - 4 : btnHeight); // Hoher Enter
Button btn = new Button
{
Text = sch,
Size = new Size(btnWidth, btnH),
Location = new Point(x, startY),
Font = new Font(ch == ' ' ? "Arial" : "Arial", 18, FontStyle.Bold),
Tag = ch,
BackColor = Color.FromArgb(240, 240, 240),
FlatStyle = FlatStyle.Flat,
FlatAppearance = { BorderSize = 1, MouseOverBackColor = Color.LightGray },
};
btn.Click += Key_Click;
switch (btn.Text)
{
case var t when t == " ":
btn.Width = 58;
btn.Enabled = false;
break;
case var t when t == "_":
btn.Width = (btnHeight + spacing) * 12 - 4;
btn.Text = "Leertaste";
break;
case var t when t == "⇧":
btn.Width = (int)((double)btnHeight * 1.5);
btn.Text = "Shift";
break;
case var t when t == "↔":
btn.Width = (int)((double)btnHeight * 1.5);
btn.Text = "Tab";
break;
case var t when t == "⌫":
btn.Width = btnHeight * 2;
break;
case var t when t == "↵":
btn.Width = 90;
btn.Text = "OK";
btn.BackColor = Color.FromArgb(0, 192, 0);
btn.ForeColor = Color.White;
btn.FlatAppearance.BorderSize = 1;
btn.FlatAppearance.BorderColor = Color.Green;
break;
default:
btn.Width = btnHeight;
break;
}
this.Controls.Add(btn);
keys[row][col] = btn;
x += btn.Width + spacing;
}
startY += keys[row][0].Height + spacing;
}
// OK wird in Reihen integriert
this.Size = new Size((int)(screen.WorkingArea.Width * 0.80), (btnHeight + spacing) * 5 + 10);
this.MaximumSize = new Size(1000, (btnHeight + spacing) * 5 + 10);
UpdateLayout();
}
private void OK_Click(object sender, EventArgs e)
{
this.Close();
}
private void Tab_Click(object sender, EventArgs e)
{
DialogResult result = DialogResult.None;
if (targetTextBox.Parent?.SelectNextControl(targetTextBox, true, true, true, true) == true) result = DialogResult.OK;
else result = DialogResult.Cancel;
this.Close();
}
private void Key_Click(object sender, EventArgs e)
{
Button btn = sender as Button;
char ch = (char)btn.Tag;
switch (btn.Text)
{
case var t when t == "Shift": Shift_Click(btn, null);
break;
case var t when t == "Tab": Tab_Click(btn, null);
break;
case var t when t == "OK": OK_Click(btn, null);
break;
case var t when t == "⌫":
if (targetTextBox.Text.Length > 0)
targetTextBox.Text = targetTextBox.Text.Substring(0, targetTextBox.Text.Length - 1);
break;
default: targetTextBox.Text += btn.Text;
break;
}
if (isShift && char.IsLetter(ch)) ch = char.ToUpper(ch);
targetTextBox.Focus();
targetTextBox.SelectionStart = targetTextBox.Text.Length;
}
private void ToggleMode_Click()
{
isNumeric = !isNumeric;
UpdateLayout();
}
private void Shift_Click(object sender, EventArgs e)
{
Button shiftBtn = (Button)sender;
isShift = !isShift;
shiftBtn.BackColor = isShift ? Color.Yellow : Color.FromArgb(240, 240, 240);
UpdateLayout();
}
private void UpdateLayout()
{
if (!isNumeric)
{
// Zeige ALLE QWERTZ-Buttons
for (int row = 0; row < qwertzRows.Length; row++)
{
string rowText = qwertzRows[row];
for (int col = 0; col < keys[row].Length && col < rowText.Length; col++)
{
char ch = rowText[col];
if (keys[row][col].Text.Length > 1) continue;
keys[row][col].Text = isShift && char.IsLetter(ch) ? char.ToUpper(ch).ToString() : ch.ToString();
keys[row][col].Tag = ch;
keys[row][col].Visible = true; // QWERTZ sichtbar
}
}
}
else
{
// **VERSTECKE ALLE QWERTZ-Buttons** und zeige nur NumPad
HideAllQwertzButtons();
SetupRealNumPad();
}
this.Refresh();
}
private void HideAllQwertzButtons()
{
// Blende ALLE Keys aus (QWERTZ komplett weg)
foreach (var row in keys)
{
foreach (var btn in row.Where(b => b != null))
{
btn.Visible = false;
}
}
}
private void SetupRealNumPad()
{
int y = 10, xBase = 10, btnWidth = 70, btnHeight = 55, spacing = 8;
if (isCalc) this.Size = new Size((btnWidth + spacing) * 4 + xBase, (btnHeight + spacing) * 5 + xBase);
if (isNumeric) this.Size = new Size((btnWidth + spacing) * 3 + xBase, (btnHeight + spacing) * 4 + xBase);
// NumPad-Grids füllen (erste 4 Reihen)
for (int row = 0; row < numpadLayout.Length; row++)
{
string rowText = numpadLayout[row];
btnHeight = 55;
xBase = 10;
for (int col = 0; col < rowText.Length; col++)
{
char ch = rowText[col];
if (ch == ' ') { xBase += btnWidth + spacing; continue; } // Leerspace für breiten 0
if (ch == '↵')
{
Button okBtn = keys[row][col];
// OK-Button rechts unten (NumPad-Enter-Stil)
okBtn.Text = "OK";
okBtn.Size = (isCalc) ? new Size(btnWidth, btnHeight * 2 + spacing) : new Size(btnWidth, btnHeight);
okBtn.Location = new Point(xBase, y);
okBtn.BackColor = Color.FromArgb(0, 192, 0);
okBtn.ForeColor = Color.White;
okBtn.Font = new Font("Arial", 14, FontStyle.Bold);
okBtn.FlatStyle = FlatStyle.Flat;
okBtn.FlatAppearance.BorderSize = 1;
okBtn.FlatAppearance.BorderColor = Color.Green;
okBtn.Visible = true;
okBtn.Click += OK_Click;
continue;
}
if (ch == '+') { btnHeight = btnHeight * 2 + spacing; }
Button btn = keys[row][col];
btn.Text = ch.ToString();
btn.Tag = ch;
btn.Size = (row == 4 && col == 0) ? new Size(btnWidth * 2 + spacing, btnHeight) : new Size(btnWidth, btnHeight); // Breiter 0
btn.Location = new Point(xBase, y);
btn.Font = new Font("Arial", 18, FontStyle.Bold);
btn.BackColor = Color.FromArgb(240, 240, 240); // NumPad-Look
btn.FlatStyle = FlatStyle.Flat;
btn.FlatAppearance.BorderSize = 1;
btn.Visible = true;
btn.Enabled = true;
xBase += btn.Width + spacing;
}
y += (btnHeight > 55) ? (btnHeight / 2) + (spacing / 2) : btnHeight + spacing;
}
// Verstecke ungenutzte Keys (Reihen 4+)
for (int row = 5; row < keys.Length; row++)
for (int col = 0; col < keys[row].Length; col++)
keys[row][col].Visible = false;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
this.Location = new Point((screen.WorkingArea.Width - this.Width) / 2, screen.WorkingArea.Height - this.Height);
}
}
}

View File

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{D5D68E54-F738-45E5-82FD-DA987F2E0589}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>VirtualKeyboard</RootNamespace>
<AssemblyName>VirtualKeyboard</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="QwertzKeyboard.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="QwertzKeyboard.Designer.cs">
<DependentUpon>QwertzKeyboard.cs</DependentUpon>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>