How to create groups of SCROLLING Controls (using IMAGE)

Important Details

  1. The Image control must have one of ,VSCROLL ,HSCROLL or ,HVSCROLL
    otherwise controls will not appear
  2. using the parent argument in CREATE() does not work
  3. prop:Parent must be set prior to calling SETPOSITION() otherwise you will not see the controls
    PROGRAM
    MAP
    END    
Window WINDOW('Caption'),AT(,,395,224),GRAY,FONT('Segoe UI',8)
        IMAGE,AT(25,1,143,216),USE(?IMAGE1),VSCROLL
        IMAGE,AT(182,2,149,215),USE(?IMAGE2),VSCROLL
    END    
    CODE
    OPEN(Window)
    DO CreateControls
    ACCEPT
    END
    
CreateControls	ROUTINE
    DATA
Y		LONG(10)	
NewFEQ Signed,AUTO
    CODE
    LOOP 20 TIMES
        NewFEQ = CREATE(0,CREATE:Button) !, ?Image1)
        NewFeq{PROP:Parent} = ?Image1
        NewFEQ{PROP:Text} = 'Button ['& NewFeq &']'
        SETPOSITION(NewFeq, 10, Y, 60, 10) ; Y += 20
        NewFeq{PROP:Scroll} = TRUE
        NewFEQ{PROP:Hide}   = FALSE	  
    END	
    
    Y = 10
    LOOP 20 TIMES
        NewFEQ = CREATE(0,CREATE:Button) !, ?Image2)
        NewFeq{PROP:Parent} = ?Image2
        NewFEQ{PROP:Text} = 'Button ['& NewFeq &']'
        SETPOSITION(NewFeq, 10, Y, 60, 10) ; Y += 20
        NewFeq{PROP:Scroll } = TRUE
        NewFEQ{PROP:Hide}=FALSE	  
    END
7 Likes

BTW, this is what it looks like when compiled and run:

1 Like

Hi Marc,

Thanks for the inspiration.

I’m planning to use this technique in a future app.

David


3 Likes

Wow, I didn’t know this technique. It can be very useful.
Thank you Mark (and DigiClarion for bringing back to life this topic) !

This is great, just what I was looking for to start with. I have implemented this and made some changes for what I need. However, i have some issues that I would if someone can help with.

  1. If I change the BUTTON to an IMAGE, it does not seem to want to have its PARENT set to the ?image1

  2. I made another program to have the items scroll on the window, and NOT inside an Image control. This works with scrolling images if I scroll using the scrollbar on the right. Where it does not work is if Im on a touch screen machine and i want to scroll up and down using my finger going up and down on the window itself.

So, im wondering if there is a way to make the window scroll up or down, based on the mouse being clicked and moving up and down

How did you manage to get the Images in the scrolling control. I had issues with this. Any help would be appreciated.

Thanks

need code like this:

                MAP
                  MODULE('')
                    CallWindowProc(LONG,UNSIGNED,SIGNED,UNSIGNED,LONG),LONG,PASCAL,NAME('CallWindowProcA')
                  END
                  SubClassFunc1(UNSIGNED,UNSIGNED,UNSIGNED,LONG),LONG,PASCAL
                  MoveScrollBar()
                END

ViewHeight      LONG
ViewAllHeight   LONG
SavedProc1      LONG
MouseY          LONG
SAV:MouseY      LONG

