Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / General 2 / January 2004



Tip: Looking for answers? Try searching our database.

print a usercontrol...any takers?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Phil - 30 Jan 2004 17:51 GMT
Second posting in the vain hope that a printing guru steps into the fray...

there must be a sensible way to print a usercontrol...isn't there?

or is how about a loop to print out each part of the control in its correct
place? how to deal with possible types of controls in the usercontrol?

help...stumped!

"Phil" <comp (plus number1)@ntlworld.com> wrote in message
news:om4Sb.31711$OA3.11430727@newsfep2-win.server.ntli.net...
> Dave,
>
> Had a proper look at this now. It works *but* I don't think it's the
> solution. It only prints out the visible portion of the window. If the
> window is not big enough to encompass the whole form, only the visible
> section gets printed...
>
> I need something that I can put into each usercontrol to get it to print
> itself...
>
> Phil
>
> "DaveW" <nomail@nomail.com> wrote in message
> news:bv2p43$p9j$1$8302bc10@news.demon.co.uk...
> > Hi Phil,
> >
> > Hope the below helps.  You can also SCALE the output if required by
adding
> > parms to the Printer.PaintPicture
> >
> > 'Screen Print Declare
> > Public Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal
> bScan
> > As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
> > Public Const TheScreen = 0
> > Public Const TheForm = 1
> >
> > Private Sub cmdPrint_Click()
> >     keybd_event vbKeySnapshot, TheForm, 0&, 0&
> >     DoEvents
> >     Printer.PaintPicture Clipboard.GetData(vbCFBitmap), 0, 0
> >     Printer.EndDoc
> > End Sub
> >
> > Regards
> > Dave
> >
> > "Phil" <comp (plus number1)@ntlworld.com> wrote in message
> > news:XQ3Rb.7$CK2.12823@newsfep2-gui.server.ntli.net...
> > > Hi,
> > >
> > > I have a VB6 form made up of sections, where each section is contained
> in
> > a
> > > usercontrol. This makes life fairly easy on the whole - all apart from
> > > printing (which I hate at the best of times).
> > > I need some ideas on the best way forward to print out this form. I've
> > tried
> > > asking the control to print, various attempts at copying to
pictureboxes
> > > from web code snippets, etc, but I'm a bit stumped.
> > > Is there really no way of asking a usercontrol to print itself (even
as
> a
> > > bitmap) ???
> > >
> > > Thanks
> > >
> > > Phil
Frank Adam - 30 Jan 2004 18:32 GMT
>Second posting in the vain hope that a printing guru steps into the fray...
>
[quoted text clipped - 4 lines]
>
>help...stumped!

You can step through the conrols on your usercontrol.
dim c as control
for each c in usercontrol.controls
    debug.print c.name
    debug.print typename(c)
next

Once you know the type of the control, then you can determine how you
want it printed and how to get the stuff out that you want to print.
ie:
select case typename(c)
    case is "Listbox" : Call PrintListBoxContents(c)
    case is "TextBox" : Call PrintTextBoxContents(c)
end select

Private Sub PrintListBoxContents(c as Control)
'may be able to pass in as ListBox , but doubt VB will like that.

    if c.listcout > 0 then
        printer.print "contents of " & c.Name
        for i = 0 to c.listcount-1
            printer.print c.list(i)
        next
    endif
end sub

Private Sub PrintTextBoxContents(c as control)
    dim s() as string, i as long
    printer.print "contents of " & c.Name
    'take care of multilines too
    if c.multiline = true then
        s = split(c.Text,vbcrlf)
        else
            redim s(0)
            s(0) = c.Text
    endif
    for i = lbound(s) to ubound(s)
        printer.print s(i)
    next
End Sub
   
Once in the right print routine, you can also determine their
positions, so perhaps you can then make up an exact copy of the visual
page, using the prnter's positional properties, but with multiline
textboxes and list or combos you're hosed trying to do that.  
       
Hope that sort of helps. Dammit, it's almost already written for you.
;-)

Signature

Regards, Frank

Mike Williams - 30 Jan 2004 18:37 GMT
> Second posting in the vain hope that a printing guru steps into the fray...
> there must be a sensible way to print a usercontrol...isn't there?

Okay. I'll do it for you. You'll have to give me some time though. I need at
least three cans of Bud inside me before I can produce any worthwhile code,
and I haven't opened the first can yet! Also, I've never used any User
Controls and so I'll have to learn just a little bit about how to handle
them first. I'll probably have a result later tonight, with a bit of luck.

