Laden...

Forenbeiträge von Andreas.May Ingesamt 915 Beiträge

17.12.2007 - 15:10 Uhr

Also warum bekommst du sie nicht:

Ganz einfach du machst zuerst Application.Run(new Form1()); und das ist falsch.

Zu einem weil den string nicht an die Form übergibst sonst würde dein ButtonStart Cklick Event keinen Sinn machen.

Und zum anderen läuft deine Application in einem GUi Thread stell dir ne while(true) Schleife for die solange läuft bis false zurückkommt, erst dann würde deine string Test den Wert aus args[0] erhallten 🙂

Propbiers mal so rum:


string Test = "";

static void Main(string[] args)
{
  Application.Run(new Form1(args[0]));
   
}

private void btn_Start_Click(object sender, System.EventArgs e, args)
{
System.Windows.Forms.MessageBox.Show(Test);
}

17.12.2007 - 13:50 Uhr

Okay, dann gebe ich dir nen Tipp, sei ein fauler Programmierer 🙂

Erstelle am besten ein UserControl mit einen Eingabefeld. Nebendran legst du ein Bildchen mit einen Telefonsymbol. Danach schreibst du eine Form <PhoneDialog>, diese soll die statische Methode static string ShowDialog(string _sPhoneNumber, Point _Location) beinhalten. In der statischen Methode ShowDialog machst du nun den Aufruf der <PhoneDialog>. In der <PhoneDialog> setzt du einen private Member namens private string m_sPhoneString. Bei der statischen Methode übergibst du dann an den private Member der nun sichtbar ist den _sPhoneNumber string.

Soo nun gehst in den Designer und entfernst den Rand der Form, danach setzt du deine Buttons rein, dessen Events verknüpfst du auf eine Methode in der du dann m_sPhoneString füllst. Im Anschluss gehst wieder in die ShowDialog Methode und gibst als returnwert von <PhoneDialog>.m_sPhoneString zurück.

Als letztes gehst in dein UserControl und machst ein OnMouseDown Event auf das Telefonsymbol, in der dazugehörigen Methode rufst du dann die <PhoneDialog>.ShowDialog(<EditText>.Text, e.MouseEvent.Location) auf. Als returnwert bekommst dann einen string den du dann über deine TAPI-Anbindung jagen kannst.

Tada, du hast nen UserControl das an mehreren Stellen in deinem Programm verwenden kannst und zudem schick aussieht und jedesmal nen Modales Fenster hochploppt wenn jemand mit der Maus auf das Telefonsymbol Klickt. Das hat dann auch nen gewissen Vista look & feel 🙂

17.12.2007 - 11:45 Uhr

Hrm,

ich würde das wie folgt angehen - Aber zeurst ein paar Voraussetzungen damit das klappt. Die "fremde Anwendung" läuft in deinem Prozess ja oder nein?

Wenn ja, dann folgendes:

Mach ne DLL die als Hook.dll später eingefügt wird in deine Solution, diese Hook.dll muss als referenz eingebunden werden. Dannach ists recht simple, schreib ne Methode Hook und Unhook ich habs aufs nötigste mal reduziert.

   
 public  class Hook
    {
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID);

        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        private HookProc myCallbackDelegate = null;

        [DllImport("kernel32")]
        public extern static int LoadLibrary(string librayName);

        public enum HookType : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }

        public Hook()
        {

            // initialize our delegate
            this.myCallbackDelegate = new HookProc(this.MyCallbackFunction);

            int hInst = LoadLibrary(Application.StartupPath + @"Hook.dll");

            // setup global wnd proc hook
            SetWindowsHookEx(HookType.WH_CALLWNDPROC, this.myCallbackDelegate, hInst, AppDomain.GetCurrentThreadId());

        }

        private int MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code < 0)return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);

            if (code > 0)
            {
                Console.WriteLine("WindowsNachricht: {0} wurde gesendet mit wparam:{1} und lparam:{2}", code, wParam, lParam);
            }

            //return the value returned by CallNextHookEx
            return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
        }


    }


Wenn nein, dann folgendes:

A.) Das einfachste wäre ne EnumWindows wo du nach dem Dialogfeld suchst, das sieht so aus:


    internal class CWin32
    {

[Flags]
        public enum WindowStyles : uint
        {
            WS_OVERLAPPED = 0x00000000,
            WS_POPUP = 0x80000000,
            WS_CHILD = 0x40000000,
            WS_MINIMIZE = 0x20000000,
            WS_VISIBLE = 0x10000000,
            WS_DISABLED = 0x08000000,
            WS_CLIPSIBLINGS = 0x04000000,
            WS_CLIPCHILDREN = 0x02000000,
            WS_MAXIMIZE = 0x01000000,
            WS_BORDER = 0x00800000,
            WS_DLGFRAME = 0x00400000,
            WS_VSCROLL = 0x00200000,
            WS_HSCROLL = 0x00100000,
            WS_SYSMENU = 0x00080000,
            WS_THICKFRAME = 0x00040000,
            WS_GROUP = 0x00020000,
            WS_TABSTOP = 0x00010000,
            WS_MINIMIZEBOX = 0x00020000,
            WS_MAXIMIZEBOX = 0x00010000,
            WS_CAPTION = WS_BORDER | WS_DLGFRAME,
            WS_TILED = WS_OVERLAPPED,
            WS_ICONIC = WS_MINIMIZE,
            WS_SIZEBOX = WS_THICKFRAME,
            WS_TILEDWINDOW = WS_OVERLAPPEDWINDOW,
            WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,
            WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,
            WS_CHILDWINDOW = WS_CHILD,
            DS_MODALFRAME = 0x80,
            WS_DIALOG = WS_DLGFRAME |DS_MODALFRAME | WS_POPUP
        }
    public delegate bool EnumWindowsProc(IntPtr hwnd, int lParam);

    /// <summary>
        /// 
        /// </summary>
        /// <param name="callback"></param>
        /// <param name="lPar"></param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        public static extern int EnumWindows(EnumWindowsProc callback, int lPar);
       [DllImport("user32.dll", SetLastError = true)]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        [DllImport("kernel32.dll")]
        public static extern uint GetCurrentProcessId();

    [DllImport("user32.dll", SetLastError = true)]
        public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
}

