WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Samples

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Transparent Images in Dialogs


This code allows you to add images to a Winbatch dialog but making sure the background of the image matches the default window color. It might also be possible to get it to work for images on buttons as well.

#DefineFunction DisplayTransparentImage(image,xStart,yStart,ptSizex,ptSizey,dialog_handle)
   gdi32=dllload(strcat(dirwindows(1),"gdi32.dll"))
   user32=dllload(strcat(dirwindows(1),"user32.dll"))
   WS_CHILD=1073741824
   WS_VISIBLE=268435456
   WS_POPUP=2147483648
   WS_CAPTION=12582912
   SS_BITMAP=14
   COLOR_WINDOW = 5
   IMAGE_BITMAP = 0
   LR_DEFAULTCOLOR    = 0
   LR_LOADFROMFILE    = 16
   LR_LOADTRANSPARENT = 32
   WS_BORDER = 8388608
   SRCCOPY = 13369376 ; &HCC0020
   NOTSRCCOPY = 3342344 ; &H330008
   SRCAND = 8913094 ; &H8800C6
   SRCPAINT = 15597702 ; &HEE0086
   STM_SETIMAGE = 370
   ;Get default window background colour
   cTransparentColor = dllcall(user32,long:"GetSysColor",long:COLOR_WINDOW)
   win_hdl = DllHwnd("")
   hBmp=DllCall(user32,long:"LoadImageA",lpnull,lpstr:image,long:IMAGE_BITMAP,long:0,long:0,long:LR_DEFAULTCOLOR|LR_LOADFROMFILE|LR_LOADTRANSPARENT)
   dc=dllcall(user32,long:"GetDC",long:dialog_handle)
   hdctemp=dllcall(gdi32,long:"CreateCompatibleDC",long:dc)
   
   ; Select the bitmap
   dllcall(gdi32,long:"SelectObject",long:hdctemp,long:hBmp)
   
   ;   GetObject(hBmp, sizeof(BITMAP), @bm);
   ;   ptSize.x := bm.bmWidth; // Get width of bitmap
   ;   ptSize.y := bm.bmHeight; // Get height of bitmap
   ;   DPtoLP(hdcTemp, ptSize, 1); // Convert from device
   ;                                      // to logical points
   ;   // Create some DCs to hold temporary data.
   hdcBack = dllcall(gdi32,long:"CreateCompatibleDC",long:dc)
   hdcObject = dllcall(gdi32,long:"CreateCompatibleDC",long:dc)
   hdcMem = dllcall(gdi32,long:"CreateCompatibleDC",long:dc)
   hdcSave = dllcall(gdi32,long:"CreateCompatibleDC",long:dc)
   
   ;   // Create a bitmap for each DC. DCs are required for a number of GDI functions.
   ;   // Monochrome DC
   bmAndBack = dllcall(gdi32,long:"CreateBitmap",long:ptSizex, long:ptSizey, long:1, long:1, lpnull)
   ;   // Monochrome DC
   bmAndObject = dllcall(gdi32,long:"CreateBitmap",long:ptSizex, long:ptSizey, long:1, long:1, lpnull)
   bmAndMem=dllcall(gdi32,long:"CreateCompatibleBitmap",long:dc,long:ptSizex,long:ptSizey)
   bmSave=dllcall(gdi32,long:"CreateCompatibleBitmap",long:dc,long:ptSizex,long:ptSizey)
   
   ;   // Each DC must select a bitmap object to store pixel data.
   bmBackOld = dllcall(gdi32,long:"SelectObject",long:hdcBack,long:bmAndBack)
   bmObjectOld = dllcall(gdi32,long:"SelectObject",long:hdcObject,long:bmAndObject)
   bmMemOld = dllcall(gdi32,long:"SelectObject",long:hdcMem,long:bmAndMem)
   bmSaveOld = dllcall(gdi32,long:"SelectObject",long:hdcSave,long:bmSave)
   ;   // Set proper mapping mode.
   mapmode = dllcall(gdi32,long:"GetMapMode",long:dc)
   dllcall(gdi32,long:"SetMapMode",long:hdcTemp,long:mapmode)
   ;   // Save the bitmap sent here, because it will be overwritten.
   dllcall(gdi32,long:"BitBlt",long:hdcSave, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcTemp, long:0, long:0, long:SRCCOPY)
   ;   // Set the background color of the source DC to the color contained in the parts of the bitmap that should be transparent
   cColor = dllcall(gdi32,long:"SetBkColor",long:hdcTemp, long:cTransparentColor)
   ;   // Create the object mask for the bitmap by performing a BitBlt from the source bitmap to a monochrome bitmap.
   dllcall(gdi32,long:"BitBlt",long:hdcObject, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcTemp, long:0, long:0, long:SRCCOPY)
   ;   // Set the background color of the source DC back to the original color.
   dllcall(gdi32,long:"SetBkColor",long:hdcTemp, long:cColor)
   ;   // Create the inverse of the object mask.
   dllcall(gdi32,long:"BitBlt",long:hdcBack, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcObject, long:0, long:0, long:NOTSRCCOPY)
   ;   // Copy the background of the main DC to the destination.
   dllcall(gdi32,long:"BitBlt",long:hdcMem, long:0, long:0, long:ptSizex, long:ptSizey, long:dc, long:xStart, long:yStart, long:SRCCOPY)
   ;   // Mask out the places where the bitmap will be placed.
   dllcall(gdi32,long:"BitBlt",long:hdcMem, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcObject, long:0, long:0, long:SRCAND)
   ;   // Mask out the transparent colored pixels on the bitmap.
   dllcall(gdi32,long:"BitBlt",long:hdcTemp, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcBack, long:0, long:0, long:SRCAND)
   ;   // XOR the bitmap with the background on the destination DC.
   dllcall(gdi32,long:"BitBlt",long:hdcMem, long:0, long:0, long:ptSizex, long:ptSizey, long:hdcTemp, long:0, long:0, long:SRCPAINT)
   ;   // Copy the destination to the screen.
   ;dllcall(gdi32,long:"BitBlt",long:dc, long:xStart, long:yStart, long:ptSizex, long:ptSizey, long:hdcMem, long:0, long:0, long:SRCCOPY)
   SS_BLACKFRAME = 7
   bitmap = dllcall(gdi32,long:"SelectObject",long:hdcMem, long:bmMemOld)
   hstatic=dllcall(user32,long:"CreateWindowExA",long:0,lpstr:"Static",long:0,long:WS_VISIBLE|WS_CHILD|SS_BITMAP,long:xStart,long:yStart,long:ptSizex,long:ptSizey,long:dialog_handle,long:0,long:0,long:0)
   dllcall(user32,long:"SendMessageA",long:hstatic,long:STM_SETIMAGE,long:IMAGE_BITMAP,long:bitmap)
   ;   // Delete the memory bitmaps.
   a = dllcall(gdi32,long:"SelectObject",long:hdcBack, long:bmBackOld)
   dllcall(gdi32,long:"DeleteObject",Long:a)
   a = dllcall(gdi32,long:"SelectObject",long:hdcObject, long:bmObjectOld)
   dllcall(gdi32,long:"DeleteObject",Long:a)
   a = dllcall(gdi32,long:"SelectObject",long:hdcMem, long:bmMemOld)
   dllcall(gdi32,long:"DeleteObject",Long:a)
   a = dllcall(gdi32,long:"SelectObject",long:hdcSave, long:bmSaveOld)
   dllcall(gdi32,long:"DeleteObject",Long:a)
   ;   // Delete the memory DCs.
   dllcall(gdi32,long:"DeleteDC",long:hdcMem)
   dllcall(gdi32,long:"DeleteDC",long:hdcBack)
   dllcall(gdi32,long:"DeleteDC",long:hdcObject)
   dllcall(gdi32,long:"DeleteDC",long:hdcSave)
   dllcall(gdi32,long:"DeleteDC",long:hdcTemp)
