print a usercontrol...any takers?
|
|
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
|
|
|