Laden...

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

11.03.2008 - 19:25 Uhr

Na ja, möglich ists ja dennoch auf andere Foren im Internet die selben Fragen zu stellen - anderer Benutzername, Frage umformuliert und das wars. Also verhindern kann man es denke ich nicht. Bleibt halt nur die Frage ob man sich die Mühe machen sollte es überhaupt zu tun.

Innerhalb des selben Forums ist es natürlich überprüfbar und würde auch keinen Sinn machen. Selbst das pushen ist ne dumme Idee, da ich vermute das einige lieber den Knopf "(Themen ohne Antwort)" benutzen.

11.03.2008 - 19:21 Uhr

Zwar wird das folgende bemekert werden, da es das OOP prinzip ausser kraft setzt aber hätte damit kein Problem 😉


        public new event MouseEventHandler MouseWheel;
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (this.MouseWheel != null)
                this.MouseWheel(this, e);

            //base.OnMouseWheel(e);
        }

11.03.2008 - 17:00 Uhr

Hallo Spoochie,

einen Systemweiten hook habe ich hätte ich dir unter folgenden Link. Einfach runterscrollen und du findest einen C# Keyboardhook.

Zum herausfinden welche Paramter für was zuständig sind für empfehle ich dir die Microsoft Platform SDK für Windows Server 2003 herunter zu laden. Dort ist fast alles sehr gut dokumentiert. Auch das Suchen nach entsprechenden Windowsfunktionen wird dadurch enorm erleichtert.

Die implementierung empfehle ich dir dann die Seite www.pinvoke.net zu realisieren, dort sind sogut wie alle dll imports für C# und VB zu finden.


HHOOK SetWindowsHookEx(        
    int idHook,
    HOOKPROC lpfn,
    HINSTANCE hMod,
    DWORD dwThreadId
);

int idHook:
Definiert den hook typ wie zum Beispiel den WH_KEYBOARD_LL für Windows NT und höher der dir eine Struktur mit informationen über die Tastatur zurückliefert oder einen WH_KEYBOARD hook typ der dir die Prozedurnachrichten zurückliefert usw.

HOOKPROC lpfn:
Definiert den zeiger auf denm die hook prozedur verarbeitet wird, also die Callback Methode.

hMod
Definiert den zeiger des injizierten DLL.
Da z.B eine Client-DLL wie User32 die benörigten Funktionsaufrufe besitzt, kann man auch diese Instanz in einen fremden Prozess injizierten oder eine entsprechende dynamic-link library die selbst dafür schreiben kannst. Solltest einen Hook auf deine eigene Anwendung schreiben so bleibt der Zeiger hier bei null.

dwThreadId
Definiert den Identifier für den Thread (nicht Prozess) auf dem die Hook-Prozedur ausgeführt wird. Wenn dieser Zeigerals null deklariert wird, so werden alle verarbeitenden Threads des injizierten Prozesses für die Hookprozedur verwendet.

Es gibt dazu noch mehr, aber die SDK kann dir da beweiten mehr informationen bieten als ich als ähm Handwerker unter den Programmierern 😉

11.03.2008 - 12:28 Uhr

Hrm, nutze auch wenn ich Datenstrukturen als Quelle habe erstmal ein Dataset das ich mit Datatables und entsprechenden Columns fülle die dann den Datenstrukturen entsprechen. Im anschluss fülle ich dann einfach die Datatables mit den Datenstrukturen. Ausserdem reagiere ich halt bei änderungen der Datenstrukturen auf entsprechende Events die dann die Datatable dann füllen leeren usw.

Was besseres viel mir dazu auch nicht ein, ausserdem spielts kaum eine rolle wegen doppelter Datenhaltung, es vereinfacht mehr als das man damit neue Baustellen aufreisst.

05.03.2008 - 17:56 Uhr

Huch, stimmt🙂

05.03.2008 - 17:51 Uhr

