Page 1 of 1

Coloring a ListView via Callback and SplitterGadgets. . .

Posted: Tue May 18, 2004 8:30 pm
by Lars
I tried to color a ListViewGadget() by handling #WM_CTLCOLORLISTBOX
in the WindowCallback (see an example by Danilo from the code archiv).
Worked pretty well so far, but when i added a Splittergadget() that was
put other my ListView it didn't color right any more.

Code: Select all

ColorBrush = CreateSolidBrush_(RGB($00, $00, $00))            ; BACKGROUND
Procedure WindowCallBack(hwnd, msg, wParam, lParam)
  Shared ColorBrush
  Result = #PB_ProcessPureBasicEvents
  If msg = #WM_CTLCOLORLISTBOX
    SetTextColor_(wParam, RGB(0, 0, 200))                ; FOREGROUND
    SetBkMode_(wParam, #TRANSPARENT)
    Result = ColorBrush
  EndIf
  
  ProcedureReturn Result
EndProcedure

If OpenWindow(0, 205, 186, 775, 569,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered, "Test")
  If CreateGadgetList(WindowID())
    SetWindowCallback(@WindowCallBack())
    
    ListViewGadget(0, 660, 165, 110, 285)
    For i = 1 To 4
      AddGadgetItem(0, -1, Str(i))
    Next i
    
    EditorGadget(1, 5, 165, 650, 285)
    ;/comment the splittergadget out to see the effect without problems :/
    SplitterGadget(2, 5, 165, 765, 285, 1, 0, #PB_Splitter_Vertical | #PB_Splitter_SecondFixed)
  EndIf
EndIf

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow
DeleteObject_(ColorBrush)
End
As you can see, the Splittergadget affects the coloring of the listview in a
bad case. . .

Any ideas? Another way of coloring, of handling the callback, the
SplitterGadget or something?

Thanks a lot!

Posted: Wed May 19, 2004 2:03 am
by Sparkie
The problem arises when the parent of the ListViewGadget changes over to the SplitterGadget. The #WM_CTLCOLORLISTBOX message never makes it to the WindowCallback(). Here's a little something I picked up from freak...

Code: Select all

Global OldCallback
ColorBrush = CreateSolidBrush_(RGB($00, $00, $00))            ; BACKGROUND 
Procedure WindowCallBack(hwnd, msg, wParam, lParam) 
  Shared ColorBrush 
  Result = #PB_ProcessPureBasicEvents 
  If msg = #WM_CTLCOLORLISTBOX 
    SetTextColor_(wParam, RGB(0, 0, 200))                ; FOREGROUND 
    SetBkMode_(wParam, #TRANSPARENT)
    ProcedureReturn ColorBrush 
  EndIf 
  
  ProcedureReturn CallWindowProc_(OldCallback, hwnd, msg, wParam, lParam)
EndProcedure 

If OpenWindow(0, 205, 186, 775, 569,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered, "Test") 
  If CreateGadgetList(WindowID()) 
    SetWindowCallback(@WindowCallBack()) 
    
    ListViewGadget(0, 660, 165, 110, 285) 
    For i = 1 To 4 
      AddGadgetItem(0, -1, Str(i)) 
    Next i 
    
    EditorGadget(1, 5, 165, 650, 285) 
    ;/comment the splittergadget out to see the effect without problems :/ 
    SplitterGadget(2, 5, 165, 765, 285, 1, 0, #PB_Splitter_Vertical | #PB_Splitter_SecondFixed)
    OldCallback = SetWindowLong_(GetParent_(GadgetID(0)), #GWL_WNDPROC, @WindowCallBack()) 
  EndIf 
EndIf 

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow 
DeleteObject_(ColorBrush) 
End 

Posted: Wed May 19, 2004 7:34 pm
by Lars
Thanks!

///Edit
Now understood the code and. . .
DAMN, it's nice! :)

Posted: Wed May 19, 2004 10:21 pm
by Lars
It does not work correctly at all :(

The source you gave me defines the ListView Callback as
WindowCallback, too. That's wrong, as said in your thread. As an effect of
this, no events are given by WaitWindowEvent().

Run your code with debugger and click the 'X'. When you are lucky, no
memory-access-violation is performed until then. As you will see, the
debugger keeps running, there is just no #PB_Event_CloseWindow given
back by WaitWindowEvent() because the WindowCallback returns no
#PB_ProcessPureBasicEvents.


If i define the Callback not as Windowcallback, the Items are not painted,
until i select them.

I don't get it :?

Posted: Wed May 19, 2004 11:15 pm
by Sparkie
Sorry Lars for not performing proper testing before posting. :oops:

ProcedureReturn ColorBrush may be part of the problem. I'll see if I can figure this out later tonight/tomorrow morning. Don't hold your breath though as I am still learning. :?

Posted: Thu May 20, 2004 2:31 pm
by Sparkie
Well I see my first mistake was not removing line 17

Code: Select all

SetWindowCallback(@WindowCallBack())
That solves part of the problem. I'm off to work now but I'll work on this some more later today.

Posted: Thu May 20, 2004 7:15 pm
by Lars
I tried to tell you that in my post, but as you may have noticed my english
is not really good.
I'm on it, too, let's see who finds the solution first :wink:

But thanks for your great help!

Posted: Thu May 20, 2004 7:21 pm
by Lars
LoL, that one was easy:
Just defining a callback that gives back #PB_ProcessPureBasicEvents if the
Event is <> #WM_CTLCOLORLISTBOX as WindowCallback.

Code: Select all

Global OldCallback 
ColorBrush = CreateSolidBrush_(RGB($00, $00, $00))            ; BACKGROUND 
Procedure WindowCallBack(hwnd, msg, wParam, lParam) 
  Shared ColorBrush 
  If msg = #WM_CTLCOLORLISTBOX 
    SetTextColor_(wParam, RGB(0, 0, 200))                ; FOREGROUND 
    SetBkMode_(wParam, #TRANSPARENT) 
    ProcedureReturn ColorBrush 
  EndIf 
  
  ProcedureReturn CallWindowProc_(OldCallback, hwnd, msg, wParam, lParam) 
EndProcedure 
Procedure WindowCallBack2(hwnd, msg, wParam, lParam) 
  Shared ColorBrush 
  If msg = #WM_CTLCOLORLISTBOX 
    SetTextColor_(wParam, RGB(0, 0, 200))                ; FOREGROUND 
    SetBkMode_(wParam, #TRANSPARENT) 
    ProcedureReturn ColorBrush 
  EndIf 
  
  ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure 


If OpenWindow(0, 205, 186, 775, 569,  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered, "Test") 
  If CreateGadgetList(WindowID()) 
    SetWindowCallback(@WindowCallBack2()) 
    
    ListViewGadget(0, 660, 165, 110, 285) 
    For i = 1 To 4 
      AddGadgetItem(0, -1, Str(i)) 
    Next i 
    
    EditorGadget(1, 5, 165, 650, 285) 
    ;/comment the splittergadget out to see the effect without problems :/ 
    SplitterGadget(2, 5, 165, 765, 285, 1, 0, #PB_Splitter_Vertical | #PB_Splitter_SecondFixed) 
    OldCallback = SetWindowLong_(GetParent_(GadgetID(0)), #GWL_WNDPROC, @WindowCallBack()) 
  EndIf 
EndIf 

Repeat: Until WaitWindowEvent() = #PB_Event_CloseWindow 
DeleteObject_(ColorBrush) 
End

Posted: Sun May 23, 2004 1:29 am
by Sparkie
Sometimes the answer stares you in the face but you just can't see it. Good job Lars!