OFNOTIY Struct from lParam pointer

  • Thread starter Thread starter SpotNet
  • Start date Start date
S

SpotNet

Hi Newsgroup,

While trying to customise my common dialogs and learn C#, I'm having trouble
getting this to work;

OFNOTIFY ofny = (OFNOTIFY)Marshal.PtrToStructure(lParam, typeof(OFNOTIFY));

Under the "case CDN_FOLDERCHANGE:" switch. I haven't seen this in any C#
documentation, but C++ doc's does this, in a different way like

OFNOTIFY ofny = (OFNOTIFY)lParam; (using the C++ pointer notation though).

From the same documentation I can get;

case WM_NOTIFY:
NMHDR nmhdr = (NMHDR)Marshal.PtrToStructure(lParam, typeof(NMHDR));

and

case WM_INITDIALOG:
ofn = (OPENFILENAME)Marshal.PtrToStructure(lParam,
typeof(OPENFILENAME));

to work well translating it from the C++ doc's from the web, but can't get
the OFNOTIFY, despite it stating this structure comes from lParam in the
hook proc under the CDN_FOLDERCHANGE switch message.

My Hook proc is typically defined as;
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
protected IntPtr HookProc(IntPtr hWnd, int iMsg, IntPtr wParam, IntPtr
lParam)

Can some one point me in the correct direction on what I'm missing. I'm
thinking C++ programmers have it all, wish I knew it (as well as C# too).

Regards,
- SpotNet
 
but can't get the OFNOTIFY, despite it stating this structure comes from lParam in the
hook proc under the CDN_FOLDERCHANGE switch message.

So what happens when you try it? How did you declare the OFNOTIFY
struct?


Mattias
 
Hello Mattias,

OFNOTIFY, is declared, what happens is that the program freezes for about 10
seconds then throws an exception, a bit later. Also a correction it's not
the "case CDN_FOLDERCHANGE:" switch but, rather the "case CDN_SELCHANGE:"
switch I make the declaration. I'll try be as brief as possible in the code
example;

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
CharSet.Auto)]
protected internal struct NMHDR
{
internal IntPtr hwndFrom; internal UInt32 idFrom;internal UInt32 code;
}//NMHDR

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
CharSet.Auto)]
protected internal struct OFNOTIFY
{
//[MarshalAs(UnmanagedType.Struct)]
internal NMHDR hdr;
internal OPENFILENAME lpOFN;
internal string pszFile;
}//OFNOTIFY

protected internal struct OFNOTIFYEX
{
[MarshalAs(UnmanagedType.Struct)]
internal NMHDR hdr;
//[MarshalAs(UnmanagedType.LPStruct)]
internal OPENFILENAME lpOFN;
internal IntPtr psf;
internal IntPtr pidl; //Maybe null
}//OFNOTIFYEX

[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
CharSet.Auto)]
protected internal class OPENFILENAME {...}//Wee al know it's contents..

