By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,900 Members | 1,358 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,900 IT Pros & Developers. It's quick & easy.

Calling a Windows API Function

P: n/a
I am trying to develop a wrapper class for the Windows API functions in Visual Studio 2008:
GetOpenFileName
GetSaveFileName

I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential, CharSet=CharSet.Auto)]
public class OpenFileName
{
int lstructSize;
int hwndOwner;
int hInstance;
string lpstrFilter = null;
string lpstrCustomFilter = null;
int lMaxCustomFilter;
int lFilterIndex;
string lpstrFile = null;
int lMaxFile = 0;
string lpstrFiteTitle = null;
int lMaxFileTitle = 0;
string lpstrInitialDir = null;
string lpstrTitle = null;
int lFlags;
ushort nFileOffset;
ushort nFileExtension;
string lpstrDefExt = null;
int lCustData;
int lpfHook;
int lpTemplateName;
}

[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out] OpenFileName ofn);

namespace myNameSpace
{
class GetFileNames
{
}
}

The compilier complains:

Error 1 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 33 15 myNameSpace
Error 2 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 33 46 myNameSpace
Error 3 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 35 15 myNameSpace
Error 4 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 35 46 myNameSpace
Error 5 The modifier 'extern' is not valid for this item
E:\myNameSpace\myNameSpace\GetFileNames.cs 32 70 myNameSpace
Error 6 The modifier 'extern' is not valid for this item
E:\myNameSpace\myNameSpace\GetFileNames.cs 34 70 myNameSpace

Errors 1 and 3 refer to the bool.qualifier
Errors 2 and 4 refer to the OpenFileName qualifier
Errors 5 and 6 refer to the extern

The DLLImport statements were originally retrieved from pinvoke.net using the PInvoke.net add-in.
They were modified to use the fully qualified System.Runtime.InteropServices.DllImport reference.

What am I doing wrong?
Nov 10 '08 #1
Share this Question
Share on Google+
23 Replies


P: n/a
Stewart Berman wrote:
I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential,
CharSet=CharSet.Auto)] public class OpenFileName
{
int lstructSize;
int hwndOwner;
int hInstance;
string lpstrFilter = null;
string lpstrCustomFilter = null;
int lMaxCustomFilter;
int lFilterIndex;
string lpstrFile = null;
int lMaxFile = 0;
string lpstrFiteTitle = null;
int lMaxFileTitle = 0;
string lpstrInitialDir = null;
string lpstrTitle = null;
int lFlags;
ushort nFileOffset;
ushort nFileExtension;
string lpstrDefExt = null;
int lCustData;
int lpfHook;
int lpTemplateName;
}

[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out] OpenFileName ofn);

What am I doing wrong?
Your static extern etc. functions should be declared as static members
of a class (even if, in reality, they are extern). And I would really
make OpenFileName a struct instead, passing it by reference.

--
Rudy Velthuis http://rvelthuis.de

"There are only two tragedies in life: one is not getting what
one wants, and the other is getting it."
-- Oscar Wilde (1854-1900)
Nov 10 '08 #2

P: n/a
Stewart Berman wrote:
I am trying to develop a wrapper class for the Windows API functions
in Visual Studio 2008:
FWIW:

http://pinvoke.net/default.aspx/comd...nFileName.html
http://pinvoke.net/default.aspx/comd...eFileName.html
--
Rudy Velthuis http://rvelthuis.de

"Each problem that I solved became a rule which served afterwards
to solve other problems."
-- Rene Descartes (1596-1650), "Discours de la Methode"
Nov 10 '08 #3

P: n/a
"Stewart Berman" <sa******@nospam.nospamwrote in message
news:mc********************************@4ax.com...
>I am trying to develop a wrapper class for the Windows API functions in
Visual Studio 2008:
GetOpenFileName
GetSaveFileName
Have you seen this:?
http://www.experts-exchange.com/Prog..._21017042.html
--
Mark Rae
ASP.NET MVP
http://www.markrae.net

Nov 10 '08 #4

P: n/a
The definition you pointed to is:
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);

Which is what I had as I got it from pinvoke.net:
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);

Am I missing something?

