[Implemented] GadgetOutput

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

[Implemented] GadgetOutput

Post by freedimension »

For some Gadgets it would be very helpful, if there were a GadgetOutput Command to be able to directly draw in it's Window.
At the moment I'm trying hard to draw something in a ScrollAreaGadget. Because of flickering in an ImageGadget placed inside the ScrollAreaGadget (with me it only occurs when XP Skin Support is enabled) I wanted to try out another alternative, but without GadgetOutput no StartDrawing and no DrawImage.

thx4reading

(Implemented as 'CanvasOutput()')
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Post by Fred »

Doing this would be not easy because at each paint (or gadget redraw) yoiur graphics will be lost. That's why the ImageGadget is needed here.
plouf
Enthusiast
Enthusiast
Posts: 281
Joined: Fri Apr 25, 2003 6:35 pm
Location: Athens,Greece

Post by plouf »

Would be possible then to add the possibility to have
a SetGadgetCallBack() so it can catch repaint messages ?
plus more thinks so you haven't have to check main window
if you need a specific gadget action ?
Christos
freedimension
Enthusiast
Enthusiast
Posts: 613
Joined: Tue May 06, 2003 2:50 pm
Location: Germany
Contact:

Post by freedimension »

Fred wrote:Doing this would be not easy because at each paint (or gadget redraw) yoiur graphics will be lost. That's why the ImageGadget is needed here.
That's why I would do this when catching the WM_PAINT Message. All I have to know is the right OutputID but I don't know a way to get it (not even an unofficial one).

@ plouf: That's already possible with the SetWindowCallback Function. All you have to do is to check the hWnd Parameter of your Callback Function. The hWnd-Value for the Gadget can be retrieved through the GadgetID Function.

Although for a ScrollAreaChildWindow it is a little bit harder:

Code: Select all

