Hi everyone.

I'm having problems trying to write this small application to print a bitmap with a printer.
Attached is the application.

Instead of printing the bitmap of the car, all it gave me is a black box. My guess is i'm having problems with the bit values of the CreateDIBSection function and bitmap bits of the StretchDIBits function.

Please forgive me if my code is messy. I have just starting programming with Assembly.

Thanks for your help!

Code:

PrintSetUp proc hWnd:HWND, hDC:DWORD
local w_logpixx :DWORD
local w_logpixy :DWORD
local p_logpixx :DWORD
local p_logpixy :DWORD
local xscale :REAL10
local yscale :REAL10
local p_horzres :DWORD
local p_vertres :DWORD
local w_left :DWORD
local w_top :DWORD
local factor :DWORD
local tmpflt :REAL10
local tmpval :DWORD
local scaledWidth :DWORD
local scaledHeight :DWORD
local tmpDC :DWORD
local newDC :DWORD
local rc_bitblt :DWORD
local rc_stretchblt :DWORD
local tmpcmpbm :DWORD
local RGBQuadSize :DWORD
local numLines :DWORD
local bitsPerPixel :DWORD
local total :dword
local palEntrySize :dword
local prvBM :dword
local numEntries :word
local logPalHD :dword

invoke PrintDlgSetup, hWnd, ADDR pDlg
.if eax == 0
invoke MessageBox,NULL,ADDR PrintDlgSetup_error,OFFSET AppName,MB_OK
.endif

invoke PrintDlg, ADDR pDlg
.if eax == 0
invoke MessageBox,NULL,ADDR PrintDlg_error,OFFSET AppName,MB_OK
.endif

invoke DocInfoSetup, ADDR dInfo
.if eax == 0
invoke MessageBox,NULL,ADDR DocInfoSetup_error,OFFSET AppName,MB_OK
.endif

invoke StartDoc, pDlg.hDC, ADDR dInfo
.if eax == 0
invoke MessageBox,NULL,ADDR StartDoc_error,OFFSET AppName,MB_OK
.endif

invoke StartPage, pDlg.hDC
.if eax <= 0
invoke MessageBox,NULL,ADDR StartPage_error,OFFSET AppName,MB_OK
.endif

invoke GetDC, hWnd
mov tmpDC, eax
.if eax == 0
invoke MessageBox,NULL,ADDR GetDC_error,OFFSET AppName,MB_OK
.endif

invoke GetDeviceCaps, tmpDC, LOGPIXELSX
mov w_logpixx, eax

invoke GetDeviceCaps, tmpDC, LOGPIXELSY
mov w_logpixy, eax

invoke GetDeviceCaps, pDlg.hDC, LOGPIXELSX
mov p_logpixx, eax

invoke GetDeviceCaps, pDlg.hDC, LOGPIXELSY
mov p_logpixy, eax

mov eax, w_logpixx
.if eax > p_logpixx
fild w_logpixx
fild p_logpixx
fdiv
fstp xscale
.else
fild p_logpixx
fild w_logpixx
fdiv
fstp xscale
.endif

mov eax, w_logpixy
.if eax > p_logpixy
fild w_logpixy
fild p_logpixy
fdiv
fstp yscale
.else
fild p_logpixy
fild w_logpixy
fdiv
fstp yscale
.endif

invoke GetDeviceCaps, pDlg.hDC, HORZRES
mov p_horzres, eax

invoke GetDeviceCaps, pDlg.hDC, VERTRES
mov p_vertres, eax

invoke GetDeviceCaps, pDlg.hDC, BITSPIXEL
mov bitsPerPixel, eax

fild wwidth
fld xscale
fmul
frndint
fistp scaledWidth
fild scaledWidth
fdiv factor
fstp tmpflt

fild p_horzres
fdiv factor
fld tmpflt
fsub
frndint
fistp w_left

fild wheight
fld yscale
fmul
frndint
fistp scaledHeight
fild scaledHeight
fdiv factor
fstp tmpflt

fild p_vertres
fdiv factor
fld tmpflt
fsub
frndint
fistp w_top

push sizeof BITMAPINFOHEADER
pop bInfo.bmiHeader.biSize
push wwidth
pop bInfo.bmiHeader.biWidth
push wheight
pop bInfo.bmiHeader.biHeight
mov bInfo.bmiHeader.biPlanes, 1
mov bInfo.bmiHeader.biBitCount, 24
mov bInfo.bmiHeader.biCompression, BI_RGB
mov bInfo.bmiHeader.biSizeImage, 0
mov bInfo.bmiHeader.biXPelsPerMeter, 0
mov bInfo.bmiHeader.biYPelsPerMeter, 0
mov bInfo.bmiHeader.biClrUsed, 0
mov bInfo.bmiHeader.biClrImportant, 0

invoke CreateDIBSection,tmpDC,ADDR bInfo,DIB_RGB_COLORS,addr bitmapPt,0,0
.if eax == 0
invoke MessageBox,NULL,ADDR CreateDIBSection_error,OFFSET AppName,MB_OK
invoke GetLastError
push eax
pop ecx
invoke NumberToString, ecx
invoke MessageBox,NULL,ADDR StrNumBuf,OFFSET AppName,MB_OK
.else
mov tmpBM, ax
.endif

