Laden...

Forenbeiträge von Kileak Ingesamt 62 Beiträge

11.08.2009 - 15:46 Uhr

Die Werte werden direkt zugewiesen, und auch in deinem Beispiel haben die Variablen 'id' und 'title' in der DoSomething-Methode die richtigen Werte (die im Konstruktor als Parameter übergeben wurden).

Sicher das Du die Zuweisung in deinem eigentlichen Code genauso handhabst, und im Konstruktor nicht vielleicht einfach das this. vergessen hast, und dadurch die lokalen 'id' und 'title' benutzt hast?

04.08.2009 - 16:58 Uhr

Zum Anzeigen der Shortcuts in einem Textfeld könntest du das PreviewKeyDown-Event nutzen und im KeyPress-Event die Verarbeitung durch die Textbox deaktivieren.

Eine schnell hingekritzelte (nicht gerade schönes und sicher überarbeitungswürdige) Lösung zum Anzeigen der Shortcuts in einer Textbox könnte dann z.B. so aussehen

private void shortcutBox_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
    string shortcut = "";

    if (e.Control)
    {
        shortcut += "Strg";
    }

    if (e.Alt)
    {
        if (!shortcut.Equals(string.Empty))
            shortcut += " + ";

        shortcut += "Alt";
    }

    if (e.Shift)
    {
        if (!shortcut.Equals(string.Empty))
            shortcut += " + ";

        shortcut += "Shift";
    }

    if (!shortcut.Equals(string.Empty))
        shortcut += " + ";

    char pressedKey = (char)e.KeyValue;

    if (Char.IsLetterOrDigit(pressedKey))
    {
        shortcut += pressedKey;
    }
    
    textBox1.Text = shortcut;
}

private void shortcutBox_KeyPress(object sender, KeyPressEventArgs e)
{
    e.Handled = true;
}
04.08.2009 - 15:10 Uhr

Beim Erzeugen des Arrays deiner Struktur hast Du es doch eigentlich schon bemerkt

const int maxInputs = 16;
fisInputs[] inputArray = new fisInputs[maxInputs];

Auch das Array möchte erstmal mit der Anzahl der möglichen Einträge initialisiert werden. Nicht anders verhält es sich mit den Arrays innerhalb deiner Struktur.

Beispiel: (nameCount entspr. der Anzahl der möglichen Namen)

inputArray[n].mfsNames = new string[nameCount];

Danach kannst du dann, die im Array "enthaltenen" Objekte erzeugen

inputArray[n].mfsNames[i] = "dummyString";

Das hat nebenbei auch nichts mit einem "String"-Array zu tun, für deine int und float-Arrays gilt da dasselbe.

01.07.2009 - 14:12 Uhr

Der Name der Klasse deutet doch eigentlich schon die Lösung an 😉

TimeSpan ist genau das was Du haben möchtest, nämlich die Zeitspanne, die der Mitarbeiter da war.


DateTime startDate = new DateTime(2009, 12, 11, 10, 0, 0);
DateTime endDate = new DateTime(2009, 12, 12, 8, 0, 0);

TimeSpan timeSpan = endDate - startDate;

MessageBox.Show(timeSpan.ToString());

Über die Properties Hours/Minutes/etc. kommst Du dann auch gleich noch an jede einzelne Komponente der Zeitspanne.

Über MSDN hätte man das aber auch relativ einfach rausfinden können sollen 😉

30.06.2009 - 17:02 Uhr

Inzwischen hab ich es doch noch mit Windows Messages zum Laufen gebracht.

Für den Fall das doch jemand mal auf dasselbe Problem stösst.

Setzen der aktuellen Thread-ID hat schon mal geholfen, dass der Hook nicht gleich das ganze System mitnimmt.

public int Hook()
{
     CallWndProcHookProcedure = new HookProc(CallWndProcHookProc);
            
     handle = SetWindowsHookEx((int)HookType.WH_CALLWNDPROC, CallWndProcHookProcedure, IntPtr.Zero, (int)AppDomain.GetCurrentThreadId());
                        
     return handle;
}

