autodefine "off"

$INCLUDE "windowssdk.inc"

BITMAP bm
	DOCINFO di
	PRINTDLG pd

UINT left,top,width,height
WINDOW win

OPENWINDOW win,0,0,800,600,@MINBOX,0,"Print the Clipboard",&main
	SETWINDOWCOLOR win,RGB(240,240,240)
	CONTROL win,@BUTTON,"Exit",660,40,120,20,0x50000001,1
	CONTROL win,@BUTTON,"PrintWindow",660,80,120,20,0x50000000,2
	CONTROL win,@BUTTON,"Clip Horizontal",660,120,120,20,0x50000000,3
	CONTROL win,@BUTTON,"Clip Vertical",660,160,120,20,0x50000000,4
	CONTROL win,@BUTTON,"Use XnView",660,200,120,20,0x50000000,5
	FRONTPEN win,RGB(0,0,250)
	BACKPEN win,RGB(240,240,240)
	SETFONT win,"Arial",48,700,0|0x00FF0000
	MOVE win,20,60
	PRINT win,"Testing . . ."
	MOVE win,40,140
	PRINT win,"Testing . . ."

WAITUNTIL IsWindowClosed(win)
	END

SUB main(),INT
	SELECT @MESSAGE
CASE @IDCREATE
	CENTERWINDOW win
CASE @IDCLOSEWINDOW
CASE& @IDDESTROY
	CLOSEWINDOW win
CASE @IDCONTROL
	SELECT @CONTROLID
CASE 1 'Exit
	CLOSEWINDOW win
CASE 2 'Print window using PRINTWINDOW
	PRINTWINDOW win
CASE 3 'Print Bitmap from Clipboard - horizontal
	GETCLIENTSIZE win,left,top,width,height
	CopyToClipboardHorz(win,left,top,width,height)
CASE 4 'Print Bitmap from Clipboard - Vertical
	GETCLIENTSIZE win,left,top,width,height
	CopyToClipboardVert(win,left,top,width,height)
CASE 5 'Use XnView
	SYSTEM "C:\\Program Files (x86)\\XnView\\xnview.exe","-clipaste"
ENDSELECT
ENDSELECT
RETURN 0
ENDSUB

'Horizontal code --------------------

SUB CopyToClipboardHorz(WINDOW win,UINT left,UINT top,UINT width,UINT height)
IF (OpenClipboard(win.hWnd))
' create a memory bitmap
	HDC hDC=GetDC(0)
	HDC cDC=CreateCompatibleDC(hDC)
	HBITMAP hBM=SelectObject(cDC,CreateCompatibleBitmap(hDC,width,height))
' copy window pixels to this bitmap
	HDC dc=GETHDC(win)
	BitBlt(cDC,0,0,width,height,dc,left,top,SRCCOPY)
	RELEASEHDC(win,dc)
	hBM=SelectObject(cDC,hBM)
	DeleteDC(cDC)
	ReleaseDC(0,hDC)
' put the bitmap into clipboard
	EmptyClipboard()
	SetClipboardData(CF_BITMAP,hBM) 'do not delete hBM after this!
	CloseClipboard()
	PrintImageDialogHorz(win,hBM,100)
ENDIF
ENDSUB
SUB PrintImageDialogHorz(WINDOW w1,HBITMAP iHandle,UINT margin)
	GetObject(iHandle,LEN(bm),&bm)
	UINT bmpw=bm.bmWidth
	UINT bmph=bm.bmHeight
	ZeroMemory(&di,LEN(di))
	di.cbSize=LEN(di)
	di.lpszDocName="Printing Picture..."
	HDC prn=GetPrinterDC(w1.hWnd)
	UINT cxpage=GetDeviceCaps(prn,HORZRES)-2*margin
	UINT cypage=(bmph*GetDeviceCaps(prn,HORZRES))/(bmpw*1.0)
	UINT dif=(GetDeviceCaps(prn,VERTRES)-cypage)/2.0
	UINT hdcMem=CreateCompatibleDC(prn)
	HBITMAP hbmOld=SelectObject(hdcMem,iHandle)
	StartDoc(prn,&di)
	StartPage(prn)
	SetMapMode(prn,MM_ISOTROPIC)
	SetWindowExtEx(prn,cxpage,cypage,NULL)
	SetViewportExtEx(prn,cxpage,cypage,NULL)
	SetViewportOrgEx(prn,0,0,NULL)
	StretchBlt(prn,margin,dif,cxpage,cypage,hdcMem,0,0,bmpw,bmph,SRCCOPY)
	_EndPage(prn)
	EndDoc(prn)
	DeleteDC(prn)
	SelectObject(hdcMem,hbmOld)
	DeleteDC(hdcMem)