"Rudy Velthuis" <ne********@rvelthuis.dewrote:
>Stewart Berman wrote:
>I am trying to develop a wrapper class for the Windows API functions
in Visual Studio 2008:

FWIW:

http://pinvoke.net/default.aspx/comd...nFileName.html
http://pinvoke.net/default.aspx/comd...eFileName.html
Nov 10 '08 #5

P: n/a
>Your static extern etc. functions should be declared as static members
>of a class (even if, in reality, they are extern).
I am new to C# and do not understand your suggestions. Can you please provide a link to code?
And I would really
make OpenFileName a struct instead, passing it by reference.
My limited understanding is that the only difference between a class and a structure is that a class
is allocated in the heap and passed by reference while a structure is allocated on the stack and
passed by either value or reference. I have always thought that the stack should be limited to
simple arguments passed by value and pointers to complex structures. The OpenFileName structure
seems a bit much to put on the stack. However, I am new to C# and maybe a bit confused.

Is that another difference between a class and a stack?

"Rudy Velthuis" <ne********@rvelthuis.dewrote:
>Stewart Berman wrote:
>I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential,
CharSet=CharSet.Auto)] public class OpenFileName
{
int lstructSize;
int hwndOwner;
int hInstance;
string lpstrFilter = null;
string lpstrCustomFilter = null;
int lMaxCustomFilter;
int lFilterIndex;
string lpstrFile = null;
int lMaxFile = 0;
string lpstrFiteTitle = null;
int lMaxFileTitle = 0;
string lpstrInitialDir = null;
string lpstrTitle = null;
int lFlags;
ushort nFileOffset;
ushort nFileExtension;
string lpstrDefExt = null;
int lCustData;
int lpfHook;
int lpTemplateName;
}

[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out] OpenFileName ofn);

What am I doing wrong?

Your static extern etc. functions should be declared as static members
of a class (even if, in reality, they are extern). And I would really
make OpenFileName a struct instead, passing it by reference.
Nov 10 '08 #6

P: n/a
No. I don't take free trials unless I actually believe the site will be worth paying for.

On Mon, 10 Nov 2008 01:48:45 -0000, you wrote:

"Mark Rae [MVP]" <ma**@markNOSPAMrae.netwrote:
>"Stewart Berman" <sa******@nospam.nospamwrote in message
news:mc********************************@4ax.com.. .
>>I am trying to develop a wrapper class for the Windows API functions in
Visual Studio 2008:
GetOpenFileName
GetSaveFileName

Have you seen this:?
http://www.experts-exchange.com/Prog..._21017042.html
Nov 10 '08 #7

P: n/a
Stewart Berman wrote:
The definition you pointed to is:
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);

Which is what I had as I got it from pinvoke.net:
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);

Am I missing something?
That in the example (OK, it is VB, but I assume you can read that) it
is part of a class.
--
Rudy Velthuis http://rvelthuis.de

"I've always wanted to be somebody, but I should have been
more specific." -- George Carlin
Nov 10 '08 #8

P: n/a
Stewart Berman wrote:
Your static extern etc. functions should be declared as static
members of a class (even if, in reality, they are extern).

I am new to C# and do not understand your suggestions. Can you
please provide a link to code?
And I would really
make OpenFileName a struct instead, passing it by reference.

My limited understanding is that the only difference between a class
and a structure is that a class is allocated in the heap and passed
by reference while a structure is allocated on the stack and passed
by either value or reference. I have always thought that the stack
should be limited to simple arguments passed by value and pointers to
complex structures. The OpenFileName structure seems a bit much to
put on the stack. However, I am new to C# and maybe a bit confused.

Is that another difference between a class and a stack?