#EndFunction

;============================================================
;============================================================
;============================================================


#DefineFunction MyDialogCallbackProc(MyDialog_Handle,MyDialog_Message,MyDialog_ID,rsvd1,rsvd2)
   ;DialogprocOptions Constants
   MSG_INIT=0                ; The one-time initilization
   MSG_BUTTONPUSHED=2        ; Pushbutton or Picturebutton

   switch MyDialog_Message
      case MSG_INIT
         DialogProcOptions(MyDialog_Handle,MSG_BUTTONPUSHED,@TRUE)
         return(-1)

     case MSG_BUTTONPUSHED
        switch MyDialog_ID
           case 003
               DisplayTransparentImage("C:\Program Files\WinBatch\System\wbowl.bmp",10,20,165,288,MyDialog_Handle)
           return(-2)

        endswitch    ;MyDialog_ID
        return(-1)      ;  Do default processing

   endswitch       ; MyDialog_Message
   return(-1)      ;  Do default processing
#EndFunction       ;End of Dialog Callback MyDialogCallbackProc

;============================================================
;============================================================
;============================================================


MyDialogFormat=`WWWDLGED,6.1`

MyDialogCaption=`WIL Dialog 1`
MyDialogX=001
MyDialogY=001
MyDialogWidth=150
MyDialogHeight=168
MyDialogNumControls=003
MyDialogProcedure=`MyDialogCallbackProc`
MyDialogFont=`DEFAULT`
MyDialogTextColor=`DEFAULT`
MyDialogBackground=`DEFAULT,0|255|255`
MyDialogConfig=0