Im Hook an sich können dann die Nachrichten der C++-Anwendung abgefangen werden, und so z.B. mit WM_COPYDATA beliebige Daten übertragen werden.

private static int CallWndProcHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode < 0)
            {
                return CallNextHookEx(handle, nCode, wParam, lParam);
            }
                        
            CWPSTRUCT msg = (CWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(CWPSTRUCT));

            switch (msg.message)
            {
                case WM_COPYDATA:
                    {
                        // retrieve CopyDataStruct from window-message
                        COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(msg.lparam, typeof(COPYDATASTRUCT));

                        // retrieve data-struct from copydatastrucct
                        Data data = (Data)Marshal.PtrToStructure(cds.lpData, typeof(Data)); 
                    } break;                
            } 
            
            return CallNextHookEx(handle, nCode, wParam, lParam);
        }

Dazu ein passendes Struct, das die Daten enthält, die übertragen werden sollen (und das CopyDataEvent-Struct)

[StructLayout(LayoutKind.Sequential)]
    public struct Data
    {
        public int id;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
        public string user;

        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 500)]
        public string password;
    }

 [StructLayout(LayoutKind.Sequential)]
        public struct CWPSTRUCT
        {
            public IntPtr lparam;
            public IntPtr wparam;
            public int message;
            public IntPtr hwnd;
        }

In der C++-Anwendung das entsprechende Gegenstück, das befüllt wird, und dann mit dem WM_COPYDATA-Event auf den Weg gebracht wird.


struct tData {
	int id;
	char user[500];
	char passw[500];
};

COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = sizeof(tData);
cpd.lpData = &testData;

SendMessage(hWnd, WM_COPYDATA, (WPARAM)::GetDesktopWindow(), (LPARAM)&cpd);		

30.06.2009 - 14:28 Uhr

Hab hier ein kleines Problem, Daten von einer C-Anwendung in eine C#-Anwendung zu bekommen. Die C-Anwendung empfängt dabei bestimmte Daten und soll diese an die C#-Anwendung übertragen, die dann entsprechend ihre Oberfläche aktualisieren soll. An sich dürfte das ja über Window Messages kein grosses Hindernis darstellen (dachte ich mir 😉)

In einem kleinen ersten Test mit einer WinForms-Anwendung und Überschreiben der WndProc-Funktion und Abfangen der WM_COPYDATA-Message funktionierte das auch ganz gut.

Allerdings steh ich jetzt vor dem Problem, das ich in meiner eigentlichen SmartClient-Anwendung kein Form-Objekt habe, dessen WndProc-Funktion ich überschreiben könnte. Also nen SystemHook einrichten. Nach MSDN und zig anderen Seiten kam ich zu folgendem Entwurf

DLL-Imports

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
        
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

[DllImport("kernel32.dll")]
static extern IntPtr LoadLibrary(string lpFileName);

Den Hook eingerichtet...

public int Hook()
{
     CallWndProcHookProcedure = new HookProc(CallWndProcHookProc);

     handle = SetWindowsHookEx((int)HookType.WH_CALLWNDPROC, CallWndProcHookProcedure, (IntPtr)LoadLibrary("User32"), 0);

     return handle;
}

Und im WndProc-Hook die Nachrichten erst mal weiter durchgereicht (dachte ich zumindest)

private static int CallWndProcHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
     if (nCode < 0)
     {
         return CallNextHookEx(handle, nCode, wParam, lParam);
     }

     return CallNextHookEx(handle, nCode, wParam, lParam);            
}

Starte ich allerdings die Anwendung, hängt sie sich beim Einrichten des Hooks auf und der Explorer gleich mit dazu (einzige Möglichkeit einen Neustart zu umgehen war dann Taskmanager->Abmelden und neu anmelden).

Hab ich da einen grundlegenden Fehler drin, oder gibt es eine andere Möglichkeit die Daten zu übertragen?