Und hier für die Maus:


    public class CHook
    {
        #region Declarations
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hModule"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool FreeLibrary(IntPtr hModule);
        /// <summary>
        /// defines the callback type for the hook
        /// </summary>
        private delegate int mouseHookProc(int code, int wParam, ref MSLLHOOKSTRUCT lParam);
        /// <summary>
        /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
        /// </summary>
        /// <param name="idHook">The id of the event you want to hook</param>
        /// <param name="callback">The callback.</param>
        /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
        /// <param name="threadId">The thread you want to attach the event to, can be null</param>
        /// <returns>a handle to the desired hook</returns>
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, mouseHookProc callback, IntPtr hInstance, uint threadId);
        /// <summary>
        /// Unhooks the windows hook.
        /// </summary>
        /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
        /// <returns>True if successful, false otherwise</returns>
        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
        /// <summary>
        /// Calls the next hook.
        /// </summary>
        /// <param name="idHook">The hook id</param>
        /// <param name="nCode">The hook code</param>
        /// <param name="wParam">The wparam.</param>
        /// <param name="lParam">The lparam.</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref MSLLHOOKSTRUCT lParam);
        /// <summary>
        /// Loads the library.
        /// </summary>
        /// <param name="lpFileName">Name of the library</param>
        /// <returns>A handle to the library</returns>
        [DllImport("kernel32.dll")]
        private static extern IntPtr LoadLibrary(string lpFileName);
        /// <summary>
        ///
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        private struct MSLLHOOKSTRUCT
        {
            public POINT pt;
            public int mouseData;
            public int flags;
            public int time;
            public IntPtr dwExtraInfo;
        }
        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;

            public POINT(int x, int y)
            {
                this.X = x;
                this.Y = y;
            }

            public static implicit operator System.Drawing.Point(POINT p)
            {
                return new System.Drawing.Point(p.X, p.Y);
            }

            public static implicit operator POINT(System.Drawing.Point p)
            {
                return new POINT(p.X, p.Y);
            }
        }
        private const int WH_MOUSE_LL = 14;
        #endregion

        #region Instance Variables
        /// <summary>
        /// Handle to the hook, need this to unhook and call the next hook
        /// </summary>
        private IntPtr m_hHook = IntPtr.Zero;
        /// <summary>
        /// Handle to the module handle instance, need this to unload the library
        /// </summary>
        private IntPtr m_hInstance = IntPtr.Zero;
        #endregion

        #region Events
        /// <summary>
        /// Occurs when one of the hooked keys is pressed
        /// </summary>
        public event MouseEventHandler MouseMove;
        public event MouseEventHandler MouseDown;
        public event MouseEventHandler MouseUp;
        public event MouseEventHandler MouseWheel;
        #endregion

        #region Constructors and Destructors
        /// <summary>
        /// Initializes a new instance
        /// </summary>
        public CHook() { }
        /// <summary>
        /// Release unmanaged code
        /// </summary>
        ~CHook()
        {
            this.UnHook();
        }
        #endregion

        #region Methods
        /// <summary>
        /// Installs the global hook 'mouse'
        /// </summary>
        public void Hook()
        {
            this.m_hInstance = LoadLibrary("User32");
            this.m_hHook = SetWindowsHookEx(WH_MOUSE_LL, this.HookProc, this.m_hInstance, 0);
        }
        /// <summary>
        /// Uninstalls the global hook
        /// </summary>
        public void UnHook()
        {
            FreeLibrary(this.m_hInstance);
            UnhookWindowsHookEx(m_hHook);
        }
        /// <summary>
        /// 
        /// </summary>
        private enum MouseMessages
        {
            WM_LBUTTONDBLCLK = 0x203,
            WM_LBUTTONDOWN = 0x201,
            WM_LBUTTONUP = 0x202,
            WM_MBUTTONDOWN = 0x207,
            WM_MBUTTONUP = 0x208,
            WM_RBUTTONDOWN = 0x204,
            WM_RBUTTONUP = 0x205,
            WM_MOUSEMOVE = 0x200,
            WM_MOUSEWHEEL = 0x20A,
            WM_MOUSEHWHEEL = 0x20E,
        }
        /// <summary>
        /// The callback for the mouse hook
        /// </summary>
        /// <param name="code"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int HookProc(int code, int wParam, ref MSLLHOOKSTRUCT lParam)
        {
            if (code >= 0)
            {
                if(this.MouseDown !=null 
                    && (wParam == (int)MouseMessages.WM_LBUTTONDOWN
                    || wParam == (int)MouseMessages.WM_MBUTTONDOWN
                    || wParam == (int)MouseMessages.WM_RBUTTONDOWN))
                {
                    MouseButtons eMouseButtons = MouseButtons.None;
                    switch ((MouseMessages)wParam)
                    {
                        case MouseMessages.WM_LBUTTONDOWN:
                            eMouseButtons = MouseButtons.Left;
                            break;

                        case MouseMessages.WM_MBUTTONDOWN:
                            eMouseButtons = MouseButtons.Middle;
                            break;

                        case MouseMessages.WM_RBUTTONDOWN:
                            eMouseButtons = MouseButtons.Right;
                            break;
                    }

                    this.MouseDown(this, new MouseEventArgs(eMouseButtons, 0, lParam.pt.X, lParam.pt.Y, 0));
                }
                else if (this.MouseUp != null
                    && (wParam == (int)MouseMessages.WM_LBUTTONUP
                    || wParam == (int)MouseMessages.WM_MBUTTONUP
                    || wParam == (int)MouseMessages.WM_RBUTTONUP))
                {
                    MouseButtons eMouseButtons = MouseButtons.None;
                    switch ((MouseMessages)wParam)
                    {
                        case MouseMessages.WM_LBUTTONDOWN:
                            eMouseButtons = MouseButtons.Left;
                            break;

                        case MouseMessages.WM_MBUTTONDOWN:
                            eMouseButtons = MouseButtons.Middle;
                            break;

                        case MouseMessages.WM_RBUTTONDOWN:
                            eMouseButtons = MouseButtons.Right;
                            break;
                    }

                    this.MouseUp(this, new MouseEventArgs(eMouseButtons, 0, lParam.pt.X, lParam.pt.Y, 0));
                }
                else if (this.MouseWheel != null
                    && (wParam == (int)MouseMessages.WM_MOUSEWHEEL || wParam == (int)MouseMessages.WM_MOUSEHWHEEL))
                    this.MouseWheel(this, new MouseEventArgs(MouseButtons.None, 0, lParam.pt.X, lParam.pt.Y, 0));
                else if (this.MouseMove != null
                    && wParam == (int)MouseMessages.WM_MOUSEMOVE)
                    this.MouseMove(this, new MouseEventArgs(MouseButtons.None, 0, lParam.pt.X, lParam.pt.Y, 0));
            }
            return CallNextHookEx(m_hHook, code, wParam, ref lParam);
        }
        #endregion
    }

05.03.2008 - 16:12 Uhr

Für Khalid's Lösung kannst dir den HitTest ganz einfach gestallten ohne viel Aufwand.


  public bool HitTest(System.Drawing.Point e)
       {
           return new System.Drawing.Region(this.Rect).IsVisible(e);
       }

05.03.2008 - 15:59 Uhr

Hier die Lösung:



// 1. Durchlauf
for (int i = 0; i < 4; i++)
{
  DatensatzStruktur temp = new DatensatzStruktur ();

Das gildet auch für die andere Schleife.

Hrm, verweise dich auf einen bestehenden Thread zur erklärug. Ansonsten im OpenBook gibts auch etwas dazu.

05.03.2008 - 15:54 Uhr

Hehe ja das Ding ist etwas schwer zu verstehen und ist eigentlich für die Sidebar gedacht. Aber Nachrichten finden geht, nur dauert es halt.

Irgendwie wäre es cool wenn jemand das mal als Projekt machen würde, nen einfachen WMI logger bei dem man die Nachrichten selektieren kann die man "verdächtigt" dafür verantwortlich zu sein.

Probier einfach nen bisschen rum, try and error gehört da einfach dazu .-)

Denk dran, die Lösung reinzuposten.

05.03.2008 - 15:37 Uhr

Hallo sorry das ich mich nicht mehr so lange gemeldet habe.

Ich habe den Hook mal etwas mehr unseren lieben C# standard angepasst 😉