Mike
Frank Adam - 30 Jan 2004 19:07 GMT
>Okay. I'll do it for you. You'll have to give me some time though. I need at
>least three cans of Bud inside me before I can produce any worthwhile code,
>and I haven't opened the first can yet! Also, I've never used any User

You should try beer. Works for me. ;-)

Signature

Regards, Frank

Mike Williams - 30 Jan 2004 19:28 GMT
> You should try beer. Works for me. ;-)

Bud's beautiful, Frank! Much better than the normal beers that taste like
squashed up bread and yeast :-)

Mike
Mike Williams - 30 Jan 2004 19:41 GMT
> Okay. I'll do it for you. You'll have to give me some time though.
> I need at least three cans of Bud inside me before I can produce
> any worthwhile code, and I haven't opened the first can yet!

Can't quite get the hang of those bloody User Controls! Still trying to get
at its hDC from code in the Form in which the User Control lives. Frank said
something about . . .

Property Get TheHdc() as long
TheHdc = usercontrol.hdc
End Property

. . . but I don't even know where to put that stuff! Maybe Frank can give me
a quick lesson? (And skip the lessons in beer drinking!)

Anyway, here's something to get you going, Phil. It's just a beginning, but
you should be able to do something neater with it:

1. Place the following in a standard Code Module:

Option Explicit
Public Const WM_PAINT = &HF
Public Const WM_PRINT = &H317
Public Const PRF_CLIENT = &H4&    ' Draw client area.
Public Const PRF_CHILDREN = &H10&
Public Const PRF_OWNED = &H20&
Public Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

2. In a VB Form place one Picture Box and your User Control and the
following code:

Option Explicit
Private Sub Form_Load()
Picture1.BorderStyle = 0
Picture1.BackColor = vbWhite
Picture1.AutoRedraw = True
Picture1.Visible = False
End Sub

3. In your User Control itself place the following code:

Option Explicit
Private Const WM_PAINT = &HF
Private Const WM_PRINT = &H317
Private Const PRF_CLIENT = &H4&    ' Draw client area.
Private Const PRF_CHILDREN = &H10&
Private Const PRF_OWNED = &H20&
Private Declare Function SendMessage Lib "user32" Alias _
"SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
ByVal wParam As Long, ByVal lParam As Long) As Long

4. Also place a Command Button (Command1 in this example) on your User
Control itself and use the following code in its click event:

Private Sub Command1_Click()
Form1.Picture1.Width = Width
Form1.Picture1.Height = Height
Form1.Picture1.Cls
SendMessage hwnd, WM_PAINT, Form1.Picture1.hDC, 0
SendMessage hwnd, WM_PRINT, Form1.Picture1.hDC, PRF_CHILDREN + PRF_CLIENT +
PRF_OWNED
Printer.Print ' always start print jobs with this
Printer.ScaleMode = vbInches
' print the UserControl at position (1, 1) inches
Printer.PaintPicture Form1.Picture1.Image, 1, 1
Printer.EndDoc
End Sub

To print the UserControl you need to click the button (Command1) on the User
Control itself (this is just temporary until I figure out how to do it
properly). As I've said, it needs a lot of tidying up but it should
definitely give you a start.

Mike
BeastFish - 30 Jan 2004 20:38 GMT
Just take the easy way and use the ActiveX Control Interface Wizard and
select to add the hDC property to the UserControl.  Let the wizard to the
work for ya :-)

> Can't quite get the hang of those bloody User Controls! Still trying to get
> at its hDC from code in the Form in which the User Control lives. Frank said
[quoted text clipped - 6 lines]
> . . . but I don't even know where to put that stuff! Maybe Frank can give me
> a quick lesson? (And skip the lessons in beer drinking!)
Mike Williams - 30 Jan 2004 20:46 GMT
> Just take the easy way and use the ActiveX Control Interface Wizard
> and select to add the hDC property to the UserControl.  Let the
> wizard to the work for ya :-)

Brilliant! I never knew such a beast existed. I'll play with it when I sober
up (the Active X Wizard, I mean!).

Mike
Frank Adam - 30 Jan 2004 21:02 GMT
>> Okay. I'll do it for you. You'll have to give me some time though.
>> I need at least three cans of Bud inside me before I can produce
[quoted text clipped - 10 lines]
>. . . but I don't even know where to put that stuff! Maybe Frank can give me
>a quick lesson? (And skip the lessons in beer drinking!)