private bool EnumWindows(IntPtr hWnd, int lParam)
        {
            uint nProcessId = 0;

            // search only thread owner dialogs
            if (CWin32.GetWindowThreadProcessId(hWnd, out nProcessId) > 0
                && CWin32.GetCurrentProcessId() == nProcessId)
            {
                int nStyle = CWin32.GetWindowLong(hWnd, (int)CWin32.WindowLong.GWL_STYLE);
                CWin32.WindowStyles eWindowStyles = (CWin32.WindowStyles)nStyle;

                eWindowStyles = eWindowStyles & CWin32.WindowStyles.WS_DIALOG;
                if (eWindowStyles == CWin32.WindowStyles.WS_DIALOG)
                    return false;
            }
            return true;
        }


B.) Du schreibst die erste Lösung als C++ hook, denk dran deine Headerdatei nutzt unmanged Code, um den Code nun in managed zu übersetzten nutze _GC vor deinen public class <classname> in deiner Quellcodedatei (.Cpp).
Denk dran Übergabeparameter von C++ unmanged zu managed sollten nur int werte sein die du als Property übergibst da du nur xxBIT zur Verfügung hast .Denk dran das ein C++ Hook anderen Spielregeln unterliegt indem du nur die DEBUG Dll verwendest da ohne die Debuginfos Fehler im C# Code entstehen. Und fertig ist dein Prozessübergreifender hook in C# …. oder doch nicht? – Nein ist er nicht, denk dran, wir schreiben in nicht verwalteten Speicher eines Fremden Programms herum, du musst ca. alle 5-20 Sekunden deinen Hook erneut instanzieren und neu Aufrufen, mach das über einen Thread und einen Timer, denk dran den Thread unbedingt separat zu instanzieren! Das liegt daran das der reservierte Speicherbereich vom Fremdprogramm entweder überschrieben oder vom Garbage Collector gefressen wird. Aber dann sollte es gehen.

Ein C++ Hook in C# klappt ohne Sicherheitseinstellungen nur auf WinXP, WIN 2000, Win98, Win95. Win Vista weis ich nicht, Win2003 Server -> geht definitiv nicht.

17.12.2007 - 11:03 Uhr

Hrm, dort wo deine Verbindung aufbaust, schau mal ob das geht:


using(OleDbConnection myCon = new OleDbConnection(<Verbindungsstring>)
{

  // irgendwas tun

  myCon.Close();
}

17.12.2007 - 10:55 Uhr

Wusste ich doch, dass ich nur was simples übersehen habe... Vielen Dank!

Mir passiert so etwas auch ständig, irgendwas vergisst man immer 🙂

17.12.2007 - 10:38 Uhr

hm... 🤔
Spontan würde ich jetzt sagen, dass das von der Schriftgröße abhängt, aber wie man den jetzt genau ermittelt, weiß ich nicht. (Ich muss zugeben, dass ich mir vorher darüber noch nie gedanken gemacht habe)

Das geht ca. wie folgt 🙂


  using (Graphics gfx = new Graphics())
            {
                SizeF FontSize = gfx.MeasureString("TEXT", <Font>);
               
            }

17.12.2007 - 10:33 Uhr

Du hast vergessen die Controls auf das Parent zu kleistern, dann gehts 😉
Also wenn eine Form dein Parent ist so also, Form.Controls.Add(comboBox).
Kannst es direkt in die Schleife reinbringen.

17.12.2007 - 10:29 Uhr

Hrm, zuerst das videowindow.Stop(); danach Marshal.ReleaseComObject benutzen, danach GC.Collect und im Anschluss GC.WaitForPandingFinalizer.

Ansonsten kannst es über Events versuchen, schau unter start->Ausführen-> "Regedit" unter den Einträgen des COM Objects nach. Wenn da mehrere Regestrierungen vorhanden sind, kannst du diese über [DLLImport] als static extern miteinbinden über die entsprechende guid.

/PS

Ich hab mich bestimmt vertippt bei dem ein oder anderen Schlüsselwort.

17.12.2007 - 10:23 Uhr

Okay, ich muss zugeben das ich mich mit WPF nicht auskenne. Aber ich bin mir nicht sicher ob das damit geht.

Aber ich denke es wäre leichter zwei UserControls dafür zu schreiben.

1.) UserControl
Pfeile -> die OnPaintMethode überschreiben, Pfeiltasten mit Graphicpath erzeugen, effecte usw. dazufügen. Ein Property erstellen was die Richtung des Pfeiles angibt und für den Designer sichtbar machen.

2.) UserControl
Unterbau -> zwei UserControls Pfeile über den Designer einbinden, die Ausrichtung erstellen. Dann eine Klasse <ImageKlasse> erstellen, mit der Methode OnPaintDraw(Graphics _gfx) und den Property Image. Dannach erstellst du noch eine Klasse mit die Abgeleitet wird von List<ImageKlasse>, du fügst dann das Property Current hinzu. Danach gehst in dein UserControl und bindest die Collection Klasse ein. Bei der OnPaint Methode baust du dir deine Routine für das OnClick Ereigniss gepart mit der Collectionklasse zusammen.