"Rudy Velthuis" <ne********@rvelthuis.dewrote:
Stewart Berman wrote:
I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential,
CharSet=CharSet.Auto)] public class OpenFileName
{
Make all members public:
public int lstructSize;
public int hwndOwner;
public int hInstance;
public string lpstrFilter = null;
public string lpstrCustomFilter = null;
public int lMaxCustomFilter;
public int lFilterIndex;
public string lpstrFile = null;
etc...

Like I said, they should be static functions of a class:

public class APILib
{
[DllImport("comdlg32.dll", SetLastError=true,
CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true,
CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out]
OpenFileName ofn);
}

Now you can use them like below:

OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = filter;
ofn.file = new string(new Char[256] {});
ofn.maxFile = ofn.file.Length;

// etc...

if (APILib.GetOpenFileName(ofn))
{
// get data from ofn
}
--
Rudy Velthuis http://rvelthuis.de

"Maybe this world is another planet's Hell."
-- Aldous Huxley (1894-1963)
Nov 10 '08 #9

P: n/a
I agree with you, in particular about that site.

"Stewart Berman" <sa******@nospam.nospamwrote in message
news:up********************************@4ax.com...
No. I don't take free trials unless I actually believe the site will be
worth paying for.
Nov 10 '08 #10

P: n/a
"Rudy Velthuis" <ne********@rvelthuis.dewrote:
>Stewart Berman wrote:
Your static extern etc. functions should be declared as static
members of a class (even if, in reality, they are extern).

I am new to C# and do not understand your suggestions. Can you
please provide a link to code?
And I would really
make OpenFileName a struct instead, passing it by reference.

My limited understanding is that the only difference between a class
and a structure is that a class is allocated in the heap and passed
by reference while a structure is allocated on the stack and passed
by either value or reference. I have always thought that the stack
should be limited to simple arguments passed by value and pointers to
complex structures. The OpenFileName structure seems a bit much to
put on the stack. However, I am new to C# and maybe a bit confused.

Is that another difference between a class and a stack?

"Rudy Velthuis" <ne********@rvelthuis.dewrote:
Stewart Berman wrote:

I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential,
CharSet=CharSet.Auto)] public class OpenFileName
{

Make all members public:
> public int lstructSize;
public int hwndOwner;
public int hInstance;
public string lpstrFilter = null;
public string lpstrCustomFilter = null;
public int lMaxCustomFilter;
public int lFilterIndex;
public string lpstrFile = null;

etc...

Like I said, they should be static functions of a class:

public class APILib
{
[DllImport("comdlg32.dll", SetLastError=true,
CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true,
CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out]
OpenFileName ofn);
}

Now you can use them like below:

OpenFileName ofn = new OpenFileName();
ofn.structSize = Marshal.SizeOf(ofn);
ofn.filter = filter;
ofn.file = new string(new Char[256] {});
ofn.maxFile = ofn.file.Length;

// etc...

if (APILib.GetOpenFileName(ofn))
{
// get data from ofn
}
I assume the need to imbed the imports in a class is due to the dot net framework. I don't
understand the need to make the members of the OpenFileName class public. They will only be
referred to with the code that instantiated the class. Why do they need to be public?
Nov 10 '08 #11

P: n/a
On Sun, 09 Nov 2008 20:05:14 -0800, Stewart Berman
<sa******@nospam.nospamwrote:
[...]
I assume the need to imbed the imports in a class is due to the dot net
framework. I don't
understand the need to make the members of the OpenFileName class
public. They will only be
referred to with the code that instantiated the class. Why do they need
to be public?
All due respect, your messages in this thread suggest that you may not
really understand C# well enough to effectively use a more advanced
feature like p/invoke. Rather than run the risk of engaging in a
variation of "cargo cult programming"
(http://en.wikipedia.org/wiki/Cargo_cult_programming) in which you engage
in canned rituals to achieve certain goals without really understanding
what's behind those rituals, you should probably spend more time learning
the basics before moving on to the more complicated things.

Practically all of these questions are simply basic rules that are part of
the C# language, fundamental to all class design. They aren't even all
that unique to C#, as they are shared in some form by other
object-oriented languages like C++ and Java as well.

I'd like to suggest that you really should spend a fair amount more time
learning OOP concepts in general, and the C# language specifically, before
you attempt to successfully use p/invoke or other advanced C#/.NET
features.

Pete
Nov 10 '08 #12

P: n/a
Stewart Berman wrote:
I assume the need to imbed the imports in a class is due to the dot
net framework.
It is actually due to the C# language. Not all languages on .NET
require this.
I don't understand the need to make the members of
the OpenFileName class public. They will only be referred to with
the code that instantiated the class. Why do they need to be public?
Because otherwise they'll be private (which is the default
accessibility for class members), and so no code in any other class
would be able to access them.
--
Rudy Velthuis http://rvelthuis.de

"Wagner's music is better than it sounds."
-- Mark Twain (1835-1910)
Nov 10 '08 #13

P: n/a
Hello Stewart Berman,

Thanks for using Microsoft Newsgroup Support Service, my name is Ji Zhou
[MSFT] and I will be working on this issue with you.

As you already found the imported function's declaration should be embedded
in a class. Otherwise we will receive the error you mentioned in your first
post. The reason is, in C# language, there is not a concept of global
function or global variable while the C++ does have. If we want to simulate
the global function using C#, we need to create a host class and put the
function declaration in that class as public static type. Then, we can
access it via NameSpace.Class.Function everywhere else in the project.

As to why the fields of the class OpenFileName should be declared as
public, the public fields can be accessed from the OpenFileName instance
directly. If we use the private field, after we create an instance of
OpenFileName, we cannot initialize the private fields value. The P/Invoke
may fails for the incorrect parameter.

One more thing to state is that, what is the business reason for calling
the native API GetOpenFileName and GetSaveFileName from C#. Based on my
experience, since the .NET Framework provide this function in the assembly
System.Windows.Forms.dll, why not directly use the SaveFileDialog and
OpenFileDialog in .NET?

Codes look like,

private void button1_Click(object sender, System.EventArgs e)
{
Stream myStream = null;
OpenFileDialog openFileDialog1 = new OpenFileDialog();

openFileDialog1.InitialDirectory = "c:\\" ;
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*" ;
openFileDialog1.FilterIndex = 2 ;
openFileDialog1.RestoreDirectory = true ;

if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = openFileDialog1.OpenFile()) != null)
{
using (myStream)
{
// Insert code to read the stream here.
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error: Could not read file from disk. Original
error: " + ex.Message);
}
}
}

