[Solved]ListIconGadget() active

Just starting out? Need help? Post your questions and find answers here.
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

[Solved]ListIconGadget() active

Post by Distorted Pixel »

Hi,

I have an image behind the ListIconGadget() and I need the ListIconGadget to be active to use it. I also wouldn't mind to maybe make the gadget a bit transparent if possible, but not necessary. Mainly just need it active. How would I go about making the gadget active to use it?

I found the following code here on the forums and added and or changed some of the original code to suit my needs. Mainly to make the ListIconGadget headers able to be colored other than grey.
The credit for the original code I believe goes to srod

https://mega.nz/file/t90CmRxJ#mAuxbMdeU ... zXVAU32TD8

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
  Global oldListIconCallback, hHeader, brush
  brush=CreateSolidBrush_(#Yellow)


Procedure SubclassedListIcon(hWnd, uMsg, wParam, lParam) 
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, hWnd, uMsg, wParam, lParam) 
  Select uMsg
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
        If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            text$=GetGadgetItemText(0, -1, *pnmcd\dwItemSpec)
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              *pnmcd\rc\left+2 : *pnmcd\rc\top+1
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            *pnmcd\rc\bottom-1 : *pnmcd\rc\right-1
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Blue) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Red) 
            EndIf
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

;InitSprite()
UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  ImgFile = LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImgFile)
  
  ListIconGadget(0, 175, 150, 700, 500, "No.", 30, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) 
  hHeader = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0) 
;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon()) 

;Add 10 more columns.
  ;For i = 1 To 13
  AddGadgetColumn(0, 1, "Player names", 150) 
  AddGadgetColumn(0, 2, "Pos", 50)
  AddGadgetColumn(0, 3, "KP", 35)
  AddGadgetColumn(0, 4, "TA", 35)
  AddGadgetColumn(0, 5, "PS", 35)
  AddGadgetColumn(0, 6, "SH", 35)
  AddGadgetColumn(0, 7, "PC", 35)
  AddGadgetColumn(0, 8, "HE", 35)
  AddGadgetColumn(0, 9, "ST", 35)
  AddGadgetColumn(0, 10, "SP", 35)
  AddGadgetColumn(0, 11, "BC", 35)
  AddGadgetColumn(0, 12, "FT", 35)
  AddGadgetColumn(0, 13, "PF", 35)
  ;Next  
;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i            

  Repeat 
  Until WaitWindowEvent() = #PB_Event_CloseWindow 
  DeleteObject_(brush)
EndIf
Last edited by Distorted Pixel on Fri May 30, 2025 2:52 am, edited 2 times in total.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Make ListIconGadget() active

Post by BarryG »

Distorted Pixel wrote: Sun Oct 09, 2022 1:50 amI need the ListIconGadget to be active to use it
PureBasic doesn't officially support overlapped gadgets. So in your case, you need to force it to the top of the image:

Code: Select all

; Put this before your event loop.
BringWindowToTop_(GadgetID(0))
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Make ListIconGadget() active

Post by Distorted Pixel »

BarryG wrote: Sun Oct 09, 2022 2:18 am
Distorted Pixel wrote: Sun Oct 09, 2022 1:50 amI need the ListIconGadget to be active to use it
PureBasic doesn't officially support overlapped gadgets. So in your case, you need to force it to the top of the image:

Code: Select all

; Put this before your event loop.
BringWindowToTop_(GadgetID(0))
It works, but doesn't work. Mostly doesn't. It shows up in front for a split second and goes behind the image/window. If I start clicking around on the image, one row at a time or the header shows up until finally the whole gadget is visible and it is active or usable.
Last edited by Distorted Pixel on Sun Oct 09, 2022 12:06 pm, edited 1 time in total.
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
BarryG
Addict
Addict
Posts: 4173
Joined: Thu Apr 18, 2019 8:17 am

Re: Make ListIconGadget() active

Post by BarryG »