08.06.2009 - 11:09 Uhr

Wenn ich aus DataViewGridCell() das hier mache: DataGridViewCell();
dann kommt folgende Fehlermeldung:

Fehler 1 Es konnte keine Instanz der abstrakten Klasse oder Schnittstelle "System.Windows.Forms.DataGridViewCell" erstellt werden. C:\Users\Muecke\Desktop\Navyfield\NFManager\Form1.cs 55 44 NFManager

Oh, etwas voreilig gepostet X(

Wie Nitro schon sagt, wäre die beste Möglichkeit es direkt über eine Datasource zu machen, aber wenn du die Zeilen unbedingt selbst erzeugen willst, ist dein erster Ansatz nicht so verkehrt...


DataGridViewRow dgvRow = new DataGridViewRow();
DataGridViewCell dgvCell = new DataGridViewTextBoxCell();

dgvCell.Value = dr[0].ToString();
dgvRow.Cells.Add(dgvCell);

datagridview.Rows.Add(dgvRow);

So sollte es funktionieren, wenn die entsprechenden Spalten im DataGrid vorhanden sind, ansonsten müsstest Du diese vorher noch entsprechend hinzufügen


dataGridView.Columns.Add(new DataGridViewColumn(new DataGridViewTextBoxCell()));

Dennoch würde ich auch eher über die Verwendung einer Datasource nachdenken, kompakter, übersichtlicher und was noch alles 😉

08.06.2009 - 10:46 Uhr

Einfach auf etwaige "Verschreiber" deines Vorposters achten, und es nicht per Copy&Paste übernehmen 😉

13.05.2009 - 15:58 Uhr

Regex r = new Regex(@"""[a-zA-Z0-9<>/=\\"" ]*""");

Bin zwar kein Regex-Experte aber <span...> hätte er dir mangels der entsprechenden Zeichen im Ausdruck eh nicht matchen können. Wie oben angepasst, funktionierts zumindest für den von dir angegebenen Fall.

13.05.2009 - 15:42 Uhr

ProcessStartInfo psi = new ProcessStartInfo("command.exe");
psi.WindowStyle = ProcessWindowStyle.Hidden;
            
Process.Start(psi);

sollte gehen...

28.03.2009 - 11:29 Uhr

Bin mir nicht sicher ob es nicht eine elegantere Methode gibt, aber was z.B. geht ist sich eine eigene Item-Klasse zu schreiben, in der Du die ToString()-Methode überschreibst, um festzulegen was in der Listbox angezeigt werden soll.

Die könnte zum Beispiel so aussehen


public class ListItem
{
    private string _stringValue;
    private int _intValue;

    public string StringValue
    {
        get { return _stringValue; }
        set { _stringValue = value; }
    }

    public int IntValue
    {
        get { return _intValue; }
        set { _intValue = value; }
    }

    public override string ToString()
    {
        return StringValue;
    }

    public ListItem(string strVal, int intVal)
    {
        StringValue = strVal;
        IntValue = intVal;
    }
}

In deiner Anwendung kannst Du dann die ListItems entsprechend füllen und der Listbox hinzufügen.


listBox.Items.Add(new ListItem("TestString", 1));
listBox.Items.Add(new ListItem("TestString", 2));

25.03.2009 - 13:50 Uhr

Wenn die Zelle ein CheckBox-Control ist, kannst Du den Checked-Status z.B. im AfterCellUpdate-Event über Value prüfen (der ist entsprechend der Auswahl true/false) oder wenn Du es direkt bei der Auswahl prüfen willst im CellChange-Event über das Text-Property der Zelle (steht entsprechend "True"/"False" drin).


private void ultraGrid1_CellChange(object sender, CellEventArgs e)
{
    if (e.Cell.Column.Key.Equals("Inactive"))
    {
        bool selected = e.Cell.Text.Equals("True");

        if (selected)
            MessageBox.Show("Selected");
        else
            MessageBox.Show("Deselected");
        }
    }
}