Hi all!
I've written a wrapper class for the common dialogs that uses the API functions to bring upp all the dialogs.
It has a much smaller footprint then the Common Dialog Control provided with VB and it also includes an advanced printer properties dialog and the browse for folder dialog.
It has most of the usefull properties that the control has but it's much easier to use because of two importent things. It doesn't have a flags property but instead the most common flags are pre-set.
The second advantage is that all the ShowXXX methods returns a boolean which is false if the user has pressed the cancel button.
I attached the code which you all are free to use in any matter you might feel fit.
Please rate this post if it was useful for you!
Please try to search before creating a new post,
Please format code using [ code ][ /code ], and
Post sample code, error details & problem details
Joacim, is the dialog modal and does it always show up at the left upper corner like the usual API dialog? I hated that, that's why I could not use it.
Originally posted by Joacim Andersson Yes the dialogs are modal. You just have to call the Init method first and pass the form you want to be the owner of the dialog.
Thanks man! I'm going to try this out. It's one of those things that so many of "intend" to do and it just never gets done. Great to see somebody swimming upstream
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
Hey, nice class
I always wanted to know how to use the Browse For Folder dialog
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
Can someone post the "InStrRev" defination? I'm not near a vb6 box while I'm at work so I can't remake this function without knowing what it does. (I have an idea, but I don't want to get it wrong)
Thanks,
Michael
Application/Web Developer
Visual Basic 6.0 SP5
Active Server Pages
Oracle 9i
Under the assumption that InStrRev is doing the same thing as InStr, just starting at then end and going to the start of the string.
I have added the following 2 functions to the class, and replaced all the offending functions with my own. *shrug* It seems to work, and I'm certain my two functions could be optimized more so than they are...
Code:
Private Function myReplace(ByVal strTheString As String, ByVal strToReplace As String, ByVal strReplaceWith As String) As String
Dim strNewString As String
Dim intIndex As Integer
'Finds ever instace of the sought string and replaces it.
strNewString = strTheString
Do While InStr(strNewString, strToReplace) > 0 'This could be modified so it doesn't have to call InStr twice.
intIndex = InStr(strNewString, strToReplace)
strNewString = Left$(strNewString, intIndex - 1) & strReplaceWith & Right$(strNewString, Len(strNewString) - Len(Left$(strNewString, intIndex)) - Len(strToReplace) + 1)
Loop
myReplace = strNewString
End Function
Private Function myInStrRev(ByVal strTheString As String, ByVal strSoughtString As String) As Long
Dim intCtr As Long
For intCtr = Len(strTheString) To 0 Step -1
If Mid(strTheString, intCtr, 1) = strSoughtString Then
Exit For
End If
Next intCtr
myInStrRev = intCtr
End Function
If anyone has VB5 and wants to test it out or optimize my routines, by all means go ahead...
Regards,
Michael
Application/Web Developer
Visual Basic 6.0 SP5
Active Server Pages
Oracle 9i
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
For that code to work, you'll need to see the declaration of InStrRev (it's different from InStr). Otherwise, it won't work because the parameters you pass are out of place!
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
Originally posted by Jotaf98 For that code to work, you'll need to see the declaration of InStrRev (it's different from InStr).
Otherwise, it won't work because the parameters you pass are out of place!
It doesn't matter.
InStrRev do has two additinal optional arguments but they aren't used in this class.
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
Hey, I used your class in one of my projects, the Debugger. I left is as it was, with the comments and all
I know this has nothing to do with it, but I can't upload it to Planet-Source-Code.com! It says that I'm using GetRight or something
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
Well yes it's possible but it's not easy.
First of all you need a resourse for the template and for that you need a much more advanced resource editor then the one shipped with VB.
For it to work with VB you'll also need a TLB file which you must build in C++.
I'll tried this a couple of times but the result wasn't that good and I got a GPF some of the times I tried to show the dialog.
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
Heh, sorry, I wasn't saying it was because of YOUR class, I just needed some help
I think I'll post it in a new thread.
Anyway, I've heard that you can use the API to get a handle to the dialog box and then create controls there!
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
No, you use a template, made with a resource editor, and send the template name to the API function.
You'll also create a call-back procedure that the dialog (or rather the API) will call to sink all the events in the dialog.
Originally posted by Jotaf98 Hey, I used your class in one of my projects, the Debugger. I left is as it was, with the comments and all
I know this has nothing to do with it, but I can't upload it to Planet-Source-Code.com! It says that I'm using GetRight or something
Any idea?
Sounds like you are using, (or it thinks you are using) a program that will allow you to resume broken downloads. These programs also tend to have a "leech" function where you can download all the documents off a particular site, including the HTML and whatnot. If you really wanted to get their code, you could anyhow, so i dont know why they are doing that, but it sounds like thats what they are looking for.
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
Yeah, I know - I just found out that they're selling the whole site on CD
Anyway, I'm sure I've seen a demo on custom controls in common dialogs before... and it said "It's kinda hard because you must find the handle of the common dialog and then create the controls there, through API". That's why I didn't download it, it needed +20 lines of code for a simple button
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
Originally posted by Jotaf98
Anyway, I'm sure I've seen a demo on custom controls in common dialogs before... and it said "It's kinda hard because you must find the handle of the common dialog and then create the controls there, through API". That's why I didn't download it, it needed +20 lines of code for a simple button
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
No, sorry
But I know it was based on another demo, that allowed you to create a button in the title bar of a form, trough API (creating a control trough API gives you a lot more options, VB just provides us with the default ones ). The author of that code just had to find a handle to the common dialog to create controls there. I think it was at http://www.planet-source-code.com , but I'm not sure.
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
Originally posted by anizmohammed Option Explicit
Dim cdl As CCommonDialogs
Private Sub Form_Click()
Set cdl = New CCommonDialogs
Form2.Show
cdl.Init (Form2)
cdl.ShowFolder
End Sub
This is my code It shows error
Type mismatch while i call the init function
of your class file can any one helpme how to use it
Don't use the paranteses when you call the Init method (or use a Call statement) because when you do you pass the form ByVal instead of ByRef.
Code:
Dim cdl As CCommonDialogs
Private Sub Form_Click()
Set cdl = New CCommonDialogs
Form2.Show
cdl.Init Form2 'or Call cdl.Init(Form2)
cdl.ShowFolder
End Sub
Originally posted by Jotaf98 Look, there's another way to create classes:
Dim CD As New CCommonDialog
That's much easier than what you're using.
That might be easier to type but it's not a better way to declare and use an object.
This is because how VB initilize an object.
When you declare and init an object in the following matter:
Code:
Dim obj As Class
Set obj = New Class
The object will be initilized on the second row. That is with the Set statement.
But if you do the following:
Code:
Dim obj As New Class
The object will not be initlized before it is first used.
That is when you first assign a value to a property or when you call a method.
But then VB has to check if the object already exist, that is if it already has been initilized, and that takes time.
Furthermore VB has to do that check every time you use the object!
Code:
Private cdl As New CCommonDialog 'object isn't created
Private Sub Form_Load()
Dim sFile As String
cdl.Init Me 'check if object is created, if not create it.
cdl.ShowOpen 'check if object is created, if not create it.
sFile = cdl.FileName 'check if object is created, if not create it.
'and so on
End Sub
So I always use the two liner to create an object!
I'm not gonna give you my IP address! Ok... Portugal, South-Western Europe, 3rd rock from the sun (our star is easy to find, a 47 Ursae Majoris in the Milky Way :p )
Posts
1,457
Heh, thanks, I didn't know that about classes - I just used them like that and they seemed fine to me
To learn how to use realistic effects in your games like fire, rain, snow and magic effects, read my article on particles systemshere.
Jotaf's Theories!
"Cats land on their feet. Toast lands peanut butter side down. A cat with toast strapped to its back will hover above the ground in a state of quantum indecision."
I need some help. I love this class! It does everything I need so far, but I'm having a problem. How can I retrieve the number of copies the user sets when I call ShowPrinter? I'm trying to print a form using Form1.PrintForm and when I tried printing multiple copies by changing the copies on the print dialog, it only printed one copy. Here's my code:
Private Sub Print_Click()
On Error GoTo ErrorHandler
NotCanceled = CommonDialog1.ShowPrinter
If NotCanceled = False Then Exit Sub
Form1.PrintForm
Exit Sub
ErrorHandler:
End Sub
When I used the comdlg32.ocx control to print the form, this code let me print multiple copies by changing the copies property at runtime:
Private Sub Print_Click()
On Error GoTo ErrorHandler
CommonDialog1.CancelError = True
CommonDialog1.Flags = cdlPDHidePrintToFile Or cdlPDNoSelection
CommonDialog1.ShowPrinter
Form1.PrintForm
Exit Sub
ErrorHandler:
End Sub
If anyone has any ideas or can tell me what I'm doing wrong (Joacim?), please respond soon.
You'll have to change the code a little bit to do that.
First add a private variable to hold a new property value.
(Add it at the beginning of the class where the rest of the member variables are)
Code:
Private m_PrintCopies As Long
Then you'll have to add a new property procedure:
Code:
Public Property Get PrintCopies() As Long
If m_PrintCopies = 0 Then
m_PrintCopies = 1
End If
PrintCopies = m_PrintCopies
End Property
Public Property Let PrintCopies(ByVal NewValue As Long)
m_PrintCopies = NewValue
End Property
You'll also has to do some changes in the ShowPrinter method.
(The changes are in bold text.)
Code:
Public Function ShowPrinter() As Boolean
Dim pd As PrintDlgStruct
Dim nRetVal As Long
pd.lpSetupTemplateName = ""
pd.lpPrintTemplateName = ""
pd.hwndOwner = m_Owner.hWnd
pd.nCopies = Me.PrintCopies
pd.flags = PD_HIDEPRINTTOFILE Or PD_NOPAGENUMS Or PD_NOSELECTION
pd.lStructSize = Len(pd)
nRetVal = PrintDlg(pd)
Me.PrintCopies = pd.nCopies
ShowPrinter = (nRetVal <> 0)
End Function
Now you still have to loop through the number of copies you want to print. So you'll have to make a small change in your code as well:
Code:
Private Sub Print_Click()
Dim i As Long
On Error GoTo ErrorHandler
If CommonDialog1.ShowPrinter = True Then
For i = 1 To CommonDialog1.PrintCopies
Form1.PrintForm
Next
End If
Exit Sub
ErrorHandler:
End Sub
Hey Joacim, I'm having a problem with your code. I thought the PrintCopies property was working, but it's not right now. Whenever I call Print_Click(), it displays the print dialog, but no matter what I set copies to in the print dialog, the PrintCopies property is set to 1 and it prints the amount of copies I have set in the printer properties dialog. So, for example, if I call ShowPrinterProperties and set copies to 2, then call ShowPrinter, the print dialog has copies set to 1. Then if I click ok (leaving copies on 1) it prints 2 copies. I'm confused, can you help?
If you want to set the number of pages to be printer in the Printer Properties dialog you'll have to do some more changes to the code.
First add the following structure:
Code:
Private Type DEVMODE
dmDeviceName As String * 32
dmSpecVersion As Integer
dmDriverVersion As Integer
dmSize As Integer
dmDriverExtra As Integer
dmFields As Long
dmOrientation As Integer
dmPaperSize As Integer
dmPaperLength As Integer
dmPaperWidth As Integer
dmScale As Integer
dmCopies As Integer
dmDefaultSource As Integer
dmPrintQuality As Integer
dmColor As Integer
dmDuplex As Integer
dmYResolution As Integer
dmTTOption As Integer
dmCollate As Integer
dmFormName As String * 32
dmUnusedPadding As Integer
dmBitsPerPel As Long
dmPelsWidth As Long
dmPelsHeight As Long
dmDisplayFlags As Long
dmDisplayFrequency As Long
End Type
Then do the following changes to the ShowPrinterProperties method:
Code:
Public Function ShowPrinterProperties() As Boolean
Dim nRetval As Long, hPrinter As Long
Dim pd As PRINTER_DEFAULTS
Dim dm As DEVMODE
On Error Resume Next
dm.dmSize = Len(dm)
dm.dmCopies = m_PrintCopies
pd.pDatatype = 0
pd.pDesiredAccess = STANDARD_RIGHTS_REQUIRED Or PRINTER_ACCESS_USE
pd.pDevMode = VarPtr(dm)
nRetval = OpenPrinter(Printer.DeviceName, hPrinter, pd)
If nRetval <> 0 Then
nRetval = PrinterProperties(m_Owner.hwnd, hPrinter)
m_PrintCopies = dm.dmCopies
ClosePrinter hPrinter
End If
ShowPrinterProperties = (nRetval <> 0)
End Function
Nope, didn't fix it. I think I may know where the problem is, but I have no clue how to fix it... First of all, I have a Hewlett Packard Deskjet 720C, in case that matters. When I run my program and to to display the print properties dialog it shows the printer properties for my printer. From here I can change print options such as portrait or landscape, greyscale or color, etc... If I go into the printer properties dialog, I can also set the number of copies it should print. If I set the number of copies to print to 2, click ok, show the print dialog, set the number of copies there to 1 and click ok, it prints two copies. I got the program to display a messagebox telling me what the .PrintCopies property was set to before it prints, and no matter what I set the copies to on the print dialog or the printer properties dialog, the .PrintCopies property is always 1. This means that my program must loop one time, e.g. it tells the printer to print one time. However it always prints however many copies I set in the print properties dialog. I think for some reason, when you set the .PrintCopies property for the ccommondialogs.cls class, it doesn't remember, or it doesn't change the setting for the printer. I hope this is enough information to fix the problem. If this was confusing, tell me and I'll try to explain better. Thanks a million!
P.S. Source Edit is great! I'm trying out C++ and it's my editor of choice now.