From: Mike Williams on 16 Jun 2010 16:11 "M Wade" <nowhere(a)columbus.rr.com> wrote in message news:4C190FCC.8090905(a)columbus.rr.com... > I am not very clear on using APIs and haven't the > foggiest idea what the reference to DC is, but I > am going to see if I can understand the code you > supplied. If you have the time to study the code then of course it is often a rewarding thing to do, but if you don't have the time to do so, or if there are other more important things for you to be getting on with, then that's fine as well. Essentially the bulk of the code can be viewed as simply a "black box" that performs a specific task for you. You do really need to study the code in the Command Button Click Event though, which is the part that shows you how to call the two routines in order to allow the user to select the printer and to position your output accurately on the page. Post again if you have any questions on that part, or in fact on any other part of the code. By the way, I forgot to mentioned that you should paste the code into a VB Form containing a Command Button (although I'm sure you've already done that by now). Mike
From: Shotgun Thom on 17 Jun 2010 02:13 Marv: The Microsoft DLL that is a replacement for the common dialog ocx that Mike mentioned earlier is named vbprndlg.dll. It can be found here: http://support.microsoft.com/kb/322710 It's a pretty solid wrapper for the API. It may be worth taking a look at as well. It will return your duplex option. Mike: The biggest problem I've had with the vpprndlg.dll, or for that fact, API code is for special printer options. I have a client that has a Konica C350 by Minolta. It not only collates but can staple, punch 2 or 3 ring binder holes and makes you a cup of expresso while you wait.. It's one of those we can do everything printers. I have never been able to figure out how to set these esoteric options other than right clicking on the printer icon and setting the printer settings for a particular job that requires them and then resetting those properties when finished. I know it can be done because even simple Notepad can set these properties through the printers properties setup for just the current print job without having to go back and reset them. I just don't have a clue on how to do it in VB. Tom
From: Mike Williams on 17 Jun 2010 07:58 "Shotgun Thom" <tmoran4511(a)gmail.com> wrote in message news:c9670b3a-076a-4d2b-8d6f-4b7dcdcabc24(a)z15g2000prh.googlegroups.com... > Mike: The biggest problem I've had with the vpprndlg.dll, > or for that fact, API code is for special printer options. I > have a client that has a Konica C350 by Minolta. It not only > collates but can staple, punch 2 or 3 ring binder holes and > makes you a cup of expresso while you wait.. It's one of > those we can do everything printers. I have never been able > to figure out how to set these esoteric options other than right > clicking on the printer icon and setting the printer settings for > a particular job that requires them and then resetting those > properties when finished. When you use the MS vbprndlg DLL or any other equivalent method (API dialogs or the CommonDialog control) in a way that transfers the user's settings from the dialog to the VB Printer Object then you simply cannot get access to all possible printer settings, especially those esoteric settings that I mentioned myself in my response to the OP, the printiva "use metallic gold ribbon", and the other esoteric settings you have mentioned, the "punch 3 ring binder holes and make a cup of expresso while you're waiting" stuff ;-) That's partly because the VB Printer Object cannot "eat" such settings and partly because Windows itself does not really know about such things (at least not in detail in a standard Windows way). The details of such esoteric settings are of course stored in Devmode Extras, but as far as Windows itself is concerned some of that information is "just a bunch of numbers" and many of them are known and understood in detail only by the printer driver itself. You can however give your user access to all those settings, but you cannot do so in a way that allows you to use the VB Printer object for your printing, at least not without resorting to the kind of methods you have mentioned, such as requiring the user to right click the printer and change its default settings and then change them back again afterwards. In order to get at all that stuff in a way that does not require you to mess about with right clicking or changing default settings, you need to present a printer dialog to the user in the normal way but you need to ask the dialog to return a DC for you. That returned DC will contain all of the things that the user has selected in the printer dialog, the printer itself and all the user's settings, including all those esoteric settings, and you can then draw and print stuff to that DC in much the same way as you would draw and print things to any DC. This of course means that you cannot use the VB Printer Object and you must instead use the Windows StartDoc, EndDoc etc methods to create the document and use the standard TextOut and Drawtext and StretchBlt etc methods for drawing text and lines and boxes and images, etc. You can use whichever method you personally prefer for showing the dialog. Here is an example in which I have used the standard CommonDialog Control. As is the case with just about everything I write, it is not (and never will be) a "finished product" because I am just a hobbyist and I usually take things only as far as I need to in order to convince myself that I can do something. It should give you a good start though. Paste the following code into a VB Form containing a CommonDialog Control, a Command Button and an Image Control. For test purposes set the Image Control's Stretch property to True (so that you can see the whole image and know that it prints properly) and set its Picture property to a picture that exists on your own machine. The example prints a couple of rectangles and a picture and some text, using two pages. Since it is just test code it makes no attempt to maintain the original aspect ratio of the picture when printing it, but you can of course easily add code to do that. Mike Option Explicit Private Declare Function StartDoc Lib "gdi32" Alias _ "StartDocA" (ByVal hdc As Long, lpdi As DOCINFO) As Long Private Declare Function EndDoc Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function StartPage Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function EndPage Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function CreateCompatibleDC Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function CreateFontIndirect Lib "gdi32" _ Alias "CreateFontIndirectA" (lpLogFont As LOGFONT) As Long Private Declare Function SelectObject Lib "gdi32" _ (ByVal hdc As Long, ByVal hObject As Long) As Long Private Declare Function CreatePen Lib "gdi32" _ (ByVal nPenStyle As Long, ByVal nWidth As Long, _ ByVal crColor As Long) As Long Private Declare Function DeleteObject Lib "gdi32" _ (ByVal hObject As Long) As Long Private Declare Function DeleteDC Lib "gdi32" _ (ByVal hdc As Long) As Long Private Declare Function StretchBlt Lib "gdi32" _ (ByVal hdc As Long, _ ByVal x As Long, ByVal y As Long, _ ByVal nWidth As Long, ByVal nHeight As Long, _ ByVal hSrcDC As Long, ByVal xSrc As Long, _ ByVal ySrc As Long, _ ByVal nSrcWidth As Long, ByVal nSrcHeight As Long, _ ByVal dwRop As Long) As Long Private Declare Function SetStretchBltMode Lib "gdi32" _ (ByVal hdc As Long, ByVal nStretchMode As Long) As Long Private Declare Function TextOut Lib "gdi32" Alias _ "TextOutA" (ByVal hdc As Long, ByVal x As Long, ByVal _ y As Long, ByVal lpString As String, ByVal nCount _ As Long) As Long Private Declare Function GetDeviceCaps Lib "gdi32" _ (ByVal hdc As Long, ByVal nindex As Long) As Long Private Declare Function SetBkMode Lib "gdi32" _ (ByVal hdc As Long, ByVal nBkMode As Long) As Long Private Declare Function Rectangle Lib "gdi32" _ (ByVal hdc As Long, ByVal x1 As Long, ByVal y1 As Long, _ ByVal x2 As Long, ByVal y2 As Long) As Long Private Const LF_FACESIZE As Long = 32& Private Const LOGPIXELSX As Long = 88& Private Const LOGPIXELSY As Long = 90& Private Const PHYSICALOFFSETX As Long = 112& Private Const PHYSICALOFFSETY As Long = 113& Private Const PHYSICALWIDTH As Long = 110& Private Const PHYSICALHEIGHT As Long = 111& Private Const POINTSPERINCH As Long = 72& Private Const NORMAL As Long = 400& Private Const BOLD As Long = 700& Private Const TRANSPARENT As Long = 1& Private Const OPAQUE As Long = 2& Private Const STRETCH_ANDSCANS As Long = 1& Private Const STRETCH_ORSCANS As Long = 2& Private Const STRETCH_DELETESCANS As Long = 3& Private Const STRETCH_HALFTONE As Long = 4& Private Const PS_SOLID As Long = 0& Private Type DOCINFO cbSize As Long lpszDocName As String lpszOutput As String lpszDatatype As String fwType As Long End Type Private Type LOGFONT lfHeight As Long lfWidth As Long lfEscapement As Long lfOrientation As Long lfWeight As Long lfItalic As Byte lfUnderline As Byte lfStrikeOut As Byte lfCharSet As Byte lfOutPrecision As Byte lfClipPrecision As Byte lfQuality As Byte lfPitchAndFamily As Byte lfFaceName As String * LF_FACESIZE End Type Private Type PrinterInfo Handle As Long PixPerInchX As Long PixPerInchY As Long OffsetX As Long OffsetY As Long PageWidthInches As Single PageHeightInches As Single End Type Private MyPrinter As PrinterInfo Private UserCancelled As Boolean Private LF1 As LOGFONT Private oldFont As Long, oldPen As Long Private myFont1 As Long, myFont2 As Long, myFont3 As Long Private myPen1 As Long, myPen2 As Long Private Sub GetMyPrinter() UserCancelled = False CommonDialog1.PrinterDefault = False CommonDialog1.CancelError = True ' The following cdlPDReturnDC flag is essential, but ' you can combine it with other flags if you wish CommonDialog1.Flags = cdlPDReturnDC On Error GoTo dlgError CommonDialog1.ShowPrinter On Error GoTo 0 MyPrinter.Handle = CommonDialog1.hdc MyPrinter.PixPerInchX = GetDeviceCaps _ (MyPrinter.Handle, LOGPIXELSX) MyPrinter.PixPerInchY = GetDeviceCaps _ (MyPrinter.Handle, LOGPIXELSY) MyPrinter.OffsetX = GetDeviceCaps _ (MyPrinter.Handle, PHYSICALOFFSETX) MyPrinter.OffsetY = GetDeviceCaps _ (MyPrinter.Handle, PHYSICALOFFSETY) MyPrinter.PageWidthInches = CSng(GetDeviceCaps _ (MyPrinter.Handle, PHYSICALWIDTH)) / _ MyPrinter.PixPerInchX MyPrinter.PageHeightInches = CSng(GetDeviceCaps _ (MyPrinter.Handle, PHYSICALHEIGHT)) / _ MyPrinter.PixPerInchY ' Set up a few fonts that can be easily used ' throughout the printing code (this is just the ' way I personally prefer to do it rather than ' create and destroy a font each time I use one) With LF1 .lfFaceName = "Times New Roman" + Chr$(0) ' 12 point standard .lfEscapement = 0 .lfHeight = 12 * (-MyPrinter.PixPerInchY / POINTSPERINCH) .lfWeight = NORMAL End With myFont1 = CreateFontIndirect(LF1) With LF1 .lfFaceName = "Times New Roman" + Chr$(0) ' 16 point standard .lfEscapement = 0 .lfHeight = 16 * (-MyPrinter.PixPerInchY / POINTSPERINCH) .lfWeight = NORMAL End With myFont2 = CreateFontIndirect(LF1) With LF1 .lfFaceName = "Times New Roman" + Chr$(0) ' 12 point rotated by 90 degrees .lfEscapement = 900 .lfHeight = 12 * (-MyPrinter.PixPerInchY / POINTSPERINCH) .lfWeight = NORMAL End With myFont3 = CreateFontIndirect(LF1) ' store the old font handle and set the initial font to myFont1 oldFont = SelectObject(MyPrinter.Handle, myFont1) ' set up a couple of black pens (0.01 inches and 0.025 inches) myPen1 = CreatePen(PS_SOLID, MyPrinter.PixPerInchX * 0.01, vbBlack) myPen2 = CreatePen(PS_SOLID, MyPrinter.PixPerInchX * 0.025, vbBlack) ' store the old pen handle and set the initial pen to myPen1 oldPen = SelectObject(MyPrinter.Handle, myPen1) SetBkMode MyPrinter.Handle, TRANSPARENT ' FontTransparent ' Set the stretch mode to the desired mode SetStretchBltMode MyPrinter.Handle, STRETCH_DELETESCANS 'SetStretchBltMode MyPrinter.Handle, STRETCH_HALFTONE Exit Sub dlgError: UserCancelled = True End Sub Private Sub TextPrint(s1 As String, x As Single, y As Single) Dim xpos As Long, ypos As Long xpos = x * MyPrinter.PixPerInchX - MyPrinter.OffsetX ypos = y * MyPrinter.PixPerInchY - MyPrinter.OffsetY TextOut MyPrinter.Handle, xpos, ypos, s1, Len(s1) End Sub Private Sub RectPrint(x1 As Single, y1 As Single, _ x2 As Single, y2 As Single) Rectangle MyPrinter.Handle, _ x1 * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _ y1 * MyPrinter.PixPerInchY - MyPrinter.OffsetY, _ x2 * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _ y2 * MyPrinter.PixPerInchY - MyPrinter.OffsetY End Sub Private Function PrintImage(p1 As StdPicture, _ x As Single, y As Single, wide As Single, _ high As Single) As Boolean Dim hOldBitmap As Long, hMemoryDC As Long hMemoryDC = CreateCompatibleDC(Me.hdc) hOldBitmap = SelectObject(hMemoryDC, p1.Handle) ' Note: I use StretchBlt here because it is what ' I normally use for the printing of various ' images, but you could probably use the ' Render method instead if you wish StretchBlt MyPrinter.Handle, _ x * MyPrinter.PixPerInchX - MyPrinter.OffsetX, _ y * MyPrinter.PixPerInchY - MyPrinter.OffsetY, _ wide * MyPrinter.PixPerInchX, _ high * MyPrinter.PixPerInchY, _ hMemoryDC, _ 0, 0, _ Me.ScaleX(p1.Width, vbHimetric, vbPixels), _ Me.ScaleY(p1.Height, vbHimetric, vbPixels), _ vbSrcCopy hOldBitmap = SelectObject(hMemoryDC, hOldBitmap) DeleteDC hMemoryDC End Function Private Sub Command1_Click() Dim lret As Long, s1 As String, docinf As DOCINFO ' Display a printer dialog and set up a printer DC ' in accordance with the user's selection and set ' up a few fonts and a couple of pens GetMyPrinter ' Exit if the user pressed Cancel in the dialog If UserCancelled Then Exit Sub End If ' start a document docinf.cbSize = 20 ' Size of DOCINFO structure lret = StartDoc(MyPrinter.Handle, docinf) 'Start document If lret < 0 Then MsgBox "Failed to start document" Exit Sub End If lret = StartPage(MyPrinter.Handle) 'Start a new page If lret < 0 Then MsgBox "Failed to start page!" EndDoc MyPrinter.Handle Exit Sub End If ' print a rectangle using myPen1 with an exact one ' inch all round border SelectObject MyPrinter.Handle, myPen1 RectPrint 1, 1, MyPrinter.PageWidthInches - 1, _ MyPrinter.PageHeightInches - 1 ' print a rectangle just inside it using the thicker myPen2 SelectObject MyPrinter.Handle, myPen2 RectPrint 1.1, 1.1, MyPrinter.PageWidthInches - 1.1, _ MyPrinter.PageHeightInches - 1.1 ' print an image at location 1.2,1.2 at size 3 x 2 inches PrintImage Image1.Picture, 1.2, 1.2, 3, 2 ' print some text using myFont1 SelectObject MyPrinter.Handle, myFont1 s1 = "This is some text on page ONE " TextPrint s1, 1.2, 1.2 ' print some text (positions in inches) ' print some more text using myFont2 SelectObject MyPrinter.Handle, myFont2 s1 = "This should be in myFont2, which we have set to 16 points" TextPrint s1, 1.2, 2 ' print some m ore text using myFont3 SelectObject MyPrinter.Handle, myFont3 s1 = "And this should be 12 points rotated at 90 degrees." TextPrint s1, 1.2, 7 lret = EndPage(MyPrinter.Handle) 'End the page lret = StartPage(MyPrinter.Handle) ' start a new page ' now change back to myFont1 SelectObject MyPrinter.Handle, myFont1 s1 = "And this is on page Two" TextPrint s1, 1, 1 lret = EndPage(MyPrinter.Handle) 'End the page lret = EndDoc(MyPrinter.Handle) 'End the document ' Reset font back to original and delete font we created SelectObject MyPrinter.Handle, oldFont DeleteObject myFont1 'Delete the fonts DeleteObject myFont2 DeleteObject myFont3 SelectObject MyPrinter.Handle, oldPen DeleteObject myPen1 ' Delete the pens DeleteObject myPen2 ' Delete the printer DC DeleteDC MyPrinter.Handle End Sub
From: Shotgun Thom on 17 Jun 2010 13:29 Thanks, Mike. I see what you're doing. This will be helpful in future projects and I thank you. The problem with the Konica client is that we are using the TxText control, which has two internal print routines. A print page method and a print doc method. When calling these methods we actually do pass the Printer.hDC to the control. However, it seems to have no impact on the settings of those special print options. Still have to change the defaults directly in the printer and then set it back afterwards for it to take effect. I really don't like doing it that way. BTW, one danger of doing it this way is duplicate settings. You'll love this. The Konica allows you to select the number of copies to print directly in it's setup program. He needed 44 copies and set the copies option to 44. After clicking OK he noticed the copies number in the command dialog box said 1 so he changed it to 44. Hit print... and you guessed it.... he got 44 sets of 44 copies. Cleaned out the paper bins before he realized it. :) Thanks, again, Mike! Tom
From: Mike Williams on 17 Jun 2010 17:26 "Shotgun Thom" <tmoran4511(a)gmail.com> wrote in message news:8ddc34e9-af22-43f5-85cb-13feac34ffcb(a)x27g2000prf.googlegroups.com... > Thanks, Mike. I see what you're doing. This will be > helpful in future projects and I thank you. You're welcome. > The problem with the Konica client is that we are using the > TxText control, which has two internal print routines. A > print page method and a print doc method. When calling > these methods we actually do pass the Printer.hDC to the > control. However, it seems to have no impact on the settings > of those special print options. Still have to change the defaults > directly in the printer and then set it back afterwards for it to > take effect. I really don't like doing it that way. Well it won't succeed if you are passing the VB Printer Object's hDC (as is implied in your statement, "we pass the Printer.hDC") because the VB Printer Object has not been set up to deal with (and actually cannot be set up to deal with) those special print options. I've never heard of the TxText control and therefore have no knowledge of how it fits into your program, but you will have much more chance of success if you use the code I posted to show the printer dialog to the user in such a way that it returns a DC from the dialog (exactly as it does in the code I posted) and if you pass /the returned hDC/ to the TxText control. > BTW, one danger of doing it this way is duplicate settings. You'll > love this. The Konica allows you to select the number of copies > to print directly in it's setup program. He needed 44 copies and > set the copies option to 44. After clicking OK he noticed the copies > number in the command dialog box said 1 so he changed it to 44. > Hit print...and you guessed it.... he got 44 sets of 44 copies. > Cleaned out the paper bins before he realized it. :) That's a good one! I don't know how the Konica deals with such things, nor from your brief explanation do I know the full details of how this actually occurred (perhaps the TxText Control you are using and the Konica itself ended up /both/ being set for 44 copies, and I'm sure there is a way of making sure it does not happen like that again) but it is interesting nonetheless. Maybe under such circumstances you could hang the surplus 1892 pages on the back of the toilet door (or do they perhaps call them something other than toilets on your side of the big pond?). At least they'd be of some use there ;-) You'd need to alter your code so that it does /not/ do duplex printing though. I think for such a use at least one side of the page should have no ink on it ;-) > Thanks, again, Mike! You're welcome. Mike
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 Prev: Windows 7 Compliance: VB6 and Adhering to REstart Manager messages Next: Poooooor Fred... |