Nach etwas hin und herhast es dann fertig, im Prinzip recht einfach, kostet halt nur etwas Zeit und Aufwand.

17.12.2007 - 10:03 Uhr

Hrm, hast du vor nen Taschenrechner zu basteln und wenn ja, soll dieser in deiner Anwendung an verschiedenen stellen mehrfach benutzt werden?

17.12.2007 - 09:56 Uhr

Hrm, ich würde unter der Windows API über Send Messages nachschauen. Dann unter den Windowsnachrichten irgendwas mit OnKeyDown suchen.
Ich denke entweder kann man dann einen intervall als lparam übergeben oder Windows erwartet irgendwan eine KeyUp Message.

14.12.2007 - 13:32 Uhr

Hrm, falls nochmal jemand solch ein Problem hat - Lösen über einen VB Script ist eine schlechte Idee.

Man kann zwar die kostenlose Microsoft Office XP (Primary Interop Assemblies = PIAs) verwenden aber macht beim hinzufügen eines Scriptes sämtliche Virenscanner nervös und schlägt sich durch etliche Sicherheitsabfragen durch. Ein wirkungsvoller aber alter Ersatz ist dabei DAO X(

14.12.2007 - 09:56 Uhr

Danke dir für die Antwort - der SQL Server 2005 ist ohne Zweifel genial 🙂

Allerdings arbeite ich an einen Programm das SQL- so wie Access Datenbanken unterstützt. Bisher funktioniert auch alles einwandfrei, für den SQL Server 2000 und 2005 habe ich bereits in T-SQL alles benötigte geschrieben. Nun ist die Access Datenbank dran und ich bin mir nicht sicher, ob ich die in T-SQL geschriebenen Funktionen in Access auch über DbCommand überhaupt benutzen kann. Ich dachte ich löse das am besten über VB Scripte die zur Laufzeit Funktionen bereitstellen und dann wieder gelöscht werden.

Aber ich habe da etwas im Forum gefunden schäm nachdem ich etwas gründlicher gesucht habe. LINK

13.12.2007 - 18:22 Uhr

Hallo Community,

ich habe mehr eine allgemeine Frage zu Modulen unter MS Access.

Wenn ich eine Funktion innerhalb einer Access Abfrage aufrufen möchte:“SELECT MyFunctionName(TEST.Phone) AS Phone FROM TEST;“
Dann kann ich hierfür ein Modul schreiben das die Funktion: „MyFunctionName(<Type> <Parameter>) „ beinhaltet.

Nun zu meiner Frage: Kann ich in C# wenn ich eine Datenbankverbindung zur MS Acesss Datenbank besitze, irgendwie ein VB Modul mitgeben und wenn ja wie sieht den so etwas aus 🤔

13.12.2007 - 10:41 Uhr

Zum kopieren ist das hier etwas besser, da es auch die rechte für Ole Automation Procedures aktiviert und die HTML-TAG's draussen sind.


-- Ole automation procedures on
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO

--Okay here is Regex for SQL
IF OBJECT_ID (N'dbo.RegexMatch') IS NOT NULL
   DROP FUNCTION RegexMatch
GO
CREATE FUNCTION RegexMatch
    (
      @pattern VARCHAR(2000),
      @matchstring VARCHAR(MAX)--Varchar(8000) got SQL Server 2000
    )
RETURNS INT
AS BEGIN
    DECLARE @objRegexExp INT
    DECLARE @objErrorObject INT
    DECLARE @strErrorMessage VARCHAR(255)
    DECLARE @hr INT
    DECLARE @match BIT

    SELECT  @strErrorMessage = 'creating a regex object'
    EXEC @hr= sp_OACreate 'VBScript.RegExp', @objRegexExp OUT
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'Pattern', @pattern
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'IgnoreCase', 1
    IF @hr = 0
        EXEC @hr= sp_OAMethod @objRegexExp, 'Test', @match OUT, @matchstring
    IF @hr <> 0
        BEGIN
            RETURN NULL
        END
    EXEC sp_OADestroy @objRegexExp
    RETURN @match
   END
GO
IF OBJECT_ID(N'dbo.RegexFind') IS NOT NULL
    DROP FUNCTION dbo.RegexFind
GO
CREATE FUNCTION RegexFind(
    @pattern VARCHAR(255),
    @matchstring VARCHAR(MAX),
    @global BIT = 1,
   @Multiline bit =1)
RETURNS
    @result TABLE
        (
        Match_ID INT,
          FirstIndex INT ,
          length INT ,
          Value VARCHAR(2000),
          Submatch_ID INT,
          SubmatchValue VARCHAR(2000),
         Error VARCHAR(255)
        )


AS -- columns returned by the function
   BEGIN
    DECLARE @objRegexExp INT,
        @objErrorObject INT,
        @objMatch INT,
        @objSubMatches INT,
        @strErrorMessage VARCHAR(255),
       @error VARCHAR(255),
        @Substituted VARCHAR(8000),
        @hr INT,
        @matchcount INT,
        @SubmatchCount INT,
        @ii INT,
        @jj INT,
        @FirstIndex INT,
        @length INT,
        @Value VARCHAR(2000),
        @SubmatchValue VARCHAR(2000),
        @objSubmatchValue INT,
        @command VARCHAR(8000),
        @Match_ID INT
        
    DECLARE @match TABLE
        (
          Match_ID INT IDENTITY(1, 1)
                       NOT NULL,
          FirstIndex INT NOT NULL,
          length INT NOT NULL,
          Value VARCHAR(2000)
        )    
    DECLARE @Submatch TABLE
        (
          Submatch_ID INT IDENTITY(1, 1),
          match_ID INT NOT NULL,
          SubmatchNo INT NOT NULL,
          SubmatchValue VARCHAR(2000)
        )
      


    SELECT  @strErrorMessage = 'creating a regex object',@error=''
    EXEC @hr= sp_OACreate 'VBScript.RegExp', @objRegexExp OUT
    IF @hr = 0
        SELECT  @strErrorMessage = 'Setting the Regex pattern',
                @objErrorObject = @objRegexExp
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'Pattern', @pattern
    IF @hr = 0
        SELECT  @strErrorMessage = 'Specifying a case-insensitive match'
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'IgnoreCase', 1
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'MultiLine', @Multiline
    IF @hr = 0
        EXEC @hr= sp_OASetProperty @objRegexExp, 'Global', @global
    IF @hr = 0
        SELECT  @strErrorMessage = 'Doing a match'
    IF @hr = 0
        EXEC @hr= sp_OAMethod @objRegexExp, 'execute', @objMatch OUT,
            @matchstring
    IF @hr = 0
        SELECT  @strErrorMessage = 'Getting the number of matches'    
    IF @hr = 0
        EXEC @hr= sp_OAGetProperty @objmatch, 'count', @matchcount OUT
    SELECT  @ii = 0
    WHILE @hr = 0
        AND @ii < @Matchcount
        BEGIN
/*The Match object has four read-only properties.
The FirstIndex property indicates the number of characters in the string to the left of the match.
The Length property of the Match object indicates the number of characters in the match.
The Value property returns the text that was matched.*/
            SELECT  @strErrorMessage = 'Getting the FirstIndex property',
                    @command = 'item(' + CAST(@ii AS VARCHAR) + ').FirstIndex'    
            IF @hr = 0
                EXEC @hr= sp_OAGetProperty @objmatch, @command,
                    @Firstindex OUT
            IF @hr = 0
                SELECT  @strErrorMessage = 'Getting the length property',
                        @command = 'item(' + CAST(@ii AS VARCHAR) + ').Length'    
            IF @hr = 0
                EXEC @hr= sp_OAGetProperty @objmatch, @command, @Length OUT
            IF @hr = 0
                SELECT  @strErrorMessage = 'Getting the value property',
                        @command = 'item(' + CAST(@ii AS VARCHAR) + ').Value'    
            IF @hr = 0
                EXEC @hr= sp_OAGetProperty @objmatch, @command, @Value OUT
            INSERT  INTO @match
                    (
                      Firstindex,
                      [Length],
                      [Value]
                    )
                    SELECT  @firstindex + 1,
                            @Length,
                            @Value
            SELECT  @Match_ID = @@Identity        
/*The SubMatches property of the Match object is a collection of strings. It will only hold values if your regular expression has capturing groups. The collection will hold one string for each capturing group. The Count property (returned as SubmatchCount) indicates the number of string in the collection. The Item property takes an index parameter, and returns the text matched by the capturing group.
\*/
            IF @hr = 0
                SELECT  @strErrorMessage = 'Getting the SubMatches collection',
                        @command = 'item(' + CAST(@ii AS VARCHAR)
                        + ').SubMatches'    
            IF @hr = 0
                EXEC @hr= sp_OAGetProperty @objmatch, @command,
                    @objSubmatches OUT
            IF @hr = 0
                SELECT  @strErrorMessage = 'Getting the number of submatches'    
            IF @hr = 0
                EXEC @hr= sp_OAGetProperty @objSubmatches, 'count',
                    @submatchCount OUT
            SELECT  @jj = 0
            WHILE @hr = 0
                AND @jj < @submatchCount
                BEGIN
                    IF @hr = 0
                        SELECT  @strErrorMessage = 'Getting the submatch value property',
                                @command = 'item(' + CAST(@jj AS VARCHAR)
                                + ')' ,@submatchValue=NULL  
                    IF @hr = 0
                        EXEC @hr= sp_OAGetProperty @objSubmatches, @command,
                            @SubmatchValue OUT
                    INSERT  INTO @Submatch
                            (
                              Match_ID,
                              SubmatchNo,
                              SubmatchValue
                            )
                            SELECT  @Match_ID,
                                    @jj+1,
                                    @SubmatchValue
                    SELECT  @jj = @jj + 1
                END        
            SELECT  @ii = @ii + 1
        END
    IF @hr <> 0
        BEGIN
            DECLARE @Source VARCHAR(255),
                @Description VARCHAR(255),
                @Helpfile VARCHAR(255),
                @HelpID INT
  
            EXECUTE sp_OAGetErrorInfo @objErrorObject, @source OUTPUT,
                @Description OUTPUT, @Helpfile OUTPUT, @HelpID OUTPUT
            SELECT  @Error = 'Error whilst '
                    + COALESCE(@strErrorMessage, 'doing something') + ', '
                    + COALESCE(@Description, '')
        END
    EXEC sp_OADestroy @objRegexExp
     EXEC sp_OADestroy        @objMatch
     EXEC sp_OADestroy        @objSubMatches

INSERT INTO @result
          (Match_ID,
          FirstIndex,
          [length],
          [Value],
          Submatch_ID,
          SubmatchValue,
         error)


    SELECT  m.[Match_ID],
           [FirstIndex],
           [length],
           [Value],[SubmatchNo],
           [SubmatchValue],@error
  FROM    @match m
    LEFT OUTER JOIN   @submatch s
    ON m.match_ID=s.match_ID    
IF @@rowcount=0 AND LEN(@error) > 0
INSERT INTO @result(error) SELECT @error
RETURN
END
GO

13.12.2007 - 09:31 Uhr

Uha, vielen Dank 🙂

Der Tipp ist Goldrichtig, zwar ist das für SQL 2005 ausgelegt aber ich habe da ne nette Seite aufgrundessen gefunden das Regex für SQL Server 2000 bietet 🙂Hier der Link

12.12.2007 - 14:39 Uhr

Hrm, die ganzen Standardverbindungen hast du ausprobiert ?

"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\myData.mny;UserId='';Password=;"

12.12.2007 - 13:28 Uhr

Ich kann es nicht beschwören ob das Funktioniert aber versuch mal folgendes:

"FILEDSN=c:\myData.mny;Uid=myUsername;Pwd=;" als Connection String über ODBC

11.12.2007 - 16:56 Uhr

Verwendetes Datenbanksystem: MS SQL Server

Hallo Community,
gibt es eine Möglichkeit in MS SQL einen Script für Reguläre Ausdrücke Auszuführen?

Mein Problem besteht darin das ich eine Reorganisation von Telefonnummern schreiben soll um eine art Telefonnummern Index hinzubekommen. Das ganze funktioniert unter Regex im C# Code recht gut. Doch bei mehreren tausend Datensätzen komme ich wohl um eine SQL Function nicht herum.

Ich habe da zwar etwas gefunden via PATINDEX('%[0-9]%',@variable) usw. aber ich denke da muss es doch etwas leichteres für faule Menschen geben 😃

11.12.2007 - 16:03 Uhr

Hrm, ich bin leider Heute etwas neben mir.

Aber was gibt dir den das Event DataMemberChanged als object sender und EventArgs e den so alles mit?

Vielleicht lässt sich da etwas leichter mit Arbeiten. So das nicht die Row suchen musst und gleich eine Liste von Objecten in z.B. ein anderes DataTable speichern kannst.

Wenn es da nichts interessantes zu gibt, schau mal in DataGridView.DataBindings["CheckBox"] rein, was alles für Möglichkeiten hast.

11.12.2007 - 15:06 Uhr

Hrm, okay, das wird nun kompliziert 😉


Binding bLR = comboBox2.DataBindings.Add("Text", dsPKBwElastisch1, "tblLieferung.RetourNr");

So, das Problem kann nun wie folgt entstehen, das tblLieferung.RetourNr vom Typ int entspricht. Während der eingetragene Typ wegen Text nun vom typ String entspricht. Beim validieren durch TAB oder Pfeiltasten wird die Formatierung nicht aufgehoben.

Mach folgendes:

Nun:


comboBox2.DataBindings.Add("Text", dsPKBwElastisch1, "tblLieferung.RetourNr",false, DataSourceUpdateMode.OnValidation);

Wichtig ist das False, ob es validiert werden soll oder nicht, kannst du dann via DataSourceUpdateMode selbst festlegen. Das Problem gab es schon einmal. Falls das nicht hilft muss ich nochmal drüber nachdenken 😮)