Structure PB_ScrollAreaData 
    ScrollAreaChild.l
    ScrollStep.l
  EndStructure
  hScrollArea = GadgetID(gadget) 
  *SAGdata.PB_ScrollAreaData = GetWindowLong_(hScrollArea, #GWL_USERDATA)
hWnd = *SAGdata\ScrollAreaChild ;this is the hWnd of the ScrollAreaChildWindow
I hope this will not change in a future version of PB
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

@plouf :
Would be possible then to add the possibility to have
a SetGadgetCallBack() so it can catch repaint messages ?
As a gadget is considered as a window under MS-Windows you can do a SetWindowCallback() on a gadget, and thus intercept any gadget events (#WM_PAINT for example) in this callback independtly of your main window events loop.

I have done such an example :

Code: Select all

Structure SKIN
  fg.l
  bg.l
  mode.l
  brush.l
  old.l
EndStructure

;----------------------------------------------------------

Procedure ComboCallBack( hWnd.l, Msg.l, wParam.l, lParam.l ) 
  
  *skin.SKIN = GetWindowLong_( hWnd, #GWL_USERDATA )
  Result.l   = CallWindowProc_( *skin\old, hWnd, Msg, wParam, lParam )
  
  If (Msg=#WM_DESTROY)
  
    DeleteObject_( *skin\brush )
    GlobalFree_( *skin )
    PostQuitMessage_(0)
    
  ElseIf (Msg=#WM_CTLCOLOREDIT) Or (Msg=#WM_CTLCOLORLISTBOX)
    
    SetTextColor_( wParam, *skin\fg ) 
    SetBkColor_  ( wParam, *skin\bg ) 
    SetBkMode_   ( wParam, *skin\mode )
    Result = *skin\brush
  
  EndIf
  
  ProcedureReturn Result 
  
EndProcedure

;----------------------------------------------------------

Procedure.l CustomCombo( id.l, fgColor.l, bgColor.l, brColor.l, mode.l )
  
  skinStruct.l = GlobalAlloc_(0,SizeOf(SKIN))
  If skinStruct <> #NULL
    *skin.SKIN  = skinStruct
    *skin\fg    = fgColor
    *skin\bg    = bgColor
    *skin\mode  = mode
    *skin\brush = CreateSolidBrush_( brColor )
    *skin\old   = SetWindowLong_( GadgetID(id), #GWL_WNDPROC, @ComboCallBack() )
    SetWindowLong_( GadgetID(id), #GWL_USERDATA, *skin )
  EndIf
  
EndProcedure

;----------------------------------------------------------

OpenWindow( 0, 200,400,200,100, #PB_Window_SystemMenu, "Colorisation et Callback" ) 

CreateGadgetList( WindowID() ) 
ComboBoxGadget( 0, 10, 10, 180, 120, #PB_ComboBox_Editable )
ComboBoxGadget( 1, 10, 40, 180, 120, #PB_ComboBox_Editable )
ComboBoxGadget( 2, 10, 70, 180, 120, #PB_ComboBox_Editable )

For i=0 To 2
  AddGadgetItem( i, -1, "une ligne d'exemple" )
  AddGadgetItem( i, -1, "et encore une autre" )
  AddGadgetItem( i, -1, "une p'tite dernière" )
  AddGadgetItem( i, -1, "pour finir..." )
  SetGadgetState( i, i )
Next

CustomCombo( 0, $00FFFF, $888888, $000000, #OPAQUE )
CustomCombo( 1, $BBFFFF, $AAFFAA, $FFCCCC, #OPAQUE )
CustomCombo( 2, $AA0000, $888888, $DDFFFF, #TRANSPARENT )

Repeat : Until WaitWindowEvent() = #PB_EventCloseWindow
End
Note this line, very important :

Code: Select all

*skin\old   = SetWindowLong_( GadgetID(id), #GWL_WNDPROC, @ComboCallBack() )
which allow you to overlap the current API callback...
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
plouf
Enthusiast
Enthusiast
Posts: 281
Joined: Fri Apr 25, 2003 6:35 pm
Location: Athens,Greece

Post by plouf »

yep flype exactly what i was meaning tnx
Christos
User avatar
Flype
Addict
Addict
Posts: 1542
Joined: Tue Jul 22, 2003 5:02 pm
Location: In a long distant galaxy

Post by Flype »

if there were a GadgetOutput Command to be able to directly draw in it's Window
You may use this way :

Code: Select all

Structure GT
  dc.l
  brush.l
  oldcb.l
EndStructure

;----------------------------------------------------------

Procedure MyGadgetCallBack( hWnd.l, Msg.l, wParam.l, lParam.l ) 
  
  *gt.GT = GetWindowLong_( hWnd, #GWL_USERDATA )
  Result.l = CallWindowProc_( *gt\oldcb, hWnd, Msg, wParam, lParam )
  
  If Msg = #WM_PAINT Or Msg = #WM_ERASEBKGND
    
    ; just a little example

    r.RECT
    GetClientRect_( hWnd, r )
    r\top + 20
    FillRect_( *gt\dc, r, *gt\brush )
    
  EndIf
  
  ProcedureReturn Result 
  
EndProcedure

;----------------------------------------------------------

Procedure.l CustomGadget( id.l )
  
  gtStruct.l = GlobalAlloc_(0,SizeOf(GT))
  If gtStruct <> #NULL
    *gt.GT    = gtStruct
    *gt\dc    = GetDC_( GadgetID( id ) )
    *gt\brush = CreateSolidBrush_( $FFFFFF )
    *gt\oldcb = SetWindowLong_( GadgetID(id), #GWL_WNDPROC, @MyGadgetCallBack() )
    SetWindowLong_( GadgetID(id), #GWL_USERDATA, *gt )
  EndIf
  
EndProcedure

;----------------------------------------------------------

OpenWindow( 0, 200,200,200,300, #PB_Window_SystemMenu, "Colorisation et Callback" ) 

CreateGadgetList( WindowID() )
TextGadget  ( 0, 10, 10, 180, 280, "Hello World !", #PB_Text_Border )
CustomGadget( 0 )

While WaitWindowEvent() <> #PB_EventCloseWindow : Wend
End
No programming language is perfect. There is not even a single best language.
There are only languages well suited or perhaps poorly suited for particular purposes. Herbert Mayer
Post Reply