This posting is meant to be informational, rather than directly compilable. You will not be able to compile it as it make a number of calls to supporting procedures contained in my DLL's. The purpose of the procedure is for printing out images on a printer using PB code. The concepts are not difficult, but if you have not done this stuff before, they might seem daunting. Feel free to go through this code, and if you need any clarification/tech support, by all means, send me an e-mail or post in these forums.
All code posted here is released to the Public Domain.
All code posted here is released to the Public Domain.
Code:
%HANDLETYPE = 10001 %ICON2 = %HANDLETYPE + 1 %WINDOW = %ICON2 + 1 %DC = %WINDOW + 1 %MEMDC = %DC + 1 %BITMAP = %MEMDC + 1 %DIB = %BITMAP + 1 %FONT = %DIB + 1 %BRUSH = %FONT + 1 %PEN = %BRUSH + 1 %MENU = %PEN + 1 %PRINTERDC = %MENU + 1 %comm = %PRINTERDC + 1 %tcp = %comm + 1 %pop3 = %tcp + 1 %disk = %pop3 + 1 %filemappingfm = %disk + 1 %filemappingmap = %filemappingfm + 1 %event = %filemappingmap + 1 %mutex = %event + 1 %criticalsection = %mutex + 1 %smtp = %criticalsection + 1 %scalepage = 1 %scaleimage = 2 %pixels = 3 %stretch = 4 %center = 5 %match = 6 %right = 7 %bottom = 8 TYPE printccc pdf as long choose as long default as long issource as long sprinter as asciiz*1024 stitle as asciiz*1024 charsprinted as long fax as long sfont as asciiz*128 lfont as long copies as long landscape as long centerx as long centery as long centerlines as long pagestart2 as long pageend2 as long pagestart as long pageend as long color1 as dword sdoc as asciiz*128 outfile as asciiz*%maxpath vt as dword header as long maxlines as long hwnd as long enableissource as long newpage as long rotation as long count as long himage1 as long himage2 as asciiz*%max_path scalextype as long scaleytype as long scalex as ext scaley as ext posxtype as long posytype as long posx as ext posy as ext testandreturn as long returnimagex as long returnimagey as long returnoffsetx as long returnoffsety as long returnpagex as long returnpagey as long END TYPE function PrintImage (x2 as printccc) export as long function = 0 if areprinters() then exit function local xptrb as printccc ptr, xb as printccc xptrb = varptr(x2) xb = @xptrb[0] local flag as long IF xb.sprinter = "" THEN xb.sprinter = getdefaultprinterclay : flag = -1 if xb.sdoc = "" then xb.sdoc = date$ + $spc + time$ LOCAL L1 AS LONG, s AS STRING for L1 = 1 to getprintercount if instr2(1, getprintername(L1), xb.sprinter) then xb.sprinter = getprintername(L1) : flag = -1 : exit for end if next if flag = 0 then exit function local hprinter as long, pdevmode as devmode ptr, hmem as dword, xb1 as printer_defaults xb1.desiredaccess = %printer_all_access L1 = openprinter(xb.sprinter, hprinter, xb1) if L1 = 0 or hprinter = %null then exit function local xa1 as string, xa2 as string, xa3 as string, xa4 as string, xa5 as string, xa6 as string local xa1ptr as printer_info_2 ptr, xa2ptr as printer_info_2 ptr, xa3ptr as printer_info_2 ptr xa1 = string$(100000, 0) xa2 = string$(100000, 0) xa1ptr = strptr(xa1) @xa1ptr.pdevmode = strptr(xa2) getprinter hprinter, 2, byval xa1ptr, len(xa1), L1 xa3 = xa1 xa4 = xa2 xa2ptr = strptr(xa3) @xa2ptr.pdevmode = strptr(xa4) @xa1ptr.attributes = (@xa1ptr.attributes and (not %printer_attribute_direct)) @xa1ptr.attributes = (@xa1ptr.attributes or %printer_attribute_queued) setprinter hprinter, 2, byval xa1ptr, 0 #if 1 if xb.landscape then hmem = globalalloc(%ghnd, 100000) if hmem = %null then setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if pdevmode = globallock(hmem) if documentproperties(0, hprinter, xb.sprinter, byval pdevmode, byval 0, %dm_out_buffer) < 0 then globalunlock pdevmode globalfree hmem setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if @pdevmode.dmfields = (@pdevmode.dmfields or %dm_orientation) if xb.landscape < 0 then @pdevmode.dmorientation = %dmorient_landscape else @pdevmode.dmorientation = %dmorient_portrait end if if documentproperties(0, hprinter, xb.sprinter, byval pdevmode, byval pdevmode, %dm_out_buffer or %dm_in_buffer) < 0 then globalunlock pdevmode globalfree hmem setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if end if #endif LOCAL hdc as dword hdc = createdc("WINSPOOL", xb.sprinter, byval 0, byval pdevmode) if hdc = %null then if pdevmode then globalunlock pdevmode if hmem then globalfree hmem setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if local wdoc as docinfo wdoc.cbsize = len(wdoc) wdoc.lpszdocname = varptr(xb.sdoc) if startdoc(hdc, wdoc) =< 0 then if pdevmode then globalunlock pdevmode if hmem then globalfree hmem deletedc hdc setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if startpage hdc local xptr as printccc ptr, x as printccc, lux as long xptr = varptr(x2) printing = -1 for lux = 1 to max(1, @xptr[0].count) x = @xptr[lux - 1] if x.newpage then endpage hdc startpage hdc end if local himage2 as long, himage3 as long select case getobjecttype2(x.himage1) case %icon2 himage2 = icontobitmap(x.himage1) case %dib, %bitmap himage2 = copyimage(x.himage1, %image_bitmap, 0, 0, %lr_createdibsection) case else himage2 = loadimageasbitmap(ve, x.himage2, ve) end select select case getobjecttype2(himage2) case %dib case else iterate for end select if x.rotation then himage3 = rotatebitmap(himage2, x.rotation) deleteobject himage2 himage2 = himage3 end if local LX as long, LY as long, loffsetx as long, loffsety as long, llines as long local lx2 as long, ly2 as long, lx5 as long, ly5 as long local loffsetx2 as long, loffsety2 as long LX = getdevicecaps(hdc, %horzres) LY = getdevicecaps(hdc, %vertres) loffsetx = getdevicecaps(hdc, %physicaloffsetx) loffsety = getdevicecaps(hdc, %physicaloffsety) LX = min(LX, getdevicecaps(hdc, %physicalwidth) - (2 * max(loffsetx, getdevicecaps(hdc, %logpixelsx) \ 4))) LY = min(LY, getdevicecaps(hdc, %physicalheight) - (2 * max(loffsety, getdevicecaps(hdc, %logpixelsy) \ 4))) getbitmapxy himage2, lx2, ly2 local cx as ext, cy as ext if x.scalextype = %match and x.scaleytype = %match then x.scaleytype = 0 if x.scalextype = %stretch then cx = LX elseif x.scalextype = %scalepage then cx = LX * x.scalex elseif x.scalextype = %scaleimage then cx = lx2 * x.scalex elseif x.scalextype = %pixels then cx = x.scalex else local hdc2 as dword, lx3 as long, lx4 as long hdc2 = getdc(%hwnd) lx3 = getdevicecaps(hdc2, %logpixelsx) releasedc %hwnd, hdc2 lx4 = getdevicecaps(hdc, %logpixelsx) if lx3 > lx4 then cx = min(lx, lx2 * (lx3 / lx4)) else cx = min(lx, lx2 * (lx4 / lx3)) end if end if if x.scaleytype = %match then cy = cx * (ly2 / lx2) else if x.scaleytype = %stretch then cy = LY elseif x.scaleytype = %scalepage then cy = LY * x.scaley elseif x.scaleytype = %scaleimage then cy = ly2 * x.scaley elseif x.scaleytype = %pixels then cy = x.scaley else hdc2 = getdc(%hwnd) lx3 = getdevicecaps(hdc2, %logpixelsy) releasedc %hwnd, hdc2 lx4 = getdevicecaps(hdc, %logpixelsy) if lx3 > lx4 then cy = ly2 * (lx3 / lx4) else cy = ly2 * (lx4 / lx3) end if end if end if if x.scalextype = %match then cx = cy * (lx2 / ly2) end if cx = fix(min(cx, lx)) cy = fix(min(cy, ly)) ! push lx2 ! push ly2 lx2 = cx : ly2 = cy if x.posxtype = %center then loffsetx = loffsetx + max(0, ((lx - lx2) \ 2) - (0.0## * loffsetx)) elseif x.posxtype = %scalepage then loffsetx = max(loffsetx, min((lx + loffsetx) - lx2, loffsetx + (lx * x.posx))) elseif x.posxtype = %pixels then loffsetx = max(loffsetx, min((lx + loffsetx) - lx2, loffsetx + x.posx)) elseif x.posxtype = %right then loffsetx = (loffsetx + lx) - lx2 end if if x.posytype = %center then loffsety = loffsety + max(0, ((ly - ly2) \ 2) - (0.0## * loffsety)) elseif x.posytype = %scalepage then loffsety = max(loffsety, min((ly + loffsety) - ly2, loffsety + (ly * x.posy))) elseif x.posytype = %pixels then loffsety = max(loffsety, min((ly + loffsety) - ly2, loffsety + x.posy)) elseif x.posytype = %bottom then loffsety = (loffsety + ly) - ly2 end if ! pop ly2 ! pop lx2 x.returnimagex = cx x.returnimagey = cy x.returnoffsetx = loffsetx x.returnoffsety = loffsety x.returnpagex = LX x.returnpagey = LY if @xptr[0].testandreturn then @xptr[lux - 1] = x deleteobject himage2 iterate for end if local memdc as dword, membit as dword memdc = createcompatibledc(hdc) membit = createcompatiblebitmap(hdc, lx2, ly2) membit = selectobject(memdc, membit) himage3 = selectobject(memdc, himage2) local L3 as long, L2 as long, sab as string, L6 as long local msg as tagmsg gosub domess2 if killprinter then reset killprinter reset printing function = 0 abortdoc hdc if pdevmode then globalunlock pdevmode if hmem then globalfree hmem deletedc hdc deleteobject selectobject(memdc, himage3) deleteobject selectobject(memdc, membit) deletedc memdc setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter exit function end if stretchblt2 hdc, loffsetx, loffsety, cx, cy, memdc, 0, 0, lx2, ly2, %srccopy deleteobject selectobject(memdc, himage3) deleteobject selectobject(memdc, membit) deletedc memdc NEXT endpage hdc enddoc hdc deletedc hdc if pdevmode then globalunlock pdevmode if hmem then globalfree hmem deleteobject selectobject(memdc, himage3) deleteobject selectobject(memdc, membit) deletedc memdc setprinter hprinter, 2, byval xa2ptr, 0 if hprinter then closeprinter hprinter reset killprinter, printing function = -1 exit function domess2: while peekmessage(msg, 0, 0, 0, %pm_remove) translatemessage msg dispatchmessage msg wend return END function