Change the order of the gadget creation:

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
Global oldListIconCallback, hHeader, brush
brush=CreateSolidBrush_(#Yellow)

Procedure SubclassedListIcon(hWnd, uMsg, wParam, lParam) 
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, hWnd, uMsg, wParam, lParam) 
  Select uMsg
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
      If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            text$=GetGadgetItemText(0, -1, *pnmcd\dwItemSpec)
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              *pnmcd\rc\left+2 : *pnmcd\rc\top+1
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            *pnmcd\rc\bottom-1 : *pnmcd\rc\right-1
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Blue) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Red) 
            EndIf
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

;InitSprite()
UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  
  ListIconGadget(0, 175, 150, 700, 500, "No.", 30, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) 
  hHeader = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0) 
  ;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon()) 
  BringWindowToTop_(GadgetID(0))
  
  ;Add 10 more columns.
  ;For i = 1 To 13
  AddGadgetColumn(0, 1, "Player names", 150) 
  AddGadgetColumn(0, 2, "Pos", 50)
  AddGadgetColumn(0, 3, "KP", 35)
  AddGadgetColumn(0, 4, "TA", 35)
  AddGadgetColumn(0, 5, "PS", 35)
  AddGadgetColumn(0, 6, "SH", 35)
  AddGadgetColumn(0, 7, "PC", 35)
  AddGadgetColumn(0, 8, "HE", 35)
  AddGadgetColumn(0, 9, "ST", 35)
  AddGadgetColumn(0, 10, "SP", 35)
  AddGadgetColumn(0, 11, "BC", 35)
  AddGadgetColumn(0, 12, "FT", 35)
  AddGadgetColumn(0, 13, "PF", 35)
  ;Next  
  ;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i
  
  ImgFile = LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImgFile)
  
  Repeat 
  Until WaitWindowEvent() = #PB_Event_CloseWindow 
  DeleteObject_(brush)
EndIf
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Make ListIconGadget() active

Post by netmaestro »

If you want a listicon with an image behind it the right way to go about it would be to put your listicon gadget inside a canvas gadget that has the #PB_Canvas_Container flag. Draw your image on the canvas, then you can just use SetActiveGadget on the listicon.
BERESHEIT
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Make ListIconGadget() active

Post by RASHAD »

Just add DisableGadget() after ImageGadget()

Code: Select all

UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess)
  ImgFile = LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImgFile)
  DisableGadget(1,1)
  ......
  ..............
To eliminate flicker too
Escape to Quit

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
  Global oldListIconCallback, hHeader, brush
  brush=CreateSolidBrush_(#Yellow)


Procedure SubclassedListIcon(hWnd, uMsg, wParam, lParam) 
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, hWnd, uMsg, wParam, lParam) 
  Select uMsg
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
        If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage 
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            text$=GetGadgetItemText(0, -1, *pnmcd\dwItemSpec)
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              *pnmcd\rc\left+2 : *pnmcd\rc\top+1
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            *pnmcd\rc\bottom-1 : *pnmcd\rc\right-1
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Blue) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Red) 
            EndIf
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

;InitSprite()
UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess|#PB_Window_Invisible)
  LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImageID(0))
  DisableGadget(1,1)
  
  ListIconGadget(0, 175, 150, 700, 500, "No.", 30, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) 
  HideGadget(0,1)
  hHeader = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0)   

  AddGadgetColumn(0, 1, "Player names", 150) 
  AddGadgetColumn(0, 2, "Pos", 50)
  AddGadgetColumn(0, 3, "KP", 35)
  AddGadgetColumn(0, 4, "TA", 35)
  AddGadgetColumn(0, 5, "PS", 35)
  AddGadgetColumn(0, 6, "SH", 35)
  AddGadgetColumn(0, 7, "PC", 35)
  AddGadgetColumn(0, 8, "HE", 35)
  AddGadgetColumn(0, 9, "ST", 35)
  AddGadgetColumn(0, 10, "SP", 35)
  AddGadgetColumn(0, 11, "BC", 35)
  AddGadgetColumn(0, 12, "FT", 35)
  AddGadgetColumn(0, 13, "PF", 35)
  ;Next  
