SweetyVD (Visual Designer)

Share your advanced PureBasic knowledge/code with the community.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

Thanks for your example with the canvas that sits on the main canvas
I keep it, simple enough to test the different possibilities

I've added 2 more buttons to test with different gadgets and see how the overlays look like.
It works quite well with most Gadget.
But less well, if I add a calendar, it flickers when you move it.
Or an explorerListGadget with painted scrollbars.

Capturing gadgets is really interesting. Maybe it's good to make a mix of different solutions depending on the gadgets
User avatar
Caronte3D
Addict
Addict
Posts: 1027
Joined: Fri Jan 22, 2016 5:33 pm
Location: Some Universe

Re: SweetyVD (Visual Designer)

Post by Caronte3D »

IMHO, resolving the flickering effect is good, but is not so important at first.
This isn't a animation package at all :lol:
Kudos, ChrisR :wink:
FlatEarth

Re: SweetyVD (Visual Designer)

Post by FlatEarth »

ChrisR wrote:Capturing gadgets is really interesting. Maybe it's good to make a mix of different solutions depending on the gadgets
you're welcome, Yes I agree with you.
Of course, as a third way in Windows, the SetCapture_ API works great for direct drag controls but unfortunately it does not cover all the controls.My first priority is to capture controls with WM_PRINT, because it has less incompatibility.
Last edited by FlatEarth on Fri Jan 31, 2020 5:38 pm, edited 1 time in total.
FlatEarth

Re: SweetyVD (Visual Designer)

Post by FlatEarth »

Caronte3D wrote:IMHO, resolving the flickering effect is good, but is not so important at first.
This isn't a animation package at all :lol:
Kudos, ChrisR :wink:
Flickering drastically reduces the quality and user-friendliness of the designer.It is very important for the designer manufacturer. Contrary to some users.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

It's clear that the visual aspect of any software is important for users to use and appropriate it.
Especially on a designer.

On my side, I've already spent a lot of time.
It was really a problem in the previous versions. It's a little better now and nice to have the real gadgets.
I don't have much feedbacks to get a feeling

But the other functions, such as Open/Import, are also necessary.
Is there any beginning of existing pb parsing around ?

Zebuddi had added an option to save/restore the main map and reload SweetyVD from it.
It Could be useful but I can't find it. If you are around :)
PureLust
Enthusiast
Enthusiast
Posts: 477
Joined: Mon Apr 16, 2007 3:57 am
Location: Germany, NRW

Re: SweetyVD (Visual Designer)

Post by PureLust »

ChrisR wrote:The flicker on windows is a big headache
and I try to avoid using the APIs as much as possible for cross platform compatibility.
As far as i know, GUI flickering is not a big issue on OSX or Linux, it's only a big Problem on Windows.

To avoid GUI flickering on Windows, have you tried [DeFlicker]?
It's very powerful in reducing flickering and it's really easy to implement (just 2 additional Lines to your code)

You could use CompilerIf to include it only if compiled on Windows, so your code will stay platform independent.

[Edit] just added CompilerIFs and OS check to DeFlicker, so crossplatform shouldn't be a problem.
[Dynamic-Dialogs] - create complex GUIs the easy way
[DeFlicker] - easily deflicker your resizeable Windows
[WinFX] - Window Effects (incl. 'click-through' Window)
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

Hi PureLust,
I've seen your great module and it's saved and kept in warm.
but I have to admit I didn't use it here, I just run the example.
In fact, I'm confused about how to use it in the project.
But your module was the basis of my research

SmartWindowRefresh is doing its job well to resize the window.

I then used this procedure on the Main Canvas container. It is called before and after each move of Gadget.