11.12.2007 - 14:59 Uhr

Hrm, also Friend entspricht in C# am ehesten dem "internal void Methode" "internal int m_nValue" usw.

11.12.2007 - 14:57 Uhr

Hrm, da gibt es schon einen Beitrag zu: Link

11.12.2007 - 14:42 Uhr

Also dieser "globale" Hook.

Dieser reagiert immer auf deinem gesamten Thread!

GUI's die z.B in anderen Threads laufen musst dann nur den Hook Anpassen, statt GetCurrentThreadId dann eben die GetCurrentProzessId mitgeben und die GetCurrentThreadId auf 0 belassen.

Denke mal das wars was gesucht hattest.


 public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(HookType code, HookProc func, IntPtr hInstance, int threadID);

        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);

        private delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);
        private HookProc myCallbackDelegate = null;

        public enum HookType : int
        {
            WH_JOURNALRECORD = 0,
            WH_JOURNALPLAYBACK = 1,
            WH_KEYBOARD = 2,
            WH_GETMESSAGE = 3,
            WH_CALLWNDPROC = 4,
            WH_CBT = 5,
            WH_SYSMSGFILTER = 6,
            WH_MOUSE = 7,
            WH_HARDWARE = 8,
            WH_DEBUG = 9,
            WH_SHELL = 10,
            WH_FOREGROUNDIDLE = 11,
            WH_CALLWNDPROCRET = 12,
            WH_KEYBOARD_LL = 13,
            WH_MOUSE_LL = 14
        }

        public Form1()
        {
            InitializeComponent();

            // initialize our delegate
            this.myCallbackDelegate = new HookProc(this.MyCallbackFunction);

            // setup a global gui-thread mouse hook
            SetWindowsHookEx(HookType.WH_MOUSE, this.myCallbackDelegate, IntPtr.Zero, AppDomain.GetCurrentThreadId());
        }

        private enum MMsg : int
        {
            HC_ACTION = 0,
            WH_MOUSE_LL = 14,
            WM_MOUSEMOVE = 0x200,
            WM_LBUTTONDOWN = 0x201,
            WM_LBUTTONUP = 0x202,
            WM_LBUTTONDBLCLK = 0x203,
            WM_RBUTTONDOWN = 0x204,
            WM_RBUTTONUP = 0x205,
            WM_RBUTTONDBLCLK = 0x206,
            WM_MBUTTONDOWN = 0x207,
            WM_MBUTTONUP = 0x208,
            WM_MBUTTONDBLCLK = 0x209,
            WM_MOUSEWHEEL = 0x20A,
        }

        private int MyCallbackFunction(int code, IntPtr wParam, IntPtr lParam)
        {
            if (code < 0)return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);

            MMsg buttonPressed = (MMsg)wParam.ToInt32();

            if (buttonPressed == MMsg.WM_LBUTTONDOWN) // usw..
            {
                Console.WriteLine("Left mouse down");

                // hier dann dein: Ende + Start vom Timer
            }
           
            //return the value returned by CallNextHookEx
            return CallNextHookEx(IntPtr.Zero, code, wParam, lParam);
        }
    }


