benners Posted July 6 Share Posted July 6 I have a gui that displays a colour and alters its transparency based on a sliders value. I thought it would be nice to have a background like that seen in other graphic programs. I made a bmp and successfully implemented Then I thought I would try to do it without using an external image. I have managed to get this working but it is not smooth. The image does not fade in and out as smooth as with a bmp and the slider control tooltip jumps around. It has taken days throwing stuff at the screen to see what works but I can't sort this. The two functions that make up the main drawing operations are CV_CreateARGBBitmap and CV_SetARGBOpacity. CV_SetARGBOpacity is butchered from a help file example. Any advice or code improvements are welcomed. The files are attached. Colour Viewer.au3 transparent.bmp Link to comment Share on other sites More sharing options...
Solution Andreik Posted July 7 Solution Share Posted July 7 Maybe posting a specific question without unnecessary code increase the chances that you will receive a fast answer from other users. Anyway, here is a demo that should help you. Make the necessary changes to fit your project. expandcollapse popup#include <GDIPlus.au3> _GDIPlus_Startup() Global $hDisplay = _GDIPlus_BitmapCreateFromScan0(178, 146) Global $hGraphics1 = _GDIPlus_ImageGetGraphicsContext($hDisplay) Global $hColor = _GDIPlus_BitmapCreateFromScan0(178, 146) Global $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hColor) Global $hTransparent = _GDIPlus_BitmapCreateFromFile(@ScriptDir & '\transparent.bmp') Global $hGUI, $cPic, $cSlider, $hSlider, $cDummy $hGUI = GUICreate('Example', 198, 250) $cPic = GUICtrlCreatePic('', 10, 10, 178, 146) $cSlider = GUICtrlCreateSlider(10, 165, 178, 40) $hSlider = GUICtrlGetHandle($cSlider) $cColor = GUICtrlCreateInput('D62828', 10, 215, 178, 25, 0x01) $cDummy = GUICtrlCreateDummy() GUICtrlSetLimit($cSlider, 255, 0) GUICtrlSetFont($cColor, 12) GUICtrlSetData($cSlider, 127) GUISetState(@SW_SHOW, $hGUI) GUIRegisterMsg(0x0114, 'WM_HSCROLL') UpdateColor() While True Switch GUIGetMsg() Case $cDummy If GUICtrlRead($cDummy) = $cSlider Then UpdateColor() Case -3 ExitLoop EndSwitch WEnd _GDIPlus_GraphicsDispose($hGraphics1) _GDIPlus_GraphicsDispose($hGraphics2) _GDIPlus_BitmapDispose($hTransparent) _GDIPlus_BitmapDispose($hColor) _GDIPlus_BitmapDispose($hDisplay) _GDIPlus_Shutdown() Func UpdateColor() Local $sColor = GUICtrlRead($cColor) Local $iAlpha = GUICtrlRead($cSlider) _GDIPlus_GraphicsDrawImageRect($hGraphics1, $hTransparent, 0, 0, 178, 146) _GDIPlus_GraphicsClear($hGraphics2, '0x' & Hex($iAlpha, 2) & $sColor) _GDIPlus_GraphicsDrawImageRect($hGraphics1, $hColor, 0, 0, 178, 146) ImageToCtrl($hDisplay, $cPic) GUICtrlSetTip($cSlider, $iAlpha) EndFunc Func ImageToCtrl($hBitmap, $cCtrl) Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _WinAPI_DeleteObject(GUICtrlSendMsg($cCtrl, 0x0172, 0, $hHBITMAP)) _WinAPI_DeleteObject($hHBITMAP) EndFunc Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Switch $lParam Case $hSlider GUICtrlSendToDummy($cDummy, $cSlider) EndSwitch EndFunc benners 1 Link to comment Share on other sites More sharing options...
benners Posted July 7 Author Share Posted July 7 Firstly, thanks for the reply. I'm sure I can exchange some of my bloated code for your streamlined version. It still uses the bmp that I wanted to get away from though. 20 hours ago, benners said: Then I thought I would try to do it without using an external image. I posted the full code as there were other functions that may have impacted the smoothness of the fading and the slider tooltips as has happened to me in the past. I also specified the two functions that were the meat and potatoes of the drawing operations so that anyone who would be kind enough to help could just examine those specifically'. 20 hours ago, benners said: The two functions that make up the main drawing operations are CV_CreateARGBBitmap and CV_SetARGBOpacity. The CV_CreateCheckerboardBitmap function was my attempt to reproduce the transparent.bmp. It worked but not to my satisfaction. Cheers Link to comment Share on other sites More sharing options...
Andreik Posted July 7 Share Posted July 7 (edited) 34 minutes ago, benners said: Firstly, thanks for the reply. I'm sure I can exchange some of my bloated code for your streamlined version. It still uses the bmp that I wanted to get away from though. It should be easy to adapt to your current code, just don't create new resources each time the slider is moving. Edit: here is an example of how you can create the checkerboard expandcollapse popup#include <GDIPlus.au3> _GDIPlus_Startup() Global $hDisplay = _GDIPlus_BitmapCreateFromScan0(178, 146) Global $hGraphics1 = _GDIPlus_ImageGetGraphicsContext($hDisplay) Global $hColor = _GDIPlus_BitmapCreateFromScan0(178, 146) Global $hGraphics2 = _GDIPlus_ImageGetGraphicsContext($hColor) Global $hTransparent = CreateTransparentLayer(178, 146) Global $hGUI, $cPic, $cSlider, $hSlider, $cDummy $hGUI = GUICreate('Example', 198, 250) $cPic = GUICtrlCreatePic('', 10, 10, 178, 146) $cSlider = GUICtrlCreateSlider(10, 165, 178, 40) $hSlider = GUICtrlGetHandle($cSlider) $cColor = GUICtrlCreateInput('D62828', 10, 215, 178, 25, 0x01) $cDummy = GUICtrlCreateDummy() GUICtrlSetLimit($cSlider, 255, 0) GUICtrlSetFont($cColor, 12) GUICtrlSetData($cSlider, 127) GUISetState(@SW_SHOW, $hGUI) GUIRegisterMsg(0x0114, 'WM_HSCROLL') UpdateColor() While True Switch GUIGetMsg() Case $cDummy If GUICtrlRead($cDummy) = $cSlider Then UpdateColor() Case -3 ExitLoop EndSwitch WEnd _GDIPlus_GraphicsDispose($hGraphics1) _GDIPlus_GraphicsDispose($hGraphics2) _GDIPlus_BitmapDispose($hTransparent) _GDIPlus_BitmapDispose($hColor) _GDIPlus_BitmapDispose($hDisplay) _GDIPlus_Shutdown() Func UpdateColor() Local $sColor = GUICtrlRead($cColor) Local $iAlpha = GUICtrlRead($cSlider) _GDIPlus_GraphicsDrawImageRect($hGraphics1, $hTransparent, 0, 0, 178, 146) _GDIPlus_GraphicsClear($hGraphics2, '0x' & Hex($iAlpha, 2) & $sColor) _GDIPlus_GraphicsDrawImageRect($hGraphics1, $hColor, 0, 0, 178, 146) ImageToCtrl($hDisplay, $cPic) GUICtrlSetTip($cSlider, $iAlpha) EndFunc Func ImageToCtrl($hBitmap, $cCtrl) Local $hHBITMAP = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _WinAPI_DeleteObject(GUICtrlSendMsg($cCtrl, 0x0172, 0, $hHBITMAP)) _WinAPI_DeleteObject($hHBITMAP) EndFunc Func CreateTransparentLayer($iWidth, $iHeight, $iSquareSize = 10, $iColor1 = 0xFFFFFFFF, $iColor2 = 0xFF808080) Local $hLayer = _GDIPlus_BitmapCreateFromScan0($iSquareSize * 2, $iSquareSize * 2) Local $hContext = _GDIPlus_ImageGetGraphicsContext($hLayer) Local $hBrush = _GDIPlus_BrushCreateSolid($iColor1) _GDIPlus_GraphicsClear($hContext, $iColor2) _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iSquareSize, $iSquareSize, $hBrush) _GDIPlus_GraphicsFillRect($hContext, $iSquareSize, $iSquareSize, $iSquareSize, $iSquareSize, $hBrush) Local $hTexture = _GDIPlus_TextureCreate($hLayer) _GDIPlus_GraphicsDispose($hContext) _GDIPlus_BrushDispose($hBrush) _GDIPlus_BitmapDispose($hLayer) $hLayer = _GDIPlus_BitmapCreateFromScan0($iWidth, $iHeight) $hContext = _GDIPlus_ImageGetGraphicsContext($hLayer) _GDIPlus_GraphicsFillRect($hContext, 0, 0, $iWidth, $iHeight, $hTexture) _GDIPlus_GraphicsDispose($hContext) _GDIPlus_BrushDispose($hTexture) Return $hLayer EndFunc Func WM_HSCROLL($hWnd, $iMsg, $wParam, $lParam) #forceref $hWnd, $iMsg, $wParam Switch $lParam Case $hSlider GUICtrlSendToDummy($cDummy, $cSlider) EndSwitch EndFunc Changing CV_CreateCheckerboardBitmap() with CreateTransparentLayer() and the lag is already gone (using your current code without any further adaptation). Of course there are other things that can be improved but right now your function is the killer with so many loops and drawing operations. Add CreateTransparentLayer() to your current code and change this line Local $g_hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap(CV_CreateCheckerboardBitmap($CV_RECTWIDTH, $CV_RECTHEIGHT, 5)) with Local $g_hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap(CreateTransparentLayer($CV_RECTWIDTH, $CV_RECTHEIGHT, 5)) Edited July 7 by Andreik benners 1 Link to comment Share on other sites More sharing options...
benners Posted July 8 Author Share Posted July 8 Well I managed to adapt your code to fit in mine and it works better than before. I had to alter the updatecolor slightly as the the input it reads from has argb format. I also got it to work with the checkerboard function as well. Happy days, Thanks. Func CV_CreateCheckerboardBitmap() Local $iCheckerSize = 5 ;_ define the size of each checker square Local $hBitmap = _GDIPlus_BitmapCreateFromScan0($CV_RECTWIDTH, $CV_RECTHEIGHT) ; create a new bitmap with the specified width and height Local $hGraphics = _GDIPlus_ImageGetGraphicsContext($hBitmap) ;_ get the graphics context of the bitmap Local $hBrush1 = _GDIPlus_BrushCreateSolid(0xFFFFFFFF) ;_ create white brush for the checkerboard colors Local $hBrush2 = _GDIPlus_BrushCreateSolid(0xFFC2C6C3) ;_ create grey brush for the checkerboard colors ; Loop through the bitmap height in steps of checker size For $y = 0 To $CV_RECTHEIGHT - 1 Step $iCheckerSize ; Loop through the bitmap width in steps of checker size For $x = 0 To $CV_RECTWIDTH - 1 Step $iCheckerSize ; Determine which color to use based on the checker pattern If Mod($x / $iCheckerSize + $y / $iCheckerSize, 2) = 0 Then ; Fill the rectangle with the first brush (white) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $iCheckerSize, $iCheckerSize, $hBrush1) Else ; Fill the rectangle with the second brush (black) _GDIPlus_GraphicsFillRect($hGraphics, $x, $y, $iCheckerSize, $iCheckerSize, $hBrush2) EndIf Next Next _GDIPlus_BrushDispose($hBrush1) ;_ dispose of the brushes _GDIPlus_BrushDispose($hBrush2) _GDIPlus_GraphicsDispose($hGraphics) ;_ dispose of the graphics context Return $hBitmap ; return the created bitmap EndFunc ;==>CV_CreateCheckerboardBitmap I'll try your checkerboard function as well> 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