We firstly create an instance of OpenFileDialog and set its properties like
the InitialDirectory, Filter, Filter Index and so on. After that, we can
call its.ShowDialog() to pop up the open file dialog. You can get more
information in the following two MSDN articles.

http://msdn.microsoft.com/en-us/libr...openfiledialog.
aspx
http://msdn.microsoft.com/en-us/libr...savefiledialog.
aspx

If you have any future questions or concerns, please feel free to let me
know and I will try my best to follow up. Have a nice day, Stewart!
Best regards,
Ji Zhou (v-****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/en-us/subs...#notifications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://support.microsoft.com/select/...tance&ln=en-us.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 10 '08 #14

P: n/a
"Rudy Velthuis" <ne********@rvelthuis.dewrote:
>Stewart Berman wrote:
>I assume the need to imbed the imports in a class is due to the dot
net framework.

It is actually due to the C# language. Not all languages on .NET
require this.
>I don't understand the need to make the members of
the OpenFileName class public. They will only be referred to with
the code that instantiated the class. Why do they need to be public?

Because otherwise they'll be private (which is the default
accessibility for class members), and so no code in any other class
would be able to access them.
I realized that about three seconds after I hit the send button on the message.
Nov 11 '08 #15

P: n/a
I am down to one last problem. If the user selects one file everything works fine. However, if the
user selects more that one file only the path is returned.

The OpenFileName.lpstrFile definition now looks like:
[MarshalAs(UnmanagedType.LPWStr)]
public string lpstrFile;

I have a buffer defined:
string m_sFile;

I initialize it:
m_sFile = new string('\0', 10240)

I then assign it to lpstrFile:
m_OFN.lpstrFile = m_sFile.Clone();