Mike, the Property Get code goes into the Usercontrol's general proc
area. Think of it as if you were using a function to get a variable's
value.
Further, the hdc is a private variable, you can (just as in a standard
module) declare privates or publics in the UC.

If you declare a public variable, then there is ready access to it off
the parent, if you declare it as private then you have to provide
access to it as you see it fit to. It also allows you to preview any
changes to a given variable. Internally you would normally refer
directly to the local variable.

For instance : aircode !

usercontrol :

Dim localA as long, localB As long 'privates
Public C as Long

Private Sub UserControl_Initialize()
    localA = 100
End Sub

'i'll put that hdc thing here too :)
Property Get GetHdc() As long
    GetHdc = hdc
End Property

'expose localA as A
Property Get A() as long
    A = localA       
End Property

'Expose a way to set this local property from the caller
Property Let A(inA as long)
    'now we can muck with this and limit it
    if inA > 1000 then
        localA = 1000
        else
            localA = inA
    endif
    'and even do some other tasks accordingly
    if localA > 100 then
        localB = 100
        else
            localB = localA * 2
    endif
End Property

'expose localB as well
Property Get B() as long
    b = localB
End Property

But, we won't allow any outside access to setting B's value, so there
will not be a Property Let for that.

Now in the form you can go

private sub command1_Click()
    with usercontrol1
        debug.print .a, .b ' should be 100, 0
        .a = 1000 ' this shold change a and b
        debug.print .a, .b ' .b should reflect the change made in
                ' the Property Set A. Output shold be 1000, 2000
       
        'C is public. you can do what you like with it and the UC
        ' won't have a clue about it changing.
        .C = 13783
        debug.print .C

        'On the other hand this will cause an error as B is "readonly"
        .b = 12344
    end with
end sub

Does this help ?

Signature

Regards, Frank

Mike Williams - 30 Jan 2004 21:26 GMT
> Does this help ?

It doesn't help at the moment, Frank, but it'll definitely help in the
morning, when I sober up ;-)

Cheers

Mike
Mike Williams - 31 Jan 2004 09:43 GMT
> 1. Place the following in a standard Code Module:
> Option Explicit
[quoted text clipped - 6 lines]
>  "SendMessageA" (ByVal hwnd As Long, ByVal wMsg As Long, _
>  ByVal wParam As Long, ByVal lParam As Long) As Long

In my posting I inadvertently said that you should place the above
declarations in a Code Module and in your User Control. You only need them
in one of those places, of course. Also, if you want the printing stuff
totally built into your User Control (which I suspect you do) then that is
the best place to put the declarations. You could also move the invisible
Picture Box to your user control as well so that you will need no code at
all in your Form.

Mike
Phil - 30 Jan 2004 21:42 GMT
Mike / Frank - thanks for the pointers. I'm definitely going to give these a
bash tomorrow (brain just too frazzled now...and that's without any Bud)...

looks promising!!!

> > Second posting in the vain hope that a printing guru steps into the
> fray...
[quoted text clipped - 7 lines]
>
> Mike
Barry - 31 Jan 2004 03:22 GMT
I joined this thread a little late but in order to print a
usercontrol, why not put it on a form and then do a PrintForm?  It
seems to work for me.

Barry

>Mike / Frank - thanks for the pointers. I'm definitely going to give these a
>bash tomorrow (brain just too frazzled now...and that's without any Bud)...
[quoted text clipped - 14 lines]
>>
>> Mike

bceggersATcomcastDOTnet
Mike Williams - 31 Jan 2004 09:35 GMT
> I joined this thread a little late but in order to print
> a usercontrol, why not put it on a form and then do
> a PrintForm?  It seems to work for me.

Yes. You can do that. But I think the original poster wants to give a User
Control its own "built in" Print method, so that he (and anyone else that
uses it) can print it anywhere on the page simply by using its Print method.
Also, PrintForm forces you to print the Form at the top left corner of the
page and it does not allow you to print anything else on that same page
(which is a *major* limitation), whereas printing a User Control (or any
other Control that has a Hwnd property) with the method I have suggested
will allow you to print lots of individual User Controls and other stuff at
various positions on the page. Also the PrintForm method has "bugs" which
cause it to often fail or just print half of the Form. In fact, I regularly
use a slight variation of the method I have suggested to replace the VB
PrintForm method so that I can print Forms anywhere on the page and print
other stuff on top of or around them.

Mike
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.