Hier also global low level hook für C# fürs keyboard:


 public class CHook
    {
        #region Declarations
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hModule"></param>
        /// <returns></returns>
        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool FreeLibrary(IntPtr hModule);
        /// <summary>
        /// defines the callback type for the hook
        /// </summary>
        private delegate int keyboardHookProc(int code, int wParam, ref KBDLLHOOKSTRUCT lParam);
        /// <summary>
        /// Sets the windows hook, do the desired event, one of hInstance or threadId must be non-null
        /// </summary>
        /// <param name="idHook">The id of the event you want to hook</param>
        /// <param name="callback">The callback.</param>
        /// <param name="hInstance">The handle you want to attach the event to, can be null</param>
        /// <param name="threadId">The thread you want to attach the event to, can be null</param>
        /// <returns>a handle to the desired hook</returns>
        [DllImport("user32.dll")]
        private static extern IntPtr SetWindowsHookEx(int idHook, keyboardHookProc callback, IntPtr hInstance, uint threadId);
        /// <summary>
        /// Unhooks the windows hook.
        /// </summary>
        /// <param name="hInstance">The hook handle that was returned from SetWindowsHookEx</param>
        /// <returns>True if successful, false otherwise</returns>
        [DllImport("user32.dll")]
        private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
        /// <summary>
        /// Calls the next hook.
        /// </summary>
        /// <param name="idHook">The hook id</param>
        /// <param name="nCode">The hook code</param>
        /// <param name="wParam">The wparam.</param>
        /// <param name="lParam">The lparam.</param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(IntPtr idHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam);
        /// <summary>
        /// Loads the library.
        /// </summary>
        /// <param name="lpFileName">Name of the library</param>
        /// <returns>A handle to the library</returns>
        [DllImport("kernel32.dll")]
        private static extern IntPtr LoadLibrary(string lpFileName);
        /// <summary>
        /// 
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x100;
        private const int WM_KEYUP = 0x101;
        private const int WM_SYSKEYDOWN = 0x104;
        private const int WM_SYSKEYUP = 0x105;
        #endregion

        #region Instance Variables
        /// <summary>
        /// Handle to the hook, need this to unhook and call the next hook
        /// </summary>
        private IntPtr m_hHook = IntPtr.Zero;
        /// <summary>
        /// Handle to the module handle instance, need this to unload the library
        /// </summary>
        private IntPtr m_hInstance = IntPtr.Zero;
        #endregion

        #region Events
        /// <summary>
        /// Occurs when one of the hooked keys is pressed
        /// </summary>
        public event KeyEventHandler KeyDown;
        /// <summary>
        /// Occurs when one of the hooked keys is released
        /// </summary>
        public event KeyEventHandler KeyUp;
        #endregion

        #region Constructors and Destructors
        /// <summary>
        /// Initializes a new instance
        /// </summary>
        public CHook() { }
        /// <summary>
        /// Release unmanaged code
        /// </summary>
        ~CHook()
        {
            this.UnHook();
        }
        #endregion

        #region Methods
        /// <summary>
        /// Installs the global hook 'keyboard'
        /// </summary>
        public void Hook()
        {
            this.m_hInstance = LoadLibrary("User32");
            this.m_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, this.HookProc, this.m_hInstance, 0);
        }
        /// <summary>
        /// Uninstalls the global hook
        /// </summary>
        public void UnHook()
        {
            FreeLibrary(this.m_hInstance);
            UnhookWindowsHookEx(m_hHook);
        }
        /// <summary>
        /// The callback for the keyboard hook
        /// </summary>
        /// <param name="code"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private int HookProc(int code, int wParam, ref KBDLLHOOKSTRUCT lParam)
        {
            if (code >= 0)
            {
                Keys key = (Keys)lParam.vkCode;

                KeyEventArgs kea = new KeyEventArgs(key);
                if ((wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) && (this.KeyDown != null))
                    this.KeyDown(this, kea);
                else if ((wParam == WM_KEYUP || wParam == WM_SYSKEYUP) && (this.KeyUp != null))
                    this.KeyUp(this, kea);
                if (kea.Handled)
                    return 1;

            }
            return CallNextHookEx(m_hHook, code, wParam, ref lParam);
        }
        #endregion
    }

Falls doch die WindowsNachrichten abfangen möchtest, einfach in deinem C++ hook die BOOL APIENTRY DllMain rausschmeißen und stattdessen über LoadLibrary das ganze implementieren. Siehe hierzu die oberen Threads.

Aber für deine Zwecke reichen die globalen low level hooks für die Maus und die Tastatur aus.

03.03.2008 - 15:38 Uhr

Gibt es dafür überhaupt einen Fachbegriff, muss zugeben neige auch eher dazu "überschreiben" dazu zu sagen oder heisst es "neu machen" oder die "Methode verstecken" ... ?

03.03.2008 - 15:23 Uhr

Hab mal etwas rumprobiert und klappen tut es einfach nicht, wie gesagt wird eine interne Fehlermeldung ausgelöst. Dagegen machen kannst nichts.

Aber könntest versuchen etwas zu tricksen, einfach ein UserControl zu erzeugen und dort die Webbrowserkomponente einbinden, dort dann das JavaScript ausführen und dir etwas entsprechendes zurückliefern. Evtl. mit WebRequest und HttpWebResponse oder etwas ähnlichen, mit dem Thema Web habe ich mich in .Net noch nicht beschäfftigt. Aber würde einfach mal versuchen darüber einen leichteren Weg zu generieren.

03.03.2008 - 15:08 Uhr

JAck30lena hat schon recht. Überschreiben im Sinne von new:


        public event EventHandler ShowDialogEvent;
        public new DialogResultShowDialog()
        {
            if (this.ShowDialogEvent != null)
                this.ShowDialogEvent(this, EventArgs.Empty);
            return base.ShowDialog();
        }

03.03.2008 - 11:44 Uhr

Na hab da noch was nettes gefunden Link.

Klick einfach auf die das "Leistung Panel", dort dann rechte Maustaste auf Eigenschaften des Panels dann kannst dort den WMI Watcher freischalten und Nachrichten begutachten. Musts halt etwas rumprobieren, finde das Ding aber auch sonst ganz nett nicht nur für die WMI Nachrichten.

01.03.2008 - 16:15 Uhr

Hrm, das ist nun wirklich doof.

Vieleicht machst mal den WMI logger an und schaust nach ob "überhaupt" irgendeine Nachricht bekommst. Vielleicht war Win32_LogicalDisk einfach nur das falsche Stichwort dafür - Versuchs einfach mal die WMI Nachrichten zu loggen. Im netz fand ich dazu folgendes:

Start->Ausführen->Regedit : "regedit" "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\WMI\GlobalLogger" Siehe dazu Link.

Unter "C:\WINDOWS\SYSTEM32\Logfiles\WMI" solltest dann das Logfile finden.