The problem is that GetOpenFileName (through the C# interface) does not populate the buffer with the
information. It apparently returns a pointer to a new string. Now if only one file is selected the
path and file name are in the returned string. However, if more than one file is selected the
return string only contains the path and the length of the returned string corresponds to the number
of characters in the path. Normally, the buffer would contain the path followed by a '\0' and then
a series of file names separated by a '\0'. It appears something in the C# interface to unmanaged
code is expecting a null terminated string and is truncating the information at the first '\0'.

I apparently missed something in the interface definition but I can't seem to spot it.

Any suggestions would be appreciated.
Stewart Berman <sa******@nospam.nospamwrote:
>I am trying to develop a wrapper class for the Windows API functions in Visual Studio 2008:
GetOpenFileName
GetSaveFileName

I put together a starter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

[System.Runtime.InteropServices.StructLayout(Layout Kind.Sequential, CharSet=CharSet.Auto)]
public class OpenFileName
{
int lstructSize;
int hwndOwner;
int hInstance;
string lpstrFilter = null;
string lpstrCustomFilter = null;
int lMaxCustomFilter;
int lFilterIndex;
string lpstrFile = null;
int lMaxFile = 0;
string lpstrFiteTitle = null;
int lMaxFileTitle = 0;
string lpstrInitialDir = null;
string lpstrTitle = null;
int lFlags;
ushort nFileOffset;
ushort nFileExtension;
string lpstrDefExt = null;
int lCustData;
int lpfHook;
int lpTemplateName;
}

[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetOpenFileName([In, Out] OpenFileName ofn);
[DllImport("comdlg32.dll", SetLastError=true, CharSet = CharSet.Auto)]
static extern bool GetSaveFileName([In, Out] OpenFileName ofn);

namespace myNameSpace
{
class GetFileNames
{
}
}

The compilier complains:

Error 1 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 33 15 myNameSpace
Error 2 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 33 46 myNameSpace
Error 3 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 35 15 myNameSpace
Error 4 Expected class, delegate, enum, interface, or struct
E:\myNameSpace\myNameSpace\GetFileNames.cs 35 46 myNameSpace
Error 5 The modifier 'extern' is not valid for this item
E:\myNameSpace\myNameSpace\GetFileNames.cs 32 70 myNameSpace
Error 6 The modifier 'extern' is not valid for this item
E:\myNameSpace\myNameSpace\GetFileNames.cs 34 70 myNameSpace

Errors 1 and 3 refer to the bool.qualifier
Errors 2 and 4 refer to the OpenFileName qualifier
Errors 5 and 6 refer to the extern

The DLLImport statements were originally retrieved from pinvoke.net using the PInvoke.net add-in.
They were modified to use the fully qualified System.Runtime.InteropServices.DllImport reference.

What am I doing wrong?
Nov 12 '08 #16

P: n/a
Hello Stewart Berman,

As I have stated in my previous reply, in the .NET environment, we have
already provided the corresponding API, OpenFileDialog class which is more
powerful and easier to use than the comdlg32.dll's GetOpenFileName. Why not
use the OpenFileDialog class?

The codes are very simple to get multiple selected files,

OpenFileDialog opf = new OpenFileDialog();
opf.Multiselect = true;
if (opf.ShowDialog() == DialogResult.OK)
{
foreach (string name in opf.FileNames)
{
Debug.Print(name + "\r\n");
}
}

If you have any business reason for having to choose the comdlg32's native
API, please feel free let me know. Then we can have a future discussion on
this issue. Have a good day!

Best regards,
Ji Zhou (v-****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.

Nov 13 '08 #17

P: n/a
>>If you have any business reason for having to choose the comdlg32's native

I need to understand the interface between C# and the underlying operating system. This is a
training exercise that consists of converting a few VB 6 applications that make a large number of
API calls to C#.

Is there a set of sample code for doing this? Where can I find the source code for the
OpenFileDialog class? Is there a sample application that drops into assembler?

BTW, I solved my problem with the OpenFileName interface using fixed. I now have some problems with
C# Classes but that is the subject of another posting.

Stewart Berman
v-****@online.microsoft.com ("\"Ji Zhou [MSFT]\"") wrote:
>Hello Stewart Berman,

As I have stated in my previous reply, in the .NET environment, we have
already provided the corresponding API, OpenFileDialog class which is more
powerful and easier to use than the comdlg32.dll's GetOpenFileName. Why not
use the OpenFileDialog class?

The codes are very simple to get multiple selected files,

OpenFileDialog opf = new OpenFileDialog();
opf.Multiselect = true;
if (opf.ShowDialog() == DialogResult.OK)
{
foreach (string name in opf.FileNames)
{
Debug.Print(name + "\r\n");
}
}

If you have any business reason for having to choose the comdlg32's native
API, please feel free let me know. Then we can have a future discussion on
this issue. Have a good day!

Best regards,
Ji Zhou (v-****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Nov 14 '08 #18

P: n/a
Stewart Berman <sa******@nospam.nospamwrote:
>
>>>If you have any business reason for having to choose the comdlg32's native

I need to understand the interface between C# and the underlying operating
system.
That's going to be very difficult to do. C# is even farther removed from
the operating system than VB6 is.
>Is there a set of sample code for doing this? Where can I find the source
code for the OpenFileDialog class?
You can't. It's part of the Common Language Runtime.
>Is there a sample application that drops into assembler?
You're talking about managed code here. That's as far from assembler as
you can get today.
--
Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Nov 15 '08 #19

P: n/a
The conversion of the VB6 application was just a simple training exercise.

I am trying to get acquainted with the current possibilities and limitations of the "new" languages.
Is there a white paper on the underlying differences between C# and C++?

I have not used C++ in almost ten years. The last commercial application I developed dropped into
assembler from C++ to switch into real mode to talk to the hardware -- please note that this was
original developed for Windows 3.1 although it still works in XP . (Must make note to try it in
Vista.)

Is this -- dropping into assembler -- still available in C++? Maybe I should have gone there
instead of C#.
>You're talking about managed code here. That's as far from assembler as
you can get today.
But where there's a will there's a way -- one can always put the transition to assembler in a DLL.

Tim Roberts <ti**@probo.comwrote:
>Stewart Berman <sa******@nospam.nospamwrote:
>>
>>>>If you have any business reason for having to choose the comdlg32's native

I need to understand the interface between C# and the underlying operating
system.

That's going to be very difficult to do. C# is even farther removed from
the operating system than VB6 is.
>>Is there a set of sample code for doing this? Where can I find the source
code for the OpenFileDialog class?

You can't. It's part of the Common Language Runtime.
>>Is there a sample application that drops into assembler?

You're talking about managed code here. That's as far from assembler as
you can get today.
Nov 17 '08 #20

P: n/a
Stewart Berman <sa******@nospam.nospamwrote:
>
I am trying to get acquainted with the current possibilities and limitations of the "new" languages.
Is there a white paper on the underlying differences between C# and C++?
Yes, Google brings up several. However, there is more to it than just the
language. More important than the difference between the two languages is
the difference between "unmanaged code" and "managed code".

C and the C++ you know are what Microsoft now called "unmanaged". They
compile straight to machine code and run on their own. C# and the managed
version of C++ called C++/CLI compile to an intermediate language, very
much like Java. VB, C#, and C++/CLI all create this intermediate language
(as do several other more obscure languages; J#, F#, IronPython, IronRuby,
among others). The IL is then compiled at run-time, and runs under the
control of the .NET Common Language Runtime. In a sense, it's another
layer removed from the hardware.
>Is this -- dropping into assembler -- still available in C++? Maybe I should have gone there
instead of C#.
Yes, for 32-bit apps (again, assuming traditional unmanaged C++).
Microsoft's 64-bit compilers do support inline assembler at all.
>>You're talking about managed code here. That's as far from assembler as
you can get today.

But where there's a will there's a way -- one can always put the transition to assembler in a DLL.
Yes, even with managed code, although you have to use some magic to get
there.
--
Tim Roberts, ti**@probo.com
Providenza & Boekelheide, Inc.
Nov 18 '08 #21

P: n/a
>>>You're talking about managed code here. That's as far from assembler as
>>>you can get today.

But where there's a will there's a way -- one can always put the transition to assembler in a DLL.

Yes, even with managed code, although you have to use some magic to get
there.
Getting there is usually not the greatest challenge -- it's getting back out without leaving a trail
of broken pointers, unfreed memory and unpopped arguments on the stack. Watch closely -- at no
times do my fingers leave my hands.

Sometimes you need to be able to go under the covers to do problem determination. Microsoft's first
C++ product (C7) had a little problem. If you had an exe that called a dll to create an object and
you then destroy the object while running code in the exe the garbage collector freed the memory
pointed to by the object. Unfortunately it freed it from the exe's heap instead of the dll's. So,
a few thousand instructions later when that area of the exe's heap got reused and your program tried
to use what was originally there it crashed. Debugging that one by following the code through the
thunking layer was a lot of "fun". Given the current layers of abstraction a problem like that
would be almost impossible for a developer to track down. The program just dies in unreproducable
ways.
Nov 21 '08 #22

P: n/a
I tried the OpenFileDialog class and I have a few questions:
1. How do you specify force show hidden files?
2. Why, when you can only select files from one folder is the path repeated with each file name in
FileNames[]? Shouldn't there be a Path property? Unmanaged code using the API only returns the
path once following by the list of file names.
3. If the user presses the Cancel button the class still returns one file with a zero length string
as the name. That is opf.FileNames.Count is 1 and opf.FileNames[0] is "". Shouldn't the
FileNames.Count be zero if no files were selected?

v-****@online.microsoft.com ("\"Ji Zhou [MSFT]\"") wrote:
>Hello Stewart Berman,

As I have stated in my previous reply, in the .NET environment, we have
already provided the corresponding API, OpenFileDialog class which is more
powerful and easier to use than the comdlg32.dll's GetOpenFileName. Why not
use the OpenFileDialog class?

The codes are very simple to get multiple selected files,

OpenFileDialog opf = new OpenFileDialog();
opf.Multiselect = true;
if (opf.ShowDialog() == DialogResult.OK)
{
foreach (string name in opf.FileNames)
{
Debug.Print(name + "\r\n");
}
}

If you have any business reason for having to choose the comdlg32's native
API, please feel free let me know. Then we can have a future discussion on
this issue. Have a good day!

Best regards,
Ji Zhou (v-****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Nov 21 '08 #23

P: n/a
>3. If the user presses the Cancel button the class still returns one file with a zero length string
>as the name. That is opf.FileNames.Count is 1 and opf.FileNames[0] is "". Shouldn't the
FileNames.Count be zero if no files were selected?
A little research shows that it returns whatever was in the FileName property when the ShowDialog
method is called. Apparently, setting the FileName property sets the FileNames.Count to 1 and the
FileNames[0] to the contents of the FileName property. The only way to get back a zero count when
the user cancels is to set FileName = null before calling the ShowDialog method.

Stewart Berman <sa******@nospam.nospamwrote:
>I tried the OpenFileDialog class and I have a few questions:
1. How do you specify force show hidden files?
2. Why, when you can only select files from one folder is the path repeated with each file name in
FileNames[]? Shouldn't there be a Path property? Unmanaged code using the API only returns the
path once following by the list of file names.
3. If the user presses the Cancel button the class still returns one file with a zero length string
as the name. That is opf.FileNames.Count is 1 and opf.FileNames[0] is "". Shouldn't the
FileNames.Count be zero if no files were selected?

v-****@online.microsoft.com ("\"Ji Zhou [MSFT]\"") wrote:
>>Hello Stewart Berman,

As I have stated in my previous reply, in the .NET environment, we have
already provided the corresponding API, OpenFileDialog class which is more
powerful and easier to use than the comdlg32.dll's GetOpenFileName. Why not
use the OpenFileDialog class?

The codes are very simple to get multiple selected files,

OpenFileDialog opf = new OpenFileDialog();
opf.Multiselect = true;
if (opf.ShowDialog() == DialogResult.OK)
{
foreach (string name in opf.FileNames)
{
Debug.Print(name + "\r\n");
}
}

If you have any business reason for having to choose the comdlg32's native
API, please feel free let me know. Then we can have a future discussion on
this issue. Have a good day!

Best regards,
Ji Zhou (v-****@online.microsoft.com, remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
ms****@microsoft.com.

This posting is provided "AS IS" with no warranties, and confers no rights.
Nov 21 '08 #24

This discussion thread is closed

Replies have been disabled for this discussion.