Windows GUI

New to FreeBASIC? Post your questions here.
MrSwiss
Posts: 3367
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Windows GUI

Postby MrSwiss » Oct 24, 2016 9:06

@Provoni,

your issue with Len(String) vs. Len(ZString):
probably due to a ZString return, instead of String. You might want to check the effective Len() yourself.

Code: Select all

Function GetStrgLen(ByVal tStrg As String) As Long
    Dim As Long ret = 0
    Dim As UByte tch
   
    Do
        tch = tStrg[ret]
        If tch = &h00 Then Exit Do
        ret += 1
    Loop

    Return ret
End Function

' see different lenght definition below:
Dim As String  * 18 Test = "ABCDabcd1234567890" ' &h00 added automatically
Dim As ZString * 19 ZT   = "ABCDabcd1234567890" ' leave a UByte 'empty' for &h00

Print "String:  "; Test
Print "ZString: "; ZT
print
Print "GetStrgLen(String):  "; GetStrgLen(Test)
Print "GetStrgLen(ZString): "; GetStrgLen(ZT)
Print
Print "Len(String):  "; Len(Test)
Print "Len(ZString): "; Len(ZT)
Print
Print " Now we reset both Variables to 10 '+' then test again."
Test = String(10, "+") : ZT = String(10, "+")
Print "String:  "; Test
Print "ZString: "; ZT
print
Print "GetStrgLen(String):  "; GetStrgLen(Test)
Print "GetStrgLen(ZString): "; GetStrgLen(ZT)
Print
Print "Len(String):  "; Len(Test); "  WRONG!!! The predefined String-Lenght from String-Header!"
Print "Len(ZString): "; Len(ZT)
Print : Print
Print "Press any key to quit! ";

Sleep
[edit] Added code to show possible problem with Len() on fixed size String. [/edit]
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 24, 2016 17:40

Provoni,

regarding the problem with Listbox_GetText, I see that this function returns LTrim(Buffer, Chr(0)), Buffer is the buffer which contains the text. But LTrim seems not to work to eleminate Chr(0). This seems to be a problem in all functions of WinGUI where a text is retrieved from a control. I will correct this in the next relase, thank you for your information.

Regarding your problem with two windows, I do not yet have a proposal, I did not have much time the last two days. I will try to work on it tomorrow.
Josep Roca
Posts: 471
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Windows GUI

Postby Josep Roca » Oct 24, 2016 18:02

> But LTrim seems not to work to eleminate Chr(0).

Indeed. You must use RTrim, because the null is at the end of the string, not at the beginning.
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 25, 2016 7:51

Oops, thank you!
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 25, 2016 9:17

Provoni,

I think this will solve your problem with two windows. I rewrote my code "TwoWindows.bas" and replaced WaitEvent by the message loop proposed by Josep Roca:

Code: Select all

'TwoWindows.bas
'October 25, 2016

#Include "WinGUI.bi"

Dim Shared As HWND Window_Main, Window_Text, Edit_1, Edit_2, Edit_3, Edit_4, Edit_5,   Edit_6, Button_Ok, Button_Exit
Dim Shared As MSG msg


Sub CreateWindow_Main
   'Main window
   
   Window_Main = Window_New (0, 50, 200, 200, "Window 1")
   Edit_1 = EditBox_New     (10, 10, 150, 20, "text...",, Window_Main)
   Edit_2 = EditBox_New     (10, 40, 150, 20, "text...",, Window_Main)
   Edit_3 = EditBox_New     (10, 70, 150, 20, "text...",, Window_Main)
   Button_Ok = Button_New   (10, 100, 150, 20, "Ok",, Window_Main)
   Button_Exit = Button_New (10, 130, 150, 20, "Exit",, Window_Main)     
End Sub


Sub CreateWindow_Text
  'Second window
   
   Window_Text = Window_New   (250, 50, 200, 150, "Window 1")
   Edit_4 = EditBox_New     (10, 10, 150, 20, "text...",, Window_Text)
   Edit_5 = EditBox_New     (10, 40, 150, 20, "text...",, Window_Text)
   Edit_6 = EditBox_New     (10, 70, 150, 20, "text...",, Window_Text)
   