;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i
  oldListIconCallback = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon()) 
  HideGadget(0,0)
  HideWindow(0,0)
  Repeat
    WaitWindowEvent(1) 
  Until GetAsyncKeyState_(#VK_ESCAPE) & $8000 = $8000
  DeleteObject_(brush)
EndIf
Egypt my love
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Make ListIconGadget() active

Post by Distorted Pixel »

BarryG wrote: Sun Oct 09, 2022 4:12 am Change the order of the gadget creation:
I might try that at some point to see it work that way, but for now I just added DisableGadget() after creating Loading image and creating ImageGadget()

netmaestro wrote: Sun Oct 09, 2022 7:46 am If you want a listicon with an image behind it the right way to go about it would be to put your listicon gadget inside a canvas gadget that has the #PB_Canvas_Container flag. Draw your image on the canvas, then you can just use SetActiveGadget on the listicon.
I have another screen in my program a CanvasGadget() and I disabled it there and forgot that I had to disable the ImageGadget here also LOL. I will also try the #PB_Canvas_Container flag option inside a CanvasGadget() at some point to learn more about the CanvasGadget() and all you can do with it.

RASHAD wrote: Sun Oct 09, 2022 9:03 am Just add DisableGadget() after ImageGadget()
Yea, I forgot that I had to disable it. I have another screen where I did that with a CanvasGadget() LOL. this is the option I had chosen so far and it worked. thank you for catching my missing DisableGadget problem.

Now I'm working on making the ListIconGadget transparent. I found an example if a ListViewGadget and I'm learning from it as I am the ListIconGadget. I can write the program I'm working on without all these special tricks/features, but they are cool when you get them working.

I have started to try and dabble in WinAPI to not be stuck with limitations of PB and 3rd Party libs. There is a lot you can do with just the PB commands, but I don't want to stop there. That way I have more options/possibilities with projects
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Make ListIconGadget() active

Post by RASHAD »

I do not think that there is any way to make ListIcon transparent
viewtopic.php?t=79968
Egypt my love
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Make ListIconGadget() active

Post by Distorted Pixel »

RASHAD wrote: Sun Oct 09, 2022 7:58 pm I do not think that there is any way to make ListIcon transparent
viewtopic.php?t=79968
The fake transparent isn't perfect, but it works, it might be worth using. Thank you for showing it to me. I'm going to play around with it
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Make ListIconGadget() active

Post by RASHAD »

Egypt my love
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Make ListIconGadget() active

Post by breeze4me »

A layered style can be applied to a control in Windows 8 or later. So, it is possible to make gadgets transparent.

SetLayeredWindowAttributes function
Windows 8: The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.
https://learn.microsoft.com/en-us/windo ... ng-windows
In order to use layered child windows, the application has to declare itself Windows 8-aware in the manifest.
Targeting your application for Windows

Code: Select all

<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
    <application>
        <!-- Windows 8 -->
        <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application>
</compatibility>
To do so, add the above six lines to the menifest resource section of the compiled executable.
For example, as below.

Code: Select all

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application>
      <!--The ID below indicates app support for Windows 8 -->
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
    </application>
  </compatibility>
  <assemblyIdentity
    version="1.0.0.0"
    processorArchitecture="amd64"
    name="CompanyName.ProductName.YourApp"
    type="win32" />
  <description></description>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity
        type="win32"
        name="Microsoft.Windows.Common-Controls"
        version="6.0.0.0"
        processorArchitecture="amd64"
        publicKeyToken="6595b64144ccf1df"
        language="*" />
    </dependentAssembly>
  </dependency>
	<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="asInvoker"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>
  <asmv3:application  xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">     <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">       <dpiAware>true</dpiAware>     </asmv3:windowsSettings>   </asmv3:application>
</assembly>
Example of a compiled executable.
https://www.dropbox.com/s/5ui1hymzsfyl2 ... t.zip?dl=0

* Problem:
The "transparent background" means that a click is delivered directly to the parent window, so you need to click exactly the white letter part to change an item.
This is just an example of the potential for gadget transparency, so this was not considered in the code below.

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
  Global oldListIconCallback, hHeader, brush
  brush=CreateSolidBrush_(#Yellow)


Procedure SubclassedListIcon(hWnd, uMsg, wParam, lParam) 
  Protected hdi.hd_item
  result = CallWindowProc_(oldListIconCallback, hWnd, uMsg, wParam, lParam) 
  Select uMsg
    Case #WM_ERASEBKGND    ;Note: Required to fix some drawing issues.
      RedrawWindow_(GadgetID(1), 0, 0, #RDW_ERASENOW | #RDW_UPDATENOW)
      
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
        If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            text$=GetGadgetItemText(0, -1, *pnmcd\dwItemSpec)
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              *pnmcd\rc\left+2 : *pnmcd\rc\top+1
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            *pnmcd\rc\bottom-1 : *pnmcd\rc\right-1
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Blue) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Red) 
            EndIf
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

UseJPEGImageDecoder()
CatchImage(0, ?label____jpg, ?label____jpg_End - ?label____jpg)
ResizeImage(0, DesktopScaledX(1024), DesktopScaledY(768))

;InitSprite()
;UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_Invisible)   ;Note:  #PB_Window_Invisible is essential.
  
  ;ImgFile = LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImageID(0))
  
  DisableGadget(1, 1)
  
  ListIconGadget(0, 175, 150, 700, 500, "No.", 30, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) 
  SetGadgetColor(0, #PB_Gadget_BackColor, $B599C1)
  SetGadgetColor(0, #PB_Gadget_FrontColor, $FFFFFF)
  
  ;Apply the layered attribute to the gadget.
  SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)
  SetLayeredWindowAttributes_(GadgetID(0), $B599C1, 0, #LWA_COLORKEY)
  
  ButtonGadget(2, 800, 700, 100, 25, "Exit")
  
  hHeader = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0) 
;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon()) 