protected IntPtr HookProc(IntPtr hWnd, int iMsg, IntPtr wParam, IntPtr
lParam)
{
IntPtr hwndparent = Win32API.GetParentApi(hWnd);

switch (iMsg)
{
case Win32MessageConstant.WM_INITDIALOG:
ofn = (OPENFILENAME)Marshal.PtrToStructure(lParam,
typeof(OPENFILENAME));

//All works fine here and a bit further down the track.....

case Win32MessageConstant.WM_NOTIFY:

NMHDR nmhdr = (NMHDR)Marshal.PtrToStructure(lParam,
typeof(NMHDR));
//Super!! All is good thus far

switch (nmhdr.code) //That's right "nmhdr.code" yields
appropriately
{
case CDN_SELCHANGE:
OFNOTIFY ofny =
(OFNOTIFY)Marshal.PtrToStructure(lParam, typeof(OFNOTIFY));

case CDN_INCLUDEITEM:
OFNOTIFYEX ofnyex =
(OFNOTIFYEX)Marshal.PtrToStructure(lParam, typeof(OFNOTIFYEX));



*******All goes wrong for me whenever I try OFNOTIFY and OFNOTIFYEX
Mattias**********
If I take them out and put Console.WriteLines(...); I can see when the
switch is executed. When I use them, I'm told;

-------------------------------------------------------------------------------------------------------
An unhandled exception of type 'System.NullReferenceException' occurred in
mscorlib.dll

Additional information: Object reference not set to an instance of an
object.
-------------------------------------------------------------------------------------------------------

How Rude!

}//HookProc

Hope this sheds a little more light on this Mattias, as I've said before
I've copied and 'translated' a lot of this from C++ documentation as there
no C# documatation on this. Thanks you so much as well for your reply.

Regards,
-SpotNet

:
: >but can't get the OFNOTIFY, despite it stating this structure comes from
lParam in the
: >hook proc under the CDN_FOLDERCHANGE switch message.
:
: So what happens when you try it? How did you declare the OFNOTIFY
: struct?
:
:
: Mattias
:
: --
: Mattias Sjögren [C# MVP] mattias @ mvps.org
: http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
: Please reply only to the newsgroup.
 
[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
CharSet.Auto)]
protected internal struct OFNOTIFY
{
//[MarshalAs(UnmanagedType.Struct)]
internal NMHDR hdr;
internal OPENFILENAME lpOFN;
internal string pszFile;
}//OFNOTIFY

Why do you set Size=0 in the StructLayout attribute?

The lpOFN member should be a pointer to an OPENFILENAME struct, it
should not contain the struct inline. So it's better represented as an
IntPtr. I suspect that's what causing the exception.

Since the docs say that pdzFile is only valid for CDN_SHAREVIOLATION,
I'd change that to an IntPtr as well. That would ensure that the CLR
doesn't attempt to dereference a possibly invalid string pointer.

protected internal class OPENFILENAME {...}//Wee al know it's contents..

Well I know what _should_ be the content, but I don't know how you
declared it. By leaving out importand parts of your code you're just
making it harder for us to help you find any errors.



Mattias
 
Hello Mattias,

Indeed it works and well. Size = 0, I got off someone else's example (in
C++) now removed, specific structures have been changed to IntPtr's and all
works well. Just for the sake of it, my OPENFILENAME class looks like;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
protected internal class OPENFILENAME
{
internal Int32 lStructSize = 0;
internal IntPtr hwndOwner = IntPtr.Zero;
internal IntPtr hInstance = IntPtr.Zero;
internal string lpstrFilter = null;
internal string lpstrCustomFilter = null;
internal Int32 nMaxCustFilter = 0;
internal Int32 nFilterIndex = 0;
internal string lpstrFile = null;
internal Int32 nMaxFile = 0;
internal string lpstrFileTitle = null;
internal Int32 nMaxFileTitle = 0;
internal string lpstrInitialDir = null;
internal string lpstrTitle = null;
internal Int32 Flags = 0;
internal Int16 nFileOffset = 0;
internal Int16 nFileExtension = 0;
internal string lpstrDefExt = null;
internal IntPtr lCustData = IntPtr.Zero;
internal OFNHookProc lpfnHook = null;
internal string lpTemplateName = null;
internal IntPtr pvReserved = IntPtr.Zero;
internal Int32 dwReserved = 0;
internal Int32 FlagsEx = 0;
}//OPENFILENAME

Thanks so much Mattias and you've help me to realise how much more I need to
learn, with great enjoyment ;~). There seems to be alot of C++ and VB.NET
examples of the common dialogs from Google searches, neither of which seem
to work when a 'direct (indirect) translation' is applied to C#.

Many thanks Mattias.

Regards,
- SpotNet