Wenn du die Mousepositionen noch brauchst kannst den LParam mit Marshal.PtrToStructure in das MOUSEHOOKSTRUCT umwandeln (befindet sich in der MS Platform SDK). Aber ich denke möchtest ja nur nen Timer Starten und Stoppen, da reicht das.

11.12.2007 - 14:02 Uhr

Nein werden sie nicht. Gib mir einen Moment und ich poste dir die Lösung dazu.

11.12.2007 - 11:18 Uhr

Original von Björn
Hm wenn das nur Programmintern ist, reicht dann nicht ein MouseDown Event zu definieren?

MfG
Björn

Wenn er nur eine Form benutzt hast du natürlich recht mit protected override void OnMouseDown(MouseEventArgs e) den Timer Stoppen bzw neu starten.

11.12.2007 - 11:16 Uhr

Also ka, was es jtzt neues gibt aber ich hatte immer die Web Browser ActiveX Benutzt.

Die findest du immer unter "C:\WINDOWS\System32\shdocvw.dll".

Einfach einbinden wie gehabt mit using AxSHDocVw;

private AxSHDocVw.AxWebBrowser myBrowser = new AxSHDocVw.AxWebBrowser();

Vergiss nicht nacht BeginnInit in der Methode InitalizeComponents folgendes zu machen.


 this.myBrowser.Enabled = true;
 this.myBrowser.Location = new System.Drawing.Point(5, 5);
 this.myBrowser.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("wbb1.OcxState")));

