Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

CommonDialog1.InitDir and Windows ME 1

Status
Not open for further replies.

barrytraver

Programmer
Nov 28, 2000
40
US
Windows ME has apparently introduced some strange behavior for the Open dialog box control:

(1) CommonDialog1.InitDir apparently can't be used to set the directory shown except perhaps for the _very first time_ the program is run. (After that the Open dialog box seems to ignore whatever value
CommonDialog1.InitDir is set to.)

(2) In addition to apparently ignoring CommonDialog1.InitDir for later calls, a second call of the Open dialog box after a _single file_ has been selected returns to the _same_ directory previously shown (that's
normal, expected behavior) BUT a second call of the Open dialog box after _multiple files_ have been selected returns not to the directory previously shown but to its _parent_ directory!

To confirm the second point, just put a command button and a common dialog control on a form, leaving the default names,and use the following code:

Private Sub Command1_Click()
CommonDialog1.CancelError = True
CommonDialog1.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorer
On Error GoTo CDCancel
CommonDialog1.InitDir = "C:\WINDOWS\SYSTEM\"
Do
CommonDialog1.ShowOpen
Loop
CDCancel:
End
End Sub

Try it with Windows ME, and I think you'll find that the same thing happens for you. If you choose one file in C:\WINDOWS\SYSTEM, for example, the next time the Open dialog box is displayed, it is still set to C:\WINDOWS\SYSTEM. Select two files in C:\WINDOWS\SYSTEM, however, and the next time the Open dialog box is shown, it is set to C:\WINDOWS (not C:\WINDOWS\SYSTEM).

Yes, I've tried resetting the value of CommonDialog1.InitDir within the DO loop (and, yes, I've tested to make sure that the value or CommonDIalog1.InitDir was indeed being changed, and it was), BUT (as I said before) it seems that -- with Windows ME, at least -- CommonDialog1.InitDir only seems to apply to the _very first time_ that the Open dialog box is called when the program is run.

Anyone have any comments on this (or any workarounds)? Thanks in advance for your help.

Barry

P.S. I'm using the professional edition of VB 6.
 
Oops! I just registered, and it says "Vendor" instead of "Programmer." How can I correct this?
 
Have you tried instantiating ab object, rather than using the control??

Simon
 
Never mind about the &quot;Programmer/Vendor&quot; question. I was reading the wrong line <sigh>. Sorry!

Please don't ignore, however, the CommonDialog1.InitDir and Windows ME question! <grin> Thanks!
 
S. Williams (and others here),

> Have you tried instantiating an object rather than using the control?

I haven't tried that, because -- although I have the professional edition of VB 6 -- I'm pretty much an &quot;old dog&quot; using it in the manner of VB 3. It's not quite that bad, but it's still essentially true that when I write programs I basically simply &quot;draw the interface and add the code,&quot; and I have not yet gotten a handle on &quot;object-oriented programming.&quot;

I am, however, willing to learn. Any suggestions as to a &quot;crash course&quot; in what I need to do to &quot;instantiate an object&quot; rather than using the Common Dialog Open control?

Thanks in advance for any additional advice you or others here may provide.

Barry

P.S. The problems with the Open dialog box do not seem to exist with Windows 95 or Windows 98.
 
The basics of it are:

Dim objComDlg As Object
Set objComDlg = CreateObject(&quot;MSComDlg.CommonDialog&quot;)
objComDlg.ShowOpen


Before you do the third line above, you can set other properties of the object in the same way that you set the properties on the control. IE

Dim objComDlg As Object
Set objComDlg = CreateObject(&quot;MSComDlg.CommonDialog&quot;)
objComDlg.Filter = &quot;All Files (*.*)|*.*&quot;
objComDlg.Flags = cdlOFNAllowMultiselect

objComDlg.ShowOpen


can be used to select multiple files of any type.

For some reason this only works with late binding - Dim objComDlg As Object - and does not work with early binding. I would be interested to know why, if anyone has any ideas??

