How to Remove the BORDER of a LIST control

Below is a small testbed program to remove the border around a LIST control
The hard work of figuring out which API calls to make was done by Dave Bratovich

PROGRAM
  INCLUDE('svapi.INC'),ONCE
  MAP
    include('svapifnc.inc'),ONCE
    RemoveBitMask     (*LONG inoutValue, LONG xMask)
    RemoveListBorder  (LONG hwnd)
  END

UI:View LONG(1)
LIST1:Queue QUEUE
Hi             STRING(6)
There          STRING(25)
            END

Window WINDOW('Drop List Line Height'),AT(,,346,120),GRAY,SYSTEM,FONT('Segoe UI',8)
		LIST,AT(30,18,150,16),USE(UI:View),CENTER,FONT(,16,,FONT:bold),DROP(4),FROM(|
                  'Show All|#1' & |
                 '|Show Openings|#2' & |
                 '|Show Verticals|#3' & |
                 '|Show Rebar|#4')
		LIST,AT(30,39,208),USE(?LIST1),FLAT,FROM(LIST1:Queue),FORMAT(|
                      '44L(2)' & '|M' & '~Hi~'    & '@S10@' |
                  &   '20L(2)' & '|M' & '~There~' & '@S25@' |
                  )
		BUTTON('Remove Border'),AT(261,39),USE(?RemoveBorder)
	END

  CODE
  LOOP 10 TIMES
    LIST1:Queue.Hi    = ALL( CHR(64 + RECORDS(LIST1:Queue)) )
    LIST1:Queue.There = ALL( CHR(96 + RECORDS(LIST1:Queue)) )
    ADD(LIST1:Queue)
  END

  OPEN(Window)
  ACCEPT
	CASE ACCEPTED()
     OF ?RemoveBorder; RemoveListBorder( ?List1{Prop:Handle} )
   END
  END

RemoveListBorder  PROCEDURE(LONG hwnd)
!there are several equates used in this procedure, see SvAPI.inc for them
SWP_MySettings    EQUATE( SWP_NOMOVE + SWP_NOSIZE + SWP_NOOWNERZORDER + SWP_NOZORDER + SWP_FRAMECHANGED )
NewStyle          LONG,AUTO
    CODE
    NewStyle = GetWindowLong(hwnd,GWL_STYLE)
    RemoveBitMask(NewStyle,WS_BORDER     )
    RemoveBitMask(NewStyle,WS_DLGFRAME   )
    RemoveBitMask(NewStyle,WS_THICKFRAME )
    SetWindowLong(hwnd,GWL_STYLE,NewStyle)

    NewStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
    RemoveBitMask(NewStyle,WS_EX_CLIENTEDGE)
    RemoveBitMask(NewStyle,WS_EX_STATICEDGE)
    RemoveBitMask(NewStyle,WS_EX_WINDOWEDGE)
    SetWindowLong(hwnd,GWL_EXSTYLE,NewStyle)

    SetWindowPos(hwnd,0,0,0,0,0, SWP_MySettings)

RemoveBitMask     PROCEDURE(*LONG inoutValue, LONG xMask)
   ! note: this procedure assumes that the xMask only has exactly  ONE BIT SET
   CODE
   IF BAND(inoutValue, xMask)
      inoutValue = BXOR(inoutValue, xMask)
   END
1 Like

It does work with any window (control) that has the following window styles set…
WS_BORDER
WS_DLGFRAME
WS_THICKFRAME
WS_EX_CLIENTEDGE
WS_EX_STATICEDGE
WS_EX_WINDOWEDGE

and it will remove the style from that control if it was used.

Default CW lists use WS_EX_CLIENTEDGE but a list using the FLAT property uses WS_BORDER.

I was curious exactly what a LIST looks like without Borders so grabbed some screen captures and modified the example to show both before and after…

On the Left are Normal 3D and Flat with borders.
On the Right side the Borders are Removed.
There are check boxes to try without Window Gray or to add TRN to see what a transparent LIST looks like.

image


With a Manifest the look changes as shown below. I added a 3rd list with PROP:NoTheme=1 where you see the List Header row is classic gray not white.

image


Below is the modified source. I added Scroll Bars to see if that looks different. Also Proportional Thumb Prop:PropVscroll.

PROGRAM  !from ClarionHub How to Remove the BORDER of a LIST control https://clarionhub.com/t/how-to-remove-the-border-of-a-list-control/292
  INCLUDE('svapi.INC'),ONCE
  MAP
    include('svapifnc.inc'),ONCE
    RemoveBitMask     (*LONG inoutValue, LONG xMask)
    RemoveListBorder  (LONG hwnd)
  END

UI:View LONG(1)
LIST1:Queue QUEUE
Hi             STRING(6)
There          STRING(25)
            END
GrayOff      BYTE
TrnON        BYTE

