Seite 1 von 4

SetGadgetItemData & SetGadgetItemColor fuer Panel

Verfasst: 03.02.2008 21:30
von edel

Code: Alles auswählen

;{ pb intern struct
CompilerIf Defined(PB_GadgetVT, #PB_Structure) = #False
Structure PB_GadgetVT
  GadgetType.l   
  SizeOf.l       
  GadgetCallback.l
  FreeGadget.l
  GetGadgetState.l
  SetGadgetState.l
  GetGadgetText.l
  SetGadgetText.l
  AddGadgetItem2.l
  AddGadgetItem3.l
  RemoveGadgetItem.l
  ClearGadgetItemList.l
  ResizeGadget.l
  CountGadgetItems.l
  GetGadgetItemState.l
  SetGadgetItemState.l
  GetGadgetItemText.l
  SetGadgetItemText.l
  OpenGadgetList2.l
  GadgetX.l
  GadgetY.l
  GadgetWidth.l
  GadgetHeight.l
  HideGadget.l
  AddGadgetColumn.l
  RemoveGadgetColumn.l
  GetGadgetAttribute.l
  SetGadgetAttribute.l
  GetGadgetItemAttribute2.l
  SetGadgetItemAttribute2.l
  SetGadgetColor.l
  GetGadgetColor.l
  SetGadgetItemColor2.l
  GetGadgetItemColor2.l
  SetGadgetItemData.l
  GetGadgetItemData.l
EndStructure
CompilerEndIf

CompilerIf Defined(PB_Gadget, #PB_Structure) = #False
Structure PB_Gadget
  Gadget.l
  *VT.PB_GadgetVT
  UserData.l
  OldCallback.l
  Daten.l[4]
EndStructure

Structure PB_Panel_User_Data
   user_data.l
   forecolor.l
   backcolor.l
   static_callback.l
EndStructure

CompilerEndIf ;}

Declare PB_GetPanelStaticItem(*gadget.PB_Gadget   ,item)
Declare PB_GetGadgetItemData (*gadget.PB_Gadget   ,item)
Declare PB_SetGadgetItemData (*gadget.PB_Gadget   ,item,value)

Procedure PB_PanelStaticCB(hwnd,msg,wparam,lparam)
   Protected *pud.PB_Panel_User_Data   
   Protected callback.l
   
   *pud        = GetWindowLong_(hwnd,#GWL_USERDATA)
   callback = *pud\static_callback
   
   If #WM_DESTROY = msg
      FreeMemory(*pud)      
   EndIf
   
   ProcedureReturn CallWindowProc_(callback,hwnd,msg,wparam,lparam)
EndProcedure

Procedure PB_PanelParentCB(hwnd,msg,wparam,lparam)
   Protected *pud.PB_Panel_User_Data   
   Protected *dis.DRAWITEMSTRUCT
   Protected shWnd.l
   Protected callback.l = GetProp_(hWnd,"_oldCallback")
   Protected fore.l,back.l,backbrush.l,text.s
   
   
   If #WM_DESTROY = msg
      SetWindowLong_(hwnd,#GWL_WNDPROC,callback)
      RemoveProp_(hwnd,"_oldCallback")
   EndIf 
   
   If #WM_DRAWITEM = msg
      *dis = lParam
      If *dis\CtlType = #ODT_TAB
         shWnd = PB_GetPanelStaticItem(IsGadget(*dis\CtlID),*dis\itemID)
         *pud  = GetWindowLong_(shWnd,#GWL_USERDATA)   
       
        If *pud                      
           fore = *pud\ForeColor
           back = *pud\BackColor
           
           If back = #PB_Default
              back = GetSysColor_(#COLOR_BTNFACE)              
           EndIf
           
           If fore = #PB_Default
              fore = GetSysColor_(#COLOR_BTNTEXT)              
           EndIf            
           
        Else                   
           fore = GetSysColor_(#COLOR_BTNTEXT)
           back = GetSysColor_(#COLOR_BTNFACE)
        EndIf
               
         backbrush = CreateSolidBrush_(back)
         
         fore = SetTextColor_(*dis\hdc, fore)                
         FillRect_(*dis\hdc, *dis\rcItem, backbrush)
         SetBkMode_(*dis\hdc, #TRANSPARENT)
         text = GetGadgetItemText(*dis\CtlID,*dis\ItemID)                                 
         DrawText_(*dis\hdc, text, Len(text), *dis\rcItem, #DT_CENTER | #DT_SINGLELINE | #DT_VCENTER)           
         DeleteObject_(backbrush)           
          SetTextColor_(*dis\hdc, fore)
          
          ProcedureReturn  0
          
         EndIf
         
   EndIf
   
   
   ProcedureReturn CallWindowProc_(callback,hwnd,msg,wparam,lparam)
EndProcedure

Procedure PB_GetPanelStaticItem(*gadget.PB_Gadget   ,item)
  Protected tci.TC_ITEM\mask = #TCIF_PARAM
  If SendMessage_(*gadget\gadget   ,#TCM_GETITEM   ,item   ,@tci)
    ProcedureReturn tci\lParam
  EndIf
EndProcedure

Procedure PB_SetGadgetItemColor(*Gadget.PB_Gadget,item.l,ColorType.l,Color,col.l)   
   Protected hwnd = PB_GetPanelStaticItem(*gadget,item)
   Protected *pud.PB_Panel_User_Data
   Protected result.l,panel_callback.l
   
   *pud = GetWindowLong_(hwnd   ,#GWL_USERDATA)
      
   If Not *pud
      *pud = AllocateMemory(SizeOf(PB_Panel_User_Data))
      
      If Not *pud ; no memory
         ProcedureReturn 0
      EndIf
      
      SetWindowLong_(hwnd   ,#GWL_USERDATA,*pud)
      *pud\static_callback = SetWindowLong_(hwnd,#GWL_WNDPROC,@PB_PanelStaticCB())
      *pud\ForeColor = -1
      *pud\BackColor = -1      
      
   EndIf
   
   panel_callback = GetProp_(GetParent_(*Gadget\gadget),"_oldCallback")
   
   If Not panel_callback
      panel_callback = SetWindowLong_(GetParent_(*Gadget\gadget),#GWL_WNDPROC,@PB_PanelParentCB())
   EndIf    
   
   SetWindowLong_(*Gadget\gadget, #GWL_STYLE, GetWindowLong_(*Gadget\gadget, #GWL_STYLE) | #TCS_OWNERDRAWFIXED)
   
   SetProp_(GetParent_(*Gadget\gadget),"_oldCallback",panel_callback)      
   
   Select ColorType
      Case #PB_Gadget_FrontColor
         *pud\ForeColor = color
      Case #PB_Gadget_BackColor
         *pud\BackColor  = color
   EndSelect
         
   SetWindowPos_(*Gadget\gadget,0,0,0,0,0,#SWP_NOMOVE|#SWP_NOSIZE|#SWP_NOZORDER|#SWP_FRAMECHANGED)      
EndProcedure

Procedure PB_GetGadgetItemColor(*Gadget.PB_Gadget,item.l,ColorType.l,col.l)   
   Protected hwnd = PB_GetPanelStaticItem(*gadget,item)
   Protected *pud.PB_Panel_User_Data
   Protected result.l
   
   *pud = GetWindowLong_(hwnd   ,#GWL_USERDATA)
      
   Select ColorType
      Case #PB_Gadget_FrontColor
         result = *pud\ForeColor
      Case #PB_Gadget_BackColor
         result = *pud\BackColor
   EndSelect   
   
   ProcedureReturn result
EndProcedure

Procedure PB_GetGadgetItemData(*gadget.PB_Gadget   ,item)
   Protected hwnd = PB_GetPanelStaticItem(*gadget   ,item)
   Protected *pud.PB_Panel_User_Data   
   If hwnd
      *pud = GetWindowLong_(hwnd   ,#GWL_USERDATA)      
      If *pud
         ProcedureReturn *pud\user_data
      EndIf
   EndIf
EndProcedure

Procedure PB_SetGadgetItemData(*gadget.PB_Gadget,item,value)
   Protected hwnd = PB_GetPanelStaticItem(*gadget,item)
   Protected *pud.PB_Panel_User_Data
   Protected result.l
   
   *pud = GetWindowLong_(hwnd,#GWL_USERDATA)
   
   If Not *pud
      *pud = AllocateMemory(SizeOf(PB_Panel_User_Data))
      
      If Not *pud ; no memory
         ProcedureReturn 0
      EndIf
            
      SetWindowLong_(hwnd   ,#GWL_USERDATA,*pud)
      *pud\static_callback = SetWindowLong_(hwnd,#GWL_WNDPROC,@PB_PanelStaticCB())
      *pud\ForeColor = -1
      *pud\BackColor = -1 
   EndIf
   
   result              =    *pud\user_data      
   *pud\user_data =    value   
   
   ProcedureReturn result
EndProcedure

Procedure PB_PanelGadget(id.l   ,x.l   ,y.l   ,cx.l   ,cy.l)
   Protected value = PanelGadget(id,x,y,cx,cy)
   Protected *gadget.PB_Gadget
   
   If id = #PB_Any
      id = value
   EndIf
   
   *gadget = IsGadget(id)
   
   If *gadget
      *gadget\vt\SetGadgetItemData   = @PB_SetGadgetItemData()
      *gadget\vt\GetGadgetItemData   = @PB_GetGadgetItemData()
      *gadget\vt\SetGadgetItemColor2 = @PB_SetGadgetItemColor()
      *gadget\vt\GetGadgetItemColor2 = @PB_GetGadgetItemColor()
   EndIf
   
   ProcedureReturn value
EndProcedure

Macro PanelGadget
   PB_PanelGadget
EndMacro

Test :

Code: Alles auswählen

Define hwnd

hwnd = OpenWindow(0,#PB_Ignore,#PB_Ignore,300,300,"Test")
			 CreateGadgetList(hwnd)
			 PanelGadget(0,0,0,300,300)
			 
			 AddGadgetItem(0,0,"1")
			 AddGadgetItem(0,1,"2")
			 AddGadgetItem(0,2,"3")
			 			 
			 SetGadgetItemColor(0,2,#PB_Gadget_FrontColor,$0D9FF2)
			 SetGadgetItemColor(0,2,#PB_Gadget_BackColor,$ff)
			 
			 
			 Repeat
			 
			 Until WaitWindowEvent() = 16
Folgende Funktionen funktionieren damit auch bei einem PanelGadget.

SetGadgetItemData
GetGadgetItemData
SetGadgetItemColor
GetGadgetItemColor

Verfasst: 03.02.2008 22:49
von mk-soft
Starkes Towak :allright:

somit kann man ja alle für Gadgets die Standardfunktionen verbiegen.
Wie bist du denn an Struktur und den Aufbau VT-Tabelle gekommen?

Dafür gibts von mir :allright: :allright: :allright: :allright: :allright: :allright: :allright: :allright: :allright: :allright: Punkte.

FF :wink:

Verfasst: 03.02.2008 23:04
von edel
Ich schau mir auch ihn und wieder die Ordner an, die installiert werden ;)
Mehr dazu gibt es im SDK Ordner. Alternativ auch mal die Linuxversion
ziehen. Dort gibt fast zu jeder Lib nen Beispiel bzw Header.

Was ist denn "Towak" ?

Verfasst: 03.02.2008 23:13
von mk-soft
indianische Kraut. Brennt gut :mrgreen:

Verfasst: 03.02.2008 23:42
von HeX0R
Meintest du nicht etwa starker Tobak ?

Verfasst: 04.02.2008 17:35
von Lord
Hallo edel!

Deine Include-Datei funkioniert soweit ganz prima, aber trotzdem habe ich noch zwei Probleme entdeckt:

1. AddGadgetItemData() färbt das gewählte Panel-Tab schwarz.
Diese läßt sich zwar durch ein anschließendes SetGadgetItemColor() beheben, ist aber irgendwie nicht sinnvoll, wenn man nur einen Wert für das Tab speichern will, die Farbe des Tabs aber unverändert bleiben soll.

2. GetGadgetItemData() ohne vorherigen Aufruf eines entsprechenden SetGadgetItemData() oder SetGadgetItemColor() für das entsprechende Tab führt zu einem IMA.
Normalerweise ist ein GetGadgetItemData() ohne vorheriges SetGadgetItemData nicht unbedingt notwendig, aber wenn man eben feststellen will, ob etwas bereits gespeichert wurde, kann das zu Problemen führen. Man müßte dann ja trotzdem eine weitere Variable mitführen.

Lord

Verfasst: 04.02.2008 18:11
von edel
Danke fuer das Testen. Leider habe ich im Moment kein Windows da,
habe es aber mal so gut es geht angepasst.

Verfasst: 04.02.2008 22:05
von Lord
Hallo edel!

Deine Anpassungen haben funktioniert. :allright:

Bleibt mir nur noch der Wunsch nach einer kleinen 'Schönheitskorrektur'. :oops:

Wenn ein GetGadgetItemData() auf ein nicht vorhandenes Tab ausgeführt wird, wird '0' zurückgegeben, bei einem vorhandenem Tab, daß noch keinen Wert per SetGadgetItemData() erhalten hat, wird aber eine '1' zurückgegeben.
Logischer wäre es meiner Meinung nach, wenn der Rückgabewert für ein nicht vorhandenes Tab '-1' ist und ein 'jungfräuliches' Tab als Rückgabewert eine '0' hat.

Lord

Verfasst: 05.02.2008 08:06
von edel
In beiden faellen muesste 0 zurueckgegeben werden.
Man koennte ja auch -1 setzen.

Bin immer noch zu faul Vista hochzufahren, daher ungetestet.

Code: Alles auswählen

Procedure PB_GetGadgetItemData(*gadget.PB_Gadget   ,item)
   Protected hwnd = PB_GetPanelStaticItem(*gadget   ,item)
   Protected *pud.PB_Panel_User_Data   
   if hwnd
      *pud = GetWindowLong_(hwnd   ,#GWL_USERDATA)      
      if *pud
         ProcedureReturn *pud\user_data
      endif
   else
      ProcedureReturn -1
   endif
EndProcedure 

Verfasst: 05.02.2008 15:35
von Lord
Hallo edel!
edel hat geschrieben: Bin immer noch zu faul Vista hochzufahren, daher ungetestet.
Wenn alle Faule so produktiv wären.... :wink:


Aber jetzt wieder zurück zum Thema.
Ich habe da noch etwas festgestellt. Eine Textfarbänderung für ein nicht aktives Tab wird nicht sofort angezeigt:

Code: Alles auswählen

IncludeFile "PanelGadget.pbi"

hwnd = OpenWindow(0,#PB_Ignore,#PB_Ignore,300,300,"Test")
CreateGadgetList(hwnd)
PanelGadget(0,0,0,300,300)

AddGadgetItem(0,0,"1"):SetGadgetItemData(0,0,1)
AddGadgetItem(0,1,"2"):SetGadgetItemData(0,1,1)
AddGadgetItem(0,2,"3"):SetGadgetItemData(0,2,1)

; bei allen Tabs Textfarbe ändern
SetGadgetItemColor(0,0,#PB_Gadget_FrontColor,$FF0000)
SetGadgetItemColor(0,1,#PB_Gadget_FrontColor,$00C000)
SetGadgetItemColor(0,2,#PB_Gadget_FrontColor,$0000FF)

; Tab 3 selektieren
SetGadgetState(0,2)

; und jetzt bei einem nicht selektierten Tab die Textfarbe ändern
; Ergebnis: die Farbänderung wird nicht angezeigt
SetGadgetItemColor(0,0,#PB_Gadget_FrontColor,$FFFF00)
;SetGadgetState(0,0)



Repeat

Until WaitWindowEvent() = 16
Die Textfarbänderung eines nicht selektierten Tabs wird erst angezeigt wenn
- ein manuelles Selektieren des Tabs stattfindet
- der Tab per SetGadgetState() aktiviert wird
- mittels InvalidateRect_(GadgetID(#Panel), 0, #True) ein Neuzeichnen erzwungen wird

Läßt sich dieses Erzwingen des Neuzeichnens nicht in dem Include einbauen?

Nochmal zum Thema Rückgabewert. Ich meine, daß es doch sinnvoll sein kann, zwischen einem nicht vorhandenen und einem noch nicht mit einem Wert 'befülltem' Tab unterschieden werden sollte und ein 'unbefülltes' Tab durch den Wert '0' am sinnvollsten repräsentiert wird. Jedenfalls besser als durch eine andere Zahl, da '-1' ja bereits anderweitig benötigt wird, eben dem nicht vorhandenen Tab.

Die neue Procedure PB_GetGadgetItemData() habe ich noch nicht getestet, werde ich aber noch machen.

Gruß

Lord

Nachtrag:

Habe gerade die neue Prozedur getestet. Ergebnis: Es wird jetzt -1 bei nicht vorhandenem Tab zurückgegeben und 1 bei noch nicht mit einem Wert beaufschlagtem Tab.
Das hilft so noch nicht richtig weiter, da man nicht unterscheiden kann zwischen 'leerem' Tab und einem mit '1' gefülltem Tab.