Simon
 
Simon,

Thanks for the explanation. I'll give it a try.

From what you say, I'm guessing that you would set InitDir in this way:

objComDlg.InitDir = &quot;C:\MyFolder\&quot;

Am I right on that?

If so (and if it actually works), how come InitDir works when you deal with the Common Dialog box as an object and not when you use it as a control?

Warm regards,

Barry
 
Hi Barry,

It is probably because InitDir only works when the control is first instantiated. Using the control, this will happen once. Using the object, this will happen whenever you do a CreateObject (but I may be wrong). I think that the control will use some kind of Property Bag, and store the last used directory. But using the CreateObject method, an entirely new version of the control will be created, and so will not have a last used directory.

Improvements to the code above:
The above code (in previous post) uses Late binding - ie VB run time components do not know what sort of thing objComDlg will be as we use the line:
Dim objComDlg As Object

But, it is better to use Early binding, as this will improve speed. The code below gives you an example of early binding.

Dim objComDlg As CommonDialog
Set objComDlg = New CommonDialog
objComDlg.InitDir = &quot;c:\aa&quot;
objComDlg.ShowOpen
Text1.Text = objComDlg.FileName
Set objComDlg = Nothing


NOTE: To use the above you have to set a reference to Microsoft Common Dialog Control. If you do not see this reference (in &quot;Project&quot;, &quot;References&quot;), then click the &quot;Browse&quot; button and find comdlg32.ocx. I found this in C:\winnt\system32

Simon
 
Simon,

It works great! With early binding, I created a Common Dialog object, set InitDir, showed the Open dialog, got the filename, destroyed the Common Dialog object, created a new Common Dialog object, set InitDir to a _different_ folder, showed the Open dialog, and it all worked as promised!

Since (thanks to you) I now have complete control over the Initial Directory shown, that should solve the problem with Windows ME and multiple-file select.

As I think I mentioned at the beginning of this thread, in Windows ME (at least on my system) if the user chooses one file, there's no problem, but if the user chooses multiple files, the next time the Open dialog is shown it is set NOT to the same directory as before BUT to the parent directory of the directory shown before (who knows why?).

To get around that, all I have to do now is to save the Path of the file(s) chosen when the Open dialog is used, and make sure the same folder is set to the same folder the next time the Open dialog is called. Many thanks for all the help!

Warm regards,

Barry

P.S. In Windows 95/98/ME, comdlg32.ocx is normally found in C:\WINDOWS\SYSTEM.

P.P.S. I've learned more in this exchange of messages than I have in a long time, and it opens doors to my learning a lot more, since now using objects doesn't seem as difficult to me as it looked before (thanks to your clear examples).
 
Simon,

Sorry to bother you again, but I've run into one more problem. When I create a Common Dialog object, how do I get the filenames if multiple files are selected?