Sollte dort dann nichts reingehen wenn den USB Stick entfernst /anfügst.... Muss ich erstmal passen 🙂

01.03.2008 - 14:07 Uhr

Hallo RoXX,

um zu erkennen ob ein neues Laufwerk hinzugefügt wurde kannst du anhand eines Scopes der Windows Management Instrumentation (WMI) Nachrichten: Win32_LogicalDisk. Siehe dazu diesen Link, wirst auch noch einiges mehr dazu im Forum finden.

Der schwerste teil deiner Frage wird eher das ändern des zugeeisenen Laufwerkbuchstabends sein. Ich mache mir da grade mal bei ner Zigarette gedanken 🙂

[Edit]
Soo kurz google gefragt und siehe da hier ein Link .

Also nachdem über WMI bzw. den Scope im Event die NAchricht erhalten hast das ein neues Laufwerk hinzugefügt wurde. Änderst es einfach anhand des Codeproject Beispiels ab und fertig 🙂

01.03.2008 - 13:59 Uhr

Na ja, ansonsten hast in deinen AddOns/Addins wirklich immer nur eine Klasse drinnen?

Den mit (MenuScreenInformation)bf.Deserialize( stream ); gehst davon schon aus.

Würde doch eher das anstreben wie es im Linkt von Codeproject gelöst wurde. Finde den Weg viel sauberer, auch wenn es mehr Zeit kostet das nun nachträglich einzufügen (naja 1/2 -1 Tag). Vorallem kann man dort anhand von Abfragen schon prüfen, ob das Plugin überhaupt geladen werden kann, statt mit einen try catch 🙂

01.03.2008 - 13:39 Uhr

Durch deine "Verweise" die mit ...TypeLib enden, hast du die COM objekte schon eingebunden. Ich hatte nur TypeLibs gelesen und dachte wären auch solche, dabei sind es schon Interop-Assemblys vom .NET Framework.

Dummerweise werden aber interne Fehler ausgelöst beim instanzieren innerhalb des COM objekts. Was sehr naheliegt das norman_timo den Nagel auf dem Kopf getroffen hat. Frag mich jetzt blos nicht wie man diese "Registrierung" hinbekommt (rede nicht von Regsrv 32). Vielleicht hat jemand aber noch dazu eine zündende Idee.

JavaScript dazu:


<html XMLNS:helpcenter>
<head>
<!--
Copyright (c) 2000 Microsoft Corporation
-->
<helpcenter:context id=idCtx />
<title>Remote Assistance</title>
<!-- The SAF class factory object -->
<object classid=CLSID:FC7D9E02-3F9E-11d3-93C0-00C04F72DAF7 height=0 id=objSAFClassFactory width=0></object>
<script LANGUAGE="Javascript">
function onContinue()
{
var g_szWorkstation = null;
var g_szUsername = null;
var c_WorkstationTag = "WORKSTATION=";
var c_UsernameTag = "&USERNAME=";
 
var szArgs = objSAFClassFactory.ExtraArgument;
 
var i = szArgs.indexOf(c_WorkstationTag);
var j = szArgs.indexOf(c_UsernameTag);
g_szWorkstation = szArgs.slice(i+c_WorkstationTag.length, j);
g_szUsername = szArgs.slice(j+c_UsernameTag.length);
 
var i = g_szUsername.indexOf("");
g_szDomainName = g_szUsername.slice(0, i);
g_szUserName = g_szUsername.slice(i+1);
g_szSessionId = -1;
 
g_oSAFRemoteDesktopConnection = objSAFClassFactory.CreateObject_RemoteDesktopConnection();
g_oSAFRemoteConnectionData = g_oSAFRemoteDesktopConnection.ConnectRemoteDesktop(g_szWorkstation);
 
objInc = objSAFClassFactory.CreateObject_Incident();
objInc.RCTicketEncrypted = false;
objInc.RcTicket = g_oSAFRemoteConnectionData.ConnectionParms( g_szWorkstation, g_szUserName, g_szDomainName, -1, "");
var objDict = objInc.Misc;
var d = new Date();
objDict.add("DtStart", Math.round(Date.parse(d)/1000));
objDict.add("DtLength", "60");
objDict.add("Status", "Active");
objDict.add("URA", 1);
objFSO = new ActiveXObject("Scripting.FileSystemObject");
tempDir = objFSO.GetSpecialFolder( 2 );
szIncidentFile = tempDir + "\UnsolicitedRA" + objFSO.GetTempName();
objInc.GetXML(szIncidentFile);
var oShell = new ActiveXObject("WScript.Shell");
var szRAURL = 'C:\WINDOWS\pchealth\helpctr\binaries\helpctr.exe -Mode "hcp://system/Remote Assistance/raura.xml" -url "hcp://system/Remote Assistance/Interaction/Client/RcToolscreen1.htm"' + ' -ExtraArgument "IncidentFile=' + szIncidentFile + '"';
oShell.Run( szRAURL, 1, true );
objFSO.DeleteFile( szIncidentFile );
objSAFClassFactory.close();
return;
}
</script>
</head>
<body onload="onContinue();">
</body>
</html>

29.02.2008 - 14:01 Uhr

Du hast mehrere Möglichkeiten um das ganze zu lösen.

Eine Möglichkeit wäre das ganze über Assemblies anzugehen, du könntest z.B. anhand von Commands (Actions) in deinem Usercontrol einen ActionEventHandler deklarierst. Anhand eines gemeinsammen Schnittstellenprojektes das somit sowohl in dem UserControl wie in den Projekten der einzelnen AddIns referenziert ist könntest du dann einen PluginManager schreiben der eben diese Aktionen (deine Basisklassen oder Schnittstellen) beim das Laden über Assembly.Load initalisiert. Der Manager kümmert sich dann darum das die Aktionen je nach Basisklasse oder Schnittstelle entsprechend auf dem UserControl ausgeführt wird. Um das Laden innehralb der Manager Klasse zu realisieren kannst du eine Load Methode schreiben die z.B. über einen Filewatcher und eben beim Load Ereigniss im UserControl selbst aufgerufen wird.

Wenn nun anhand des FileWatcher oder der Load Methode in dieser Manager Klasse ein neues File angesprochen wird, sollte das erste sein wonach du suchst innehralb dieser Datei bzw. Assembly eine gemeinsamme Schnittstelle sein, z.B. IPlugin. IPlugin bietet dann einfach z.B. die Methode OnSetup an an der dann alle Menüs Zeichenroutinen usw. initalisiert werden die der Manager dann im UserControl eben realisiert. Wird nun eine Aktion seitens des AddIns ausgelöst wandert diese über eben das verknüpfte Command an das UserControl über die Managerklasse.