ENDSUB

'Vertical code ----------------------------

SUB CopyToClipboardVert(WINDOW win,UINT left,UINT top,UINT width,UINT height)
IF (OpenClipboard(win.hWnd))
' create a memory bitmap
	HDC hDC=GetDC(0)
	HDC cDC=CreateCompatibleDC(hDC)
	HBITMAP hBM=SelectObject(cDC,CreateCompatibleBitmap(hDC,width,height))
' copy window pixels to this bitmap
	HDC dc=GETHDC(win)
	BitBlt(cDC,0,0,width,height,dc,left,top,SRCCOPY)
	RELEASEHDC(win,dc)
	hBM=SelectObject(cDC,hBM)
	DeleteDC(cDC)
	ReleaseDC(0,hDC)
' put the bitmap into clipboard
	EmptyClipboard()
	SetClipboardData(CF_BITMAP,hBM) 'do not delete hBM after this!
	CloseClipboard()
	PrintImageDialogVert(win,hBM,300) 'last param: vertical margin
ENDIF
ENDSUB
SUB PrintImageDialogVert(WINDOW w1,HBITMAP iHandle,UINT margin)
	GetObject(iHandle,LEN(bm),&bm)
	UINT bmpw=bm.bmWidth
	UINT bmph=bm.bmHeight
	ZeroMemory(&di,LEN(di))
	di.cbSize=LEN(di)
	di.lpszDocName="Printing Picture..."
	HDC prn=GetPrinterDC(w1.hWnd)
	UINT cypage=GetDeviceCaps(prn,VERTRES)-2*margin
	UINT cxpage=(bmph*cypage)/(bmpw*1.0)
	UINT dif=(GetDeviceCaps(prn,HORZRES)-cxpage)/2.0
	UINT hdcMem=CreateCompatibleDC(prn)
	iHandle=BitmapRotate90(prn,iHandle,bmpw,bmph,bm.bmPlanes,bm.bmBitsPixel)
	HBITMAP hBMOld=SelectObject(hdcMem,iHandle)
	StartDoc(prn,&di)
	StartPage(prn)
	SetMapMode(prn,MM_ISOTROPIC)
	SetWindowExtEx(prn,cxpage,cypage,NULL)
	SetViewportExtEx(prn,cxpage,cypage,NULL)
	SetViewportOrgEx(prn,0,0,NULL)
	StretchBlt(prn,dif,margin,cxpage,cypage,hdcMem,0,0,bmph,bmpw,SRCCOPY)
	_EndPage(prn)
	EndDoc(prn)
	DeleteDC(prn)
	SelectObject(hdcMem,hBMOld)
	DeleteDC(hdcMem)
ENDSUB
SUB BitmapRotate90(HDC dc,HBITMAP hBMP,UINT width,UINT height,INT xplanes,INT pixel),HBITMAP
	HDC dcsrc=CreateCompatibleDC(dc)
	HDC dcdst=CreateCompatibleDC(dc)
	HBITMAP src=SelectObject(dcsrc,hBMP)
	HBITMAP ret=CreateBitmap(height,width,xplanes,pixel,0)
	HBITMAP dst=SelectObject(dcdst,ret)
	INT x, y
FOR x=0 TO width-1
FOR y=0 TO height-1
	SetPixel(dcdst,y,x,_GetPixel(dcsrc,x,height-y-1))
NEXT y
NEXT x
	SelectObject(dcsrc,src)
	SelectObject(dcdst,dst)
	DeleteDC(dcsrc)
	DeleteDC(dcdst)
	DeleteObject(hBMP)
RETURN ret
ENDSUB

'Printer DC stuff ----------------------

SUB GetPrinterDC(HWND handle),INT
	ZeroMemory(&pd,LEN(pd))
	pd.lStructSize=LEN(pd)
	pd.hWndOwner=handle
	pd.Flags=PD_RETURNDC
	PrintDlg(&pd)
RETURN pd.hDC
ENDSUB
