Board index » Visual Studio » Common Dialog control problem

Common Dialog control problem

Visual Studio175
I have problems with that the control passes back for opening a file

where I want to have multiple files selected. The dialog window does

allow me to select multiple files, but doesn't pass back the file names

if I choose more than one (and the field is large enough as it passes

the filename back correctly for one selection and only passes the path

back for multiple - which is less charaters).



I have the following code:



******************************************************************************8

Private Sub cmdFileOpen_Click()

Dim strFiles As String



' Set the initial starting directory

cdlCommon.InitDir = App.Path



' NOTE: Don't put spaces by the Pipe character!

cdlCommon.Filter = "Access Databases (*.mdb)|*.mdb|" & _

"INI Files (*.ini)|*.ini|" & _

"All Files (*.*)|*.*"



' Set the flags to Multiple File Select,

' Long File Names and Explorer-Like interface

cdlCommon.Flags = cdlOFNAllowMultiselect + _

cdlOFNLongNames + _

cdlOFNExplorer

' Set the maximum number of bytes

' that can be returned

cdlCommon.MaxFileSize = 3000



' Display the File Open dialog box

cdlCommon.ShowOpen



' Get the path/file name selected

strFiles = cdlCommon.FileName

txtFileOpen.Text = strFiles

End Sub

*******************************************************************************8



If I choose one file, the control passes back:



C:\download\paulSheriffVB6\PaulSheriff\Employees2.mdb



If I choose 3 (or 2 gives me the same result), I get the following

inside the control:



"Employees2.mdb" "employees1.mdb" "Employees.mdb"



and the following is passed back:



C:\download\paulSheriffVB6\PaulSheriff