invoke StretchDIBits,pDlg.hDC,0,0,wwidth,wheight,0,0,wwidth,wheight,bitmapPt,ADDR bInfo,DIB_RGB_COLORS,SRCCOPY
.if eax == 0
invoke MessageBox,NULL,ADDR BitBlt_error,OFFSET AppName,MB_OK
invoke GetLastError
push eax
pop ecx
invoke NumberToString, ecx
invoke MessageBox,NULL,ADDR StrNumBuf,OFFSET AppName,MB_OK
.endif

invoke EndPage, pDlg.hDC
invoke EndDoc, pDlg.hDC
invoke DeleteDC,pDlg.hDC
invoke DeleteDC,newDC
invoke DeleteDC,tmpDC
invoke DeleteDC,hDC
ret
PrintSetUp endp
Posted on 2003-10-28 02:06:42 by trexxz
Sorry, i missed out the attachment.
Posted on 2003-10-28 02:07:47 by trexxz
If the problem it's in CreateDIBSection call you should try to change this

mov bInfo.bmiHeader.biSizeImage, 0
mov bInfo.bmiHeader.biXPelsPerMeter, 0
mov bInfo.bmiHeader.biYPelsPerMeter, 0

biXPelsPerMeter could be 600
biYPelsPerMeter should be 1

and the biSizeImage should be (biWidth*biHeight*3) + padding * biHeight

:alright:
Posted on 2003-10-28 03:53:08 by Eternal Idol Birmingham
Hi Eternal Idol Birmingham

thanks for you reply.

what is the value for "padding"? where should i get that from?

and how do you find out the values for biXPelsPerMeter and biYPelsPerMeter?

i tried using padding as 1 and implemented your recommendations but i still get a black box printed out.
Posted on 2003-10-28 04:17:37 by trexxz
Each scan line must be DWORD aligned, then it must be divisible by 4.

So if you have a bmp of 245 of width, the padding is one.
245*3 (24 bit bmp, as I saw you want to use) use one byte for earch Red, Green and Blue value.
So, 245*3 =735 / 4, it's not 0, then we need to add padding.
735+1/4 = 0, we are done.
We must add one zero in each scan line.

246 it's 2, 247 it's 3 and 248 it's 0.

C notation: padding = (4 - ((bmih.biWidth * 3) % 4)) & 3;

<<and how do you find out the values for biXPelsPerMeter and biYPelsPerMeter?
I just assumed those values, a regular printer could be 600 dpi.

If the problem it's in the CreateDIBSection call you should put also the biCompression to zero, always.
Posted on 2003-10-28 04:36:26 by Eternal Idol Birmingham
When do you fill the dibsection?
I don't know if this could work, I think you should you GetDIBits/SetDIBits.
Posted on 2003-10-28 04:50:12 by Eternal Idol Birmingham
"C notation: padding = (4 - ((bmih.biWidth * 3) % 4)) & 3;"
how do i translate this to assembly?
what does the operator "%" and "&" mean?

when u refer to the width of the bmp, do you mean the actual width of the bitmap? if so, the width is 334 pixels

I fill the dibsection by creating a compatible DC of the DC of the main window / application.
Posted on 2003-10-28 04:59:23 by trexxz
% it's modulus.

DIV SRC : Divides AH:AL, DX:AX, or EDX:EAX by SRC and stores into AL, AX
or EAX. The value stored is an integer. It is not rounded, but
rather truncated the low lower value. 5 divided by 2 = 2. The
remainder is stored in either AH, DX, or EDX.


& it's the and operator.
AND Dest,Source in assembler.

<<when u refer to the width of the bmp, do you mean the actual width of the bitmap? if so, the width is 334 pixels
Yes, then the padding it's 2.
Posted on 2003-10-28 05:11:58 by Eternal Idol Birmingham
thanks Eternal Idol Birmingham

I tried changing the values as you suggested but i still get the black box printed. :(
Posted on 2003-10-28 06:15:43 by trexxz
Have you tried without the StretchDIBits?

Are you using a black and white printer or a color one?

:alright:
Posted on 2003-10-28 06:21:10 by Eternal Idol Birmingham
I'm using StretchDIBits because it is able to target all printer DCs. (compared to BitBlt or StretchBlt)

To use StretchDIBits, i have to use DIBs. That's why i'm using CreateDIBSection to create a DIB. Am i right to do it this way? :confused:

Yes, i'm using a color printer.
Posted on 2003-10-28 09:39:09 by trexxz
Well, I'm not sure, and actually I'm at work.

I think you should test it with a "display" hdc, to see what's going on before throwing the data to the printer, testing that way will be much better.

See you.:alright:
Posted on 2003-10-28 09:45:30 by Eternal Idol Birmingham
thanks Eternal Idol Birmingham!

meanwhile, I'll try it out with GetDIBits instead of CreateDIBSection.
Posted on 2003-10-29 02:14:18 by trexxz