Announcement

Collapse
No announcement yet.

hBmp & Printer

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Dominic Mitchell
    replied
    Jeffrey,
    The win32api declaration is correct. Semen used an indirect method to
    get the bitmap bits. The direct method is to call CreateDIBSection as follows-
    Code:
      LOCAL     pbBits        AS BYTE PTR
    
      ' Create the destination bitmap(a 24 bpp top down dib)
      ' ----------------------------------------------------
      hDCDest    = CreateCompatibleDC(hDC)
      ' Calculate bytes per scan line
      cblPerLine = ((cxPaint * 3 + 3) \ 4) * 4
      cblImage   = cblPerLine * cyPaint
      tbmi.bmiHeader.biSize         = SIZEOF(tbmi.bmiHeader)
      tbmi.bmiHeader.biWidth        = cxPaint
      tbmi.bmiHeader.biHeight       = -cyPaint
      tbmi.bmiHeader.biPlanes       = 1
      tbmi.bmiHeader.biBitCount     = 24
      tbmi.bmiHeader.biCompression  = %BI_RGB
      tbmi.bmiHeader.biSizeImage    = cblImage
      tbmi.bmiHeader.biClrUsed      = 0
      tbmi.bmiHeader.biClrImportant = 0
      hDIB = CreateDIBSection(hDCDest, tbmi, %DIB_RGB_COLORS, VARPTR(pbBits), %NULL, 0)
    ------------------
    Dominic Mitchell

    [This message has been edited by Dominic Mitchell (edited November 01, 2000).]

    Leave a comment:


  • Guest's Avatar
    Guest replied
    Semen, a couple of comments on the CreateDIBSection function.
    I am far from an expert on Windows bitmaps, but ....

    1. I'm not sure your dibsection is getting any bits. The documentation
    suggests that you need to set a long variable by ref in the lplpvoid field. This
    will contain the bitmap data of the dibsection. Then, you use a
    stretchblt command passing the data pointer.

    2. The declaration in the win32api file uses byval lplpvoid as long. This
    will not work since only the temporary copy of the variable will be initialized.
    Apparently this function creates its own memory block to contain the bit data.
    So,you need to retrieve the pointer value from the function. BTW, this is not PB's
    problem, apparently Microsoft orginally declared the function this way.

    Jeff


    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Guys --
    What I currently do ... (note PB/CC; console should be in window)
    Code:
       #Compile Exe
       #Register None
       #Dim All
       #Include "Win32Api.Inc"
       #Include "ComDlg32.Inc"
    
       $FileBmp = "C:\WinNt\WinNt.bmp" ' <---------- CHANGE
    
       Global hWndConsole As Long, hConsoleDC As Long, rcfConsole As RECT
    
    
       Function GetDefaultPrinterDC As Long
    
          Dim PrinterName As Asciiz * %MAX_PATH
    
          GetProfileString "WINDOWS", "DEVICE", ",,,", PrinterName, SizeOf(PrinterName)
          PrinterName = Left$(PrinterName, Instr(PrinterName$, ",") - 1)
          If PrinterName = "" Then Exit Function
          Function = CreateDC(ByVal %Null, PrinterName$, ByVal %Null, ByVal %Null)
    
       End Function
    
       Sub GetConsoleDCRC
          Dim pt As POINTAPI
    
          hConsoleDC = GetWindowDC(hWndConsole)
          GetWindowRect hWndConsole, rcfConsole
          ClientToScreen hWndConsole, pt
          pt.x = pt.x - rcfConsole.nLeft
          pt.y = pt.y - rcfConsole.nTop
          GetClientRect hWndConsole, rcfConsole
          rcfConsole.nLeft   = rcfConsole.nLeft + pt.x
          rcfConsole.nRight  = rcfConsole.nRight + pt.x
          rcfConsole.nTop    = rcfConsole.nTop + pt.y
          rcfConsole.nBottom = rcfConsole.nBottom + pt.y
    
       End Sub
    
       Function PrintConsoleWindow As Long
    
          GetConsoleDCRC
          Local hMemDC As Long, hMemBmp As Long, hMemBmpOld As Long, bmi As BITMAPINFO, bm As BITMAP
    
          ' Prepare screen bitmap (hMemBmp)
          bmi.bmiHeader.biSize = SizeOf(bmi.bmiHeader)
          bmi.bmiHeader.biWidth = (rcfConsole.nRight - rcfConsole.nLeft)
          bmi.bmiHeader.biHeight = (rcfConsole.nBottom - rcfConsole.nTop)
          bmi.bmiHeader.biPlanes = 1
          bmi.bmiHeader.biBitCount =   24
          bmi.bmiHeader.biCompression = %BI_RGB
          hMemDC = CreateCompatibleDC (hConsoleDC)
          hMemBmp = CreateDIBSection(hMemDC, bmi, %DIB_RGB_COLORS, 0, 0, 0)
          GlobalLock hMemBmp
          hMemBmpOld = SelectObject (hMemDC, hMemBmp)
          GetObject hMemBmp, SizeOf(bm), bm
          BitBlt hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, hConsoleDC, rcfConsole.nLeft, rcfConsole.nTop, %SRCCOPY
          SelectObject hMemDC, hMemBmpOld
          DeleteDC hMemDC
    
          '----------
          Local hPrDC   As Long
          Local di     As DOCINFO
          Local dn     As Asciiz * 64
    
          hPrDC = GetDefaultPrinterDC
    
          If hPrDC Then
             Local hBmpDC As Long
    
             Local x      As Long
             Local y      As Long
    
             x = GetDeviceCaps(hPrDC, %HORZRES)
             y = CLng((x / (rcfConsole.nRight - rcfConsole.nLeft)) * (rcfConsole.nBottom - rcfConsole.nTop))
    
             dn = "Ltr"
             di.cbSize = SizeOf(di)
             di.lpszDocName = VarPtr(dn)
    
             ' scale the bitmap to the width of the page
             hBmpDC   = CreateCompatibleDC(hPrDC)
             SelectObject hBmpDC, hMemBmp
    
             If StartDoc(hPrDC, di) > 0 Then
                If StartPage(hPrDC) > 0 Then
                   StretchBlt hPrDC, 0, 0, x, y, hBmpDC, 0, 0, rcfConsole.nRight - rcfConsole.nLeft, _
                     rcfConsole.nBottom - rcfConsole.nTop, %SRCCOPY
                   EndPage hPrDC
                End If
                EndDoc hPrDC
             End If
    
             DeleteDC hPrDC
             DeleteDC hBmpDC
    
          End If
    
          DeleteObject hMemBmp
          ReleaseDc hWndConsole, hConsoleDC
    
        End Function
    
    
       Function PbMain
    
          hWndConsole = GetForegroundWindow
    
          GetConsoleDCRC
    
          Local hBmp As Long, hBmpDC As Long
          hBmp = LoadImage(ByVal %NULL, $FileBmp, %IMAGE_BITMAP, _
             rcfConsole.nRight - rcfConsole.nLeft, rcfConsole.nBottom - rcfConsole.nTop, %LR_LOADFROMFILE)
          hBmpDC = CreateCompatibleDC(hConsoleDC)
          SelectObject hBmpDC, hBmp
          BitBlt hConsoleDC, rcfConsole.nLeft, rcfConsole.nTop, _
             rcfConsole.nRight - rcfConsole.nLeft, rcfConsole.nBottom - rcfConsole.nTop, _
             hBmpDC, 0, 0, %SRCCOPY
          DeleteDC hBmpDC
          ReleaseDc hWndConsole, hConsoleDC
    
          Local i As Long
          For i = 1 To 10
             Locate 2 + i, 10: Print "      Line       " + Format$(i, "00") + "             "
          Next
    
          PrintConsoleWindow
    
       End Function
    This works on my PC under 2000 and 98, color and black/white printing.
    But something confuses me.
    I decided that to build true color DIB section for printer DC is too expensive (too many dots).
    Alone, what I do - I select DIB section into printer-compatible DC.

    Guys, somebody have problems with this code (under any OS, with network printers and so on) ?



    ------------------
    E-MAIL: [email protected]

    Leave a comment:


  • Don Dickinson
    replied
    The bottom line is that you can't rely on bitblt or stretchblt to copy a bitmap to a printer. By definition, these work on device dependent bitmaps. They might work, but there is no guarantee.
    You have to use some sort of DIB operation (like StretchDIBits as suggested by Borje). Before doing this, you must create a dib. It looks like you might be going in the right direction with CreateDIBSection - that's one way to get a dib from a bitmap. I'm not familiar with the details of this approach, though.

    Best Regards,
    Don

    ------------------

    Leave a comment:


  • Borje Hagsten
    replied
    Hm, if you have the bitmap created that way, maybe you can try
    StretchDIBits() instead? I once had to do this in a print preview
    function in an earlier version of my software, because StretchBlt
    failed to work properly with some grafik cards and printers.
    StretchDIBits turned out to be a little bit slower but seemed to
    work better. At least I got fewer support calls after I started
    using it instead..


    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Borje --
    Thanks, but alone, which I saw
    If (!StretchBlt(pd.hDC, ... errhandler("StretchBlt Failed", hwnd)

    I have no troubles on my PC, when I copy screen hDC to printer hDC.
    But theoretically users can have.

    I'm interesting, what to do if GetDeviceCaps (RC_BITBLT and RC_STRETCHBLT) shows that such operations ARE NOT AVAILABLE.

    What gues do you think about following way (I can't imitate situation)
    1) To create 24-bits DIB section, compatible with printer DC.
    To select it into Printer DC.
    2) Instead of BitBlt (stretchBlt), to copy all "pixels" directly from DIB-section, compatible with screen.
    Does this solve a problem or not ?

    [This message has been edited by Semen Matusovski (edited November 01, 2000).]

    Leave a comment:


  • Borje Hagsten
    replied
    Just a silly idea, but.. have you tried using StretchBlt instead
    of BitBlt? A tip: there's a sample under "Printing a Document" in
    win32.api.hlp that shows how print a string of text and a bitmapped
    image, by using StretchBlt. Could be useful to look at..


    ------------------

    Leave a comment:


  • Semen Matusovski
    replied
    Don --
    I want to avoid direct copying from screen hDC to printer hDC (BTW, which works fine on my PC).

    I read a recommendation to do following -
    1) Create printer-compatible memory DC (hPrDC).
    2) Create printer-compatible hPrBmp.
    3) Select hPrBmp into hPrDC (clear), copy "screen" bitmap into hPrBmp (???) and then copy that bitmap to the printer DC.

    I can't understand p.3.
    Really I have no screen hBmp, I build it from window hDC.
    Code:
         ' Prepare screen bitmap (hMemBmp)
          bmi.bmiHeader.biSize = SizeOf(bmi.bmiHeader)
          bmi.bmiHeader.biWidth = (rcfConsole.nRight - rcfConsole.nLeft)
          bmi.bmiHeader.biHeight = (rcfConsole.nBottom - rcfConsole.nTop)
          bmi.bmiHeader.biPlanes = 1
          bmi.bmiHeader.biBitCount =   24
          bmi.bmiHeader.biCompression = %BI_RGB
          hMemDC = CreateCompatibleDC (hConsoleDC)
          hMemBmp = CreateDIBSection(hMemDC, bmi, %DIB_RGB_COLORS, 0, 0, 0)
    hConsoleDC is hDC of screen window.
    After filling hMemDC and some additional actions, I have "free" hBmp and is able to select it into another screen compatible hDC.

    Now I try to follow p.3 of recommendations (but w/o sample).

    How to understand (to translate to API) -
    1) copy bitmap, which you want to Print, (hMemBmp) into hPrBmp (???) and
    2) then copy that bitmap to the printer DC.


    [This message has been edited by Semen Matusovski (edited November 01, 2000).]

    Leave a comment:


  • Don Dickinson
    replied
    BitBlt does not always work with printers unless the bitmap is monochrome. Sometimes it will work, sometimes not.
    You have to use a DIB to print reliably to windows printers. This brings up some issues of palettes, etc and gets a little complicated.
    If you search the code area for DIB you'll probably find some code.

    Best Regards,
    Don

    ------------------

    Leave a comment:


  • Semen Matusovski
    started a topic hBmp & Printer

    hBmp & Printer

    Hi, guys --
    Easy question, but ...
    There is pd As PRINTDLGAPI, received by PrintDlg(pd), and "free" true-colour hBmp.

    I have troubles with following
    Code:
         Local hBmpDC As Long
         hBmpDC = CreateCompatibleDC(pd.hDC)
         SelectObject hBmpDC, hMemBmp
         BitBlt pd.hDC, 0, 0, _
             rcfConsole.nRight - rcfConsole.nLeft, rcfConsole.nBottom - rcfConsole.nTop, _
             hBmpDC, 0, 0, %SRCCOPY
    Return values are correct, and even a printer is color.
    Print job appears, but without my picture.

    At the same time
    Code:
          Local pdHDC As Long
          pDhDC = GetWindowDC(GetDesktopWindow)
          hBmpDC = CreateCompatibleDC(pdhDC)
          SelectObject hBmpDC, hMemBmp
          BitBlt pdhDC, 0, 0, _
             rcfConsole.nRight - rcfConsole.nLeft, rcfConsole.nBottom - rcfConsole.nTop, _
             hBmpDC, 0, 0, %SRCCOPY)
          ReleaseDC GetDesktopWindow, pdHdc
    works fine on the screen.

    What am I doing wrong ?

    ------------------
    E-MAIL: [email protected]
Working...
X