Der Rest ist eigentlich dann selbsterklärend 🙂
Aber ich denke seit .Net 2.0 gibt es sicher etwas besseres, ich habe mich bis dato nur noch nicht damit befasst.

11.12.2007 - 11:08 Uhr

Es gibt dafür mehrere Möglichkeiten.

Hast du eine Hauptform als Container für deine anderen Forms, so kannst du das in der WndProc der HauptForm abfangen.

Ansonsten kannst du über die ProcessId einen globalen MouseHook auf deine Application schreiben. Siehe dazu LowLevelHook Windows API oder eben www.pinvoke.net MouseHook.

11.12.2007 - 10:24 Uhr

Hrm, das kann nun mehrere Gründe haben.

Ich vermute nur mal das deine Funktion RetoureToBox beim Validating / Validated oder Leave Event ausgelöst wird. Schau einfach mal in den entsprechenden Methoden nach ob dort die Funktion aufgerufen wird. Zumal, die Funktion etwas merkwürdig gestalltet ist, pass auf das Retouren.Count auch wirklich gleich den Combobox.Item.Count entspricht, am besten löst das etwas geschickter und einfacher.

Denk dran, du kannst ne Combobox.Items.Add(object ) Methode mit einem Object füllen, daher auch mit einer Klasse, bei der du in protected override string ToString() statt base.ToString() eben deinen gewünschten Anzeigenamen hinterlegst. So beinhaltet die Combobox schon selbst die Information die sie benötigt und du kannst deine Suche vereinfachen und brauchst keine zwei Listen zu führen wie Retouren und Combobox.ItemCollection.

17.11.2007 - 15:23 Uhr

Original von smichae
Also ich bekomme ständig Daten vom Server. Also mehrere auf einmal.

Hrm, das hatte ich übersehen. Na ja dann hat talla natürlich recht.
Das von mir geschriebene zielte darauf ab, das selbst die Server wie Clientanwendung schreibst.

Original von talla

Original von Andreas.May
- MultiThreading / Threads
Der TCPListener läuft doch schon in nem eigenen Thread.

Na ja, damit meinte ich eher die Verarbeitung der einzelnen Nachrichten (Empfang, ThreadStart -> Verarbeite Nachricht damit andere Nachrichten empfangen werden können die evtl. fast Zeitgleich eintreffen), und nicht nur den Thread der verhindern soll das seine GUI blockiert. Aber brauchen tut er es auf keinen Fall.

17.11.2007 - 13:06 Uhr

Hrm, schau dir z.B das hier mal an:


private void PrintRecursive(TreeNode treeNode)
{
   // Print the node.
   System.Diagnostics.Debug.WriteLine(treeNode.Text);
   MessageBox.Show(treeNode.Text);
   // Print each node recursively.
   foreach (TreeNode tn in treeNode.Nodes)
   {
      PrintRecursive(tn);
   }
}

// Call the procedure using the TreeView.
private void CallRecursive(TreeView treeView)
{
   // Print each node recursively.
   TreeNodeCollection nodes = treeView.Nodes;
   foreach (TreeNode n in nodes)
   {
      PrintRecursive(n);
   }
}

17.11.2007 - 13:00 Uhr

Also, das einfachste wäre du suchst im Forum mal nach den Stichwörtern: Singleton Pattern und Command Pattern evtl. steht es auch unter Command Actions.

17.11.2007 - 12:57 Uhr

Hrm, hatte mir überlegt was ich dazu schreiben soll.

Im Prinzip ist es egal ob MSSQL, MYSQL, Access oder etwas anderes, sicher ist davon nichts. Es reicht wenn du drei Dinge beherzigst, wichtige Passwörter verschlüsseln, SHA1 oder MD5 (auch MD5 ist nicht absolut sicher). Und deine fertige *.Exe Datei deiner Anwendung obfuskieren und deinen DBUser ein Passwort vergeben (also es reicht nicht aus User: sa PW: sa 😉 ).