;Add 10 more columns.
  ;For i = 1 To 13
  AddGadgetColumn(0, 1, "Player names", 150) 
  AddGadgetColumn(0, 2, "Pos", 50)
  AddGadgetColumn(0, 3, "KP", 35)
  AddGadgetColumn(0, 4, "TA", 35)
  AddGadgetColumn(0, 5, "PS", 35)
  AddGadgetColumn(0, 6, "SH", 35)
  AddGadgetColumn(0, 7, "PC", 35)
  AddGadgetColumn(0, 8, "HE", 35)
  AddGadgetColumn(0, 9, "ST", 35)
  AddGadgetColumn(0, 10, "SP", 35)
  AddGadgetColumn(0, 11, "BC", 35)
  AddGadgetColumn(0, 12, "FT", 35)
  AddGadgetColumn(0, 13, "PF", 35)
  ;Next  
;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i
  
  
  HideWindow(0, 0)
  
  Repeat
    e = WaitWindowEvent()
    
    If e = #PB_Event_Gadget And EventGadget() = 2 And EventType() = #PB_EventType_LeftClick
      Break
    EndIf
    
  Until e = #PB_Event_CloseWindow
  
  DeleteObject_(brush)
EndIf

DataSection
  label____jpg:
  
  ; Put your image data here.
  
  label____jpg_End:
EndDataSection
Image
breeze4me
Enthusiast
Enthusiast
Posts: 633
Joined: Thu Mar 09, 2006 9:24 am
Location: S. Kor

Re: Make ListIconGadget() active

Post by breeze4me »

Here is one of the ways to emulate an item click.
But, double-clicking an item that is not selected does not cause a double-click event. So, firstly click to select an item and double-click.

Alternatively, #LVM_HITTEST message seems to be available.

Code: Select all

#LVM_GETHEADER = #LVM_FIRST + 31 

