Jump to content
Tuts 4 You

How to make a control transparent?


LCF-AT

Recommended Posts

Hi guys,

I have a new problem and need some help.I wanna create a edit / static control and make the edit field transparent (onlyy text should be visible).I found some MASM examples...

https://www.masmforum.com/archive2012/

...but somehow there are not so good etc.So what I want to know is how to make such controls transparent without to know the background.I don't know whether there is any image/bitmap or anything else in the background etc  so how to find it out and execute the right code to make the control transparent if I wanna do that?Is there a method or a function already I could use?

greetz

Link to comment

Try setting the background colour to transparent, but I don't think that should work, you'll probably need to do some pinvoking to get that to work.

  • Like 1
Link to comment
Teddy Rogers

Not entirely sure what it is you are trying to achieve, perhaps WM_CTLCOLORSTATIC is what you are after?

Procedure WindowCallback(WindowID, uMsg, wParam, lParam)
  Result = #PB_ProcessPureBasicEvents
  
  Select uMsg
    Case #WM_CTLCOLORSTATIC
      Select lParam
        Case GadgetID(1)
          SetBkMode_(wParam, #TRANSPARENT)
          ProcedureReturn GetStockObject_(#HOLLOW_BRUSH)
      EndSelect
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Ted.

  • Like 1
Link to comment

Hi guys,

thanks for your feedback so far.As I said already before I want to make my controls (text area) transparent and to bring in front whats in the back of the control / Area field.Just imagine that I don't know whats in the background of the control.It can be nothing (just dialog) or a image or anything else (just keep that in mind).I also found that example c++ you did post atom0s but this isn't working pretty well and also just in case when a bitmap is in the back.I tried the same too in MASM but I don't get same results out.In my case the background image which is shown on edit control back starts from the beginning = dosen't match with the real background.Just have a look...

T_2021-10-28_210117.png.0c9de49caed6861b5b2c147c2b6e2236.png

...above you can see original and my is below.In my case the image dosen't match with the background image look.In original it works and also if I try to move the edit control position to other then the image back in edit control get also changed in original / adjusted right but not in my case...just look....

T2_2021-10-28_210117.png.09e5099c0a48cd7425f7832016bf295a.png

...in my case it keeps same.Not sure why its not working same.What could be the problem of this?Also if I enter some text and move the scrollers H/V then the background in edit control does flicker the image (don't look good).

Anyway, so is there any else method to make the control transparent without to know whats in the back?

EDIT: I tried to use that GetStockObject_(#HOLLOW_BRUSH) at WM_CTLCOLOREDIT and now it does show the background correctly.....

T3_2021-10-28_210117.png.ae2d8867467df5f8598d9e0e1b6795a4.png

....but when I now enter something / scroll etc then it does smudge everything and the redraw function seems not to handle it anymore (it does without using HOLLOW_BRUSH and using bruch from CreatePatternBrush or else).Hhmm!Look....

T4_2021-10-28_210117.png.8527b0cb7dcdacbacd802587734681d2.png

....why this now?Thats the code I have...

WndProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
	local rc:RECT
	mov eax, uMsg
	.IF eax == WM_INITDIALOG

		invoke GetStockObject,HOLLOW_BRUSH
		mov HOLLOW, eax
		invoke LoadBitmap,hInstance,201
		mov bitmap, eax
		invoke CreatePatternBrush,bitmap
		mov edBrush, eax
		invoke GetDlgItem,hWin,IDC_EDIT
		invoke SetWindowLong,eax,GWL_WNDPROC,ADDR edit_proc
		mov    old_proc,eax

	.ELSEIF eax == WM_COMMAND
		mov eax, wParam
		mov ecx, eax
		and eax, 0FFFFh  ; ID     in eax / ax
		shr ecx,16       ; notify in ecx / cx
		.IF ax == IDB_EXIT;IDM_FILE_EXIT
			Invoke SendMessage,hWin,WM_CLOSE,0,0
		.ENDIF
	.ELSEIF eax == WM_CLOSE
		invoke DeleteObject,hFont
		Invoke DestroyWindow,hWin
	.ELSEIF eax == WM_DESTROY
		Invoke PostQuitMessage,NULL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
	.elseif eax == WM_ERASEBKGND
			invoke GetClientRect,hWin,addr rc
			invoke SelectObject,wParam,edBrush
			mov edi, eax
			mov eax, rc.right
			sub eax, rc.left
			mov ecx, rc.bottom
			sub ecx, rc.top
			invoke PatBlt,wParam,0,0,eax, ecx, PATCOPY
			invoke SelectObject,wParam,edi
			mov eax, TRUE
			ret
    .elseif eax == WM_CTLCOLOREDIT
              invoke GetDlgCtrlID, lParam
              .if eax == IDC_EDIT
                  invoke SetTextColor,wParam, Red
                  invoke SetBkMode,wParam,TRANSPARENT
                  mov eax, HOLLOW
                 ;mov eax, edBrush
                  ret
              .endif
              xor eax,eax
              ret	
	.ELSE
		Invoke DefWindowProc,hWin,uMsg,wParam,lParam
		ret
	.ENDIF
	xor    eax,eax
	ret
WndProc endp


edit_proc proc hwnd:DWORD,umsg:DWORD,wparam:DWORD,lparam:DWORD
	mov eax, umsg
	.if eax == WM_VSCROLL || eax == WM_HSCROLL || eax == WM_MOUSEWHEEL || eax == WM_CHAR
		invoke CallWindowProc,old_proc,hwnd,umsg,wparam,lparam
		invoke RedrawWindow,hwnd,0,0,RDW_ERASE+RDW_INVALIDATE+RDW_UPDATENOW
		xor eax, eax
		ret
	.endif
	invoke CallWindowProc,old_proc,hwnd,umsg,wparam,lparam
	ret
edit_proc endp

...when I just disable HOLLOW bruch to put in eax then it looks not dirty.Have I to use a specific flag for RedrawWindow function when using the HOLLOW brush?Anyway, so if you got some smarter ideas how to make it transparent then just tell us to try it.Thanks.

greetz

Link to comment
Teddy Rogers

Ah! Now I understand what you are trying to achieve.

This is how I would go about it doing it...

Declare.i WindowCallback(hWnd, uMsg, wParam, lParam)

If OpenWindow(0, 0, 0, 600, 400, "Transparent Editor Gadget", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  SetWindowCallback(@WindowCallback(), 0)
  
  ; Create the editor gadget, set the font and give it some colour.
  
  EditorGadget(1, 10, 10, 580, 380, #PB_Editor_WordWrap)
  SetGadgetFont(1, LoadFont(0, "Arial", 20, #PB_Font_Bold))
  SetGadgetColor(1, #PB_Gadget_FrontColor, #Red)
  
  ; Set a bitmap image for the window background.
  
  BITMAP = LoadImage_(#Null, #OBM_COMBO, #IMAGE_BITMAP, #Null, #Null, #LR_SHARED)
  HBRUSH = CreatePatternBrush_(BITMAP)
  SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, HBRUSH)
  
  ; Make the EditorGadget transparent and update the window cache with the bitmap brush.
  
  SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)
  
  Repeat 
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow 
EndIf

Procedure.i WindowCallback(hWnd, uMsg, wParam, lParam)
  
  Select uMsg
    Case #WM_SIZE
      SetWindowPos_(GadgetID(1), #Null, 10, 10, (lParam & $FFFF) - 20, (lParam >> 16) - 20, #SWP_NOZORDER | #SWP_NOACTIVATE)
      ProcedureReturn 0
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Ted.

 

Transparent Editor Gadget.zip

  • Like 1
Link to comment

Hi Ted,

thanks for helping but I can not download your file (Virus / Firefox said) and I also don't check your small code schnippel.

Sets the bitmap image into dialog window as background
SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, HBRUSH)

In this case I can remove my code at WM_ERASEBKGND


SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)
=
invoke GetWindowLong,EditHandle,GWL_EXSTYLE or WS_EX_TRANSPARENT
invoke SetWindowLong,EditHandle,GWL_EXSTYLE,eax
?or?
  
Whats this WindowCallback with WM_SIZE?I don't get WM_SIZE in my routine where I have subclassed the EDIT control.

And where is your code at WM_CTLCOLOREDIT?If I dont use code at this message then the edit control has a white background and no bitmap anymore when using HOLLOW brush.

PS: Can you compile your exe (x86) again (without possible Firefox Virus block)?

greetz

Link to comment

Hi again,

thanks for the source code YANiS. :) So I just see that did disable the HOLLOW brush in my code and using brush from CreatePatternBrush at WM_CTLCOLOREDIT.So this I tried before too but then the background image dosen't hit correctly in Edit control like this...(lowe image)..

T_2021-10-28_210117.png

....as you also can see is that my edit control looks else because I'am using a manifest xml in resources and here I found the problem for this issue.When I'am using a manifest file (always do) then this problem happens (Image dont match in Edit with background) BUT when I do remove the manifest from resources then it works and image does match.Hhmm!So what now?I want to use manifest file and don't wanna remove it.So can anyone tell me how to fix that new found issue with manifest file?

1 24 DISCARDABLE "manifest.xml"

Above you can see my line in resources.Just add it in your case too + use normal manifest file and then you should get same bad result.

One  more question about that update stuff inside the Edit control when entering some text / pressing enter / moving scroller up / down or selecting text inside of edit.In thise cases the stuff in edit control does flicker / smudges dirty etc.So the background does not keep same at all as it should or as I want.So how to manage that?

Just enter / paste many text inside and now select from top 2 below or else (scroller gets down or up) and now the background gets dirty because in select mode gets nothing updated.Or just use the scroller H or V and scroll and it does flicker a lot.All this looks really un-pretty & dirty.How to make it work flawless and smooth and clean and pretty etc? :) Just if its possible but I think somehow it should be possible.

greetz

Link to comment
Teddy Rogers
4 hours ago, LCF-AT said:

PS: Can you compile your exe (x86) again (without possible Firefox Virus block)?

Year is 2021 and still using 32bit!? I have recompiled and reattached.

I think the only code you need to reference is what I left as Win32...

  ; Set a bitmap image for the window background.
  
  BITMAP = LoadImage_(#Null, #OBM_COMBO, #IMAGE_BITMAP, #Null, #Null, #LR_SHARED)
  HBRUSH = CreatePatternBrush_(BITMAP)
  SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, HBRUSH)
  
  ; Make the EditorGadget transparent and update the window cache with the bitmap brush.
  
  SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)

All you need to do is create the background image using CreatePatternBrush then update the window where you want the brush (image) applied using SetClassLongPtr.

Once that is done make the edit control transparent (with WS_EX_TRANSPARENT style) and update the main windows cache to apply the new bitmap brush using SetWindowLongPtr (the OS updates the window cache when you apply the transparent style to the edit control).

"SetWindowCallbackWindowCall" is PureBasic code so I can process window events manually, to get sizing information from lParam.

"WM_SIZE" was to show that the window and edit control can be resized with the background pattern being updated and maintained...

Ted.

  • Like 1
Link to comment

Hi again,

thanks for the update of your file Ted but also this dosent help very much.It really sucks!Nothing works correctly as I wish.Why is there a WS_EX_TRANSPARENT style and does not do any transparent?In this case I as user should just enable that style to get my control TRANSPARENT without to care about anything else like I have to care now (subclass / update etc 💩).Its a total PITA and each time if I want to do or wish any little thing like in that case (just make transparent) I don't get it work to find a method which could do that as I wish.Uhhmmm!Always the same Krabappel!That really makes no fun anymore. :cry:

greetz

Link to comment
Teddy Rogers

Start afresh. Create a basic window and editor as normal with no background and transparency effects. Then add the steps in my previous post.

Another slight variation and breakdown which may help...

Declare.i WindowCallback(hWnd, uMsg, wParam, lParam)

If OpenWindow(0, 0, 0, 600, 400, "Transparent Editor Gadget", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget)
  SetWindowCallback(@WindowCallback(), 0)
  
  ; Create the editor gadget, set the font and give it some colour.
  
  EditorGadget(1, 10, 10, 580, 380, #PB_Editor_WordWrap)
  SetGadgetFont(1, LoadFont(0, "Arial", 20, #PB_Font_Bold))
  SetGadgetColor(1, #PB_Gadget_FrontColor, #Red)
  
  ; Set a bitmap image for the window background.
  
  BITMAP = LoadImage_(#Null, #OBM_COMBO, #IMAGE_BITMAP, #Null, #Null, #LR_SHARED)
  HBRUSH = CreatePatternBrush_(BITMAP)
  SetClassLongPtr_(WindowID(0), #GCL_HBRBACKGROUND, HBRUSH)
  
  ; Make the EditorGadget transparent.
  
  EDITOR_EXSTYLE = GetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE)
  SetWindowLongPtr_(GadgetID(1), #GWL_EXSTYLE, EDITOR_EXSTYLE | #WS_EX_TRANSPARENT)
  
  ; Ensure window and children caches are updated with transparency and bitmap brush.
  
  RedrawWindow_(WindowID(0), #Null, #Null, #RDW_ERASE | #RDW_INVALIDATE | #RDW_FRAME | #RDW_ALLCHILDREN)
  
  Repeat 
    Event = WaitWindowEvent() 
  Until Event = #PB_Event_CloseWindow 
EndIf

Procedure.i WindowCallback(hWnd, uMsg, wParam, lParam)
  
  Select uMsg
    Case #WM_SIZE
      MoveWindow_(GadgetID(1), 10, 10, (lParam & $FFFF) - 20, (lParam >> 16) - 20, #True)
      ProcedureReturn 0
  EndSelect
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

Ted.

  • Like 1
Link to comment

Hi Ted,

I tried your steps already.

Problem 1: Try using a manifest file in your source like I do and test it now.In my case the background image dosent match anymore in EDIT conrtol.If you dont use manifest file then background image does match (see my images in pre post).

Problem 2: I could use a manfiest file + using HOLLOW Brush instead of CreatePatternBrush / Brush and the background image does match in  EDIT control BUT the text inside the EDIT control get dirty again = not updated ALSO when its calling the subclass of Editcontrol to call RedrawWindow function.Anyhow the RedrawWindow + HOLLOWBRUSH do not work together = all in edit control keeps dirty and not updated.

Problem 3: Update / Flicker / smeared / jerk issues when doing anything in Editcontrol.It starts already when moving the H or V scroller (put much text into) and do scroll and the background in EC does jump / shake etc.Or select text with mouse and all gets smeared.If you now add WM_MOUSEMOVE to update in SClass then it flickers.

All in all its not really working nice and my question is whether there is any way to make it nice without get those issues you know.

PS: By the way Ted, I see that you did use a RichEdit control in your file.Try using a normal Edit control + and image (no pattern image).So what I want is not really much right.Just a edit control I wanna make transparent and without to get any jumpNrun / Flicker jerk smeared issues when using the EC.Pure basic right.Now I just ask whether anyone can realize that task.Sorry guys if I sound pretty pedantic in that case but things like that making me just angry you know.Please excuse this. :)

greetz

Link to comment

Doesn't take into account an edit control with scroll bars, so might not work exactly, but without scroll bars is not too bad, adapted from some code i have used before (and merged with your code slightly), so might be useful for you:

 

.DATA
hEdit           DD 0
hBackBrush      DD 0
hBitmap         DD 0

WndProc PROC USES EBX hWin:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
    LOCAL wNotifyCode:DWORD
    LOCAL rect:RECT
    LOCAL rectwin:RECT
    LOCAL x:DWORD
    LOCAL y:DWORD    
    
    mov eax, uMsg
    .IF eax == WM_INITDIALOG
        Invoke GetDlgItem, hWin, IDC_EDIT
        mov hEdit, eax                                  ; Save handle to edit control
        invoke LoadBitmap,hInstance,201
        mov hBitmap, eax
        invoke CreatePatternBrush, hBitmap              ; Create a brush from bitmap
        mov hBackBrush, eax                             ; Save background brush
        
        
    .ELSEIF eax == WM_COMMAND
        Invoke InvalidateRect, hEdit, NULL, TRUE        ; Refresh if anything happens
    
        mov eax, wParam
        shr eax, 16
        mov wNotifyCode, eax
        mov    eax,wParam
        and    eax,0FFFFh
        
        ; Normal code continues
        
    .ELSEIF eax == WM_CTLCOLOREDIT
        mov eax, lParam
        .IF eax == hEdit
            Invoke GetWindowRect, hWnd, Addr rectwin    ; Window placement
            Invoke GetWindowRect, lParam, Addr rect     ; Control placement
    
            Invoke SetBkMode, wParam, TRANSPARENT
            Invoke SetTextColor, wParam, Red
            
            mov eax, rectwin.left
            mov ebx, rect.left
            sub eax, ebx
            mov x, eax
            
            mov eax, rectwin.top
            mov ebx, rect.top
            sub eax, ebx
            mov y, eax
            
            Invoke SetBrushOrgEx, wParam, x, y, 0       ; Set the brush origin (relative placement)
            mov eax, hBackBrush                         ; Return background pattern brush (image but now offset)
            ret
        .ENDIF
    
    ; comment out this section unless using a child dialog within another dialog
    .ELSEIF eax == WM_CTLCOLORDLG
        Invoke GetWindowRect, hWnd, Addr rectwin        ; Window placement
        Invoke GetWindowRect, lParam, Addr rect         ; Control placement
        
        mov eax, rectwin.left
        mov ebx, rect.left
        sub eax, ebx
        mov x, eax
        
        mov eax, rectwin.top
        mov ebx, rect.top
        sub eax, ebx
        mov y, eax
        
        Invoke SetBrushOrgEx, wParam, x, y, 0           ; Set the brush origin (relative placement)
        mov eax, hBackBrush                             ; Return background pattern brush (image but now offset)

 

Spellbook.gif

Edited by fearless
added gif
  • Like 1
Link to comment

Hi fearless,

thank you for trying to help me but also your code isn't not much better working when using scrollers.When using subclass for edit control and update on WM_HSCROLL / WM_VSCROLL then it flickers +/-.It really seems that there isn't any better method to get it work 1A without all those issues I told about it before. :(

One more thing fearless.Could you please check out & tell me what the problem is with that manifest file & WM_CTLCOLOREDIT.When NOT using a manifest file in resources and using this code...

    .elseif eax == WM_CTLCOLOREDIT
              invoke GetDlgCtrlID, lParam
              .if eax == IDC_EDIT
              	  invoke SetBkMode,wParam,TRANSPARENT
                  invoke SetTextColor,wParam, Red
                  mov eax, edBrush ; <-- hBackBrush
                  ret

....then the image / brush does match inside the edit control with the original backgound (DLG Image)....and with WITH I get this...

M1_2021-11-01_165041.png.3e46e3e41b43f3d451e4cdaf354be042.png..M2_2021-11-01_165041.png.13c0f271012af9bc106838809d288066.png

...you see the text of image dosen't match anymore just by adding this line into resources...

1 24 DISCARDABLE "manifest.xml"

....How to fix that?I always use manifest because I prefer the look.

Now when I use the HOLLOW Brush / NULL Brush instead of hBackBrush & using manifest then it shows the image correctly....

M3_2021-11-01_165041.png.64e4e4f432032acbaf6115545a942c58.png..M4_2021-11-01_165041.png.42ce91c4240731f1b2f9ad272a4c71af.png

...how to get this thing working?The Edit control should work like glass pane where the text gets drawn on it.Is there anything I have to enable on Edit style / ExStyle WHEN using manifest to get the background match etc?Maybe you can figure out that problem when using a MF file.Thanks.

greetz

Link to comment

Hi,

I have to adjust the X,Y values when using a manifest like this to make it match....

P_2021-11-02_230804.png.d0166bbc03c94b1b0c5cb2252a6584ea.png

...adding values of 6 & 29 looks pretty same matching as without using manifest.Otherwise I would really like to know why the manifest makes that problem.Does nobody know that yet?

greetz

Link to comment

Probably has to do with DWM and bordering styles and sizes, adding manifest forces windows to apply the DWM styles and borders to dialogs, windows and controls if they are set to have them. Otherwise with no manifest you get the classic style of bordering which can be different in size for dialogs and windows and controls.

  • Like 1
Link to comment

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...