Der Vorteil wäre das dass UserControl nicht direkt in die AddIns referenziert wird und somit nicht direkt reingepfuscht werden kann - klar ist aber dass eine Assembly dann natürlich im selben Process aufgerufen wird und somit natürlich bei den verschiedenen Aktionen aufpassen musst ob diese etwas abarbeitet was dann die GUI blockieren könnte.

Du kannst das auch über Serialisierung gestallten, sogar deine Commands könntest dann serialisieren.

Für Pligin bzw. AddIn / AddOns gibt es viele Patterns, fand das Command Pattern bisher nur am einfachsten.

29.02.2008 - 13:03 Uhr

Hrm, bin leider in diesen Bereich nicht bewand und kenne auch das "Windows Hilfe und Support Center" nicht. Aber würde folgendes zuerst mal versuchen.
Statt einen Verweise auf die COM-Bibliotheken zu machen, würde ich eine Wrapper-Assembly verwenden. Diese erzeugst du über das Virsual Studio Tool "TLBIMP.EXE". Im Anschluss kannst du nach dem passenden Schema der COM-Interop-Assembly suchen und einbinden.

29.02.2008 - 11:36 Uhr

Phu machst es mir echt schwer sehe ansonsten den Fehler nicht. Habe etliche Hooks schon geschrieben auf den selben Weg wie du, allerdings eben über LoadLibrary auf deine "leichtere" Idee bin ich gar nicht gekommen. Allerdings nutzte ich lowlevel hooks also WH_KEYBOARD_LL und WH_MOUSE_LL aber das sollte keine Rolle spielen.-)

Ansonsten sollte es eigentlich so funktionieren wie du es geschrieben hast, direkt den Fehler sehe ich nicht. Machs einfach mal über LoadLibrary und eben über nen LowLevel hook und halt FreeLibrary. In google gibts da soviel Code dazu da lohnt es sich nicht das reinzuposten.

Aber falls es doch "so" hinkriegst wüsste ich gerne das "warum oder wie" 😮)

29.02.2008 - 11:25 Uhr

Höre zumeist Trance und Techno, am liebsten Lieder von Schiller.

/ps
Allerdings nicht das neuste 🙂

29.02.2008 - 11:10 Uhr

Hrm war zu lange nicht mehr in C++ unterwegs "APIENTRY " überlesen kannte das mit DllMain noch gar nicht sondern nur als APIENTRY WinMain. Auch wieder was gelernt 🙂

Hrm, dann wirds schwerer, versuch mal folgendes:


        BOOL APIENTRY DllMain( HINSTANCE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
        {

            switch (dwReason)
            {
                case DLL_PROCESS_ATTACH:
                    DisableThreadLibraryCalls(hModule);
                    g_hInst = hModule;
                    break;
                case DLL_THREAD_ATTACH:
                case DLL_THREAD_DETACH:
                    break;
                case DLL_PROCESS_DETACH:
                    if (g_hProc != NULL)
                        UninstallHook(g_hProc);
                    break;
            }
            return TRUE;
        }

Ansonsten, scheint alles korekt zu sein bzw, sehe nur das eben CallNextHookEx im C# code bei deinen hookCallback fehlt.


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

Ansonsten, kann mir nur schwer vorstellen das dieser Vorgang da er dann "Systemweit" gildet wegen den Sicherheitsbeschränkungen nicht funktioniert - das hebelst ja mit dem C++ Code ausser kraft da sollte der hookCallback auch in C# ausgeführt werden dürfen. Ansonsten, belasse ihn in C++ und mit PostMessage gibst dann einfach an das Handle an eines deiner Fenster/Controls das dann zur Auswertung nutzt in deinen C# Code die WindowsNachrichten weiter.

29.02.2008 - 10:52 Uhr

Der Code sieht zumindest sauber aus - vergewissere dich das in deiner .kdesigner Datei die Klasse MenuScreenEditor vom Typ MenuScreenInformation abgeleitet wurde oder falls es ein Interface sein sollte dieses implementiert. Ebenso ob einen parameterlosen public Konstruktor in der Klasse MenuScreenEditor vorhanden ist.

29.02.2008 - 10:41 Uhr

Hallo Rahvin,
leider sieht man im C++ Code den Abschnitt mit LoadLibrary nicht


	hDLL = LoadLibrary ("DeinDLLName.dll");
	HOOKPROC hProc =  (HOOKPROC)GetProcAddress (hDLL, "MouseProc");
	SetWindowsHookEx (WH_MOUSE, hProc , hDLL, 0);

Wo du den Funktionsaufruf für folgende Methode hast:


BOOL APIENTRY DllMain( HINSTANCE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    g_hInst = hModule;
 
    return TRUE;
}

Oder hast du die funktion ebenso über DLLEXPORT aufgerufen und füllst sie vom C# Code aus, wenn ja wie - Holst sie dir dann wie folgt?


Marshal.GetHINSTANCE(Assembly.Load("DeineDLL.DLL").GetModules()[0])

27.02.2008 - 17:02 Uhr

Hrm, hatte nur den Namespace flux in der MSDN eingegeben und das kleingedruckte überlesen. Wenn es den nur klein wäre 😮)

[Edit]Link eingefügt...

27.02.2008 - 15:37 Uhr

Hallo Videomawo,
also laut MSDN -> Microsoft Visual Studio 2008/.NET Framework 3.5 🙂

27.02.2008 - 15:26 Uhr

Hallo NeXoR.aT,

wenn es dir darum geht Texturen sei es nun im Bereich Skins zu designen reicht eigentlich Paint.NET ganz gut. Ist zwar nicht so "mächtig" wie Photoshop aber bietet genug Möglichkeiten für Bildbearbeitungen. Ausserdem ists kostenlos 🙂

Wenn es dir um den Bereich Spieleentwicklung und Raumdimensionen defiitionen geht fand ich 3DStudio Max immer gut, hantierte allerdings auf ner alten Version herum. Was die 3DS Max 9 auf dem Kasten hat weis ich leider nicht. Hatte mich da nur mal mit Direct3D beschäftigt 🙂

27.02.2008 - 14:52 Uhr

Hallo kaepten,