End Sub


'Main:

'Open the two windows:
CreateWindow_Main()
CreateWindow_Text()

Do
   If GetMessage(@msg, 0, 0, 0) <> 0 Then
      If IsDialogMessage(Window_Main, @msg) = 0 And IsDialogMessage(Window_Text, @msg) = 0  Then
         TranslateMessage(@msg)
         DispatchMessage(@msg)
      End If
      If msg.message = WM_LBUTTONDOWN Then
         Select Case msg.hwnd
            Case Button_Ok
               'Code ...
            Case Button_Exit
               End
         End Select
      End If
   End If
Loop Until Window_Event_Close(Window_Main, msg)

End

You see that the message loop is just a slight modification of WaitEvent, but because I do not know how many windows a user will open simultaneously in his program, I do not know how I can modify WaitEvent in order to support the use of the TAB key for a variable number of windows. Maybe it is not necessary, because the code is not complicated.
Josep Roca
Posts: 471
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Windows GUI

Postby Josep Roca » Oct 25, 2016 13:15

The way to work with multiple windows is to have a message loop and a callback function for each window. You need to specify the address of the callback when you create the window.
Provoni
Posts: 347
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Postby Provoni » Oct 25, 2016 14:26

Just great, it works now, thanks allot Joseph Roca, Lothar Schirm and also MrSwiss for all your help so far.
Provoni
Posts: 347
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Postby Provoni » Oct 25, 2016 14:36

Lothar,

Is it possible to have Open file select multiple files with shift and/or ctrl keys. And then have a string returned that contains all the file names the user has selected.
Josep Roca
Posts: 471
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Windows GUI

Postby Josep Roca » Oct 25, 2016 15:18

This requires the use of the OFN_ALLOWMULTISELECT flag, so you need to modify the LoadSaveDialog function or write a new one.
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 25, 2016 15:47

I just wanted to write a simple WinGUI.bi and WinDialogs.bi by means of using code examples and some own study of win32_fb.chm for simple applications. I am not a Windows API expert, in particular, the LoadSaveDialog was not written by me, so I think I would need more help to modify it or to write a new one.

Regarding Josep Roca's explanation "The way to work with multiple windows is to have a message loop and a callback function for each window. You need to specify the address of the callback when you create the window." I think my proposal to Provoni works well and is in line with the simple concept of WinGUI, I would not like to do more. I will add the code example into the next release with some explanation.
RNBW
Posts: 193
Joined: Apr 11, 2015 11:06
Location: UK

Re: Windows GUI

Postby RNBW » Oct 25, 2016 16:48

Lothar Schirm wrote:I just wanted to write a simple WinGUI.bi and WinDialogs.bi by means of using code examples and some own study of win32_fb.chm for simple applications. I am not a Windows API expert, in particular, the LoadSaveDialog was not written by me, so I think I would need more help to modify it or to write a new one.

Regarding Josep Roca's explanation "The way to work with multiple windows is to have a message loop and a callback function for each window. You need to specify the address of the callback when you create the window." I think my proposal to Provoni works well and is in line with the simple concept of WinGUI, I would not like to do more. I will add the code example into the next release with some explanation.

Following Lothar's philosophy of a very simple API based GUI, it is easy to extend to more windows. In the example below, a third window is created (similar to the second window) and then another "AND IsDialogMessage(Window_Text2, @msg) = 0 THEN" is added in the DO..LOOP. See the code below:

Code: Select all

'ThreeWindows.bas
'October 25, 2016

#Include "WinGUI.bi"

DIM SHARED AS HWND Window_Main, Window_Text, Window_Text2, Edit_1, _
            Edit_2, Edit_3, Edit_4, Edit_5, Edit_6, Edit_7, Edit_8, Edit_9, _
            Button_Ok, Button_Exit
DIM SHARED AS MSG msg

' Set up SUBs for three windows with 3 Editboxes
' The Window_Main will also have 2 buttons (for OK and EXIT).
' The program is exited and the windows closed by clicking the EXIT button.