Code: Select all

  Procedure SetWinRedrawON(Gadget.i, State.b=#True)
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      If DisplayHandleCornerOnMove = #False
        SendMessage_(GadgetID(Gadget),#WM_SETREDRAW,State,0)
        If State = #True
          ;InvalidateRect_(GadgetID(Gadget), #Null, State)
          RedrawWindow_(GadgetID(Gadget), #Null, #Null, #RDW_INVALIDATE|#RDW_ERASE|#RDW_ALLCHILDREN|#RDW_UPDATENOW)
        EndIf
      EndIf
    CompilerEndIf
  EndProcedure
It's not bad and it's doing the job for the Main canvas and its children

But finally I found

Code: Select all

SetWindowLongPtr_(GadgetID(#DrawArea), #GWL_STYLE, GetWindowLongPtr_(GadgetID(#DrawArea), #GWL_STYLE) | #WS_CLIPCHILDREN)
It does the same thing without having to call the procedure at each Gadget move

What I'm missing now are the gadgets themselves, when they're moved (on top of the main canvas and and its clip children, a scrollarea and windows)
Let me know if you have any indication on how I might test
And thanks for Modul_DeFlicker.pbi and the instant addition of CompilerIFs :)
User avatar
Columbo
Enthusiast
Enthusiast
Posts: 303
Joined: Wed Sep 10, 2014 7:17 am
Location: Ontario Canada
Contact:

Re: SweetyVD (Visual Designer)

Post by Columbo »

I downloaded SweetyVD 2.1.0 but when I run the SweetyVD.pb I get a message saying "Icon file not found" but it does not flag a line number in the code. I looked in the image folder and I see a file called SweetyVD.ico. If this is not the file that it is looking for then I'm not sure how to remedy this problem. If it flagged a line of code in the Purebasic IDE where it is looking for the Icon I could just temporarily comment it out so I could at least try SweetyVD.

Any suggestions?
http://www.oldtimeradiotoday.com - Listen to or download classic old time radio broadcasts.
JHPJHP
Addict
Addict
Posts: 2129
Joined: Sat Oct 09, 2010 3:47 am
Contact:

Re: SweetyVD (Visual Designer)

Post by JHPJHP »

Hi Columbo,

Open Compiler Options and remove the Use Icon reference.
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

How did you get that ?
You must have SweetyVD.ico in "Images" folder
and in Compiler Options you should have "Use Icon" selected with the path: "Images\SweetyVD.ico"

Otherwise, Thanks to JHPJHP, you can indeed delete remove the Use Icon reference in Compiler Options,

Or you can use the executables here:
SweetyVD_Linux_x64
SweetyVD_x64.exe
SweetyVD_x86.exe
User avatar
Columbo
Enthusiast
Enthusiast
Posts: 303
Joined: Wed Sep 10, 2014 7:17 am
Location: Ontario Canada
Contact:

Re: SweetyVD (Visual Designer)

Post by Columbo »

I went into the compiler options as JHP JHP suggested and I found that the path to the icon was incorrect. I changed the path and now everything is fine.

Thanks JHPJHP.
http://www.oldtimeradiotoday.com - Listen to or download classic old time radio broadcasts.
User avatar
blueb
Addict
Addict
Posts: 1041
Joined: Sat Apr 26, 2003 2:15 pm
Location: Cuernavaca, Mexico

Re: SweetyVD (Visual Designer)

Post by blueb »

Columbo wrote:I downloaded SweetyVD 2.1.0 but when I run the SweetyVD.pb I get a message saying "Icon file not found" but it does not flag a line number in the code....
Any suggestions?
When you load the SweetyVD source file"
The Compiler Options dialog shows: Use Icon: "Include\SweetyVD.ico"

but if you look inside this folder... nothing exists... so copy the 'SweetyVD.ico' from the 'Images' folder to the 'Include' folder and all is well.

(Chris will probably correct this)

On another note, I tried a simple Window that uses a FrameGadget. I didn't like the first text font I tried, so I tried a couple more, until I was happy.

While I only needed the last font.. Sweety VD kept all 3 that I tried. Perhaps this might be an issue.

Code: Select all

; -----------------------------------------------------------------------------
;           Name:
;    Description:
;         Author:
;           Date: 2020-02-02
;        Version:
;     PB-Version:
;             OS:
;         Credit:
;          Forum:
;     Created by: SweetyVD
; -----------------------------------------------------------------------------

EnableExplicit

Enumeration Window
  #Window_0
EndEnumeration

Enumeration Gadgets
  #Frame_1
  #Button_1
EndEnumeration

Enumeration FormFont
  #Font_Window_0_0
  #Font_Window_0_1
  #Font_Window_0_2
EndEnumeration

LoadFont(#Font_Window_0_0, "@Arial Unicode MS", 10, #PB_Font_Bold)
LoadFont(#Font_Window_0_1, "Lucida Calligraphy", 10, #PB_Font_Bold)
LoadFont(#Font_Window_0_2, "Lucida Sans Typewriter", 12, #PB_Font_Italic)

Define iEvent.i

Declare Open_Window_0(X = 0, Y = 0, Width = 890, Height = 680)

Procedure Open_Window_0(X = 0, Y = 0, Width = 890, Height = 680)
  If OpenWindow(#Window_0, X, Y, Width, Height, "Window_0", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
    FrameGadget(#Frame_1, 10, 90, 870, 500, "What's In Here?")
      SetGadgetFont(#Frame_1, FontID(#Font_Window_0_2))
    ButtonGadget(#Button_1, 780, 610, 100, 60, "Button_1")
  EndIf
EndProcedure

Open_Window_0()

Repeat
  iEvent = WaitWindowEvent()
  Select iEvent
    Case #PB_Event_Menu
      Select EventMenu()
      EndSelect

    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_1   ;Button_1
          MessageRequester("Information", "Button ID Name : #Button_1" +#CRLF$+#CRLF$+ "Text : Button_1")
      EndSelect

    Case #PB_Event_CloseWindow
      End
  EndSelect
ForEver
- It was too lonely at the top.

System : PB 6.10 Beta 9 (x64) and Win Pro 11 (x64)
Hardware: AMD Ryzen 9 5900X w/64 gigs Ram, AMD RX 6950 XT Graphics w/16gigs Mem
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

Hi blueb,
I think it's good now for the icon, thanks for reporting Columbo
It was good in _SweetyVD.pbp with: <icon enable="1">Images\SweetyVD.ico</icon>
But not in SweetyVD.pb with "UseIcon = Includes\SweetyVD.ico" changed now to "UseIcon = Images\SweetyVD.ico"

We're on the same page for the fonts :)
I was on it as well as for the images.
I fixed it and when changing font/Image, the old one is deleted if not used by another gadget, now.

Also,
Use relative path for Images if it is placed in current folder or sub-folder
Search SilkTheme.zip was review with a more explicit message if not found.

SweetyVD Update v2.1.1
FlatEarth

Re: SweetyVD (Visual Designer)

Post by FlatEarth »

Inspired by the following topics :

viewtopic.php?f=13&t=54098&hilit=drag+move

viewtopic.php?f=5&t=70746&hilit=capture ... B+64bit%3B

Code: Select all

Structure canvasitem
  img.i 
  x.i 
  y.i 
  width.i 
  height.i
EndStructure

Global isCurrentItem = #False
Global currentItemXOffset.i, currentItemYOffset.i
Global NewList Images.canvasitem()

Procedure AddImage(x,y,img)
  If AddElement(Images())
    Images()\img    = img
    Images()\x      = x
    Images()\y      = y
    Images()\width  = ImageWidth(img)
    Images()\height = ImageHeight(img)
  EndIf
EndProcedure

Procedure DrawCanvas()
  If StartDrawing(CanvasOutput(0))
    Box(0,0,GadgetWidth(0),GadgetHeight(0),RGB(255,255,255))
    ForEach Images()
      DrawImage(ImageID(Images()\img),Images()\x,Images()\y) ; draw all images with z-order
    Next
    If Not Drag
      With Images()
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(\x, \y, \Width, \Height, #Blue)
        DrawingMode(#PB_2DDrawing_Default)
        Box(\x-5, \y-5, 10, 10, #Blue)
        Box(\x + \Width-5, \y-5, 10, 10, #Blue)
        Box(\x + \Width-5, \y + \Height-5, 10, 10, #Blue)
        Box(\x-5, \y + \Height-5, 10, 10, #Blue)
      EndWith
    Else
      With Images()
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box(\x+5, \y+5, \Width, \Height, RGBA($42, $42, $42, $50))
        DrawImage(ImageID(\img), \x, \y, \Width, \Height)
      EndWith
    EndIf   
    StopDrawing()
  EndIf
EndProcedure

Procedure HitTest(x,y)
  isCurrentItem = #False
  If LastElement(Images()) ; search for hit, starting from end (z-order)
    Repeat
      If x >= Images()\x And x < Images()\x + Images()\width
        If y >= Images()\y And y < Images()\y + Images()\height
          MoveElement(Images(), #PB_List_Last)
          isCurrentItem = #True
          currentItemXOffset = x - Images()\x
          currentItemYOffset = y - Images()\y
          Break
        EndIf
      EndIf
    Until PreviousElement(Images())=0
  EndIf
  ProcedureReturn isCurrentItem
EndProcedure

Procedure CaptureGadget(Gadget)
  Protected Img,hdc
  If IsGadget(Gadget)
    Img = CreateImage(#PB_Any,GadgetWidth(Gadget),GadgetHeight(Gadget))
    hdc =  StartDrawing(ImageOutput(Img))
    If hdc
      SendMessage_(GadgetID(Gadget),#WM_PRINT,hDC, #PRF_CHILDREN|#PRF_CLIENT|#PRF_NONCLIENT|#PRF_ERASEBKGND)
      StopDrawing()
    EndIf  
  EndIf
  ProcedureReturn Img
EndProcedure  

If OpenWindow(0, 0, 0, 800, 600, "Move/Drag Canvas Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 10, 10, 780, 580,#PB_Canvas_Container)
  ButtonGadget(1,0,0,100,30,"Button") : HideGadget(1,1)
  CalendarGadget(2,0,0,220,160) : HideGadget(2,1)
  ExplorerListGadget(3, 10, 10, 380, 180, "*.*", #PB_Explorer_MultiSelect) : HideGadget(3,1)
  PanelGadget(4,0,0,200,100) : HideGadget(4,1)
    AddGadgetItem(4,-1,"Tab 1")
    AddGadgetItem(4,-1,"Tab 2")
  CloseGadgetList()
  CloseGadgetList()
  
  AddImage(100,100,CaptureGadget(1))
  AddImage(400,100,CaptureGadget(2))
  AddImage(40,300,CaptureGadget(3))
  AddImage(490,350,CaptureGadget(4))
  
  DrawCanvas()
  
  Repeat
    Event = WaitWindowEvent()
    
    If Event = #PB_Event_Gadget And EventGadget() = 0
      Select EventType()
        Case #PB_EventType_LeftButtonDown
          x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
          y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
          If HitTest(x,y)
            DrawCanvas()
          EndIf
          Drag = #True
        Case #PB_EventType_LeftButtonUp
          Drag = #False
        Case #PB_EventType_MouseMove
          If Drag = #True
            If isCurrentItem
              x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
              y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
              If LastElement(Images())
                Images()\x = x - currentItemXOffset
                Images()\y = y - currentItemYOffset
                DrawCanvas()
              EndIf
            EndIf
          EndIf
      EndSelect
    EndIf   
    
  Until Event = #PB_Event_CloseWindow
EndIf
User avatar
ChrisR
Addict
Addict
Posts: 1127
Joined: Sun Jan 08, 2017 10:27 pm
Location: France

Re: SweetyVD (Visual Designer)

Post by ChrisR »

Wow, super, great code :)
It's very fluid and flicker-free, thanks for sharing.

I've added some specific code, workaround for ExplorerComboGadget and ComboBoxGadget, not properly captured.
With also a SpinGadget that needs a Container

Code: Select all

Structure canvasitem
  img.i
  x.i
  y.i
  width.i
  height.i
EndStructure

Global isCurrentItem = #False
Global currentItemXOffset.i, currentItemYOffset.i
Global NewList Images.canvasitem()
Global DriveImage = LoadImage(#PB_Any, #PB_Compiler_Home + "Examples\Sources\Data\Drive.bmp")

Procedure AddImage(x,y,img)
  If AddElement(Images())
    Images()\img    = img
    Images()\x      = x
    Images()\y      = y
    Images()\width  = ImageWidth(img)
    Images()\height = ImageHeight(img)
  EndIf
EndProcedure

Procedure DrawCanvas()
  If StartDrawing(CanvasOutput(0))
    Box(0,0,GadgetWidth(0),GadgetHeight(0),RGB(255,255,255))
    ForEach Images()
      DrawImage(ImageID(Images()\img),Images()\x,Images()\y) ; draw all images with z-order
    Next
    With Images()
    If Not Drag
        ;Gadget Outline #Blue
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(\x,            \y,              \Width,    \Height,   #Blue)
        ;Inside Handles #White
        DrawingMode(#PB_2DDrawing_Default)
        Box(\x-3,          \y-3,            6,         6,         #White) 
        Box(\x+\Width-3,   \y-3,            6,         6,         #White)
        Box(\x+\Width-3,   \y+\Height-3,    6,         6,         #White)
        Box(\x-3,          \y+\Height-3,    6,         6,         #White)
        ;Outside Handles #Blue
        DrawingMode(#PB_2DDrawing_Outlined)
        Box(\x-4,          \y-4,            8,         8,         #Blue)
        Box(\x+\Width-4,   \y-4,            8,         8,         #Blue)
        Box(\x+\Width-4,   \y+\Height-4,    8,         8,         #Blue)
        Box(\x-4,          \y+\Height-4,    8,         8,         #Blue)        
;         ;Original Handles Full #Blue
;         DrawingMode(#PB_2DDrawing_Outlined)
;         Box(\x, \y, \Width, \Height, #Blue)
;         DrawingMode(#PB_2DDrawing_Default)
;         Box(\x-4,        \y-4,         8, 8, #Blue)
;         Box(\x+\Width-4, \y-4,         8, 8, #Blue)
;         Box(\x+\Width-4, \y+\Height-4, 8, 8, #Blue)
;         Box(\x-4,        \y+\Height-4, 8, 8, #Blue)
    Else
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box(\x, \y, \Width, \Height, RGBA($42, $42, $42, $50))
        DrawImage(ImageID(\img), \x, \y, \Width, \Height)
    EndIf
    EndWith  
    StopDrawing()
  EndIf
EndProcedure

Procedure HitTest(x,y)
  isCurrentItem = #False
  If LastElement(Images())   ; search for hit, starting from end (z-order)
    Repeat
      If x >= Images()\x And x < Images()\x + Images()\width
        If y >= Images()\y And y < Images()\y + Images()\height
          MoveElement(Images(), #PB_List_Last)
          isCurrentItem = #True
          currentItemXOffset = x - Images()\x
          currentItemYOffset = y - Images()\y
          Break
        EndIf
      EndIf
    Until PreviousElement(Images())=0
  EndIf
  ProcedureReturn isCurrentItem
EndProcedure

Procedure CaptureGadget(Gadget)
  Protected Img,hdc,SizeTextH
  Img = CreateImage(#PB_Any,GadgetWidth(Gadget),GadgetHeight(Gadget))
  If IsGadget(Gadget)
    hdc =  StartDrawing(ImageOutput(Img))
    If hdc
      SendMessage_(GadgetID(Gadget),#WM_PRINT,hDC, #PRF_CHILDREN|#PRF_CLIENT|#PRF_NONCLIENT|#PRF_OWNED|#PRF_ERASEBKGND)
      If GadgetType(Gadget) = 8   ;Specific ComboBoxGadget
        DrawingFont(GetGadgetFont(#PB_Default))
        DrawingMode(#PB_2DDrawing_Transparent)
        SizeTextH = TextHeight("Text")
        DrawText(4, (OutputHeight()-SizeTextH)/2, "Element_1", $000000)
      EndIf     
      If GadgetType(Gadget) = 25   ;Specific ExplorerComboGadget 
        DrawingFont(GetGadgetFont(#PB_Default))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawImage(ImageID(DriveImage), 4, (OutputHeight()-ImageHeight(DriveImage))/2)
        SizeTextH = TextHeight("Text")
        DrawText(8+ImageWidth(DriveImage), (OutputHeight()-SizeTextH)/2, "This PC", $000000)
      EndIf
      StopDrawing()
    EndIf 
  EndIf
  ProcedureReturn Img
EndProcedure 

If OpenWindow(0, 0, 0, 800, 600, "Move/Drag Canvas Image", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CanvasGadget(0, 10, 10, 780, 580,#PB_Canvas_Container)
    ButtonGadget(1,0,0,100,30,"Button") : HideGadget(1,1)
    CalendarGadget(2,0,0,220,160) : HideGadget(2,1)
    ExplorerListGadget(3, 0, 0, 380, 180, "*.*", #PB_Explorer_MultiSelect) : HideGadget(3,1)
    PanelGadget(4,0,0,200,100) : HideGadget(4,1)
      AddGadgetItem(4,-1,"Tab 1")
      TextGadget(40,20,20,120,24, "My Text")
      AddGadgetItem(4,-1,"Tab 2")
    CloseGadgetList()
    ScrollAreaGadget(5,0,0,280,180,400,300) : HideGadget(5,1)
      CheckBoxGadget(50, 20, 20, 120, 24, "CheckBox")
    CloseGadgetList()
    ExplorerComboGadget(6,0,0,120,24, "C:") : HideGadget(6,1)
    ComboBoxGadget(7,0,0,120,24,#PB_ComboBox_Image) :HideGadget(7, 1)
    ContainerGadget(8,0,0,120,24,#PB_Container_BorderLess) : HideGadget(8,1)
      SpinGadget(80,0,0,120,24,0,100,#PB_Spin_Numeric ) : SetGadgetState(80, 66)
    CloseGadgetList()
  CloseGadgetList()
  
  AddImage(180, 40,  CaptureGadget(1))
  AddImage(460, 20,  CaptureGadget(2))
  AddImage( 40, 180, CaptureGadget(3))
  AddImage(460, 220, CaptureGadget(4))
  AddImage(460, 360, CaptureGadget(5))
  AddImage( 80, 400, CaptureGadget(6))
  AddImage(240, 400, CaptureGadget(7))
  AddImage(160, 480, CaptureGadget(8))
  
  DrawCanvas()
 
  Repeat
    Event = WaitWindowEvent()
   
    If Event = #PB_Event_Gadget And EventGadget() = 0
      Select EventType()
        Case #PB_EventType_LeftButtonDown
          x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
          y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
          If HitTest(x,y)
            DrawCanvas()
          EndIf
          Drag = #True
        Case #PB_EventType_LeftButtonUp
          Drag = #False
        Case #PB_EventType_MouseMove
          If Drag = #True
            If isCurrentItem
              x = GetGadgetAttribute(0, #PB_Canvas_MouseX)
              y = GetGadgetAttribute(0, #PB_Canvas_MouseY)
              If LastElement(Images())
                Images()\x = x - currentItemXOffset
                Images()\y = y - currentItemYOffset
                DrawCanvas()
              EndIf
            EndIf
          EndIf
      EndSelect
    EndIf   
   
  Until Event = #PB_Event_CloseWindow
EndIf
Post Reply