volatile kommt relativ selten vor, muss zugeben hatte bisher nie den Fall das ich es gebraucht hätte. Volatile ist nichts anderes als ein synchron gehaltenes object das man wenn überhaupt in Multithreading-Anwendungen findet. Was man dabei beachten sollte das lokale Variablen nicht als volatile deklariert werden können und eben bei übergaben wie ref Fehler auslösen. Wobei ich jetzt auch nicht zu 100% sicher bin ob in und out davon auch betroffen sind - nie probiert.

Denke mal hattest die englische MSDN Seite aufgerufen finde es da etwas "schwieriger" erklärt. Die Deutsche Seite ist da besser.

Ein Anwendungsfall wäre z.B. ne Liste die von mehreren Threads befüllt oder verändert wird. Aber schrieb da meistens lieber ein lock hin 🙂

/ps
Denke wenn einfach mal im Forum "volatile" in die Suche eingibst wird es da sicher einige Treffer geben mit Beispielen geben.

[Edit] Den etwas schwerfälligen Satzbau verändert 😉

27.02.2008 - 13:32 Uhr

Hallo Cyron.

Anhand von WMI solltest du über das Stichwort Win32_Process fündig werden. Auch hier im Forum sollte es bereits etliche Beiträge geben 🙂

27.02.2008 - 13:24 Uhr

Hallo Walter,

zwar hast du ein anderes Problem aber die Lösung dazu ist die selbe wie in diesen Thread. Nutze den Link zu Codeprojekt lade dir das sampleprogramm runter und beachte den letzten Post von mir beginnend ab Punkt2. Mit der OnPaint Methode ist es dir dann möglich deinen Text selbst drauf zu zeichnen oder ein Control wie z.B. TextBox darauf zu setzen und dieses dann zu nutzen. Denk dran, wirst einiges noch selber dazu machen müssen, das ganze zeigt nur den Weg auf und ist kein fertiges Produkt.

27.02.2008 - 13:17 Uhr

Dafür gibt es viele Möglichkeiten, denke aber meinst damit sicher einen ToolTip. Dazu gibt es im Forum viele Beiträge 🙂

27.02.2008 - 12:37 Uhr

Die Klasse String hat die Schnittstellen IComparable<string> bzw. IComparable implementiert.

Du kannst daher ganz normal Array.Sort dafür verwenden.
Oder anders mal aufgezeigt auch wenn es umständlich ist im "Prinzip" das selbe:


 private string[] GetSorted()
        {
            string[] myArrays = new string[] { "Hugo", "Jürgen", "Hans", "Barni" };
            Array.Sort<string>(myArrays, new CFilter().Compare);

            foreach (string _st in myArrays)
                Console.WriteLine(_st);
            
            return myArrays;

        }

        private class CFilter : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                return string.Compare(x, y);
            }
        }

Ausgabe:


Barni
Hans
Hugo
Jürgen

27.02.2008 - 12:18 Uhr

Hallo plugnpray,

Vorweg, ich versuche es einfach auszudrücken nur damit das Verständniss da ist.

Die erste Möglichkeit zur Fehlerbehebung:
Über NativeWindow ist es dir möglich ein neue "Klasse" zu erstellen hierzu benötigt es die typischen Angaben über Borderstyles wie verhalten, der Klasse. Das geschieht über CreateParams. Somit ist es somit möglich Controls bzw Forms zu erstellen (eigentlich ists ja sowieso ein und das selbe).

1.)
Wenn dir also die Methode "CreateTool" in der Klasse MessageBalloon ansiehst wirst dort bei CreateParams den Klassennamen entdecken wie die Styles. Du wirst dort den Style "TTS_CLOSE" vorfinden der für den schließen Button verantwortlich ist auch für dessen darstellung. Wenn du den eintrag nicht findest (warum auch immer, evtl durchs kopieren) füge ihn hinzu.

2.) Wenn der parameter TTS_CLOSE da sein sollte und dennoch nichts passiert dann mach folgendes. Wir erstellen ein eigenes Control indem wir unsere WindowsNachrichten nach aussen legen so wie bei einen Standardcontrol.

Nun wird es leider kompliziert 🙂

Okay, erweitere die MessageTool Klasse um folgendes:


internal class MessageTool : NativeWindow
	{
		private const int WM_LBUTTONDOWN = 0x0201;
		public event DeActivateEventHandler DeActivate;

        public delegate void WndProcEventHandler(Message m);
        public event WndProcEventHandler WndProcEvent;
		
		protected override void WndProc(ref System.Windows.Forms.Message m)
		{
            if (this.WndProcEvent != null)
                this.WndProcEvent(m);

			if( m.Msg == WM_LBUTTONDOWN )
			{
				System.Diagnostics.Debug.WriteLine(m);
				// allow the balloon to close if clicked upon
				if(DeActivate!=null)
				{
					DeActivate();
				}
			}

			base.WndProc(ref m);
		}
	}

Soo der nächste Schritt, schmeiß in der Methode "CreateTool" in der Klasse MessageBalloon folgendes raus:


CreateParams cp = new CreateParams();
			cp.ClassName = TOOLTIPS_CLASS;
			cp.Style = 
				WS_POPUP | 
				TTS_BALLOON | 
				TTS_NOPREFIX |	
				TTS_ALWAYSTIP;
                //|
				//TTS_CLOSE;

Soo als nächstes fügst du den Eventhandler an geh in die Methode "CreateTool" in der Klasse MessageBalloon und füge folgendes "am Ende" hinzu:


 this.m_tool.WndProcEvent += new MessageTool.WndProcEventHandler(this.WndProc);

Nun erstellst du noch folgende Methoden in der Klasse MessageBalloon


       protected virtual void OnPaint(Graphics e)
        {

        }

        protected virtual void WndProc(Message m)
        {
            if (m.Msg == WM_PAINT)
            {
                using(Graphics gfx = Graphics.FromHwnd(m.HWnd))
                {
                    this.OnPaint(gfx);
                }
            }
        }

Du kannst nun etwas weiter in der Klasse aufräumen, usw. Nun hast du eine wirkliches "UserControl" mit einen WndProc und einer OnPaint Methode die du jetzt nach herzenslust übermalen kannst. Denk dran, zu einem "echten" UserControl gehört meiner Meinung nach noch das Property Controls das noch anfügen solltest. Über Win32 API SetParent und SetWindowPos kannst du dann die Controls wirklich mit einbinden auf das Handle von deinem eigenen ToolTip.

