Native Code RegisterClass function

B

Bebel

Hello,

I tried to register my own window class by using the RegisterClass function
of lib CoreDll.dll in Visual Basic for Visual Studio.net 2008. My Device is a
Windows Mobile 5 device. Each time I tried to register, I received a
System.NotSupportedException message. Why?

regards,

'Declarations:

<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True,
EntryPoint:="RegisterClass")> _
Friend Shared Function RegisterClassW(ByRef lpwcx As WindowClass) As
Integer
End Function

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure WindowClass
Public style As UInteger
Public Delegate Sub lpfnWndProc()
Public cbClsExtra As Integer
Public cbWndExtra As Integer
Public hInstance As IntPtr
Public hIcon As IntPtr
Public hCursor As IntPtr
Public hbrBackground As IntPtr
<MarshalAs(UnmanagedType.LPStr)> _
Public lpszMenuName As String
<MarshalAs(UnmanagedType.LPStr)> _
Public lpszClassName As String
End Structure


'Code:

Dim hInstance As IntPtr = NativeMethods.GetModuleHandle(Nothing)
Dim wndclass As NativeMethods.WindowClass = New
NativeMethods.WindowClass
With wndclass
.hInstance = hInstance
.cbClsExtra = 0
.cbWndExtra = 0
.hCursor = Nothing
.hIcon = Nothing
.hbrBackground = NativeMethods.COLOR_WINDOW
.style = NativeMethods.CS_DBLCLKS
.lpszMenuName = Nothing
.lpszClassName = "Test"
End With

Dim classAtom As Integer =
NativeMethods.RegisterClassW(wndclass)
If classAtom = 0 Then
Dim err As Integer = Marshal.GetLastWin32Error()
Throw New Win32Exception(err, "Enregistrement de la
classe impossible.")
End If

thnk you for your help,

regards
 
B

Bebel

Hello,

I have also tried do define the WNDClass structure as follow, and still get
a NotSupportedException:
'Declarations:

Public Delegate Function WndProcCallback(ByVal hWnd As IntPtr, ByVal msg
As UInteger, ByVal wparam As IntPtr, ByVal lparam As IntPtr) As IntPtr

<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)> _
Public Structure WindowClass
Public style As UInteger
Public lpfnWndProc As WndProcCallback
Public cbClsExtra As Integer
Public cbWndExtra As Integer
Public hInstance As IntPtr
Public hIcon As IntPtr
Public hCursor As IntPtr
Public hbrBackground As IntPtr
<MarshalAs(UnmanagedType.LPStr)> _
Public lpszMenuName As String
<MarshalAs(UnmanagedType.LPStr)> _
Public lpszClassName As String
End Structure


'Code:

With wndclass
.hInstance = hInstance
.cbClsExtra = 0
.cbWndExtra = 0
.hCursor = Nothing
.hIcon = Nothing
.lpfnWndProc = AddressOf Callback
'.cbSize = Marshal.SizeOf(wndclass)
.hbrBackground = NativeMethods.COLOR_WINDOW
.style = NativeMethods.CS_DBLCLKS
.lpszMenuName = Nothing
.lpszClassName = "Test"
End With


