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
|