Page 1 of 2

[Solved]ListIconGadget() active

Posted: Sun Oct 09, 2022 1:50 am
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

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 2:18 am
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))

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 3:59 am
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.

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 4:12 am
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

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 7:46 am
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.

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 9:03 am
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

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 4:01 pm
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

Re: Make ListIconGadget() active

Posted: Sun Oct 09, 2022 7:58 pm
by RASHAD
I do not think that there is any way to make ListIcon transparent
viewtopic.php?t=79968

Re: Make ListIconGadget() active

Posted: Mon Oct 10, 2022 1:53 am
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

Re: Make ListIconGadget() active

Posted: Mon Oct 10, 2022 3:46 am
by RASHAD

Re: Make ListIconGadget() active

Posted: Mon Oct 10, 2022 12:10 pm
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

Re: Make ListIconGadget() active

Posted: Mon Oct 10, 2022 1:59 pm
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

Re: Make ListIconGadget() active

Posted: Mon Oct 10, 2022 8:50 pm
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

Re: Make ListIconGadget() active

Posted: Tue Oct 11, 2022 3:35 am
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

Re: Make ListIconGadget() active

Posted: Tue Oct 11, 2022 4:53 am
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