; Globals 
Global oldListIconCallback, hHeader, brush
brush=CreateSolidBrush_(#Yellow)

Procedure SubclassedListIcon(hWnd, uMsg, wParam, lParam) 
  Protected hdi.hd_item
  
  result = CallWindowProc_(oldListIconCallback, hWnd, uMsg, wParam, lParam) 
  Select uMsg
    Case #WM_ERASEBKGND    ;Note: Required to fix some drawing issues.
      RedrawWindow_(GadgetID(1), 0, 0, #RDW_ERASENOW | #RDW_UPDATENOW)
      
    Case #WM_NOTIFY 
      *pnmh.NMHDR = lparam 
      ;--> Get handle to ListIcon header control 
        If *pnmh\code = #NM_CUSTOMDRAW
        *pnmcd.NMCUSTOMDRAW = lparam 
        ;--> Determine drawing stage 
        Select *pnmcd\dwDrawStage
          Case #CDDS_PREPAINT 
            result = #CDRF_NOTIFYITEMDRAW 
          Case #CDDS_ITEMPREPAINT 
            text$=GetGadgetItemText(0, -1, *pnmcd\dwItemSpec)
            If *pnmcd\uItemState & #CDIS_SELECTED
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH|#DFCS_PUSHED)
              *pnmcd\rc\left+2 : *pnmcd\rc\top+1
            Else
              DrawFrameControl_(*pnmcd\hdc, *pnmcd\rc, #DFC_BUTTON, #DFCS_BUTTONPUSH)
            EndIf
            *pnmcd\rc\bottom-1 : *pnmcd\rc\right-1
            SetBkMode_(*pnmcd\hdc,#TRANSPARENT) 
            If *pnmcd\dwItemSpec&1
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Blue) 
            Else
              FillRect_(*pnmcd\hdc, *pnmcd\rc, brush)
              SetTextColor_(*pnmcd\hdc, #Red) 
            EndIf
            If *pnmcd\rc\right>*pnmcd\rc\left
              DrawText_(*pnmcd\hdc, @text$, Len(text$), *pnmcd\rc, #DT_CENTER|#DT_VCENTER|#DT_SINGLELINE|#DT_END_ELLIPSIS)
            EndIf
            result = #CDRF_SKIPDEFAULT
        EndSelect 
      EndIf 
  EndSelect 
  ProcedureReturn result 
EndProcedure 

Procedure MyWindowCallback(WindowID, Message, WParam, LParam)
  Protected Result = #PB_ProcessPureBasicEvents
  Protected pt.POINT, rt.RECT
  
  If Message = #WM_LBUTTONDOWN
    pt\x = LParam & $FFFF
    pt\y = (LParam >> 16) & $FFFF
    MapWindowPoints_(WindowID, GadgetID(0), @pt, 1)
    GetClientRect_(GadgetID(0), rt)
    If PtInRect_(rt, PeekQ(pt))
      If GetActiveGadget() <> 0
        SetActiveGadget(0)
      EndIf
      PostMessage_(GadgetID(0), #WM_LBUTTONDOWN, WParam, (pt\x & $FFFF) | ((pt\y & $FFFF) << 16))
      ;PostMessage_(GadgetID(0), #WM_LBUTTONUP, WParam, (pt\x & $FFFF) | ((pt\y & $FFFF) << 16))
    EndIf
  EndIf
  
  ProcedureReturn Result
EndProcedure


UseJPEGImageDecoder()
CatchImage(0, ?label____jpg, ?label____jpg_End - ?label____jpg)
ResizeImage(0, DesktopScaledX(1024), DesktopScaledY(768))

;InitSprite()
;UsePNGImageDecoder()
If OpenWindow(0, 0, 0, 1024, 768, "", #PB_Window_ScreenCentered | #PB_Window_BorderLess | #PB_Window_Invisible)   ;Note:  #PB_Window_Invisible is essential.
  
  ;ImgFile = LoadImage(0, "Roster.png", 0)
  ImageGadget(1, 0, 0, 1024, 768, ImageID(0))
  
  DisableGadget(1, 1)
  
  ListIconGadget(0, 175, 150, 700, 500, "No.", 30, #PB_ListIcon_FullRowSelect | #PB_ListIcon_AlwaysShowSelection) 
  SetGadgetColor(0, #PB_Gadget_BackColor, $B599C1)
  SetGadgetColor(0, #PB_Gadget_FrontColor, $FFFFFF)
  
  ;Apply the layered attribute to the gadget.
  SetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE, GetWindowLongPtr_(GadgetID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)
  SetLayeredWindowAttributes_(GadgetID(0), $B599C1, 0, #LWA_COLORKEY)
  
  ButtonGadget(2, 800, 700, 100, 25, "Exit")
  
  hHeader = SendMessage_(GadgetID(0), #LVM_GETHEADER, 0, 0) 
;Subclass ListIcon so we can customdraw the header text 
  oldListIconCallback = SetWindowLong_(GadgetID(0), #GWL_WNDPROC, @SubclassedListIcon()) 

;Add 10 more columns.
  ;For i = 1 To 13
  AddGadgetColumn(0, 1, "Player names", 150) 
  AddGadgetColumn(0, 2, "Pos", 50)
  AddGadgetColumn(0, 3, "KP", 35)
  AddGadgetColumn(0, 4, "TA", 35)
  AddGadgetColumn(0, 5, "PS", 35)
  AddGadgetColumn(0, 6, "SH", 35)
  AddGadgetColumn(0, 7, "PC", 35)
  AddGadgetColumn(0, 8, "HE", 35)
  AddGadgetColumn(0, 9, "ST", 35)
  AddGadgetColumn(0, 10, "SP", 35)
  AddGadgetColumn(0, 11, "BC", 35)
  AddGadgetColumn(0, 12, "FT", 35)
  AddGadgetColumn(0, 13, "PF", 35)
  ;Next  
;Add some data
  For b=0 To 99; Add 100 rows.
    AddGadgetItem(0,-1,"")
  Next
  For i = 0 To 99
    For j = 0 To 50
      SetGadgetItemText(0,i,Str(i+j),j)
    Next j
  Next i
  
  HideWindow(0, 0)
  SetWindowCallback(@MyWindowCallback())
  
  SetActiveGadget(0)
  
  Repeat
    e = WaitWindowEvent()
    
    If e = #PB_Event_Gadget And EventGadget() = 0
      Select EventType()
        Case #PB_EventType_LeftDoubleClick
          Debug "Left Double Click"
          
        ;Case #PB_EventType_LeftClick
        ;  Debug "Left Click"
      EndSelect
    EndIf
    
    If e = #PB_Event_Gadget And EventGadget() = 2 And EventType() = #PB_EventType_LeftClick
      Break
    EndIf
    
  Until e = #PB_Event_CloseWindow
  
  DeleteObject_(brush)
EndIf

DataSection
  label____jpg:
  
  ; Put your image data here.
  
  label____jpg_End:
EndDataSection
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Make ListIconGadget() active

Post by Distorted Pixel »

RASHAD wrote: Mon Oct 10, 2022 3:46 am Real Transparency
https://www.purebasic.fr/english/viewt ... p?t=79972
Thank you, I'll take a look at this sometime tonight or next couple of days


breeze4me wrote: Mon Oct 10, 2022 12:10 pm A layered style can be applied to a control in Windows 8 or later. So, it is possible to make gadgets
Wow! The image with the flower in it is sweet looking!
I will play around with these examples.

What I'm after is to have transparency with somewhere between 80-95% occupancy. So it will be slightly see-through but not absolutely clear like the awesome flower pic. That is really good. It's easy to take an image and load it into say.... Gimp(my favorite image editor) and make it any occupancy I want, but I need to learn API so I can do it like this with gadgets.

I found a Win32 API tutorial here in the forums, but the link/s are broken so need to find some other tutorials
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
User avatar
Distorted Pixel
Enthusiast
Enthusiast
Posts: 303
Joined: Sun Aug 29, 2021 4:34 am

Re: Make ListIconGadget() active

Post by Distorted Pixel »

I've been working with RASHAD'Sreal transparency example, I'm having trouble moving the listicongadget up and have it look the same. Every time I move it there is white area where it used to be. I'm trying to move all things needing to be moved up so like I said it looks the same. I want to add another listicongadget below it

I did it on an old example without transparency. It was easy to do, but can't figure this out
To be popular is way to much work. I just want to be me, myself and I. Oh no, does that mean I'm bipolar? :shock:

No one cares how much you know until they know how much you care
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4954
Joined: Sun Apr 12, 2009 6:27 am

Re: Make ListIconGadget() active

Post by RASHAD »

Hi Distorted Pixel
Use ResizeWindow(1,new x,new y ,new Width,new Height)
And be sure that the new Height or (new Width) will contain the 2 ListIcons
Egypt my love
Post Reply