Dim classAtom As Integer = NativeMethods.RegisterClassW(wndclass)
If classAtom = 0 Then
Dim err As Integer = Marshal.GetLastWin32Error()
Throw New Win32Exception(err, "Enregistrement de la
classe impossible.")
End If


Private Function Callback(ByVal hWnd As IntPtr, ByVal msg As UInteger,
ByVal wparam As IntPtr, ByVal lparam As IntPtr) As IntPtr
Dim message As Message = message.Create(hWnd, CType(msg,
Integer), wparam, lparam)
Try
Me.WndProc(message)
Catch ex As Exception
Throw
End Try
If msg = 130 Then
Me.ReleaseHandle()
End If

Return message.Result
End Function


Thank you,

regards
 
C

Chris Tacke, eMVP

I'm telling you, it's that delegate. You need to get the proc address for
the delegate and pass that as an IntPtr - the CF marshaler just is not going
to pass the delegate directly across (not sure the FFx one would either).


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Giving back to the embedded community
http://community.OpenNETCF.com
 
B

Bebel

Hi Chris,

I tried to replace in the WindowClass structure the delegate by an IntPtr
and In my code I did the following call:

Dim mycallback As WndProcCallback = New WndProcCallback(AddressOf Callback)
'Get Function Pointer on Delegate
Dim lpfnWndProc As IntPtr =
Marshal.GetFunctionPointerForDelegate(mycallback)

Dim hInstance As IntPtr = NativeMethods.GetModuleHandle(Nothing)
Dim wndclass As NativeMethods.WindowClass = New
NativeMethods.WindowClass
With wndclass
.hInstance = hInstance
.cbClsExtra = 0
.cbWndExtra = 0
.hCursor = Nothing
.hIcon = Nothing
.lpfnWndProc = lpfnWndProc 'Fonction Pointer
'.cbSize = Marshal.SizeOf(wndclass)
.hbrBackground = NativeMethods.COLOR_WINDOW
.style = NativeMethods.CS_DBLCLKS
.lpszMenuName = Nothing
.lpszClassName = "Test"
End With

Dim classAtom As Integer =
NativeMethods.RegisterClassW(wndclass)
If classAtom = 0 Then
Dim err As Integer = Marshal.GetLastWin32Error()
Throw New Win32Exception(err, "Enregistrement de la
classe impossible.")
End If

And I still have the System.NotSuportedException

Thank you for your help

regards,
 
P

Paul G. Tobey [eMVP]

You put the W in the wrong place to get RegisterClassW. It needs to be in
the DllImport attribute, in EntryPoint. You're currently asking for the
"RegisterClass" function in coredll.dll and there isn't one. That needs to
be "RegisterClassW".

Paul T.
 
B

Bebel

Hi Paul,

I have tried to use the following declaration as suggested:
<DllImport("coredll.dll", CharSet:=CharSet.Auto, SetLastError:=True,
EntryPoint:="RegisterClassW")> _
Friend Shared Function RegisterClass(ByRef lpwcx As WindowClass) As
Integer

End Function
But it still failed with the NotSupportedException

I have also tried to change the windowclass structure as suggested by Chris
to use a function pointer instead of a delegate declaration:

Public Structure WindowClass
Public style As UInteger
<MarshalAs(UnmanagedType.FunctionPtr)> _
Public lpfnWndProc As IntPtr
Public cbClsExtra As Integer
Public cbWndExtra As Integer
Public hInstance As IntPtr
Public hIcon As IntPtr
Public hCursor As IntPtr
Public hbrBackground As IntPtr
<MarshalAs(UnmanagedType.LPWStr)> _
Public lpszMenuName As String
<MarshalAs(UnmanagedType.LPWStr)> _
Public lpszClassName As String
End Structure

And in my code. I use the Machall object to get pointer to my WndProc
function callback:

Dim mycallback As WndProcCallback = New WndProcCallback(AddressOf Callback)
Dim lpfnWndProc As IntPtr =
Marshal.GetFunctionPointerForDelegate(mycallback)
Dim hInstance As IntPtr =
NativeMethods.GetModuleHandle(Nothing)
Dim wndclass As NativeMethods.WindowClass = New
NativeMethods.WindowClass
With wndclass
.hInstance = hInstance
.cbClsExtra = 0
.cbWndExtra = 0
.hCursor = Nothing
.hIcon = Nothing
.lpfnWndProc = lpfnWndProc
'.cbSize = Marshal.SizeOf(wndclass)
.hbrBackground = 6
.style = NativeMethods.CS_DBLCLKS
.lpszMenuName = Nothing
.lpszClassName = "Test"
End With

Dim classAtom As Integer =
NativeMethods.RegisterClass(wndclass)
If classAtom = 0 Then
Dim err As Integer = Marshal.GetLastWin32Error()
Throw New Win32Exception(err, "Enregistrement de la
classe impossible.")
End If

Still System.NotSupportedException message.

What can be wrong? I also fuind in the winuser.h the declaration of
RegisterClassA function and when I tried to use it I have a Message saying
EntryPoint not found in coredll.dll. There is something wrong.

Thank for your help.

regards,
 
P

Paul G. Tobey [eMVP]

So this is where you start playing around. If I change the types of the
class name and the menu name to IntPtr, it seems to work... Something must
be wrong with the insertion of a string there.

Paul T.
 
B

Bebel

Hi Paul,

If I defined the WNDCLASS structure (remove UnmanagedType.functionPTR) as
follow, it is working:

Public Structure WNDCLASS
Public style As UInteger
Public lpfnWndProc As IntPtr
Public cbClsExtra As Integer
Public cbWndExtra As Integer
Public hInstance As IntPtr
Public hIcon As IntPtr
Public hCursor As IntPtr
Public hbrBackground As IntPtr
<MarshalAs(UnmanagedType.LPWStr)> _
Public lpszMenuName As String
<MarshalAs(UnmanagedType.LPWStr)> _
Public lpszClassName As String
End Structure

regards,

bebel
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top