Here are my flags (in case it's relevant):

objComDlg.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorer

When in the past I used the Common Dialog _control_ and multiple files are selected, in order to get the individual filenames I started with ComDlg1.FileName and parsed the string, recognizing CHR$(0) as the separator between files. (I don't know whether that's the usual way to do it, but it worked and none of the books told me the way I was supposed to perform that task.)

However, when I use instead the Common Dialog _object_ and multiple files are selected, objComDlg.FileName -- and objComDlg.FileTitle, for that matter -- don't seem to give me anything I can work with. I can't seem to get strings that I can parse or even display properly.

What am I missing here?

Regards,

Barry
 
I have just tested this, and having the Or cdlOFNExplorer on the Flags property changes the behaviour.
With this property setting, the FileName property returns the folder from which the files were selected.
Without this property setting (so that you just have objComDlg.Flags = cdlOFNAllowMultiSelect) the FileName property holds the folder that the files were selected from and the file names, separated by spaces. (IE space between the folder and the first file, and then spaces between the file names).

Simon
 
Simon,

With the regular Common Dialog Box control, the difference between the Explorer interface and the regular interface is that for the former CHR$(0) is used as a delimiter between filenames whereas for the later CHR$(32) (a normal space) is used as a delimiter.

Here's proof from Evangelos Petroutsos's Masting Visual Basic 6, page 399:

&quot;With the simple (Windows 3.11) File Open common dialog box, the filenames are separated by a space. All you have to do is to scaan the property value for spaces and extract the names of the selected files. If you specify the cdlOFNExplorer flag, which opens a Windows 98/NT Explorer-style dialog box, the filenames are delimited by the null character (Chr(0)) because long paths and filenames may contain spaces too (this excludes the use of the space as a delimiter, of course). So, the code for extracting the names of the selected files from the FileName property is different, depending on the type of File Open common dialog box.&quot;

Now, some strange behavior is observed with the Common Dialog object, and here's my guess as to what it is: the same thing is happening with the Common Dialog Box object, but the Chr(0) is taken not as a delimiter between filenames but (incorrectly) as a marker of the end of the string!

Try this after an objComDlg.ShowOpen:

M$=&quot;&quot;

M$ = M$ & &quot;Filename:&quot; & vbCrLf$ & Chr$(34) & objComDlg.FileName & Chr$(34) & vbCrLf$

M$ = M$ & &quot;FileTitle:&quot; & vbCrLf$ & Chr$(34) & objComDlg.FileTitle & Chr$(34) & vbCrLf$

M$ = M$ & &quot;InitDir:&quot; & vbCrLf$ & Chr$(34) & objComDlg.InitDir & Chr$(34) & vbCrLf$

M$ = M$ & &quot;Flags:&quot; & vbCrLf$ & vbCrLf$ & Chr$(34) & objComDlg.Flags & Chr$(34) & vbCrLf$

MsgBox = M$

It works as expected with a single file selected, but with multiple files selected, rather surprisingly you get something like this:

Filename:

&quot;C:\AA

That's all it writes!

Note well: you don't even get the closing quotation mark after the folder, so that seems to indicate that objComdlg.FileName contains something that Visual Basic is taking as an end-of-string marker. Otherwise why is M$ being radically truncated?

Yes, as you say, with multiple files selected the Filename property looks as if it's returning the folder from which the files were selected, but is that really what's happening?

Could it not simply be an accident because of the delimiter being taken as an end-of-string marker, as I have suggested? What other explanation can be given for the fact that the &quot;FileTitle,&quot; &quot;InitDir,&quot; and &quot;Flags&quot; information are not printed out in the MsgBox?

Does what I'm saying make sense? If so, is there a workaround so that I can have my Explorer-type interface and use it too? <grin>

Warm regards,

Barry
 
Simon,

If you do a Len(objComDlg.FileName) after selecting multiple files, you'll find that the length indicates that the FileName property contains more than the folder name (even if it doesn't display anything after the Chr(0) delimiter when printed to a MsgBox), so I'm all right after all.

That is, I don't have to be able to display the objComDlg.FileName string in order to be able to manipulate it to get the separate filenames! The display was what fooled me into thinking I had a problem.

I think I had known this before but had forgotten it, because I hadn't looked at the code of my program for a while (not until it stopped working properly in Windows ME).

Anyway, I'm grateful to you for teaching me how to use objComDlg. I learned a lot. Maybe I was able to contribute a little something of my own as well to the discussion in my comments on exactly how FileName uses a different delimiter in the Explorer Open dialog format than is used in the regular Open dialog format (even if I faltered a bit along the way).

It's been a l-o-n-g day (probably for both of us), but it's ending up with a problem solved, which would not have happened apart from your pointing the way. Thanks again.

Warm regards,

Barry
 
Something to consider in the future:

Instead of using a message box to display info for debugging purposes, try using Debug.Print.

Check out the code below and notice the difference!!!
Dim objComDlg As CommonDialog
Set objComDlg = New CommonDialog
objComDlg.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorer
objComDlg.Filter = &quot;All Files (*.*)|*.*&quot;
objComDlg.ShowOpen
Debug.Print objComDlg.FileName
MsgBox objComDlg.FileName
Set objComDlg = Nothing