:
: >[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
: >CharSet.Auto)]
: >protected internal struct OFNOTIFY
: >{
: > //[MarshalAs(UnmanagedType.Struct)]
: > internal NMHDR hdr;
: > internal OPENFILENAME lpOFN;
: > internal string pszFile;
: >}//OFNOTIFY
:
: Why do you set Size=0 in the StructLayout attribute?
:
: The lpOFN member should be a pointer to an OPENFILENAME struct, it
: should not contain the struct inline. So it's better represented as an
: IntPtr. I suspect that's what causing the exception.
:
: Since the docs say that pdzFile is only valid for CDN_SHAREVIOLATION,
: I'd change that to an IntPtr as well. That would ensure that the CLR
: doesn't attempt to dereference a possibly invalid string pointer.
:
:
: >protected internal class OPENFILENAME {...}//Wee al know it's contents..
:
: Well I know what _should_ be the content, but I don't know how you
: declared it. By leaving out importand parts of your code you're just
: making it harder for us to help you find any errors.
:
:
:
: Mattias
:
: --
: Mattias Sjögren [C# MVP] mattias @ mvps.org
: http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
: Please reply only to the newsgroup.
 
Hello Mattias,

Indeed it works and well. Size = 0, I got off someone else's example (in
C++) now removed, specific structures have been changed to IntPtr's and all
works well. Just for the sake of it, my OPENFILENAME class looks like;

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
protected internal class OPENFILENAME
{
internal Int32 lStructSize = 0;
internal IntPtr hwndOwner = IntPtr.Zero;
internal IntPtr hInstance = IntPtr.Zero;
internal string lpstrFilter = null;
internal string lpstrCustomFilter = null;
internal Int32 nMaxCustFilter = 0;
internal Int32 nFilterIndex = 0;
internal string lpstrFile = null;
internal Int32 nMaxFile = 0;
internal string lpstrFileTitle = null;
internal Int32 nMaxFileTitle = 0;
internal string lpstrInitialDir = null;
internal string lpstrTitle = null;
internal Int32 Flags = 0;
internal Int16 nFileOffset = 0;
internal Int16 nFileExtension = 0;
internal string lpstrDefExt = null;
internal IntPtr lCustData = IntPtr.Zero;
internal OFNHookProc lpfnHook = null;
internal string lpTemplateName = null;
internal IntPtr pvReserved = IntPtr.Zero;
internal Int32 dwReserved = 0;
internal Int32 FlagsEx = 0;
}//OPENFILENAME

Thanks so much Mattias and you've help me to realise how much more I need to
learn, with great enjoyment ;~). There seems to be alot of C++ and VB.NET
examples of the common dialogs from Google searches, neither of which seem
to work when a 'direct (indirect) translation' is applied to C#.

Many thanks Mattias.

Regards,
- SpotNet

:
: >[StructLayout(LayoutKind.Sequential, Pack = 1, Size = 0, CharSet =
: >CharSet.Auto)]
: >protected internal struct OFNOTIFY
: >{
: > //[MarshalAs(UnmanagedType.Struct)]
: > internal NMHDR hdr;
: > internal OPENFILENAME lpOFN;
: > internal string pszFile;
: >}//OFNOTIFY
:
: Why do you set Size=0 in the StructLayout attribute?
:
: The lpOFN member should be a pointer to an OPENFILENAME struct, it
: should not contain the struct inline. So it's better represented as an
: IntPtr. I suspect that's what causing the exception.
:
: Since the docs say that pdzFile is only valid for CDN_SHAREVIOLATION,
: I'd change that to an IntPtr as well. That would ensure that the CLR
: doesn't attempt to dereference a possibly invalid string pointer.
:
:
: >protected internal class OPENFILENAME {...}//Wee al know it's contents..
:
: Well I know what _should_ be the content, but I don't know how you
: declared it. By leaving out importand parts of your code you're just
: making it harder for us to help you find any errors.
:
:
:
: Mattias
:
: --
: Mattias Sjögren [C# MVP] mattias @ mvps.org
: http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
: Please reply only to the newsgroup.
 

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

Back
Top