Hoffe dir ist klar was ich meinte, hier tue ich mich etwas schwer das ganze zu erklären denke als nicht Studierter fehlen mir da die Fachbegriffe 🙂

27.02.2008 - 11:33 Uhr

Huch, hatte nicht so genau hingesehen, hattest ja schon einen post erstellt. Aufpassen wegen Crosspostings 😉

[Edit, schreibe lieber mehr dazu in den anderen Thread, besser wäre es die beiden zusammenzufügen]

27.02.2008 - 11:17 Uhr

Bin mir nicht sicher aber glaube deie string parameter könnten evtl in VBA anders intepretiert werden - bin mir da etwas unsicher was das angeht aber probieren kann ja nicht schaden .-)


[DllImport(dllFile, EntryPoint = "@init_table$qqsiususucuspct6t6", CharSet=CharSet.Unicode, ExactSpelling=true))]
        private static extern int init_table(int baud, int globalmask, int lokalmask, byte arbit, int Arbitvalue, string pfad, string pfad1, string pfad2);

27.02.2008 - 11:04 Uhr

Denke postest am besten mal die stelle deines Background Workers, mich würde vorallem deine Endlosschleife interessieren 😉

27.02.2008 - 10:06 Uhr

Hallo plugnpray,
dafür gibt es mehrere Möglichkeiten die Frage was Sinn macht musst du dir dann selber stellen.

Es gibt die Möglichkeit z.B. die NotifyMessage in den entsprechenden Controls die du verwendest über die WndProc abzufangen, dafür musst du aber jeweils eine neue Klasse erstellen von den jweiligen Control ableiten und base.SetStyle(ControlStyles.EnableNotifyMessage, true) aktivieren und die WindowsNachrichten mit private const UInt32 WM_NOTIFY = 0x004E; abfangen und über www.pinvoke.net holst dir das struct NMCUSTOMDRAW und mit Marshal.PointToStructure kannst es dann mit dem LParam auslesen. Anhand des NMCUSTOMDRAW.RECT kannst dann mit new Region(Rect.ToRectangle).IsVisible() und der WindowsNachricht WM_LBUTTONDBLCLK kannst du dann prüfen ob die angeklickte Bereich der des ToolTips entspricht. Somit wüsstest du das dass "vom Control gezeichnete" ToolTip (das kein Handle besitzt) mit der linken Maustaste angeklickt wurde. Allerdings darfst nicht vergessen, das dass ToolTip wieder verschwindet. Würde vermuten das dann WM_NOTIFY über LParam einfach IntPtr.Zero zurückgibt, somit wäre dann ja klar, das dass ToolTip nicht angezeigt wird. Um das nun sauber umzusetzen würde ich eine neue Klasse erstellen von ToolTip ableiten und das Popup Event initalisieren um mal zu schauen ob der sender = dem Control entspricht. Somit sollte das ganze via SubClasing recht sauber zu lösen sein.

Oder du gehst auf Codeproject da gibts CustomToolTips die so gestalltet wurden das leichter an die Mausklick funktion rankommst. Würde fast eher dazu tendieren, glaube sollte weniger Zeit in anspruch nehmen als der erste Lösungsweg.

/ps
Hrm, glaube wenn ich den Quellcode gleich gepostet hätte, wäre ich schneller gewesen den Beitrag zu ende zu stellen als dass Vorgehen herunter zu tippen 😉

27.02.2008 - 08:35 Uhr

Du könntest die Nodes selbst zeichnen, dazu gibt es einige Threads hier im Forum. Um dann an den ParentNodes Images zu zeichnen. Allerdings musst dir hierfür ein Krieterium einfallen lassen z.B. wenn Parent == null ist wüsstest z.B. das es sich um eine ParentNode handelt (musst ausprobieren, sieht ja recht fix).

27.02.2008 - 08:26 Uhr

Hallo Nargaff,

eine Funktion oder ein Property das dir die Sortierten Items zurückliefert ist mir leider nicht bekannt.

Aber um dennoch dieses zu implementieren würde ich folgendes für die Sortierung nachprogrammieren: Link. Auch wenn es zuerst den Anschein hat das dies Sinnlos erscheinen mag. Da ja standardmäßig bereits eine Sortierung anhand von ListView.Sorting = SortOrder.Ascending; und ListView.Sort(); vornehmen kannst. Macht es dennoch Sinn die Sortierungsalgorithmen dafür selbst zu schreiben, denn du kannst anhand dessen über Array.Sort() die Sorted Items ermitteln. Schön wäre es das ganze noch in einer neuen Klasse die von ListView abgeleitet wurde zu implementieren und dort dann das Property SortedItems zur verfügung zu stellen, die dir eben dieses sortierte Array zurück gibt.


        public ListViewColumnSorter m_clSorter; // <-- siehe dazu den Link zur MSDN Seite.
        public ListViewItem[] SortedItems
        {
            get
            {
                ListViewItem[] array = new ListViewItem[base.Items];
                base.Items.CopyTo(Copy, 0);
                Array.Sort<ListViewItem>(array, m_clSorter.Compare);
                return array;
            }
        }

/PS
(Im Editor geschrieben, Fehler daher nicht ausgeschlossen).

27.02.2008 - 07:44 Uhr

Hallo Schnuki (hrhr netter Nick) 😉

Ich denke das es dir etwas zu kompliziert gestalltest. norman_timo hat schon recht was die generischen Listen angeht, das würde dir deinen Code knapp um die Hälfte reduzieren und wäre weniger Fehleranfällig - damit meine ich expliziet die string Arrays wie dateien und plugins die später eine feste größe von 100 besitzen aber vielelicht irgendwann mal größer ausfallen könnten oder du hast schlussendlich grade mal 5 Dateien und 95 null Werte. Ebenso brauchst eigentlich keine Schleifen um schlussendlich nur den Namen eines Plugins zu ermitteln. Eigentlich kannst das alles mit weniger code gleich in getCustomFiles erledigen. Also, z.B. bei deiner dritten Schleife indem die Dateien füllst. Du kannst gleich dann über die List<string> m_sDateienList dann über m_sDateienList.Contains() das ganze Abfragen. Wobei ich finde das dass eigentlich schon ein Fehler wäre. Da eigentlich eine Hilfsklasse dafür nutzen solltest indem dir dort dann den kurzen Namen und den Pfadnamen merken solltest - den ein Dateiname kann wirklich zweimal vorkommen. Den kurzen Dateinamen brauchst auch nicht über Substring zu suchen denn über System.IO.FileInfo bekommst du ja schon den Name (ohne Pfad) wie den FullName (mit Pfad).

