Wrox Programmer Forums
Go Back   Wrox Programmer Forums > C# and C > C# 1.0 > C#
|
C# Programming questions specific to the Microsoft C# language. See also the forum Beginning Visual C# to discuss that specific Wrox book and code.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old July 27th, 2004, 04:07 PM
Registered User
 
Join Date: Jul 2004
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default Pinvoke problems

Hi,

Ive only been using C# for about a week as im a vc++ programmer so have spent a lot of time ( as probally have many people converting from vc++ ) trying to replace a lot of the functionality that seems to be missing from the .net framework clr.

The project I'm working on at the moment is to provide a lot of the win32 api functionality to console applications, such as clearing the screen, colour output, and getch() style input, positional output and mouse functions.

The majority of the code has completed nicely but i have 2 problems that I hope someone with a little more experience will be able to help me on.

I have had to convert the INPUT_RECORD structure from C to a c# types. I think I have somthing wrong with this structure as the InputRecord.Event.MouseEvent.dwMousePosition.y member is always empty, and the InputRecord.Event.MouseEvent.dwMousePosition.x member seems to be filled with the y coord, not the x.

The structure I have defined is as follows:

[StructLayout(LayoutKind.Sequential)]
        public struct COORD
        {
            public short x;
            public short y;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _uChar
        {
            public char UnicodeChar;
            public char AsciiChar;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _MOUSE_EVENT_RECORD
        {
            public COORD dwMousePosition;
            public uint dwButtonState;
            public uint dwControlKeyState;
            public uint dwEventFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _KEY_EVENT_RECORD
        {
            public bool bKeyDown;
            public ushort wRepeatCount;
            public ushort wVirtualKeyCode;
            public ushort wVirtualScanCode;
            public _uChar uChar;
            public uint dwControlKeyState;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _WINDOW_BUFFER_SIZE_RECORD
        {
            public COORD dwSize;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _MENU_EVENT_RECORD
        {
            public uint dwCommandId;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _FOCUS_EVENT_RECORD
        {
            public bool bSetFocus;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _INPUT_RECORD
        {
            public ushort EventType;
            public _Event Event;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct _Event //this was a union hence the 0 offset
        {
            [FieldOffset(0)]public _KEY_EVENT_RECORD KeyEvent;
            [FieldOffset(0)]public _MOUSE_EVENT_RECORD MouseEvent;
            [FieldOffset(0)]public _WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
            [FieldOffset(0)]public _MENU_EVENT_RECORD MenuEvent;
            [FieldOffset(0)]public _FOCUS_EVENT_RECORD FocusEvent;
        }


The original structure was defined in wincon.h as follows:

typedef struct _COORD {
    SHORT X;
    SHORT Y;
} COORD, *PCOORD;

typedef struct _KEY_EVENT_RECORD {
    BOOL bKeyDown;
    WORD wRepeatCount;
    WORD wVirtualKeyCode;
    WORD wVirtualScanCode;
    union {
        WCHAR UnicodeChar;
        CHAR AsciiChar;
    } uChar;
    DWORD dwControlKeyState;
} KEY_EVENT_RECORD, *PKEY_EVENT_RECORD;

typedef struct _MOUSE_EVENT_RECORD {
    COORD dwMousePosition;
    DWORD dwButtonState;
    DWORD dwControlKeyState;
    DWORD dwEventFlags;
} MOUSE_EVENT_RECORD, *PMOUSE_EVENT_RECORD;

typedef struct _WINDOW_BUFFER_SIZE_RECORD {
    COORD dwSize;
} WINDOW_BUFFER_SIZE_RECORD, *PWINDOW_BUFFER_SIZE_RECORD;

typedef struct _MENU_EVENT_RECORD {
    UINT dwCommandId;
} MENU_EVENT_RECORD, *PMENU_EVENT_RECORD;

typedef struct _FOCUS_EVENT_RECORD {
    BOOL bSetFocus;
} FOCUS_EVENT_RECORD, *PFOCUS_EVENT_RECORD;

typedef struct _INPUT_RECORD {
    WORD EventType;
    union {
        KEY_EVENT_RECORD KeyEvent;
        MOUSE_EVENT_RECORD MouseEvent;
        WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
        MENU_EVENT_RECORD MenuEvent;
        FOCUS_EVENT_RECORD FocusEvent;
    } Event;
} INPUT_RECORD, *PINPUT_RECORD;


If you can see anything wrong with my structure conversion please let me know as im pulling my hair out.

The function is question is as follows:

[DllImport("kernel32.dll", EntryPoint="ReadConsoleInput", SetLastError=true,
             CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
        private static extern bool ReadConsoleInput(int hConsoleInput,
            ref _INPUT_RECORD buf, int nNumberOfCharsToRead, ref int lpNumberOfCharsRead);

Where buf is a INPUT_RECORD structure passed by reference ( instead of the pointer requested by the original function definition )

Which leads me to my second question, at the moment that function is retreaving one input event at a time, really i need to be able to recieve all unhandled events on the buffer. to do this i would need an array of INPUT_RECORD structures such as
_INPUT_RECORD[] buf = new _INPUT_RECORD[128];
Is it possible for me to pass this array of structures by ref to the Pinvoked function, as if i try this I get an interop incompatible error. Can I use pointers in C# interop code ?

If anyone has any ideas please let me know.

Thanks :D
Gav
 
Old July 27th, 2004, 05:24 PM
Registered User
 
Join Date: Jul 2004
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

ive seen a problem with my structure:
The Uchar structure was infact a union so should be formated :

[StructLayout(LayoutKind.Explicit)]
public struct _uChar
{
    [FieldOffset(0)]public char UnicodeChar;
    [FieldOffset(0)]public sbyte AsciiChar;
}

or so I would have thought but this gives me a can not load type uChar error.

Any ideas please.

 
Old July 27th, 2004, 05:55 PM
Registered User
 
Join Date: Jul 2004
Posts: 4
Thanks: 0
Thanked 0 Times in 0 Posts
Default

ok this is what i finished up with and everything seems to work now :). I had a few errors in the type conversions.

[StructLayout(LayoutKind.Sequential)]
        public struct COORD
        {
            public short x;
            public short y;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct _uChar
        {
            [FieldOffset(0)]public char UnicodeChar;
            [FieldOffset(2)]public sbyte AsciiChar;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _MOUSE_EVENT_RECORD
        {
            public COORD dwMousePosition;
            public uint dwButtonState;
            public uint dwControlKeyState;
            public uint dwEventFlags;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _KEY_EVENT_RECORD
        {
            public bool bKeyDown;
            public ushort wRepeatCount;
            public ushort wVirtualKeyCode;
            public ushort wVirtualScanCode;
            public _uChar uChar;
            public int dwControlKeyState;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _WINDOW_BUFFER_SIZE_RECORD
        {
            public COORD dwSize;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _MENU_EVENT_RECORD
        {
            public int dwCommandId;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _FOCUS_EVENT_RECORD
        {
            public int bSetFocus;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct _INPUT_RECORD
        {
            public ushort EventType;
            public _Event Event;
        }

        [StructLayout(LayoutKind.Explicit)]
        public struct _Event
        {
            [FieldOffset(0)]public _KEY_EVENT_RECORD KeyEvent;
            [FieldOffset(0)]public _MOUSE_EVENT_RECORD MouseEvent;
            [FieldOffset(0)]public _WINDOW_BUFFER_SIZE_RECORD WindowBufferSizeEvent;
            [FieldOffset(0)]public _MENU_EVENT_RECORD MenuEvent;
            [FieldOffset(0)]public _FOCUS_EVENT_RECORD FocusEvent;
        }

still not to sure about the uChar bit, but it seems to work. and would still appreciate any ideas on the passing arrays of structures to external interop functions by reference.

Thanks
Gav






Similar Threads
Thread Thread Starter Forum Replies Last Post
2 problems here with me naveed77 Beginning VB 6 1 October 17th, 2006 06:04 PM
PInvoke jack_3 Visual C++ 1 November 26th, 2005 03:21 AM
PInvoke jack_3 C# 0 November 25th, 2005 08:02 PM
validate.asp problems and logon.asp problems p2ptolu Classic ASP Databases 0 February 16th, 2005 02:34 PM
Error: Invalid PInvoke metadata format shahchi1 General .NET 1 May 26th, 2004 08:16 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.