Am I missing something (I'm sure I am).



Thanks,



Tom.


-
 

Re:Common Dialog control problem

You have to treat the string differently when multiselecting ... see

www.mvps.org/vbnet/faq/main/cdlgmultiselect.htm">www.mvps.org/vbnet/faq/main/cdlgmultiselect.htm



--



Randy Birch

MVP Visual Basic

www.mvps.org/vbnet/">www.mvps.org/vbnet/

Please respond only to the newsgroups so all can benefit.





"Thomas Scheiderich" <tfs@deltanet.com>wrote in message

: I have problems with that the control passes back for opening a file

: where I want to have multiple files selected. The dialog window does

: allow me to select multiple files, but doesn't pass back the file names

: if I choose more than one (and the field is large enough as it passes

: the filename back correctly for one selection and only passes the path

: back for multiple - which is less charaters).

:

: I have the following code:

:

:

******************************************************************************8

: Private Sub cmdFileOpen_Click()

: Dim strFiles As String

:

: ' Set the initial starting directory

: cdlCommon.InitDir = App.Path

:

: ' NOTE: Don't put spaces by the Pipe character!

: cdlCommon.Filter = "Access Databases (*.mdb)|*.mdb|" & _

: "INI Files (*.ini)|*.ini|" & _

: "All Files (*.*)|*.*"

:

: ' Set the flags to Multiple File Select,

: ' Long File Names and Explorer-Like interface

: cdlCommon.Flags = cdlOFNAllowMultiselect + _

: cdlOFNLongNames + _

: cdlOFNExplorer

: ' Set the maximum number of bytes

: ' that can be returned

: cdlCommon.MaxFileSize = 3000

:

: ' Display the File Open dialog box

: cdlCommon.ShowOpen

:

: ' Get the path/file name selected

: strFiles = cdlCommon.FileName

: txtFileOpen.Text = strFiles

: End Sub

:

*******************************************************************************8

:

: If I choose one file, the control passes back:

:

: C:\download\paulSheriffVB6\PaulSheriff\Employees2.mdb

:

: If I choose 3 (or 2 gives me the same result), I get the following

: inside the control:

:

: "Employees2.mdb" "employees1.mdb" "Employees.mdb"

:

: and the following is passed back:

:

: C:\download\paulSheriffVB6\PaulSheriff

:

: Am I missing something (I'm sure I am).

:

: Thanks,

:

: Tom.

:





-

Re:Common Dialog control problem

Randy Birch wrote:



Quote
You have to treat the string differently when multiselecting ... see

www.mvps.org/vbnet/faq/main/cdlgmultiselect.htm">www.mvps.org/vbnet/faq/main/cdlgmultiselect.htm





Got it. The files are there, but separated by null bytes and strings

stop at the null byte so you have to parse the string. What I can't

figure out, is how do you know you have multiple files? If you choose

only 1 file - there is no null byte between the path and the file and

you can see the whole string. If there is multiple files, there is a

null byte after the path, then the files names (separated by a null

byte). But the path doesn't have a "\" at the end - so you might think

the last folder name is a file name.



For example, in the following you have the following result:



C:\download\paulSheriffVB6\PaulSheriff\Employees2.mdb



But if you have multiple files, you have the following:



C:\download\paulSheriffVB6\PaulSheriff



You might think that PaulSheriff is the file that was chosen here and

not check for multiple file names (would have been better if they had

put a "\" at the end that would signal you that the file names follow).



Tom.



Quote




-

Re:Common Dialog control problem

"Thomas Scheiderich" <tfs@deltanet.com>wrote in message>

Quote
Got it. The files are there, but separated by null bytes and strings

stop at the null byte so you have to parse the string. What I can't

figure out, is how do you know you have multiple files?



Test for the inclusion of the null character:



Path = CommonDialog1.filename

If InStr(Path, Chr$(0)) Then

Debug.Print "Multiple: "; Path

Else

Debug.Print "Single: "; Path

End If





LFS





-

Re:Common Dialog control problem

Larry Serflaten wrote:



Quote
"Thomas Scheiderich" <tfs@deltanet.com>wrote in message>



>Got it. The files are there, but separated by null bytes and strings

>stop at the null byte so you have to parse the string. What I can't

>figure out, is how do you know you have multiple files?

>





Test for the inclusion of the null character:





Don't strings normally end with a null byte?



Quote


Path = CommonDialog1.filename

If InStr(Path, Chr$(0)) Then

Debug.Print "Multiple: "; Path

Else

Debug.Print "Single: "; Path

End If







LFS









-

Re:Common Dialog control problem

"Thomas Scheiderich" <tfs@deltanet.com>wrote in message

[...]

Quote
Don't strings normally end with a null byte?



Try it :)



They do, but when you are using string functions in VB you do not see the

terminating null that actually ends the string proper, only the embedded

ones within the string. Some languages would gag when using their standard

library "string" functions on a string that had embedded nulls, but not all

are written this way.



Also just to pick up on something else, Larry specifically stated "null

character" and you said "null byte" -- there is an important distinction

there also, since characters in a string aren't necessarily just 1 byte

each, and you may indeed have null "bytes" in some strings that aren't

considered a "null character" (where it might be required for both bytes of

the character to be null).



Quote
>Path = CommonDialog1.filename

>If InStr(Path, Chr$(0)) Then

>Debug.Print "Multiple: "; Path

>Else

>Debug.Print "Single: "; Path

>End If

>



>

>LFS



Regards,

Nick





-

Re:Common Dialog control problem

"Thomas Scheiderich" <tfs@deltanet.com>wrote

Quote
>

>Test for the inclusion of the null character:



Don't strings normally end with a null byte?





Debug.Print Len("A") ' 1



Where is it?



<g>

LFS





-

Re:Common Dialog control problem

Larry Serflaten wrote:



Quote
"Thomas Scheiderich" <tfs@deltanet.com>wrote



>>Test for the inclusion of the null character:

>>

>Don't strings normally end with a null byte?

>





Debug.Print Len("A") ' 1



Where is it?





I understand that. But if you have embedded null bytes (or null

characters), I would assume that it would stop at the null byte (as it

does in C, but if this is not the case, as Nick mentions, I assume that

the null byte does not signify the end of the string and must have a

string current length at the start of the string.



I assume the string you mentioned would look something like:



1, A, 0 (where the 1 and the 0 are binary)



or



"test" would look something like,



4, t, e, s, t, 0 (again where 4 and 0 are binary).



For the embedded null bytes to work, then you would have something like:



"var10var20"



would look like



9, v, a, r, 1, 0, v, a, r, 2, 0 (where 9 and both 0's are binary)



Just guessing here, but I can't see how else this would work.



Len would look at the 1st byte to tell how long the string is. If it

looked up to the null byte (as C does), it would stop at the 1st 0 and

assume the string was done.



tom.



Quote


<g>

LFS









-

Re:Common Dialog control problem

"Thomas Scheiderich" <tfs@deltanet.com>wrote



Quote
>>Don't strings normally end with a null byte?



>Where is it?





I assume the string you mentioned would look something like:



1, A, 0 (where the 1 and the 0 are binary)



This newsgroup is not about C++, it is about VB.



In VB, you don't see the 1, or the 0, even if they are there.

In VB that last 0 might as well be non-exsistant because you

will never see it. You can put a null character in the middle

of a string and that you can see (or see the effects of) if you

use a method that shows the entire string.





With a textbox on a new form, use F8 to step through this code:



Private Sub Form_Load()

Dim s As String, t As String



Show

s = Chr(65) & Chr(0) & Chr(66)

Text1.Text = s

Debug.Print s



t = s

Print t

Debug.Print t

Text1.Text = t



End Sub



Printing allows you to see the string, but assigning it to a text box

will stop at the first null character. Assignments will also transfer

the entire string, but nowhere do you see a trailing null character.



It just isn't there in a normal VB string, (until to try to pass it off

to some API).....



LFS







-

Re:Common Dialog control problem

Larry Serflaten wrote:



Quote
"Thomas Scheiderich" <tfs@deltanet.com>wrote





>>>Don't strings normally end with a null byte?

>>>



>>Where is it?

>>

>

>I assume the string you mentioned would look something like:

>

>1, A, 0 (where the 1 and the 0 are binary)

>



This newsgroup is not about C++, it is about VB.





I understand this. And the question was about how a string is handled

in VB, not how it is handled in C or C++.



I was using C as a comparison, to get across what I was asking and to

see if it was a different structure as C. Since text field will not

show you any text that follows the null byte, I had assumed that this

was because it null byte determined the size of the string. But when it

was said that you could parse the whole string, the size must be

determined in another way.



Quote


In VB, you don't see the 1, or the 0, even if they are there.





That was what I said. There must be a current length field somewhere (I

assume at the beginning). You obviously wouldn't see it.



Quote
In VB that last 0 might as well be non-exsistant because you

will never see it. You can put a null character in the middle

of a string and that you can see (or see the effects of) if you

use a method that shows the entire string.





With a textbox on a new form, use F8 to step through this code:



Private Sub Form_Load()

Dim s As String, t As String



Show

s = Chr(65) & Chr(0) & Chr(66)

Text1.Text = s

Debug.Print s



t = s

Print t

Debug.Print t

Text1.Text = t



End Sub



Printing allows you to see the string, but assigning it to a text box

will stop at the first null character. Assignments will also transfer

the entire string, but nowhere do you see a trailing null character.



It just isn't there in a normal VB string, (until to try to pass it off

to some API).....





No, it is there (unless I am missing something). If I modify your code:



**************************************

dim j as integer



Show

s = Chr(65) & Chr(0) & Chr(66)



j = len(s)

print "j = " & j

***********************************



J would be equal to 3, not 1.



Thanks,



Tom.





Quote
LFS











-

Re:Common Dialog control problem

If a string has an embedded null, then yes, most VB controls and methods

stop at that null. Consider:



dim x as string

dim y as string



x = "hello" & chr$(0) & "world"

1: Print x

2: Text1.text = x

3: Label1.Caption = x

y = x

4: Print y



1 and 4 print ' hello|world', whereas 2 and 3 show only ' hello '. Thus,

while the GDI print method prints the entire string, the controls only

handle strings up to the null char.



Now, adding length tests :



6: Print Len(x)

7: Print Len(y)

8: Print LenB(x)

9: Print LenB(y)



.. reveals 6 and 7 show 11 chars (while 8 and 9 show 22 bytes). So here the

entire string is accounted for. But using the lstrlen() API function, which

reads up to the first terminating null, the length returned is 5 (since

internally with VB strings are unicode thus the call returns the WCHAR's,

not the bytes):



Private Declare Function lstrlen Lib "kernel32" _

Alias "lstrlenA" _

(lpString As Any) As Long



10: Print lstrlen(ByVal x)

11: Print lstrlen(ByVal y)



Therefore, the simplest test for determining if a multi-selection string was

selected with the common dialog was as shown earlier ... just test for the

presence of chr$(0). If present, multiple selections have been made. If not,

a single file was selected.



If InStr(sfile2open, Chr$(0)) Then

MsgBox "multiple files"

Else

MsgBox "single file"

End If

--



Randy Birch

MVP Visual Basic

www.mvps.org/vbnet/">www.mvps.org/vbnet/

Please respond only to the newsgroups so all can benefit.





-

Re:Common Dialog control problem

Randy Birch wrote:



Quote
If a string has an embedded null, then yes, most VB controls and methods

stop at that null. Consider:



dim x as string

dim y as string



x = "hello" & chr$(0) & "world"

1: Print x

2: Text1.text = x

3: Label1.Caption = x

y = x

4: Print y





I haven't tried the others yet, but I just set up a new project with a

label and text object and both show "Hello", as expected, but I don't

get anything from the print statements.



The form_load() is:



***************************************

Option Explicit



Private Sub Form_Load()

Dim x As String

Dim y As String



x = "hello" & Chr$(0) & "world"

Print "x = " & x

Text1.Text = x

Label1.Caption = x

y = x

Print "y = " & y



End Sub

***************************************



Is there a problem with having the print statements in the Form_Load?



Thanks,



Tom.



Quote


1 and 4 print ' hello|world', whereas 2 and 3 show only ' hello '. Thus,

while the GDI print method prints the entire string, the controls only

handle strings up to the null char.



Now, adding length tests :



6: Print Len(x)

7: Print Len(y)

8: Print LenB(x)

9: Print LenB(y)



.. reveals 6 and 7 show 11 chars (while 8 and 9 show 22 bytes). So here the

entire string is accounted for. But using the lstrlen() API function, which

reads up to the first terminating null, the length returned is 5 (since

internally with VB strings are unicode thus the call returns the WCHAR's,

not the bytes):



Private Declare Function lstrlen Lib "kernel32" _

Alias "lstrlenA" _

(lpString As Any) As Long



10: Print lstrlen(ByVal x)

11: Print lstrlen(ByVal y)



Therefore, the simplest test for determining if a multi-selection string was

selected with the common dialog was as shown earlier ... just test for the

presence of chr$(0). If present, multiple selections have been made. If not,

a single file was selected.



If InStr(sfile2open, Chr$(0)) Then

MsgBox "multiple files"

Else

MsgBox "single file"

End If





-

Re:Common Dialog control problem

Don't put it in the load event. Since the code draws to the form, and the

form is not yet visible, the text disappears when the form is refreshed upon

first show. Put it inside a button click instead.



--



Randy Birch

MVP Visual Basic

www.mvps.org/vbnet/">www.mvps.org/vbnet/

Please respond only to the newsgroups so all can benefit.





"Thomas Scheiderich" <tfs@deltanet.com>wrote in message

: Randy Birch wrote:

:

:>If a string has an embedded null, then yes, most VB controls and methods

:>stop at that null. Consider:

:>

:>dim x as string

:>dim y as string

:>

:>x = "hello" & chr$(0) & "world"

:>1: Print x

:>2: Text1.text = x

:>3: Label1.Caption = x

:>y = x

:>4: Print y

:

:

: I haven't tried the others yet, but I just set up a new project with a

: label and text object and both show "Hello", as expected, but I don't

: get anything from the print statements.

:

: The form_load() is:

:

: ***************************************

: Option Explicit

:

: Private Sub Form_Load()

: Dim x As String

: Dim y As String

:

: x = "hello" & Chr$(0) & "world"

: Print "x = " & x

: Text1.Text = x

: Label1.Caption = x

: y = x

: Print "y = " & y

:

: End Sub

: ***************************************

:

: Is there a problem with having the print statements in the Form_Load?

:

: Thanks,

:

: Tom.

:

:>

:>1 and 4 print ' hello|world', whereas 2 and 3 show only ' hello '. Thus,

:>while the GDI print method prints the entire string, the controls only

:>handle strings up to the null char.

:>

:>Now, adding length tests :

:>

:>6: Print Len(x)

:>7: Print Len(y)

:>8: Print LenB(x)

:>9: Print LenB(y)

:>

:>.. reveals 6 and 7 show 11 chars (while 8 and 9 show 22 bytes). So here

the

:>entire string is accounted for. But using the lstrlen() API function,

which

:>reads up to the first terminating null, the length returned is 5 (since

:>internally with VB strings are unicode thus the call returns the

WCHAR's,

:>not the bytes):

:>

:>Private Declare Function lstrlen Lib "kernel32" _

:>Alias "lstrlenA" _

:>(lpString As Any) As Long

:>

:>10: Print lstrlen(ByVal x)

:>11: Print lstrlen(ByVal y)

:>

:>Therefore, the simplest test for determining if a multi-selection string

was

:>selected with the common dialog was as shown earlier ... just test for

the

:>presence of chr$(0). If present, multiple selections have been made. If

not,

:>a single file was selected.

:>

:>If InStr(sfile2open, Chr$(0)) Then

:>MsgBox "multiple files"

:>Else

:>MsgBox "single file"

:>End If

:>

:





-

Re:Common Dialog control problem

Randy Birch wrote:



Quote
Don't put it in the load event. Since the code draws to the form, and the

form is not yet visible, the text disappears when the form is refreshed upon

first show. Put it inside a button click instead.







That makes sense.



How would I have the program run automatically, but not until the form

and all the set up is done?



Tom.





-

Re:Common Dialog control problem

You can force a non-modal form on-screen at any point by placing an explicit

Show statement in the Load event. You could also add a timer to a form, set

it to about 250, enable it in the load event, and place the code to execute

in the timer event. Just make sure you turn off the timer there, otherwise

it will execute 4 times per second (if 250 is the interval).



--



Randy Birch

MVP Visual Basic

www.mvps.org/vbnet/">www.mvps.org/vbnet/

Please respond only to the newsgroups so all can benefit.





"Thomas Scheiderich" <tfs@deltanet.com>wrote in message

: Randy Birch wrote:

:

:>Don't put it in the load event. Since the code draws to the form, and

the

:>form is not yet visible, the text disappears when the form is refreshed

upon

:>first show. Put it inside a button click instead.

:>

:>

:

: That makes sense.

:

: How would I have the program run automatically, but not until the form

: and all the set up is done?

:

: Tom.

:

:





-