MyDialog001=`011,139,036,012,PUSHBUTTON,DEFAULT,"OK",1,1,32,DEFAULT,DEFAULT,DEFAULT`
MyDialog002=`077,137,036,012,PUSHBUTTON,DEFAULT,"Cancel",0,2,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
MyDialog003=`049,099,036,012,PUSHBUTTON,DEFAULT,"test",2,3,DEFAULT,DEFAULT,DEFAULT,DEFAULT`
ButtonPushed=Dialog("MyDialog")
This code is based on a Delphi example I found, but that was drawing directly onto the dialog, not via a static control.

anyway.. my understanding is that it ends up changing the background colour (tends to be white I think) of the bitmap to be the color of the dialog. but I need to do some more playing.....

The dialog color is got from cTransparentColor = dllcall(user32,long:"GetSysColor",long:COLOR_WINDOW). While it implies in the docs that it should return the current default dialog colour, it seems to return the colour of the current dialog.

For those wanting to read more about this.. I got most of this code from http://www.howtodothings.com/showarticle.asp?article=557

Loads of other Bitmap stuff.. http://www.codeguru.com/bitmap/index.shtml

If you were wanting to save the resulting bitmap to a BMP file you could use the SaveBitmap UDF:

#DefineFunction SaveBitmap(gdi32,hdc,hbm,width,height,filename)
   DIB_RGB_COLORS=0
   BI_RGB=0
   szBITMAPINFOHEADER=40
   szBITMAPFILEHEADER=14
   szRGBQUAD=4
   szBITMAPINFO=8
   WHITE_BRUSH=0
   TRANSPARENT=1
   ;write bitmap
   ctsize=256 
   szinfo=(szBITMAPINFOHEADER)+(ctsize*szRGBQUAD)
   info=BinaryAlloc(szinfo)
   BinaryPoke4(info,0,szBITMAPINFOHEADER)
   ;fill BITMAPINFO
   DllCall(gdi32,long:"GetDIBits",long:hdc,long:hbm,long:0,long:0,lpnull,lpbinary:info,long:DIB_RGB_COLORS)
   BinaryEodSet(info,szinfo)
	biBitCount=BinaryPeek2(info,14)
	;message("",biBitCount)
	biSizeImage=BinaryPeek4(info,20)
	;message("",biSizeImage)
	BinaryPoke4(info,16,BI_RGB) ;biCompression
	Select biBitCount
		Case 4
			ctsize=16
			Break
		Case 8
			ctsize=256
			Break
		Case 16
		Case 24
		Case 32
			ctsize=0
			Break
	EndSelect
   bits=BinaryAlloc(biSizeImage)
   ;get bitmap bits
   DllCall(gdi32,long:"GetDIBits",long:hdc,long:hbm,long:0,long:height,lpbinary:bits,lpbinary:info,long:DIB_RGB_COLORS)
   BinaryEodSet(bits,biSizeImage)
	finfo=BinaryAlloc(szBITMAPFILEHEADER)
	BinaryPokeStr(finfo,0,"BM") ;bfType
	bfOffBits=szBITMAPFILEHEADER+szBITMAPINFOHEADER+(szRGBQUAD*ctsize)
   BinaryPoke4(finfo,10,bfOffBits) ;bfOffBits
   BinaryPoke4(finfo,2,bfOffBits+biSizeImage) ;bfSize
   ;bfReserved1=0
   ;bfReserved2=0
   BinaryWriteEx(finfo,0,filename,0,szBITMAPFILEHEADER)
   BinaryWriteEx(info,0,filename,szBITMAPFILEHEADER,szBITMAPINFOHEADER+(szRGBQUAD*ctsize))
   BinaryWriteEx(bits,0,filename,szBITMAPFILEHEADER+szBITMAPINFOHEADER+(szRGBQUAD*ctsize),biSizeImage)
	;free
	BinaryFree(finfo)
   BinaryFree(info)
   BinaryFree(bits)
	Return 1
#EndFunction

Article ID:   W16428
File Created: 2005:02:18:12:20:28
Last Updated: 2005:02:18:12:20:28