Laden...

[gelöst] Struktur und DllImport

Erstellt von norman_timo vor 17 Jahren Letzter Beitrag vor 17 Jahren 2.851 Views
norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 17 Jahren
[gelöst] Struktur und DllImport

Hallo alle PInvoke Spezialisten,

ich würde gerne folgendes realisieren:


        [DllImport("user32.dll", SetLastError=true)]
        internal static extern int GetScrollInfo(int hwnd, int nBar, ref SCROLLINFO scrInfo);

        [DllImport("kernel32.dll")]
        internal static extern int GetLastError();

        /*
            typedef struct tagSCROLLINFO { 
                UINT cbSize; 
                UINT fMask; 
                int  nMin; 
                int  nMax; 
                UINT nPage; 
                int  nPos; 
                int  nTrackPos; 
            }   SCROLLINFO, *LPSCROLLINFO; 
         */
        
        public struct SCROLLINFO
        {
            public UInt32 cbSize;
            public UInt32 fMask;
            public Int32 nMin;
            public Int32 nMax;
            public UInt32 nPage;
            public Int32 nPos;
            public Int32 nTrackPos;
        }

// ...

            // get scroll range from standard scrollbar
            SCROLLINFO scrInfo = new SCROLLINFO();

            int result = GetScrollInfo(Handle.ToInt32(), SB_CTL, ref scrInfo);
            if (result == 0)
            {
                result = GetLastError();
            }

            // set minimum/maximum of Vepro scrollbar
            m_HScrollbar.Minimum = minVal.ToInt32();
            m_HScrollbar.Maximum = maxVal.ToInt32();

Allerdings schlägt die Methode GetScrollInfo() mit dem Fehlercode 1008 fehl.

Fehlercodebeschreibung:

ERROR_NO_TOKEN
1008 An attempt was made to reference a token that does not exist.

Was bedeutet das nun für mich?

Hab ich etwas an der Struktur falsch gemacht, oder bedeutet das, dass die DLL-Methode einen "natürlichen" Fehler liefert, und wenn dies ein "natürlicher" Fehler ist, was bedeutet dieser dann?

Für Hilfe wäre ich sehr dankbar...

Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

369 Beiträge seit 2006
vor 17 Jahren

Probier mal folgendes Attribut vor die SCROLLINFO Struktur zu setzen: [StructLayout(LayoutKind.Sequential)]

/edit: natürlich nicht explicit sondern Sequential

308 Beiträge seit 2005
vor 17 Jahren

So nutz microsoft das:

NativeMethods.SCROLLINFO :


[StructLayout(LayoutKind.Sequential)]
public class SCROLLINFO
{
      public int cbSize;
      public int fMask;
      public int nMin;
      public int nMax;
      public int nPage;
      public int nPos;
      public int nTrackPos;
      public SCROLLINFO();
      public SCROLLINFO(int mask, int min, int max, int page, int pos);
}

Die "safe" Variante:


[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern bool GetScrollInfo(HandleRef hWnd, int fnBar, [In, Out] NativeMethods.SCROLLINFO si);

und nochmal "unsafe":


[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern bool GetScrollInfo(HandleRef hWnd, int fnBar, NativeMethods.SCROLLINFO si);

3.170 Beiträge seit 2006
vor 17 Jahren

Hallo,
aus demr Platform SDK-Doku

SB_CTL
Retrieves the parameters for a scroll bar control. The hwnd parameter must be the handle to the scroll bar control.

Wenn ich das richtig sehe will die Methode einen Handle auf die Scrollbar selbst, du übergibst aber einen Handle zum Fenster...

Non quia difficilia sunt, non audemus, sed quia non audemus, difficilia sunt! - Seneca

norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 17 Jahren

Hallo zusammen,

alles nicht die Lösung die ich gebraucht hab 😉
[Cadi hat aber hier die korrekte Übersetzung native->managed gezeigt, Danke!]

Zunächst, ist es richtig, dass ich überall Integer verwenden muss, also so:



        [DllImport("user32.dll", SetLastError=true)]
        internal static extern int GetScrollInfo(int hwnd, int nBar, ref SCROLLINFO scrInfo);

        [DllImport("kernel32.dll")]
        internal static extern int GetLastError();

        /*
            typedef struct tagSCROLLINFO { 
                UINT cbSize; 
                UINT fMask; 
                int  nMin; 
                int  nMax; 
                UINT nPage; 
                int  nPos; 
                int  nTrackPos; 
            }   SCROLLINFO, *LPSCROLLINFO; 
         */

        private const int SIF_TRACKPOS = 0x10;
        private const int SIF_RANGE = 0x1;
        private const int SIF_POS = 0x4;
        private const int SIF_PAGE = 0x2;
        private const int SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS;
        
        public struct SCROLLINFO
        {
            public int cbSize;
            public int fMask;
            public int nMin;
            public int nMax;
            public int nPage;
            public int nPos;
            public int nTrackPos;
        }


ABER: bevor ich die Methode GetScrollInfo aufrufe, muss ich 2 Werte in meinem Struct setzen:



            // get scroll range from standard scrollbar
            SCROLLINFO scrInfo = new SCROLLINFO();
            scrInfo.fMask = SIF_ALL;
            scrInfo.cbSize = Marshal.SizeOf(scrInfo);
            
            int result = GetScrollInfo(Handle.ToInt32(), SB_HORZ, ref scrInfo);
            if (result == 0)
            {
                result = GetLastError();
            }


Deshalb hat der Aufruf nicht geklappt.

Vielen Dank für Eure Hilfe trotzdem.

@Mars Stein:

ja zunächst erwartet die Funktion ein Handle auf eine Scrollbar, jedoch weiter unten in der Doku:

If the fnBar parameter is SB_CTL and the window specified by the hwnd parameter is not a system scroll bar control, the system sends the SBM_GETSCROLLINFO message to the window to obtain scroll bar information. This allows GetScrollInfo to operate on a custom control that mimics a scroll bar. If the window does not handle the SBM_GETSCROLLINFO message, the GetScrollInfo function fails.

Grüße
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

369 Beiträge seit 2006
vor 17 Jahren

Du solltest dennoch folgene Methodensignatur verwenden:

internal static extern int GetScrollInfo(IntPtr hwnd, int nBar, ref SCROLLINFO scrInfo);

Hintegrund: Der WinAPI Datentyp HWND ist letztendlich ein Zeiger, der Plattformabhängig entweder 32 oder 64bit länge hat!

/edit: und du könntet als Rückgabewert auch direkt bool verwenden.

norman_timo Themenstarter:in
4.506 Beiträge seit 2004
vor 17 Jahren

Hallo Kabelsalat,

danke für den Hinweis, ist schon berücksichtigt 😉

Gruß
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”