! timer need for update MOUSEY data :)
Window WINDOW('Caption'),AT(,,395,224),FONT('Segoe UI',8,,),TIMER(1),GRAY
       IMAGE,AT(8,4,143,216),USE(?IMAGE1),VSCROLL
       IMAGE,AT(174,4,149,215),USE(?IMAGE2),VSCROLL
       BUTTON('Up'),AT(338,4,45,32),USE(?ButtonUp)
       PROMPT('Use button or drag white space wo button in this image'),AT(334,62,61,36),USE(?Prompt1)
       STRING('<<---------'),AT(332,102),USE(?String1)
       BUTTON('Down'),AT(338,182,45,32),USE(?ButtonDown)
     END
  CODE
  OPEN(Window)
  ! get view height
  ViewHeight = ?IMAGE1{PROP:Height}
  DO CreateControls
  SavedProc1 = ?Image2{PROP:WndProc}
  ?Image2{PROP:WndProc} = ADDRESS(SubClassFunc1)
  ACCEPT
    CASE ACCEPTED()
    OF ?ButtonDown
      CurPos# = ?IMAGE2{PROP:VScrollPos}
      NewPos# = CurPos# + (ViewHeight / (ViewAllHeight / 255))
      ?IMAGE2{PROP:VScrollPos} = CHOOSE(NewPos# <= 255 , NewPos#, 255)
    OF ?ButtonUp
      CurPos# = ?IMAGE2{PROP:VScrollPos}
      NewPos# = CurPos# - (ViewHeight / (ViewAllHeight / 255))
      ?IMAGE2{PROP:VScrollPos} = CHOOSE(NewPos# > 0 , NewPos#, 0)
    END
  END

CreateControls  ROUTINE
  DATA
Y               LONG(10)
NewFEQ          Signed,AUTO
  CODE
  LOOP 20 TIMES
    NewFEQ = CREATE(0,CREATE:Button) !, ?Image1)
    NewFeq{PROP:Parent} = ?Image1
    NewFEQ{PROP:Text} = 'Button ['& NewFeq &']'
    SETPOSITION(NewFeq, 10, Y, 60, 10) ; Y += 20
    NewFeq{PROP:Scroll} = TRUE
    NewFEQ{PROP:Hide}   = FALSE
  END
  ! get last ypos + height
  ViewAllHeight = NewFeq{PROP:Ypos} + NewFeq{PROP:Height}

  Y = 10
  LOOP 20 TIMES
    NewFEQ = CREATE(0,CREATE:Button) !, ?Image2)
    NewFeq{PROP:Parent} = ?Image2
    NewFEQ{PROP:Text} = 'Button ['& NewFeq &']'
    SETPOSITION(NewFeq, 10, Y, 60, 10) ; Y += 20
    NewFeq{PROP:Scroll } = TRUE
    NewFEQ{PROP:Hide}=FALSE
  END

MoveScrollBar  PROCEDURE
  CODE
  ! down
  IF SAV:MouseY < MouseY
    CurPos# = ?IMAGE2{PROP:VScrollPos}
    NewPos# = CurPos# + ((MouseY - SAV:MouseY) / (ViewAllHeight / 255))
    ?IMAGE2{PROP:VScrollPos} = CHOOSE(NewPos# <= 255 , NewPos#, 255)
  ! up
  ELSE
    CurPos# = ?IMAGE2{PROP:VScrollPos}
    NewPos# = CurPos# - ((SAV:MouseY - MouseY) / (ViewAllHeight / 255))
    ?IMAGE2{PROP:VScrollPos} = CHOOSE(NewPos# > 0 , NewPos#, 0)
  END


SubClassFunc1  PROCEDURE(hWnd,wMsg,wParam,lParam)
WM_MOUSEMOVE   EQUATE(0200h)
WM_LBUTTONDOWN EQUATE(0201h)
WM_LBUTTONUP   EQUATE(0202h)
  CODE
  CASE wMsg
  OF WM_MOUSEMOVE
    MouseY = MOUSEY()
  OF WM_LBUTTONDOWN
    SAV:MouseY = MouseY
  OF WM_LBUTTONUP
    MoveScrollBar
  END
  RETURN(CallWindowProc(SavedProc1,hWnd,wMsg,wParam,lParam))

There still need to catch clicks through the controls.

1 Like

Hi Mark -

I’ve been working on a class that uses this concept. However, I have noticed that some artifacts can be left in between controls as you scroll the image control… Have you noticed anything like that? InvalidateRect() helps, but there’s probably a better way.