Greenhorn Posted November 5, 2008 Share Posted November 5, 2008 (edited) Hi Folks,I have a problem with DllStructSetData(), it says after a few correct settings that the Array is out of range, but I don't understand why !The loop seems to be OK, but it although throws an error after a few cycles ...I've marked the "critical section" like this:;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? Next Next ;***********************************************expandcollapse popup#Region Alpha Blending a Bitmap ; The following code sample divides a window into three horizontal areas. ; Then it draws an alpha-blended bitmap in each of the window areas as follows: ; * In the top area, constant alpha = 50% but there is no source alpha. #include <WindowsConstants.au3> #include <WinAPI.au3> Global Const $tagBITMAPINFOHEADER = 'dword Size;' & _ 'long Width;' & _ 'long Height;' & _ 'ushort Planes;' & _ 'ushort BitCount;' & _ 'dword Compression;' & _ 'dword SizeImage;' & _ 'long XPelsPerMeter;' & _ 'long YPelsPerMeter;' & _ 'dword ClrUsed;' & _ 'dword ClrImportant;' Global Const $tagPAINTSTRUCT = 'hwnd hDC;' & _ 'int fErase;' & _ 'long rcPaint[4];' & _ 'int fRestore;' & _ 'int fIncUpdate;' & _ 'byte rgbReserved[32]' Global $NULL = Ptr (0) Global Const $DIB_RGB_COLORS = 0 ; Blending Global Const $AC_SRC_OVER = 0x00 Global Const $AC_SRC_ALPHA = 0x01 Global Const $BI_RGB = 0 ; Fensterstile Global Const $WS_EX_COMPOSITED = 0x2000000 ; Gegen "Flackern" ; Nachricht zum Zeichnen abfangen. GUIRegisterMsg ($WM_PAINT, 'MY_WM_PAINT') ; Das übliche ... $hWnd = GUICreate ('AlphaBlend - Demo', 400, 350, -1, -1, _ $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) GUISetBkColor (0xFFFFFF, $hWnd) GUISetState (@SW_SHOW) While True Switch GUIGetMsg () Case -3 ExitLoop EndSwitch WEnd Func MY_WM_PAINT ($hWnd, $msg, $lParam, $wParam) Local $hDC, $ps, $lpPs ; Zeichenstruktur erzeugen $ps = DllStructCreate ($tagPAINTSTRUCT) $lpPs = DllStructGetPtr ($ps) ; Gerätekontext wird in WM_PAINT von BeginPaint zurückgegeben $hDC = BeginPaint ($hWnd, $lpPs) DrawAlphaBlend ($hWnd, $hDC) ; Am Ende von WM_PAINT muss der Gerätekontext ; mit EndPaint wieder freigegeben werden ! EndPaint ($hWnd, $lpPs) Return EndFunc Func DrawAlphaBlend ($hWnd, $hdcwnd) ; http://msdn.microsoft.com/en-us/library/ms532295(VS.85).aspx Local $hdc; handle of the DC we will create Local $hbitmap; bitmap handle Local $bf = DllStructCreate ($tagBLENDFUNCTION); structure for alpha blending Local $bmi = DllStructCreate ($tagBITMAPINFO); bitmap header Local $pvBits = DllStructCreate ('ptr pvBits') ; pointer to DIB section Local $ulWindowWidth, $ulWindowHeight; window width/height Local $ulBitmapWidth, $ulBitmapHeight; bitmap width/height Local $rt; used for getting window dimensions Local $x, $y; stepping variables Local $ubAlpha; used for doing transparent gradient Local $ubRed Local $ubGreen Local $ubBlue Local $fAlphaFactor; used to do premultiply ; get window dimensions $rt = _WinAPI_GetClientRect ($hWnd) $rtLeft = DllStructGetData ($rt, "Left") $rtTop = DllStructGetData ($rt, "Top") $rtRight = DllStructGetData ($rt, "Right") $rtBottom = DllStructGetData ($rt, "Bottom") ; calculate window width/height $ulWindowWidth = $rtRight - $rtLeft $ulWindowHeight = $rtBottom - $rtTop ; make sure we have at least some window size If ((Not $ulWindowWidth) Or (Not $ulWindowHeight)) Then _ Return ; divide the window into 3 horizontal areas $ulWindowHeight = $ulWindowHeight / 3 ; create a DC for our bitmap -- the source DC for AlphaBlend $hdc = _WinAPI_CreateCompatibleDC ($hdcwnd) $ulBitmapWidth = $ulWindowWidth - ($ulWindowWidth / 5) * 2 $ulBitmapHeight = $ulWindowHeight - ($ulWindowHeight / 5) * 2 ; setup bitmap info ; set the bitmap width and height to 60% of the width and height of each of the three horizontal areas. Later on, the blending will occur in the center of each of the three areas. DllStructSetData ($bmi, 'Size' , DllStructGetSize (DllStructCreate ($tagBITMAPINFOHEADER))) DllStructSetData ($bmi, 'Width', $ulBitmapWidth) DllStructSetData ($bmi, 'Height', $ulBitmapHeight) DllStructSetData ($bmi, 'Planes', 1) DllStructSetData ($bmi, 'BitCount', 32 ); four 8-bit components DllStructSetData ($bmi, 'Compression', $BI_RGB) DllStructSetData ($bmi, 'SizeImage', $ulBitmapWidth * $ulBitmapHeight * 4) ; create our DIB section and select the bitmap into the DC $hbitmap = CreateDIBSection ($hdc, DllStructGetPtr ($bmi), $DIB_RGB_COLORS, DllStructGetPtr ($pvBits), $NULL, 0x0) _WinAPI_SelectObject ($hdc, $hbitmap) $stBits = DllStructCreate ('uint[' & DllStructGetData ($bmi, 'Width') _ * DllStructGetData ($bmi, 'Height') & ']', DllStructGetPtr ($pvBits)) ; in top window area, constant alpha = 50%, but no source alpha ; the color format for each pixel is 0xaarrggbb ; set all pixels to blue and set source alpha to zero ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? Next Next ;*********************************************** DllStructSetData ($bf, 'Op' , $AC_SRC_OVER) DllStructSetData ($bf, 'Flags' , 0) DllStructSetData ($bf, 'Alpha' , 0x7F); half of 0xff = 50% transparency DllStructSetData ($bf, 'Format', 0); ignore source alpha channel If (Not AlphaBlend ($hdcwnd, $ulWindowWidth / 5, $ulWindowHeight / 5, _ $ulBitmapWidth, $ulBitmapHeight, _ $hdc, 0, 0, $ulBitmapWidth, $ulBitmapHeight, $bf)) Then _ Return; // alpha blend failed ; do cleanup _WinAPI_DeleteObject ($hbitmap) _WinAPI_DeleteDC ($hdc) EndFunc ;*********************************************************************** ;* The funky Funcs ... Func AlphaBlend ($hdcDest, $nXOriginDest, $nYOriginDest, $nWidthDest, $nHeightDest, _ $hdcSrc, $nXOriginSrc, $nYOriginSrc, $nWidthSrc, $nHeightSrc, ByRef $blendFunction ) Local $aRes = DllCall ('msimg32.dll', 'int', 'AlphaBlend', _ 'ptr', $hdcDest, _ ; // handle to destination DC 'int', $nXOriginDest, _ ; // x-coord of upper-left corner 'int', $nYOriginDest, _ ; // y-coord of upper-left corner 'int', $nWidthDest, _ ; // destination width 'int', $nHeightDest, _ ; // destination height 'ptr', $hdcSrc, _ ; // handle to source DC 'int', $nXOriginSrc, _ ; // x-coord of upper-left corner 'int', $nYOriginSrc, _ ; // y-coord of upper-left corner 'int', $nWidthSrc, _ ; // source width 'int', $nHeightSrc, _ ; // source height 'ptr', $blendFunction) ; // alpha-blending function Return $aRes[0] EndFunc Func CreateDIBSection ($hdc, $pbmi, $iUsage, $ppvBits, $hSection, $dwOffset) Local $aRes = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', _ 'ptr', $hdc, _; // handle to DC 'ptr', $pbmi, _; // bitmap data 'uint', $iUsage, _; // data type indicator 'ptr*', $ppvBits, _; // bit values 'ptr', $hSection, _; // handle to file mapping object 'dword', $dwOffset ) ; // offset to bitmap bit values Return $aRes[0] EndFunc Func BeginPaint($hWnd, $lpPaint) Local $aResult = DllCall('user32.dll', 'hwnd', 'BeginPaint', 'hwnd', $hWnd, 'ptr', $lpPaint) Return $aResult[0] EndFunc Func EndPaint($hWnd, $lpPaint) Local $aResult = DllCall('user32.dll', 'int', 'EndPaint', 'hwnd', $hWnd, 'ptr', $lpPaint) Return $aResult[0] EndFunc #EndRegion ;***************************************************************************Thanks a lot for audience/patience ...GreetzGreenhorn Edited November 5, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 5, 2008 Share Posted November 5, 2008 (edited) Hi Folks, I have a problem with DllStructSetData(), it says after a few correct settings that the Array is out of range, but I don't understand why ! The loop seems to be OK, but it although throws an error after a few cycles ... I've marked the "critical section" like this: ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? Next Next ;*********************************************** ; ... <snip> $stBits = DllStructCreate ('uint[' & DllStructGetData ($bmi, 'Width') _ * DllStructGetData ($bmi, 'Height') & ']', DllStructGetPtr ($pvBits)) ; in top window area, constant alpha = 50%, but no source alpha ; the color format for each pixel is 0xaarrggbb ; set all pixels to blue and set source alpha to zero ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? Next Next ;*********************************************** ; ... <snip> Thanks a lot for audience/patience ... Greetz Greenhorn So you created the array with size = DllStructGetData($bmi, 'Width') * DllStructGetData($bmi, 'Height'). What did that come out to? Are you checking it? Then you access the array at index = $x + ($y * $ulBitmapWidth). What did that come out to? Are you checking it? Put some error handling in your function to check how those values are coming out. Edited November 5, 2008 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Greenhorn Posted November 5, 2008 Author Share Posted November 5, 2008 (edited) So you created the array with size = DllStructGetData($bmi, 'Width') * DllStructGetData($bmi, 'Height'). What did that come out to? Are you checking it? Then you access the array at index = $x + ($y * $ulBitmapWidth). What did that come out to? Are you checking it? Put some error handling in your function to check how those values are coming out. I forgot to copy back the "- 1" in the first For/Next loop, sorry. (my test script is a desaster in the moment ... ) But even then it will fail ... So, I set in the double-loop the bit values for every pixel, right ? Doing this by scanning each bitmap line in $y and setting the values in the array with $x, which I have to multiplicate with the length of one line in the bitmap, because, for example, if the bitmap has a size of 250x150 pixels, pixel 0, 1 is at array index 251 ($x=1 + ($y=1 *$ulBitmapWidth), pixel 0, 2 is at array index 501($x=1 + ($y=2 *$ulBitmapWidth), right ? I did the error handling, the size of the struct is 67200 bytes, the same like $ulBitmapWidth * $ulBitmapHeight * 4(bytes), so it's OK ... *brooding* ... EDIT: Always after the 13th setting commes the error ... If I read out the values in the loop it's no error, but the script also fails ... ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight - 1 For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? ;DllStructGetData ($stBits, 1, $x + ($y * $ulBitmapWidth)); oO ??? if @error then ConsoleWrite ('Index : '&$x + ($y * $ulBitmapWidth)&'; Error : '&@error&@crlf) Next Next ;*********************************************** Greetz Greenhorn Edited November 5, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 5, 2008 Share Posted November 5, 2008 (edited) I forgot to copy back the "- 1" in the first For/Next loop, sorry. (my test script is a desaster in the moment ... ) But even then it will fail ... So, I set in the double-loop the bit values for every pixel, right ? Doing this by scanning each bitmap line in $y and setting the values in the array with $x, which I have to multiplicate with the length of one line in the bitmap, because, for example, if the bitmap has a size of 250x150 pixels, pixel 0, 1 is at array index 251 ($x=1 + ($y=1 *$ulBitmapWidth), pixel 0, 2 is at array index 501($x=1 + ($y=2 *$ulBitmapWidth), right ? Careful how you do that. Pixel numbering is 0-based (there is a pixel at 0,0). AutoIt arrays are 0-based, which is why so many For/Next loops have that -1 in there. But DLL struct arrays are 1-based. There is no DLL struct array element at [0]. So pixel 0,0 is at [1]. That's $x=0 and $y=0, so index = $x + 1 + ($y * $ulBitmapWidth). Pixel 0,1 is at 251 like you indicated. I did the error handling, the size of the struct is 67200 bytes, the same like $ulBitmapWidth * $ulBitmapHeight * 4(bytes), so it's OK ... *brooding* ... EDIT: Always after the 13th setting commes the error ... If I read out the values in the loop it's no error, but the script also fails ... ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight - 1 For $x = 1 To $ulBitmapWidth DllStructSetData ($stBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)); oO ??? ;DllStructGetData ($stBits, 1, $x + ($y * $ulBitmapWidth)); oO ??? if @error then ConsoleWrite ('Index : '&$x + ($y * $ulBitmapWidth)&'; Error : '&@error&@crlf) Next Next ;*********************************************** Greetz Greenhorn I meant more like a temporary debug breakpoint: ; ... <snip> $iArraySize = DllStructGetData($bmi, 'Width') * DllStructGetData($bmi, 'Height') $stBits = DllStructCreate('uint[' & $iArraySize & ']', DllStructGetPtr($pvBits)) ; in top window area, constant alpha = 50%, but no source alpha ; the color format for each pixel is 0xaarrggbb ; set all pixels to blue and set source alpha to zero ;*********** Here's the problem **************** For $y = 0 To $ulBitmapHeight For $x = 1 To $ulBitmapWidth $iPixelIndex = $x + ($y * $ulBitmapWidth) If ($iPixelIndex > 0) And ($iPixelIndex <= $iArraySize) Then DllStructSetData($stBits, 1, 0x000000FF, $iPixelIndex) Else MsgBox(16, "Debug", "Error! Array index out of bounds:" & @CRLF & _ "DllStructGetData($bmi, 'Width') = " & DllStructGetData($bmi, 'Width') & @CRLF & _ "DllStructGetData($bmi, 'Height') = " & DllStructGetData($bmi, 'Height') & @CRLF & _ "Calculated $iArraySize = " & $iArraySize & @CRLF & _ "$x = " & $x & " $y = " & $y & @CRLF & _ "$ulBitmapWidth = " & $ulBitmapWidth & @CRLF & _ "Calculated $iPixelIndex = " & $iPixelIndex) Exit EndIf Next Next ;*********************************************** ; ... <snip> Checking the value of $iPixelIndex will slow it down, so you may not want that in there permanently, but it should pop the MsgBox() with diagnostic info before it crashes for that particular problem. P.S. I just notice you do your loop with "For $x = 1 To $ulBitmapWidth", which is correct, but above that you have "For $y = 0 To $ulBitmapHeight". Shouldn't that be "For $y = 0 To $ulBitmapHeight - 1"? Edited November 6, 2008 by PsaltyDS Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
Malkey Posted November 6, 2008 Share Posted November 6, 2008 If what you are doing is journey based, a learning exercise, good luck. Looks like headache material. May you have lots of enthusiastic perseverance. If you want to accomplish a task by any means, the functions from gdiplus.dll are better suited to manipulate 0xAARRGGBB color format. Example:- expandcollapse popup#include <GDIPlus.au3> #include <WinAPI.au3> #include <GuiConstants.au3> #include <WindowsConstants.au3> Global $GuiSizeX = 500, $GuiSizeY = 500 $hGui = GUICreate("GDIPlus Example", $GuiSizeX, $GuiSizeY) GUISetState() _GDIPlus_Startup() ; Create Double Buffer, so doesn't need to be repainted on PAINT-Event $hGraphicGUI = _GDIPlus_GraphicsCreateFromHWND($hGui) $hBMPBuff = _GDIPlus_BitmapCreateFromGraphics($GuiSizeX, $GuiSizeY, $hGraphicGUI) $hGraphic = _GDIPlus_ImageGetGraphicsContext($hBMPBuff) ;End Double Buffer add-in 1 of 3 ;Graphics here _GDIPlus_GraphicsClear($hGraphic, 0xFFFFFFFF) ; White background $hBrush3 = _GDIPlus_BrushCreateSolid(0xFF0000FF) ; 100% opaque Blue, 0% transparency - Alpha channel FF $hBrush2 = _GDIPlus_BrushCreateSolid(0xA00000FF) ; [(0xA0/0xFF)*100] % opaque, [(0xff-0xA0/0xFF)*100] % transparency $hBrush1 = _GDIPlus_BrushCreateSolid(0x500000FF) ; _GDIPlus_GraphicsFillRect($hGraphic, 0, 0, $GuiSizeX, $GuiSizeY / 3, $hBrush1) ; Top third of window _GDIPlus_GraphicsFillRect($hGraphic, 0, $GuiSizeY / 3, $GuiSizeX, $GuiSizeY / 3, $hBrush2) ; Middle third of GUI _GDIPlus_GraphicsFillRect($hGraphic, 0, $GuiSizeY * 2 / 3 - 1, $GuiSizeX, $GuiSizeY / 3 + 1, $hBrush3) ;End of graphics ; Double Buffer GUIRegisterMsg(0xF, "MY_PAINT"); Register PAINT-Event 0x000F = $WM_PAINT (WindowsConstants.au3) GUIRegisterMsg(0x85, "MY_PAINT") ; $WM_NCPAINT = 0x0085 (WindowsConstants.au3)Restore after Minimize. _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) ;End Double Buffer add-on 2 of 3 ;To save GUI image, un-comment the next two lines. ;_GDIPlus_ImageSaveToFile($hBMPBuff, @DesktopDir & "\TestWrite1.png") ;ShellExecute(@DesktopDir & "\TestWrite1.png") While 1 $msg = GUIGetMsg() Switch $msg Case $GUI_EVENT_CLOSE _GDIPlus_BrushDispose($hBrush1) _GDIPlus_BrushDispose($hBrush2) _GDIPlus_BrushDispose($hBrush3) _GDIPlus_GraphicsDispose($hGraphic) _GDIPlus_GraphicsDispose($hGraphicGUI) _WinAPI_DeleteObject($hBMPBuff) _GDIPlus_Shutdown() Exit EndSwitch WEnd ;Func to redraw on PAINT MSG Func MY_PAINT($hWnd, $msg, $wParam, $lParam) ; Check, if the GUI with the Graphic should be repainted _GDIPlus_GraphicsDrawImage($hGraphicGUI, $hBMPBuff, 0, 0) _WinAPI_RedrawWindow($hGui, "", "", BitOR($RDW_INVALIDATE, $RDW_UPDATENOW, $RDW_FRAME)) ; , $RDW_ALLCHILDREN Return $GUI_RUNDEFMSG EndFunc ;==>MY_PAINT Link to comment Share on other sites More sharing options...
Greenhorn Posted November 9, 2008 Author Share Posted November 9, 2008 (edited) Thanks to both of you for taking notice and giving advice ! Also thx to Malkey, I've seen this script before in my searches for CreateDIBSection(). But I want to get even this function to run. It seems I got solved the problems with the Bitmap-Bits pointer. All return values seem to be OK, but no bitmap is drawn. expandcollapse popup#Region Alpha Blending a Bitmap ; The following code sample divides a window into three horizontal areas. ; Then it draws an alpha-blended bitmap in each of the window areas as follows: ; * In the top area, constant alpha = 50% but there is no source alpha. #include <WindowsConstants.au3> #include <WinAPI.au3> Global Const $tagBITMAPINFOHEADER = 'dword Size;' & _ 'long Width;' & _ 'long Height;' & _ 'ushort Planes;' & _ 'ushort BitCount;' & _ 'dword Compression;' & _ 'dword SizeImage;' & _ 'long XPelsPerMeter;' & _ 'long YPelsPerMeter;' & _ 'dword ClrUsed;' & _ 'dword ClrImportant;' Global Const $tagPAINTSTRUCT = 'hwnd hDC;' & _ 'int fErase;' & _ 'long rcPaint[4];' & _ 'int fRestore;' & _ 'int fIncUpdate;' & _ 'byte rgbReserved[32]' Global $NULL = Ptr (0) Global Const $DIB_RGB_COLORS = 0 ; Blending Global Const $AC_SRC_OVER = 0x00 Global Const $AC_SRC_ALPHA = 0x01 Global Const $BI_RGB = 0 ; Fensterstile Global Const $WS_EX_COMPOSITED = 0x2000000 ; Gegen "Flackern" ; Nachricht zum Zeichnen abfangen. GUIRegisterMsg ($WM_PAINT, 'MY_WM_PAINT') ; Das übliche ... $hWnd = GUICreate ('Alpha Blending a Bitmap', 400, 350, -1, -1, _ $WS_OVERLAPPEDWINDOW, $WS_EX_COMPOSITED) GUISetBkColor (0xFFFFFF, $hWnd) GUISetState (@SW_SHOW) While True Switch GUIGetMsg () Case -3 ExitLoop EndSwitch WEnd Func MY_WM_PAINT ($hWnd, $msg, $lParam, $wParam) Local $hDC, $ps, $lpPs ; Zeichenstruktur erzeugen $ps = DllStructCreate ($tagPAINTSTRUCT) $lpPs = DllStructGetPtr ($ps) ; Gerätekontext wird in WM_PAINT von BeginPaint zurückgegeben $hDC = BeginPaint ($hWnd, $lpPs) DrawAlphaBlend ($hWnd, $hDC) ; Am Ende von WM_PAINT muss der Gerätekontext ; mit EndPaint wieder freigegeben werden ! EndPaint ($hWnd, $lpPs) Return 0 EndFunc Func DrawAlphaBlend ($hWnd, $hdcwnd) ; http://msdn.microsoft.com/en-us/library/ms532295(VS.85).aspx Local $hdc ; handle of the DC we will create Local $hbitmap ; bitmap handle Local $bf = DllStructCreate ($tagBLENDFUNCTION); structure for alpha blending Local $bmi = DllStructCreate ($tagBITMAPINFO); bitmap header Local $pvBits ; pointer to DIB section Local $ulWindowWidth, $ulWindowHeight ; window width/height Local $ulBitmapWidth, $ulBitmapHeight ; bitmap width/height Local $rt ; used for getting window dimensions Local $x, $y ; stepping variables Local $ubAlpha ; used for doing transparent gradient Local $ubRed Local $ubGreen Local $ubBlue Local $fAlphaFactor ; used to do premultiply ; get window dimensions $rt = _WinAPI_GetClientRect ($hWnd) $rtLeft = DllStructGetData ($rt, "Left") $rtTop = DllStructGetData ($rt, "Top") $rtRight = DllStructGetData ($rt, "Right") $rtBottom = DllStructGetData ($rt, "Bottom") ; calculate window width/height $ulWindowWidth = $rtRight - $rtLeft $ulWindowHeight = $rtBottom - $rtTop ; make sure we have at least some window size If ((Not $ulWindowWidth) Or (Not $ulWindowHeight)) Then _ Return ; divide the window into 3 horizontal areas $ulWindowHeight = $ulWindowHeight / 3 ; create a DC for our bitmap -- the source DC for AlphaBlend $hdc = _WinAPI_CreateCompatibleDC ($hdcwnd) $ulBitmapWidth = $ulWindowWidth - ($ulWindowWidth / 5) * 2 $ulBitmapHeight = $ulWindowHeight - ($ulWindowHeight / 5) * 2 ; setup bitmap info ; set the bitmap width and height to 60% of the width and height of each of the three horizontal areas. ; Later on, the blending will occur in the center of each of the three areas. DllStructSetData ($bmi, 'Size' , DllStructGetSize (DllStructCreate ($tagBITMAPINFOHEADER))) DllStructSetData ($bmi, 'Width', $ulBitmapWidth) DllStructSetData ($bmi, 'Height', $ulBitmapHeight) DllStructSetData ($bmi, 'Planes', 1) DllStructSetData ($bmi, 'BitCount', 32) ; four 8-bit components DllStructSetData ($bmi, 'Compression', $BI_RGB) DllStructSetData ($bmi, 'SizeImage', $ulBitmapWidth * $ulBitmapHeight * 4) ; create our DIB section and select the bitmap into the DC $hbitmap = CreateDIBSection ($hdc, DllStructGetPtr ($bmi), $DIB_RGB_COLORS, $pvBits, $NULL, 0x0) _WinAPI_SelectObject ($hdc, $hbitmap) ; in top window area, constant alpha = 50%, but no source alpha ; the color format for each pixel is 0xaarrggbb ; set all pixels to blue and set source alpha to zero For $y = 0 To $ulBitmapHeight - 1 For $x = 1 To $ulBitmapWidth DllStructSetData ($pvBits, 1, 0x000000FF, $x + ($y * $ulBitmapWidth)) Next Next DllStructSetData ($bf, 'Op' , $AC_SRC_OVER) DllStructSetData ($bf, 'Flags' , 0) DllStructSetData ($bf, 'Alpha' , 0x7F) ; half of 0xff = 50% transparency DllStructSetData ($bf, 'Format', 0) ; ignore source alpha channel If (Not AlphaBlend ($hdcwnd, $ulWindowWidth / 5, $ulWindowHeight / 5, _ $ulBitmapWidth, $ulBitmapHeight, _ $hdc, 0, 0, $ulBitmapWidth, $ulBitmapHeight, $bf)) Then _ Return ; alpha blend failed ; do cleanup _WinAPI_DeleteObject ($hbitmap) _WinAPI_DeleteDC ($hdc) EndFunc ;*********************************************************************** ;* The funky Funcs ... Func AlphaBlend ($hdcDest, $nXOriginDest, $nYOriginDest, $nWidthDest, $nHeightDest, _ $hdcSrc, $nXOriginSrc, $nYOriginSrc, $nWidthSrc, $nHeightSrc, ByRef $blendFunction ) Local $aRes = DllCall ('msimg32.dll', 'int', 'AlphaBlend', _ 'ptr', $hdcDest, _ ; // handle to destination DC 'int', $nXOriginDest, _ ; // x-coord of upper-left corner 'int', $nYOriginDest, _ ; // y-coord of upper-left corner 'int', $nWidthDest, _ ; // destination width 'int', $nHeightDest, _ ; // destination height 'ptr', $hdcSrc, _ ; // handle to source DC 'int', $nXOriginSrc, _ ; // x-coord of upper-left corner 'int', $nYOriginSrc, _ ; // y-coord of upper-left corner 'int', $nWidthSrc, _ ; // source width 'int', $nHeightSrc, _ ; // source height 'ptr', $blendFunction) ; // alpha-blending function Return $aRes[0] EndFunc Func CreateDIBSection ($hdc, $pbmi, $iUsage, ByRef $ppvBits, $hSection, $dwOffset) Local $aRes = DllCall('gdi32.dll', 'ptr', 'CreateDIBSection', _ 'ptr', $hdc, _ ; // handle to DC 'ptr', $pbmi, _ ; // bitmap data 'uint', $iUsage, _ ; // data type indicator 'ptr*', $ppvBits, _ ; // bit values 'ptr', $hSection, _ ; // handle to file mapping object 'dword', $dwOffset ) ; // offset to bitmap bit values Local $cbSize = DllStructGetData (DllStructCreate ($tagBITMAPINFOHEADER, $pbmi), 'SizeImage') $ppvBits = DllStructCreate ('uint[' & $cbSize / 4 & ']', $aRes[4]) Return $aRes[0] EndFunc Func BeginPaint($hWnd, $lpPaint) Local $aResult = DllCall('user32.dll', 'hwnd', 'BeginPaint', 'hwnd', $hWnd, 'ptr', $lpPaint) Return $aResult[0] EndFunc Func EndPaint($hWnd, $lpPaint) Local $aResult = DllCall('user32.dll', 'int', 'EndPaint', 'hwnd', $hWnd, 'ptr', $lpPaint) Return $aResult[0] EndFunc #EndRegion ;*************************************************************************** Does somebody have any suggestions ? Greetz Greenhorn Edited November 9, 2008 by Greenhorn Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now