Mehr aufmerksamkeit in Bezug auf Sicherheit braucht man für einen normalen Endanwender nicht investieren. Schlussendlich gibt es absolut gar nichts was sicher ist.

Irgendwo gibt es immer die Möglichkeit einen neuen DB Benutzer zu erstellen, via SQL Abfragen in einem DB-Binding Field abzufragen, mit Assembler ein True False umzustellen usw. Also, wenn du Access als gut portierbar kennen gelernt hast, nutze es.

17.11.2007 - 11:04 Uhr

Nen Tipp, schau dir folgende Stichworte über die Suchfunktion im Forum an 🙂

- Serialisieren (ISerializable) und SOAP
Kurz: Grob gesagt, du hast eine Klasse die sowohl auf dem Server wie identisch auf den Client Exestieren, die dann beim deserialisieren gefüllt werden.

- MultiThreading / Threads
Kurz: Deine Senden und Empfangen Routine wird asyncron ausgeführt genauso wie die verarbeitungsschicht, was performance einbringt. Informationen können anhand von ID's wieder gefiltert und zugeordnet werden.

- Windows Dienste / ServiceProvider / WS
Kurz: Ein Dienst bietet dir die Gelegenhei, eine reine Datenschicht auszuführen ohne den bedarf einer Oberfläche. Ebenso kann ein Dienst ausgeführt werden, selbst wenn der Serverbenutzer nicht am Rechner angemeldet ist.

17.11.2007 - 10:49 Uhr

Ich kenne das Compact Framework 1.0 leider nicht, bzw. dessen Begrenzungen.

Entweder kannst versuchen eine neue Klasse zu erstellen um dann vom Button abzuleiten und in der protected override OnPaint Methode dein Bild selbst rein zu zeichnen (was nicht schwer ist). Oder du legst ein Control mit einer Backgroundimage eigenschaft in den Button, über Control Add oder WinAPI SetParent (wenn das geht).

16.11.2007 - 19:01 Uhr

Hrm, vielleicht bin ich auch Blind und übersehe etwas, aber vielleicht hilft's etwas zu vereinfachen.

       
        protected override void OnMouseDown(MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
                foreach (ItemGraphicObject btn in this.ItemGraphicList)
                {
                    if (new Region(btn.Rectangle).IsVisible(e.Location))
                    {
                        // button xx was pressed
                    }
                    break;
                }

            base.OnMouseDown(e);
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            foreach (ItemGraphicObject btn in this.ItemGraphicList)
                if (new Region(btn.Rectangle).IsVisible(e.Location))
                    btn.hover = true;
                else
                    btn.hover = false;

            base.OnMouseMove(e);
            this.Invalidate();
        }

16.11.2007 - 18:42 Uhr

Hrm, erstell ein Form mit ner ListView und lass es als <FolderDialog>.DialogShow() laufen.

Du kannst auch das Dialog OpenFileDialog missbrauchen, kostet zwar etwas mehr Zeit aber geht genausogut. Erstell eine Klasse mit der Statischen Methode Show, in der statischen Methode initalisierst du bevor OpenFleDialog.Show ausgeführt wird einen globalen WindProc Hook auf deine ProcessId. Jetzt fragst du ab bis du ein WM_CREATE Nachricht bekommst. Dann hast du das Handle des Dialogs und kannst dann mit diesen anstellen was du magst. Z.b auf dem display context herummalen (Graphics.FromHdc), mit SetParent neue Controls hinzufügen, oder wiederum einen hook nur auf die Nachrichten des Dialogs setzen um dort Nachrichten abzufangen.

16.11.2007 - 18:25 Uhr

Buh, also es gibt auch ne Möglichkeit sich direkt in MessageBox.Show reinzuklinken.
Ich habe es zwar auf Anfrage da, aber es nimmt sehr viel Zeit in anspruch.

Mach aber besser folgendes:


this.BackColor = System.Drawing.SystemColors.Info;
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;

Und benutze eines der Icons für die Darstellung:
C:\Program Files\Microsoft Visual Studio 8\Common7\VS2005ImageLibrary\VS2005ImageLibrary.zip\VS2005ImageLibrary\icons

16.11.2007 - 14:34 Uhr

Hrm, entweder hast noch nicht alles erzählt oder es wird Zeit für "deinen" Feierabend. Du hast die Lösung selbst schon niedergeschrieben 😉



        static void Main(string[] args)
        {

            if (HasValue(@"/Back", args))
                new Form1().Show();
            else
            {
               NotifyIcon icon = new NotifyIcon();
               icon.Icon = usw...
              
            }

            Application.Run();
       }

        // ja mir war langweilig ;)
        private static bool HasValue(string _sValue, string[] array)
        {
            string sFound = Array.Find<String>(array, delegate(String _sOutPut) { return _sOutPut == _sValue; });

            return (string.IsNullOrEmpty(sFound)) ? false : true;
        }


16.11.2007 - 14:20 Uhr

Mach es dir doch einfach:

Rufe aus deiner <HauptForm>heraus ein neues Formular auf mit <WaitForm>.ShowDialog.
In diesen Waitform startest einen Thread der etwas abarbeitet. Nachdem der Thread fertig mit der verarbeitung ist startest eben this.Close. This.Close überschreibst du vorher wie folgt:


  public new void Close()
        {
            if (this.InvokeRequired) this.Invoke(new MethodInvoker(this.Close));
            else { base.Close(); }
        }