Window WINDOW('LIST without Borders'),AT(,,367,200),GRAY,SYSTEM,FONT('Segoe UI',9)
        LIST,AT(7,4,150,16),USE(UI:View),CENTER,FONT(,16,,FONT:bold),DROP(4),FROM('Show All|#1|Show ' & |
                'Openings|#2|Show Verticals|#3|Show Rebar|#4')
        LIST,AT(7,26,170,50),USE(?LIST_3d),       VSCROLL,FROM(LIST1:Queue),FORMAT('44L(2)|M~Original~C@S10@20L(2)|M~Normal 3D~C@S25@')
        LIST,AT(7,83,170,50),USE(?LIST_Flat),FLAT,VSCROLL,FROM(LIST1:Queue),FORMAT('44L(2)|M~Original~C@S10@20L(2)|M~FLAT~C@S25@')
        LIST,AT(7,139,170,50),USE(?LIST_NoTheme),HVSCROLL,VCR,FROM(LIST1:Queue),FORMAT('44L(2)|M~Original~C@S10@20L(2)|M~No Theme~C@S25@')
        BUTTON('Remove Border'),AT(187,7),USE(?RemoveBorder)
        LIST,AT(187,26,170,50),USE(?LIST1_3d),       VSCROLL,FROM(LIST1:Queue),FORMAT('44L(2)|M~Borderless~C@S10@20L(2)|M~Normal 3D~C@S25@')
        LIST,AT(187,83,170,50),USE(?LIST1_Flat),FLAT,VSCROLL,FROM(LIST1:Queue),FORMAT('44L(2)|M~Borderless~C@S10@20L(2)|M~FLAT~C@S25@')
        LIST,AT(187,139,170,50),USE(?LIST1_NoTheme),HVSCROLL,VCR,FROM(LIST1:Queue),FORMAT('44L(2)|M~Borderless~C@S10@20L(2)|M~No Theme~C@S25@')
        CHECK('GRAY Off'),AT(267,9),USE(GrayOff),SKIP,TIP('GRAY off on Window')
        CHECK('TRN On'),AT(315,9),USE(TrnON),SKIP,TIP('TRN on for All Controls')
    END
X LONG
  CODE
  SYSTEM{PROP:PropVScroll}=1
  LOOP X=1 TO 12
    LIST1:Queue.Hi    = ALL( CHR(64 + X) )
    LIST1:Queue.There = ALL( CHR(96 + X) )
    ADD(LIST1:Queue)
  END
  
  OPEN(Window)
  ?LIST_NoTheme{PROP:NoTheme}=1
  ?LIST1_NoTheme{PROP:NoTheme}=1
  ACCEPT
	CASE ACCEPTED()
     OF ?RemoveBorder; DISABLE(?)
                       RemoveListBorder( ?LIST1_Flat{Prop:Handle} )   
                       RemoveListBorder( ?LIST1_3d{Prop:Handle} )
                       RemoveListBorder( ?LIST1_NoTheme{Prop:Handle} )
                       RemoveListBorder( ?UI:View{Prop:Handle} )
     OF ?GrayOff     ; 0{PROP:Gray}=1-GrayOff 
     OF ?TrnON       ; LOOP X=1 TO LASTFIELD() ; X{PROP:TRN}=TrnON ; END
   END
  END

RemoveListBorder  PROCEDURE(LONG hwnd)
!there are several equates used in this procedure, see SvAPI.inc for them
SWP_MySettings    EQUATE( SWP_NOMOVE + SWP_NOSIZE + SWP_NOOWNERZORDER + SWP_NOZORDER + SWP_FRAMECHANGED )
NewStyle          LONG,AUTO
    CODE
    NewStyle = GetWindowLong(hwnd,GWL_STYLE)
    RemoveBitMask(NewStyle,WS_BORDER     )
    RemoveBitMask(NewStyle,WS_DLGFRAME   )
    RemoveBitMask(NewStyle,WS_THICKFRAME )
    SetWindowLong(hwnd,GWL_STYLE,NewStyle)

    NewStyle = GetWindowLong(hwnd, GWL_EXSTYLE)
    RemoveBitMask(NewStyle,WS_EX_CLIENTEDGE)
    RemoveBitMask(NewStyle,WS_EX_STATICEDGE)
    RemoveBitMask(NewStyle,WS_EX_WINDOWEDGE)
    SetWindowLong(hwnd,GWL_EXSTYLE,NewStyle)

    SetWindowPos(hwnd,0,0,0,0,0, SWP_MySettings)

RemoveBitMask     PROCEDURE(*LONG inoutValue, LONG xMask)
   CODE
   inoutValue = BAND(inoutValue, BXOR(-1,xMask))    !Carl: Not AND() removes bits i.e. Boolean NAND()


Changed the Original code to Turn Off Bits to a version using “Not AND” i.e. AND with the Complement just as an example of Boolean:

Original_RemoveBitMask     PROCEDURE(*LONG inoutValue, LONG xMask)
   CODE
   IF BAND(inoutValue, xMask)  
      inoutValue = BXOR(inoutValue, xMask)
   END

!--- Carl: Not AND() removes bits i.e. Boolean NAND() ---
RemoveBitMask     PROCEDURE(*LONG inoutValue, LONG xMask)
   CODE
   inoutValue = BAND(inoutValue, BXOR(-1,xMask))    

1 Like

Can I assume that other mods might allow a border to emphasize a list by using black or a color?
Just considering how I could perhaps use it.

Seems like you could position a BOX or PANEL with BEVEL around the Borderless LIST to get the look you want. Please try some and post your results.