SUB CreateWindow_Main
   'Main window
   
   Window_Main = Window_New (0, 50, 300, 200, "Window 1")
   Edit_1 = EditBox_New     (10, 10, 150, 20, "text...",, Window_Main)
   Edit_2 = EditBox_New     (10, 40, 150, 20, "text...",, Window_Main)
   Edit_3 = EditBox_New     (10, 70, 150, 20, "text...",, Window_Main)
   Button_Ok = Button_New   (10, 100, 150, 20, "Ok",, Window_Main)
   Button_Exit = Button_New (10, 130, 150, 20, "Exit",, Window_Main)     
END SUB


SUB CreateWindow_Text
  'Second window
   
   Window_Text = Window_New   (350, 50, 300, 150, "Window 2")
   Edit_4 = EditBox_New     (10, 10, 150, 20, "text...",, Window_Text)
   Edit_5 = EditBox_New     (10, 40, 150, 20, "text...",, Window_Text)
   Edit_6 = EditBox_New     (10, 70, 150, 20, "text...",, Window_Text)
   
END SUB

SUB CreateWindow_Text2
  'Third window
   
   Window_Text2 = Window_New   (700, 50, 300, 150, "Window 3")
   Edit_7 = EditBox_New     (10, 10, 150, 20, "text...",, Window_Text2)
   Edit_8 = EditBox_New     (10, 40, 150, 20, "text...",, Window_Text2)
   Edit_9 = EditBox_New     (10, 70, 150, 20, "text...",, Window_Text2)
   
END SUB
'Main:

'Open the three windows:
CreateWindow_Main()
CreateWindow_Text()
CreateWindow_Text2()

DO
   IF GetMessage(@msg, 0, 0, 0) <> 0 THEN
      IF IsDialogMessage(Window_Main, @msg) = 0 _
         AND IsDialogMessage(Window_Text, @msg) = 0  _
         AND IsDialogMessage(Window_Text2, @msg) = 0 THEN
         TranslateMessage(@msg)
         DispatchMessage(@msg)
      END IF
      IF msg.message = WM_LBUTTONDOWN THEN
         SELECT CASE msg.hwnd
            CASE Button_Ok
               'Code ...
            CASE Button_Exit
               END
         END SELECT
      END IF
   END IF
LOOP UNTIL Window_Event_Close(Window_Main, msg)

END


There is very little extra code in addition to the creation of another window (which you would have to do anyway). I would think that further windows could be added in a similar manner.
Provoni
Posts: 347
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Postby Provoni » Oct 25, 2016 16:54

Lothar,

I am thankful that you kept it simple as it allows a novice programmer as me to come up with a decent Windows GUI for my program without investing large amounts of time. Your WinGUI provides all the functionality my program needs and I hope to share it near the end of the year.

This the current WinGUI LoadSaveDialog:

Code: Select all