This has been interesting.

Simon
 
Simon,

I've run into another problem wiht objComDlg. I'm trying to convert an already-written program that uses the Common Dialog control into one that uses the Common Dialog object.

When I use Project->References to try to add comdlg32.ocx, I get an error message that says &quot;Name conflicts with existing module, project, or object library.&quot; (It says this even if I delete the Common Dialog control from the form.)

If I start a brand-new program (Standard EXE), I have no problems. &quot;Microsoft Common Dialog Control 6.0 (SP3)&quot; may or may not show up immediately in the Project->References list (if it's there, it shows up at the very bottom, not alphabetically where you'd expect it), and I have no trouble having it accept a check mark in the box. (If I have to Browse to add it to the list, the check mark is already there when it's added, so all I have to do is click OK.) So it works with brand-new projects.

But when I try to add Microsoft Common Data Control 6.0 (SP3) (comdlg32.ocx) to an already-exisitng project, it isn't displayed in the Project->References box, and when I Browse for comdlg32.ocx and add it that way, it puts it at the bottom of the list, BUT (as I said) when I click on OK I get that error message, &quot;Name conflicts with existing module, project, or object library.&quot;

Any advice?

Warm regards,

Barry
 
Simon,

Here's some additional information that I don't know what to do with. The original code that you gave me earlier for later binding used to work _fine_:

Dim objComDlg As Object
Set objComDlg = CreateObject(&quot;MSComDlg.CommonDialog&quot;)
objComDlg.Filter = &quot;All Files (*.*)|*.*&quot;
objComDlg.Flags = cdlOFNAllowMultiselect
objComDlg.ShowOpen

Now, however, when I start VB 6, choose Standard EXE, put a command button on the form, and put that code within Command1_Click, it only partly works. That is, the multiselect no longer works (you can't select more than one file, either either Ctrl or Shift), but it does pay attention to other properties (e.g., if you change the Filter, that change does take effect).

Why would it work fine before and not work now?? <sigh>

Warm regards,

Barry
 
Simon,

HELP!

Here's yet more information on the strange behavior. I tried one of the short test programs I wrote earlier (based on your sample code), and this one still _does_ work (you _can_ select multiple files when you run the program):

Set objComDlg = New CommonDialog
objComDlg.InitDir = &quot;c:\aa&quot;
objComDlg.Filter = &quot;All Files (*.*)|*.*&quot;
objComDlg.Flags = cdlOFNAllowMultiselect Or cdlOFNExplorer
objComDlg.ShowOpen

Now this item of intormation may or may not mean anything, but if you do a Project->Reference, you see &quot;Microsoft Common Dialog Control 6.0 (SP3)&quot; at the bottom of the list, _BUT_ there is no check mark in the box (which there should be, I would think, for early binding).

What is going on here? Does this mean anything? Do I have a confused Windows Registry? Is there some other problem? (By the way, I'm running Windows ME, in case that is relevant.)

Thanks for any help or advice you may be able to provide!

Warm regards,

Barry
 
It sounds like things have just gone screwy!!!

As you said, I was under the impression that you could not use the CreateObject method or Dim X As New ... without having the reference to the object / library that you are trying to use.

I have never heard of Windows ME before (I have heard of Windows CE!!) - have you tried rebooting your computer?? Presumably so as this has been rolling on for a while??

It's at times like these you need a good joke.....
Three engineers are travelling in a car; an electrical engineer, a mechanical engineer and a Microsoft engineer, when the car breaks down.
The electrical engineer, thinking he knows it all, says, &quot;It's bound to be an electrical fault&quot; and gets under the bonnet (yes, I am English) to take a look.
Half an hour later he emerges having had no luck. So the mechanical engineer says, &quot;Well if you hadn't have been so quick, I would have saved you the trouble. It has got to be the engine. So he gets under the bonnet and starts fiddling with the engine. Two hours pass and still no joy, so he gives up.
The Microsoft engineer then comes up with his solution. He says, &quot;I know, let's shut all of the windows, get out, get back in again and open the windows and it's bound to work!&quot;

It may just work for you!!!!!

Simon
 
Simon,

Windows ME is Windows Millennium Edition, the next step after Windows 95 and Windows 98, just as Windows 2000 is the next step after Windows NT (I think).

The VB Project->References indication for Microsoft Common Dialog Control 6.0 (SP3)&quot; has indeed gone screwy for me. Early and late binding seem to be the opposite of what is indicated by Project->References for that object reference.

The reason I mention the Windows Registry is that I've had an experience before with the Windows Registry getting messed up in relation to comdlg32.ocx (I'll tell you about it in a postscript).

If there is a problem connected with the Windows Registry, then re-installing Visual Basic won't necessarily halp matters any (and, yes, I've rebooted Windows, but that didn't help any <sigh>).

I'll have to experiment more, both with creating brand-new programs and with modifying older programs, and see if I can learn more about what's going on....

Warm regards,

Barry

P.S. I'm now using VB 6 and Windows Millennium Edition (Windows ME), but the following is a description of an experience I had a year or so ago with VB 5 and Windows 95:
___________________________________

Recently in the Usenet newsgroup comp.lang.basic.visual.misc, more than one Visual Basic 5 user has reported the same problem: Suddenly, for no apparent reason Visual Basic 5 refuses to load in COMDLG32.OCX, COMCTL32.OCX, or COMCT232.OCX. Instead the error message &quot;'' could not be loaded&quot; is given (even though such files are present in C:\WINDOWS\SYSTEM and VB 5 does know the correct names of the files!).

I myself experienced that problem, which meant that I was not able to use for several weeks in VB 5 the common dialog control (that's six controls right there!), toolbar, status bar, image list, progress bar, tree view, list view, slider, etc.). I'm writing this so that other VB 5 programmers will know what to do if they encounter the problem.

Here's an important paragraph from Microsoft Knowledge Base article Q217017, which can be found at concerning the &quot;'' could not be loaded&quot; message:

&quot;This error message occurs when you install a newer version of an ActiveX control, uninstall it, and then install an older version of the same ActiveX control. The registry key for the newer version of the ActiveX control remains in the registry and Visual Basic 5.0 is now trying to use that registry key.&quot;

This could easily happen, for example, if you install (as I did) a recent shareware program and later uninstall it. The key point is that although the earlier version of the OCX is restored, the Windows registry still points to the later version of the OCX (and since it is no longer there, VB 5 is unable to load it).

To fix the problem, the Knowledge Base advises using RegClean, making the important point, &quot;RegClean will only be effective if Comctl32.ocx is deleted from the system before running RegClean.&quot; (Although not mentioned by the article, it appears that comdlg32.ocx and comct232.ocx should also be temporarily deleted before running RegClean.)

For details on using RegClean, see Knowledge Base article Q147769, &quot;RegClean 4.1a Description and General Issues,&quot; which can be found at The RegClean utility itself can be downloaded from the Microsoft site at
Here are the specific steps I took to solve the problem:

1. I downloaded RegClean from the Microsoft site.

2. I sent the three com*32.ocx files to the Recycle bin.

3. I unzipped and ran RegClean to repair the registry.

4. I restored the three com*32.ocx files from the Recycle bin.

5. I used Regsvr32.exe to register the three com*32.ocx files.

6. I tested out VB to confirm that things were indeed working again.

7. I reinstalled the Visual Basic 5 service pack 3 (a good idea after you use RegClean).

IMPORTANT LESSON TO BE LEARNED: If you install, say, a shareware program and then uninstall the program, it may mess up the registry for VB 5! That's because when you install the program, it may replace an older OCX with a newer version, and when you uninstall it, it will indeed replace the newer OCX with the older version, BUT IT DOESN'T FIX THE REGISTRY.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top