26.02.2008 - 17:07 Uhr

Hrm, sehe leider den dafür verantwortlichen Fehler nicht. Habe mal versucht das ganze ca. wie deine Screenshoots nachzubilden und klappte eigentlich ganz gut.

Die größen breiten der Spalten und der Zellen sind quasi egal, die Standardscrolleisten werden normal über Control Add hinzugefügt und besitzen daher ihre eigene verarbeitung der WindowsNachrichten. Daher, selbst wenn die OnPaint Methode überschreibst und base.Paint ausklammern würdest. Würden die Scroulleisten dennoch korrekt dargestellt werden.

Tut mir leid sehe leider den Fehler nicht, fügst du evtl. deine eigene Scrolbar an oder hantierst mit denen speziell herum (Denke aber mal, wirst nur für das Invalidate nen Methodenaufruf haben) ?

25.02.2008 - 16:13 Uhr

Bin leider kein so großer erklärbar aber man kann das relativ leicht an einen Beispiel sehen.

Angenommen du frägst nach einer Klasse ab die "Null" sein könnte aber möchtest ebenso abfragen ob ein Proeprty innerhalb dieser Klasse einen bestimmten Wert hat.

Bei der doppelten "Und Und" Anweisung "&&" wird der zweite Wert nur dann überprüft wenn der erstere bereits "true" zurückgibt.

Also Beispiel:


   Form form = null;

            if (form != null && !form.ShowIcon)
                Console.Write("Kein Fehler");

            if (form != null & !form.ShowIcon) <-- Compiler meldet Fehler
                Console.Write("Fehler: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.");

Bei doppelter veroderung also || gilt genau das selbe.

25.02.2008 - 14:27 Uhr

Also @"&quot; ist genau das selbe wie "\" daher bringt ein Replace ja nichts.
Der string bei der Ausgabe (z.B. Console) wird dann somit auch wieder zu "&quot;.

Daher string a = "c:\pfad\pfad\pfad\pfad\pfad\\dateiname";
wird zu "c:\pfad\pfad\pfad\pfad\pfad\dateiname". Die Frage ist nur, was passiert bei der Datenbankabfrage also deiner löschsyntax wird da "\" auch als "&quot; interpretiert?

25.02.2008 - 13:55 Uhr

Auch wenn ich das Problem irgendwie nicht so ganz recht verstehe (kann es nicht rekonstruieren).

Hier ein Link zu einem Artikel der genauer erklärt was ich meinte 🙂

Hatte diesen Artikel nicht gesehen, sonst hätte ich ihn früher gepostet.
Musst dann einfach noch das ergänzen was dir herbivore schrieb, unter www.pinvoke.net findest den DLLImport dazu 🙂

25.02.2008 - 12:41 Uhr

Leider wird das schwierigste dabei das finden des Dialoghandels sein.

Würde hierfür sogar ne eigene Klasse erstellen, eine statische Methode die genau der des Dialogs entspricht einfügen und bevor ich dann dort den Dialog aufrufe, einen WndProc Hook auf den Current Thread schreiben. Dort dann WM_CREATE abfangen da man ja weis das WM_CREATE genau zum Zeitpunkt des Aufrufs der Methode gestartet wird kannst mit 100%iger sicherheit davon ausgehen das WM_CREATE genau das Handle des Dialogs zurück gibt.

Wenn wie gesagt eh in dieser Klasse die Statische Methode implementierst kannst ja als übergabeparameter gleich die X und Y Koordinaten mit angeben so das gleich nachdem WM_CREATE abgefangen hast über das gefundene Handle SetWindowPos aufrufen kannst und eben an diese X und Y weiterreichst.

25.02.2008 - 12:29 Uhr

Achso, naja instanzieren kannst das Ding dann sowieso nicht, man ruft ja nur die darin statischen Member oder Methoden usw. auf.
Siehe dazu MSDN 🙂

Denke da solltest einfach eine Methode schreiben dürfen und eben das Atribut SetUp drüber setzten dürfen. Innerhalb der Methode rufst du dann halt von deiner statischen Klasse die entsprechenden Methoden auf.

/ps
Kenne allerdings NUnit nicht so wirklich 😠

25.02.2008 - 12:14 Uhr

Hallo DavidT,
leider weis ich gerade nicht genau was du mit testen meinst 🙂

Denke aber wenn es dir ums instanzieren geht von einer Statischen Klasse wie z.B. einer Singleton. Kannst das auf viele Arten lösen.

Mache das meistens über nen Property:


private static CClass m_clClass;

   public static CClass Instance
        {
            get
            {
                return (m_clClass != null)? m_clClass : new CClass ();
            }
        }

Um zu verhindern das sie ausserhalb instanziert werden kann und um damit verbundene Fehler zu vermeiden wird der Konstruktor private. Mit CClass.Instance kann die Klasse dann angesprochen werden und falls sie noch nicht instanziert wurde geschieht das zum ersten Zeitpunkt an dem sie aufgerufen wird.

22.02.2008 - 19:40 Uhr

Hrm, ich vermute nur mal was er meint.

Man kann statt eines Nodes auch ne Klasse via Databinding binden und macht keine beziehung zu Membern. Stattdessen schreibt man in der Klasse ein Property Namens Index und beim Binden der Daten wird Index automatisch an den Member ImageIndex gebunden. Das selbe gilt wenn man Image schreibt, das wird automatisch dann als Bild genutzt. Weis nicht ob das Heute noch Funktioniert.

Aber glaube eher das es eine ImageCollection gibt die das ganze vereinfacht als diesen komplizierten Weg. Bzw. vielleicht gibt es ja Standardicons und man muss diese mal ausprobieren indem einfach mal statt -1 ne 1 eingibst. Wenn der compiler meckert weist ja das irgendwie noch was fehlt 🙂

22.02.2008 - 19:31 Uhr

Hrm, denke da reicht auch nen Invalidate dann.
Habe mir zwar das Codeproject sampple nciht angesehen aber schätze das einfach an ner bestimmten Stelle die Zeichenroutine nicht angestoßen wird (daher Invalidate).