Function LoadSaveDialog(ByVal savedlog As Long = 0, ByVal filter As String = "", _
                                    ByVal fltrindex As Long = 1, ByVal initdir As String = "", _
                                    ByVal strDefExt As String = "") As String
   'Windows dialog to choose the drive/path/file name to open or save a file
   'by Volta
   'http://www.freebasic-portal.de/code-beispiele/dateien-laufwerke/dialog-datei-oeffnen-speichern-24.html

   'Parameters:
   '------------------
   '- savedlog = 0: "Open File", 1(<>0): "Save File"
   '- filter = "": "All Files", otherwise a filter according to example "fil" below
   '- fltrindex = 1, otherwise the index of the desired entry in the filter, beginning from 1
   '  (see example "fil" below)
   '- initdir = "" = ".": Current path, otherwise specified path
   '- strDefExt = "": Default extension (appended to the filename if the user fails
   '  to select an extension)
   
   'Example for a filter:
   '---------------------
   'Dim As String fil
   'fil = "Basic Files (*.bas)" + Chr(0) + "*.bas" + Chr(0) _
  '  + "Text Files (*.txt)" + Chr(0) + "*.txt" + Chr(0)_
  '  + "Image Files (*.bmp)" + Chr(0) + "*.bmp" + Chr(0)_
  '  + "Executable Files (*.exe)" + Chr(0) + "*.exe" + Chr(0)_
  '  + "All Files (*.*)" + Chr(0) + "*.*" + Chr(0, 0)
 
  'Examples:
  '---------
 
  'Dim As String FileName
 
   'Open a file without filter (easiest method):
   'FileName = LoadSaveDialog
   
   'Open a file with filter:
   'FileNameName = LoadSaveDialog (,fil)
   
   'Open a file with filter, index 2 (TXT):
   'FileName = LoadSaveDialog (,fil,2)
   
   'Open a file in path "c:\":
   'FileName = LoadSaveDialog (,,,"c:\")
   
   'Save a file:
   'DateiName = LoadSaveDialog (1)
   
   'Save a file with default extension "bak" if no extension has been defined:
   'FileName = LoadSaveDialog (1,,,,"bak")
   
   Dim FB_OFN AS OPENFILENAME
   FB_OFN.lStructSize = Len(FB_OFN)
   FB_OFN.hwndOwner = 0
   FB_OFN.hInstance = 0

   Dim strFilter As String
   If filter = "" Then
      strFilter = "All Files (*.*)" + Chr(0) +"*.*" + Chr(0, 0) 'default
   Else
      strFilter = filter + Chr(0, 0)
   End If
   FB_OFN.lpstrFilter = StrPtr(strFilter)
   FB_OFN.nFilterIndex = fltrindex

   Dim strFile As String *2048
   strFile = Space(2047) + Chr(0)
   FB_OFN.lpstrFile = StrPtr(strFile)
   FB_OFN.nMaxFile = Len(strFile)

   Dim strFileTitle As String *2048
   strFileTitle = String(2048, 0)
   FB_OFN.lpstrFileTitle = StrPtr(strFileTitle)
   FB_OFN.nMaxFileTitle = Len(strFileTitle)

   Dim strdrstr As String
   If initdir = "" Then
      strdrstr = "."     'actual path
   Else
      strdrstr = initdir
   End If
   FB_OFN.lpstrInitialDir = StrPtr(strdrstr)

   Dim strcapt As String
   If savedlog Then
      strcapt = "Save File"
      FB_OFN.lpstrTitle = StrPtr(strcapt)
      If strDefExt > "" Then
         Dim strdext As String
         strdext = strDefExt
         FB_OFN.lpstrDefExt = StrPtr(strdext)
      End If
      FB_OFN.flags = OFN_EXPLORER Or OFN_LONGNAMES Or OFN_OVERWRITEPROMPT Or OFN_HIDEREADONLY
      If GetSaveFileName(@FB_OFN) Then LoadSaveDialog = Trim(strFile)
   Else
      strcapt = "Open File"
      FB_OFN.lpstrTitle = StrPtr(strcapt)
      FB_OFN.flags = OFN_EXPLORER Or OFN_LONGNAMES Or OFN_CREATEPROMPT Or _
                     OFN_NODEREFERENCELINKS Or OFN_HIDEREADONLY
      If GetOpenFileName(@FB_OFN) Then LoadSaveDialog = Trim(strFile)
   End If
End Function
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 27, 2016 14:27

Thank you! So I will correct the small bug in ListBox_GetText and other functions where Chr(0) is not eliminated correctly and add the example with three windows, and then I regard the project to be closed (and error-free, I hope). Thanks to all of you for your contributions!

If somebody needs more functions, I can recommend Joshy's FLTK-C - easy to use, crossplatform, supports UTF, simple diagrams, graphics, displays images in various formats (bmp. jpg etc.) ...
Lothar Schirm
Posts: 333
Joined: Sep 28, 2013 15:08
Location: Bavaria, Germany

Re: Windows GUI

Postby Lothar Schirm » Oct 27, 2016 16:39

WinGUI is updated, see project site!
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Windows GUI

Postby MichaelW » Oct 29, 2016 3:14

A single window procedure can be used for multiple windows, but unless the windows have similar features and functionality, doing so will probably be more or less impractical.

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 1 guest