Page 1 of 2

String Gadget Background Transparent?

Posted: Sun Dec 02, 2007 10:45 pm
by abc123
How can i do this?

Posted: Mon Dec 03, 2007 12:15 am
by netmaestro
For a text gadget it's not so hard, but for a string gadget, editing must be taken into account. The problem is that erasing with a null brush doesn't erase anything! So, let the hacks begin...

Code: Select all

;=============================================================== 
; Program:          A bunch of dirty hacks 
; Author:           netmaestro 
; Date:             December 2, 2007 
; Target OS:        Microsoft Windows all 
; Target compiler:  PureBasic 4.xx and later 
; License:          Free, unrestricted, use at your own risk 
;=============================================================== 

Global stringpattern.l, bkswitch.l = 0 

CreateImage(0,320,240,32) 
StartDrawing(ImageOutput(0)) 
  For i=0 To 231 Step 16 
    For j = 0 To 311 Step 16 
      Box(j,i,8,8,RGB(230,230,255)) 
      Box(j+8,i,8,8,#White) 
      Box(j,i+8,8,8,#White) 
      Box(j+8,i+8,8,8,RGB(230,230,255))      
    Next 
  Next 
StopDrawing() 

Procedure WinProc(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_CTLCOLOREDIT 
      hdc = wParam 
      SetTextColor_(hdc, #Black) 
      SetBkMode_(hdc, #TRANSPARENT) 
      result = stringpattern 
  EndSelect  
  ProcedureReturn result 
EndProcedure 

OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 

CreateGadgetList(WindowID(0)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
DisableGadget(0, #True) 
StringGadget(1,10,10,200,20,"hello") 
GrabImage(0, 1, GadgetX(1)+2,GadgetY(1)+2, GadgetWidth(1)-2,GadgetHeight(1)-2) 
stringpattern = CreatePatternBrush_(ImageID(1)) 
SetWindowCallback(@WinProc()) 

Repeat:Until WaitWindowEvent()=#WM_CLOSE 

DeleteObject_(stringpattern) 

Posted: Mon Dec 03, 2007 12:27 am
by srod
Doesn't work properly here netty until you remove the Select / EndSelect in the subclass proc.

On my machine, enter some text, cursor back and then insert more text and the entire string gadget's contents become all mixed up.

As I say, the problem is rectified by removing the Select etc.

Otherwise, very nice. Hack central here we come! :)

Posted: Mon Dec 03, 2007 12:36 am
by netmaestro
I totally updated the idea, could you try it again?

Posted: Mon Dec 03, 2007 12:47 am
by srod
Yep, seems to work well. :)

Posted: Mon Dec 03, 2007 12:50 am
by srod
You can remove the timers completely if you just take the string gadget border into account. Here I did it manually :

Code: Select all

;=============================================================== 
; Program:          A bunch of dirty hacks 
; Author:           netmaestro 
; Date:             December 2, 2007 
; Target OS:        Microsoft Windows all 
; Target compiler:  PureBasic 4.xx and later 
; License:          Free, unrestricted, use at your own risk 
;=============================================================== 

CreateImage(0,320,240,32) 
StartDrawing(ImageOutput(0)) 
  For i=0 To 231 Step 16 
    For j = 0 To 311 Step 16 
      Box(j,i,8,8,RGB(230,230,255)) 
      Box(j+8,i,8,8,#White) 
      Box(j,i+8,8,8,#White) 
      Box(j+8,i+8,8,8,RGB(230,230,255))      
    Next 
  Next 
StopDrawing() 

Procedure StringProc(hwnd, msg, wparam, lparam) 
  oldproc = GetProp_(hwnd, "oldproc") 
  Select msg 
    Case #WM_KEYDOWN 
 ;     Select wparam 
 ;       Case 8, 32 
          hdc = GetWindowDC_(#Null) 
          hdcout = GetDC_(hwnd) 
          hdcin = CreateCompatibleDC_(hdc) 
          SelectObject_(hdcin, ImageID(1)) 
          BitBlt_(hdcout,0,0,200,20,hdcin,0,0,#SRCCOPY) 
          ReleaseDC_(0, hdc) 
          DeleteDC_(hdcin) 
          ReleaseDC_(hwnd, hdcout) 
          InvalidateRect_(hwnd, 0,1) 
;      EndSelect 
    Case #WM_NCDESTROY 
      RemoveProp_(hwnd, "oldproc") 
  EndSelect 
  ProcedureReturn CallWindowProc_(oldproc, hwnd, msg, wparam, lparam) 
EndProcedure 

Procedure WinProc(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_CTLCOLOREDIT 
      hdc = wParam 
      SetTextColor_(hdc, #Black) 
      SetBkMode_(hdc, #TRANSPARENT) 
      result = GetStockObject_(#NULL_BRUSH) 
  EndSelect  
  ProcedureReturn result 
EndProcedure 


OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 

CreateGadgetList(WindowID(0)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
DisableGadget(0, #True) 
UpdateWindow_(WindowID(0))
StringGadget(1,10,10,200,20,"") 
GrabImage(0, 1, 12,12, 200, 20)
SetGadgetText(1, "initial value"); Here is where you would set an initial text for the gadget 
oldproc = SetWindowLong_(GadgetID(1), #GWL_WNDPROC, @StringProc()) 
SetProp_(GadgetID(1), "oldproc", oldproc) 
SetWindowCallback(@WinProc()) 

Repeat:Until WaitWindowEvent()=#WM_CLOSE 

Posted: Mon Dec 03, 2007 12:52 am
by srod
Uhm, none of the code works with xp-themes.

Posted: Mon Dec 03, 2007 12:59 am
by netmaestro
I made another update to the first-posted code, no more beloved timers (damn) and it works with xp themes!

Posted: Mon Dec 03, 2007 1:03 am
by srod
hehe, I just hacked a lot of your code to get one which works with themes etc. I'll post and then have a look at yours :wink: :

Code: Select all

;=============================================================== 
; Program:          A bunch of dirty hacks 
; Author:           netmaestro 
; Date:             December 2, 2007 
; Target OS:        Microsoft Windows all 
; Target compiler:  PureBasic 4.xx and later 
; License:          Free, unrestricted, use at your own risk 
;=============================================================== 

Global stringpattern

CreateImage(0,320,240,32) 
StartDrawing(ImageOutput(0)) 
  For i=0 To 231 Step 16 
    For j = 0 To 311 Step 16 
      Box(j,i,8,8,RGB(230,230,255)) 
      Box(j+8,i,8,8,#White) 
      Box(j,i+8,8,8,#White) 
      Box(j+8,i+8,8,8,RGB(230,230,255))      
    Next 
  Next 
StopDrawing() 


Procedure WinProc(hwnd, msg, wparam, lparam) 
  result = #PB_ProcessPureBasicEvents 
  Select msg 
    Case #WM_CTLCOLOREDIT 
      hdc = wParam 
      SetTextColor_(hdc, #Black) 
      SetBkMode_(hdc, #TRANSPARENT) 
      result = stringpattern 
  EndSelect  
  ProcedureReturn result 
EndProcedure 


OpenWindow(0,0,0,320,240,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 

CreateGadgetList(WindowID(0)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
DisableGadget(0, #True) 
UpdateWindow_(WindowID(0))
StringGadget(1,10,10,200,20,"") 
GrabImage(0, 1, 12,12, 200, 20)
stringpattern = CreatePatternBrush_(ImageID(1)) 
SetGadgetText(1, "initial value"); Here is where you would set an initial text for the gadget 
SetWindowCallback(@WinProc()) 


Repeat:Until WaitWindowEvent()=#WM_CLOSE 

Posted: Mon Dec 03, 2007 1:06 am
by netmaestro
Pretty good, you only grab too big an image, other than that it seems the same. It's working well, and in reflection, after the refinements it's not so much of a hack really. Almost T&T worthy.

Posted: Mon Dec 03, 2007 1:06 am
by srod
Yep almost identical except I don't use the timer! :)

What am I talking about, it's all your code anyhow?


**EDIT : oops, clumsy me with the oversized grab! Course with that method I should throw some GetSystemMetrics_() etc.

I agree, it's a nice way of doing it and seems pretty tight.

Posted: Mon Dec 03, 2007 1:08 am
by netmaestro
Sorry, I accidentally left the timer proc in, though I wasn't calling it. I just forgot to erase it. Other than that, it's the same as the update you made.

Posted: Mon Dec 03, 2007 2:43 am
by Pantcho!!
you hackers!

Posted: Mon Dec 03, 2007 2:50 am
by LuCiFeR[SD]
netmaestro & Srod... Just want you both to know (no taking the piddle out of a drunk bloke now) I have nothing but very deep respect for both of you... shame you both smell of wee :) haha, sorry! I wish I had 1/5th of the talent you guys show around here! Gentlemen, if either of you venture to sunny telford, I promise to buy you a beer or ten!

Posted: Mon Dec 03, 2007 10:33 am
by srod
LuCiFeR[SD] wrote:Gentlemen, if either of you venture to sunny telford, I promise to buy you a beer or ten!
I'm on my way! :wink:

Actually, I pass Telford (on my way to Shrewsbury) a couple of times every year. The next scheduled pit-stop is early Jan when I intend to down a keg or two without spilling a drop.

Aye, looks like I'll be dancing naked through the streets of Shrewsbury again...