Damit dein <WaitForm> keine Fehler auslöst. Wenn das <WaitForm> geschlossen ist, wurde dein Thread abgearbeitet. Wenn den Inhalt aus deinem Thread in der <Waitform> weitergeben möchtest an die <Hauptform> dann erweitere noch <WaitForm>.ShowDialog um den Returnwert oder übergib es halt Global als Propertie.

Schön wäre noch nen Fortschritszähler wie eine Progressbar. Diese füllst du innerhalb deines <WaitForm> Threads mit Invoke um <ProgressBar>.Value++.

Und Fertig ist das ganze und sieht auch einigermaßen sauber aus.

15.11.2007 - 15:24 Uhr

Ähm, hatte mich verlesen schäm dachte wolltest ne Spalte ausblenden. Stattdessen wird dein ColumnHeader String von nen Bild überdeckt. Naja du kannst Anhand von Graphics.MeasureString die Breite des String abfragen + etwas abstand + Imagebreite = dein neues Width.

15.11.2007 - 15:18 Uhr

Hrm, dass get denke ich noch einfacher.

Schau dir davon an was du brauchst:


this.richTextBox1.SelectedText;
this.richTextBox1.SelectionIndent
this.richTextBox1.SelectionLength
this.richTextBox1.SelectionStart

Ps, wenn was anderes als Texte rumwühlen vorhattest, schreibs rein 🙂

15.11.2007 - 14:53 Uhr

Hrm,
ich habe zwar seid ewigkeiten das Control nicht mehr angefasst.
Aber es gibt meistens nen AutoSize Propertie das man auf AutoSize = false stellen kann.
Dann sollte das mit der spaltenbreite kein Ding sein. Auch Column[0].Visible = false sollte denke ich gehen.

Oder einen Style den man setzen kann 🙂

15.11.2007 - 14:07 Uhr

Hrm, ich würde mal von DropDownItems Ableiten und dort nachsehen ob es eine Methode zum überschreiben gibt wie OnCheck oder OnClick und dann das //base auskommentieren um zu sehen ob das Verhalten verändert wird. Wenn es dort nicht klappen sollte, würde ich das selbe mal in den jeweiligen DropDownItems versuchen.

Und wenn das alles nicht hinhaut, mal die Properties nachsehen ob ich da etwas setzen kann und ansonsten die Windwosnachricht dafür in der WndProc unterbinden.

15.11.2007 - 12:01 Uhr

Hallo Michael,

Zuerst Initialisierst du das Formular, danach lädst du im Konstruktor des Formulars deine Schleife.
Dann wirst du die Frage haben warum deine GUI blockiert 😁

15.11.2007 - 11:26 Uhr

Also, ich glaube du machst es dir etwas zu kompliziert.

Ruf das AdresseFenster nicht mit AdresseFenster.Show auf, sondern mit AdresseFenster.ShowDialog() und Les ein Propertie aus, da die Statische Fuktion soweiso solange blockiert bleibt bis das AdressFenster.Dialog beendet wird (GUI blockiert fals eines dran sein sollte).

Wenn Faul bist, mach in der AdressFenster Form, z.B. so etwas:




public new string ShowDialog(string _sOrt)
{
  <textbox>.Text = _sOrt;

base.ShowDialog(); // <-- blockiert

return <textbox>.Text;

}

private void OnButtonCloseClick(ClickEventArgs e)
{
this.Close();
}


Und wegen deiner Frage, damit verstehst warum das andere nicht funktioniert. Du musst auf der selben Instanz entweder beim Initalisieren das Event hinzufügen oder das Event ebenso statisch anfügen. Mal davon abgesehen rufst du es nirgendwo auf.

15.11.2007 - 09:36 Uhr

Okay, ich weis warum aber erklären ist nicht meine Stärke...

Stark typisierten Listen, beinhalten auch stark typisierten Datentypen.
Wenn du versuchst aus einen int = int? zu machen, bekommst in VS ne Fehlermeldung.


            int? b = null;
            int a = 0;
            int test = a = b; //<-- das nimmt dir der compiler so nicht ab.

Bei FormattingEnabled = true; Wird aus int? und int beides nen String. Die starke typisierierung wird somit aufgehoben, sowohl beim Propertie des Controls wie die von der Datenquelle (in deinem Fall Customer -> ArrayList). Lass einfach int? zu int werden.

Also statt:


  private int? mType;

        public int? CustType
        {
            get { return mType; }
            set { mType = value; }
        }

Das hier:


  private int mType;

        public int CustType
        {
            get { return mType; }
            set { mType = value; }
        }

Weil:


EnumHelper.ToList<int>(typeof(CustomerType));

Oder mach: -> Um einen Fehler auszulösen, der erklärts genauer.


EnumHelper.ToList<int?>(typeof(CustomerType));

Ansonsten ist es logisch das FormattingEnabled benutzen musst 🙂
Wer das irgendwie besser erklären kann, nur zu... Ich habe von den Fachbegriffen meistens keinen schimmer 😜

/ps

Kurze erklärung des ?? Operator
Der ??-Operator gibt den linken Operanden zurück, falls dieser nicht NULL ist. Andernfalls wird der rechte Operand zurückgegeben.

In diesem Fall ist int? ein etwas anderer Datentyp als nur int. (naja ka wie man das genau nennt..)

14.11.2007 - 18:09 Uhr

Naja klingt eher nach GUI blockiert 😉

Siehe Anhang.

14.11.2007 - 17:37 Uhr

Also, stark typisierten Listen sollten prinzipiell immer gehen? Ein Mysterium 🤔

14.11.2007 - 17:20 Uhr

Gerne doch 🙂

Vielleicht beinhaltet deine Liste nicht das Interface IList?