Simple template with menu, edit control, listbox and statusbar

Windows specific questions.
Post Reply
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

This is a basic (pun intended) 99-lines template to be used for Windows GUI applications:

Code: Select all

#Include "windows.bi"	' JJ 28.9.2020 - a WinGUI template in less than 100 lines
#Include "win\commctrl.bi"	' for CreateStatusWindow
Dim Shared as Handle hEdit, hList, hStatus	' bat@TinyFB.bat (for use with TinyIDE)
Function WndProc(hWnd As HWND, msg As  UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  Dim As RECT rc
  Dim As PAINTSTRUCT ps
  Dim As HANDLE PtDC
  Dim As HMENU hMenu, hPopup, hPop2
  Select Case msg
  Case WM_CREATE
	hMenu=CreateMenu()					' create the main menu
	hPopup=CreatePopupMenu()					' create a sub-menu
	AppendMenu(hMenu, MF_POPUP, hPopup, "&File")		' add it to the main menu
	AppendMenu(hPopup, MF_STRING, 101, "&Open") 		' one more main item
	hPop2=CreatePopupMenu()					' create a sub-menu
	AppendMenu(hPop2, MF_STRING, 121, "&sources")		' fill it
	AppendMenu(hPop2, MF_STRING, 122, "&includes")		' with various
	AppendMenu(hPop2, MF_STRING, 123, "&DLLs")		' options
	AppendMenu(hPopup, MF_POPUP, hPop2, "&Dir")		' and add it to the main menu as "Dir"
	AppendMenu(hPopup, MF_STRING, 102, "&Save") 		' one more main item
	AppendMenu(hPopup, MF_STRING, 103, "E&xit") 		' one more main item
	SetMenu(hWnd, hMenu)					' attach menu to main window
	hStatus=CreateStatusWindow(WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or SBS_SIZEGRIP, 0, hWnd, 99)
	SendMessage(hStatus, WM_SETTEXT, 0, @"This is the status bar")
	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I am an edit control",_
	WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 0, 0, 100, 100, hWnd, 101, 0, 0)
	hList=CreateWindowEx(WS_EX_CLIENTEDGE, "listbox", 0,_
	WS_CHILD Or WS_VISIBLE, 0, 0, 100, 100, hWnd, 100, 0, 0)
	SendMessage(hList, LB_ADDSTRING, 0, @"line 1")
	If Open(Command(1) For Binary Access Read As #1) = 0 Then
		Dim As UByte file_char ( LOF(1))
		Get #1, , file_char()
		Close #1
		SendMessage(hEdit, WM_SETTEXT, 0, @file_char(0))
	endif
  Case WM_COMMAND
	Select Case wParam
 		Case 101: MessageBox(hWnd, "Open not implemented", 0, MB_OK)
 		Case 102: MessageBox(hWnd, "Save not implemented", 0, MB_OK)
 		Case 121: MessageBox(hWnd, "No *.bas files found", 0, MB_OK)
 		Case 122: MessageBox(hWnd, "No *.inc files found", 0, MB_OK)
 		Case 123: MessageBox(hWnd, "No *.dll files found", 0, MB_OK)
 		Case 103: SendMessage(hWnd, WM_CLOSE, 0, 0)
	End Select
  Case WM_PAINT
	PtDC=BeginPaint(hWnd, @ps)
	SetBkMode(PtDC, TRANSPARENT)
	TextOut(PtDC, 4, 4, "Greetings from the WM_PAINT handler", 35)
	EndPaint(hWnd, @ps)
  Case WM_KEYDOWN
  	if wParam=VK_ESCAPE then SendMessage(hWnd, WM_CLOSE, 0, 0)
  Case WM_SIZE
	GetClientRect(hWnd, @rc)
	MoveWindow(hEdit, 3, 28, rc.right-66, rc.bottom-50, 0)
	MoveWindow(hList, rc.right-60, 28, rc.right-6, rc.bottom-50, 0)
  Case WM_DESTROY
      PostQuitMessage(0)
  End Select
  return DefWindowProc(hwnd, msg, wParam, lParam)
End Function
type pCall as function (xy as any ptr) as long
type DLLVERSIONINFO
	cbSize as long
	dwMajorVersion as long
	dwMinorVersion as long
	dwBuildNumber as long
	dwPlatformID as long
end type
Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
  Dim wc As WNDCLASSEX, msg As MSG, hDll As HANDLE, hIconLib As HANDLE, pGetVersion as pCall, dvi As DLLVERSIONINFO
  dvi.cbSize=sizeof(DLLVERSIONINFO)
  hIconLib=LoadLibrary("shell32")
  wc.hIcon = LoadIcon(hIconLib, 239)	' get the butterfly icon
  FreeLibrary(hIconLib)
  hDll=LoadLibrary("ComCtl32")
  pGetVersion=GetProcAddress(hDll, "DllGetVersion")
  pGetVersion(@dvi)
  if @dvi.dwMajorVersion then print "Using common controls version ";str(dvi.dwMajorVersion);".";str(dvi.dwMinorVersion)
  FreeLibrary(hDll)
  wc.cbSize = sizeof(WNDCLASSEX)
  wc.hbrBackground = COLOR_BTNFACE+1
  wc.hCursor = LoadCursor(0, IDC_ARROW)
  wc.hIconSm = wc.hIcon
  wc.hInstance = hInstance
  wc.lpfnWndProc = @WndProc
  wc.lpszClassName = @"FbGui"
  wc.style = CS_HREDRAW Or CS_VREDRAW
  RegisterClassEx(@wc)
  if CreateWindowEx(0, wc.lpszClassName, "Hello World",_
	WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
	(GetSystemMetrics(SM_CYSCREEN) / 2) - 150, 300, 300, 0, 0, hInstance, 0)=0 then
		    MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
		    return 0
  End If
  While GetMessage(@msg, 0, 0, 0)
      TranslateMessage(@msg)
      DispatchMessage(@msg)
  Wend
  return msg.wParam
End Function
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
It will produce plenty of warnings, which you can ignore completely (please, do ignore them - they are silly and absolutely useless):

Code: Select all

(13) warning 2(1): Passing pointer to scalar, at parameter 3 of APPENDMENU()
(19) warning 2(1): Passing pointer to scalar, at parameter 3 of APPENDMENU()
(24) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(26) warning 1(1): Passing scalar as pointer, at parameter 10 of CREATEWINDOWEX()
(28) warning 1(1): Passing scalar as pointer, at parameter 10 of CREATEWINDOWEX()
(29) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(34) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(73) warning 1(1): Passing scalar as pointer, at parameter 2 of LOADICON()
(76) warning 4(1): Suspicious pointer assignment
(81) warning 4(1): Suspicious pointer assignment
Regarding the warnings, there are attempts to eliminate the useless ones (all 10 warnings above are in this category); see this thread.

FreeBasic has a somewhat flexible approach to passing string pointers to Windows APIs (use trial and error to find out what works, or open a new thread to ask expert forum members what is the correct way of passing strings):

Code: Select all

	SendMessage(hStatus, WM_SETTEXT, 0, @"This is the status bar")  ' works; the @ means: pass a pointer
	SendMessage(hStatus, WM_SETTEXT, 0, "This is the status bar")   ' throws an error

	SetWindowText(hStatus, @"This is my status bar")  ' works fine
	SetWindowText(hStatus, "This is my status bar")   ' works fine

	SetWindowText(hEdit, @file_char(0))  ' works fine
	SetWindowText(hEdit, file_char(0))   ' throws an error

	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", @"Hello, I'm an edit control",...  ' works fine
	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I'm an edit control",...   ' works fine
	
	SendMessage(hEdit, WM_SETTEXT, 0, @file_char(0)) 		 ' works fine
	SendMessage(hEdit, WM_SETTEXT, 0, file_char(0))  		 ' works fine
	
	MessageBox(hWnd, @"Open not implemented", 0, MB_OK) 		' works fine
	MessageBox(hWnd, "Open not implemented", 0, MB_OK) 		 ' works fine
P.S.: If you can't yet decide which IDE to use, have a look at TinyIDE for FreeBasic
Last edited by jj2007 on Sep 28, 2020 15:20, edited 8 times in total.
Xusinboy Bekchanov
Posts: 783
Joined: Jul 26, 2018 18:28

Re: Simple template with menu, edit control, listbox and statusbar

Post by Xusinboy Bekchanov »

jj2007 wrote:Just in case, if it produces this error:

Code: Select all

(2) error 23: File not found, "inc\win\commctrl.bi" in '#Include "inc\win\commctrl.bi"	' for CreateStatusWindow'
... it means that you started the compilation from a folder different from your main FreeBasic folder (i.e. the one where fbc.exe resides). FreeBasic does find windows.bi even if you start the compilation from, say, ...\FreeBasic\MyProjects\SimpleGui, but it does not find anything below the FreeBasic\inc folder. So either compile from the main folder (..\FreeBasic), or adjust the include path.

Another good option is to choose a folder one level below the fbc.exe folder, e.g. ..\FreeBasic\MySources, and then use #Include "..\inc\win\commctrl.bi". The ..\inc means "go one folder up, from there take the inc subfolder".
In my opinion, "inc\" is not needed here.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

Xusinboy Bekchanov wrote:In my opinion, "inc\" is not needed here.
I absolutely share your opinion! Unfortunately, fbc.exe has a different opinion. Back in the 20th century, people used the PATH "environment variable" - that might be another option. However, with that old crap it will be difficult to exchange snippets here in the forum, unless you specify exactly which PATH is required to build them. But, as you know, everybody here has a different setup, so the PATH of member A will not fit the requirements of member B...
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Simple template with menu, edit control, listbox and statusbar

Post by dodicat »

No need for inc at all.
I think your fbc is on path jj2007?
Never mind, you don't need fbc on path unless your ide requires it.
Some ides ask you to point to fbc.exe when you start it, or have a path option somewhere.
This of course sets your path.
The ide simply sets the command line up properly to get fbc and get your file to compile and marries the two commands.
for instance from fbide:
Command executed:
"C:\Users\Computer\Desktop\fb\FreeBASIC-1.07.1-win32\FreeBASIC-1.07.1-win32\fbc.exe" -exx "C:\Users\Computer\Desktop\fb\code\allbas\FBIDETEMP.bas"
(As you see no mention of a .bi path, it is automated)
fbc finds the path to the all .bi file in the distro.
if it in the win folder then
#Include "win\commctrl.bi".

You seem to be continually have these problems jj2007.
Why don't you try a simple ide like fbide or fbedit?
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

dodicat wrote:Why don't you try a simple ide like fbide or fbedit?
Why do you assume that I invent these errors? This is FbEdit:

Code: Select all

J:\AllBasics\FreeBasic\fbc -s console "TmpFb.bas"
TmpFb.bas(2) error 23: File not found, "commctrl.bi" in '#Include "commctrl.bi"	' for CreateStatusWindow'

Build error(s)
Same with J:\AllBasics\FreeBasic\WinFBE_Suite\WinFBE32.exe and VonGodric's FBIde 0.4.6
And with all three IDEs it builds fine when I use #Include "..\inc\Win\commctrl.bi"
fxm
Moderator
Posts: 12083
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: Simple template with menu, edit control, listbox and statusbar

Post by fxm »

For my fbc build:
#Include "win\commctrl.bi"
works, an not:
#Include "commctrl.bi"
neither:
#Include "inc\win\commctrl.bi"

Which seems normal because '...\inc\' is the default path for files to include, and 'commctrl.bi' is in the 'win\' sub-directory of '...\inc\'.
Last edited by fxm on Sep 28, 2020 13:23, edited 1 time in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Simple template with menu, edit control, listbox and statusbar

Post by Josep Roca »

I use WinFBE and it compiles using
#Include "win\commctrl.bi" ' for CreateStatusWindow
and it does not compile using
#Include "inc\win\commctrl.bi" ' for CreateStatusWindow

So maybe your setup is wrong.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

So it has to be exactly Win\some.bi to work. Wow. See my proposal Simplify includes (remember this language is called FreeBasic, the "B" stands for "Beginners").

From the manual:

Code: Select all

#include Preprocessor statement to include contents of another source file


Syntax

#include [once] "file"


Description

#include inserts source code from another file at the point where the #include directive appears. This has the effect of compiling the source code from the include file as though it were part of the source file that includes it. Once the compiler has reached the end of the include file, the original source file continues to be compiled.

This is useful to remove code from a file and separate it into more files. It is useful to have a single file with declarations in a program formed by several modules. You may include files within an include file, although avoid including the original file into itself, this will not produce valid results. Typically, include files will have an extension of .bi and are mainly used for declaring subs/functions/variables of a library, but any valid source code may be present in an include file.

The once specifier tells the compiler to include the file only once even if it is included several times by the source code.

$Include is an alternative form of include, existing only for compatibility with QuickBASIC. It is recommended to use #include instead.

The compiler will automatically convert path separator characters ( '/' and '\' ) as needed to properly load the file. The filename name may be an absolute or relative path. 

For relative paths, or where no path is given at all, the include file is search for in the following order:

Relative from the directory of the source file

Relative from the current working directory

Relative from addition directories specified with the -i command line option

The include folder of the FreeBASIC installation (FreeBASIC\inc, where FreeBASIC is the folder where the fbc executable is located)
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

Josep Roca wrote:I use WinFBE and it compiles using
#Include "win\commctrl.bi" ' for CreateStatusWindow
and it does not compile using
#Include "inc\win\commctrl.bi" ' for CreateStatusWindow

So maybe your setup is wrong.
Certainly - a typical n00b error! It's really crystal clear (FreeBasic manual, #include):
For relative paths, or where no path is given at all, the include file is search for in the following order:

Relative from the directory of the source file

Relative from the current working directory

Relative from addition directories specified with the -i command line option

The include folder of the FreeBASIC installation (FreeBASIC\inc, where FreeBASIC is the folder where the fbc executable is located)
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Simple template with menu, edit control, listbox and statusbar

Post by dodicat »

Win\some.bi only if your .bi is in the win folder.
Some .bi files are direct e.g. fbgfx.bi, some are in the other folders.
You sometimes have to browse these other folders to get what you want to include and
#include "someotherfolder/mybi.bi"
FreeBASIC is so easy to use these includes, in C or Pascal you must set paths in an ide for includes.

What is wrong with your setup if you must use inc/ ??
Something is definitely amiss!
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Simple template with menu, edit control, listbox and statusbar

Post by UEZ »

jj2007 wrote:This is a basic (pun intended) 99-lines template to be used for Windows GUI applications:

Code: Select all

#Include "windows.bi"	' JJ 28.9.2020 - a WinGUI template in less than 100 lines
#Include "win\commctrl.bi"	' for CreateStatusWindow
Dim Shared as Handle hEdit, hList, hStatus	' bat@TinyFB.bat (for use with TinyIDE)
Function WndProc(hWnd As HWND, msg As  UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
  Dim As RECT rc
  Dim As PAINTSTRUCT ps
  Dim As HANDLE PtDC
  Dim As HMENU hMenu, hPopup, hPop2
  Select Case msg
  Case WM_CREATE
	hMenu=CreateMenu()					' create the main menu
	hPopup=CreatePopupMenu()					' create a sub-menu
	AppendMenu(hMenu, MF_POPUP, hPopup, "&File")		' add it to the main menu
	AppendMenu(hPopup, MF_STRING, 101, "&Open") 		' one more main item
	hPop2=CreatePopupMenu()					' create a sub-menu
	AppendMenu(hPop2, MF_STRING, 121, "&sources")		' fill it
	AppendMenu(hPop2, MF_STRING, 122, "&includes")		' with various
	AppendMenu(hPop2, MF_STRING, 123, "&DLLs")		' options
	AppendMenu(hPopup, MF_POPUP, hPop2, "&Dir")		' and add it to the main menu as "Dir"
	AppendMenu(hPopup, MF_STRING, 102, "&Save") 		' one more main item
	AppendMenu(hPopup, MF_STRING, 103, "E&xit") 		' one more main item
	SetMenu(hWnd, hMenu)					' attach menu to main window
	hStatus=CreateStatusWindow(WS_CHILD or WS_VISIBLE or WS_CLIPSIBLINGS or SBS_SIZEGRIP, 0, hWnd, 99)
	SendMessage(hStatus, WM_SETTEXT, 0, @"This is the status bar")
	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I am an edit control",_
	WS_CHILD Or WS_VISIBLE or ES_MULTILINE, 0, 0, 100, 100, hWnd, 101, 0, 0)
	hList=CreateWindowEx(WS_EX_CLIENTEDGE, "listbox", 0,_
	WS_CHILD Or WS_VISIBLE, 0, 0, 100, 100, hWnd, 100, 0, 0)
	SendMessage(hList, LB_ADDSTRING, 0, @"line 1")
	If Open(Command(1) For Binary Access Read As #1) = 0 Then
		Dim As UByte file_char ( LOF(1))
		Get #1, , file_char()
		Close #1
		SendMessage(hEdit, WM_SETTEXT, 0, @file_char(0))
	endif
  Case WM_COMMAND
	Select Case wParam
 		Case 101: MessageBox(hWnd, "Open not implemented", 0, MB_OK)
 		Case 102: MessageBox(hWnd, "Save not implemented", 0, MB_OK)
 		Case 121: MessageBox(hWnd, "No *.bas files found", 0, MB_OK)
 		Case 122: MessageBox(hWnd, "No *.inc files found", 0, MB_OK)
 		Case 123: MessageBox(hWnd, "No *.dll files found", 0, MB_OK)
 		Case 103: SendMessage(hWnd, WM_CLOSE, 0, 0)
	End Select
  Case WM_PAINT
	PtDC=BeginPaint(hWnd, @ps)
	SetBkMode(PtDC, TRANSPARENT)
	TextOut(PtDC, 4, 4, "Greetings from the WM_PAINT handler", 35)
	EndPaint(hWnd, @ps)
  Case WM_KEYDOWN
  	if wParam=VK_ESCAPE then SendMessage(hWnd, WM_CLOSE, 0, 0)
  Case WM_SIZE
	GetClientRect(hWnd, @rc)
	MoveWindow(hEdit, 3, 28, rc.right-66, rc.bottom-50, 0)
	MoveWindow(hList, rc.right-60, 28, rc.right-6, rc.bottom-50, 0)
  Case WM_DESTROY
      PostQuitMessage(0)
  End Select
  return DefWindowProc(hwnd, msg, wParam, lParam)
End Function
type pCall as function (xy as any ptr) as long
type DLLVERSIONINFO
	cbSize as long
	dwMajorVersion as long
	dwMinorVersion as long
	dwBuildNumber as long
	dwPlatformID as long
end type
Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
  Dim wc As WNDCLASSEX, msg As MSG, hDll As HANDLE, hIconLib As HANDLE, pGetVersion as pCall, dvi As DLLVERSIONINFO
  dvi.cbSize=sizeof(DLLVERSIONINFO)
  hIconLib=LoadLibrary("shell32")
  wc.hIcon = LoadIcon(hIconLib, 239)	' get the butterfly icon
  FreeLibrary(hIconLib)
  hDll=LoadLibrary("ComCtl32")
  pGetVersion=GetProcAddress(hDll, "DllGetVersion")
  pGetVersion(@dvi)
  if @dvi.dwMajorVersion then print "Using common controls version ";str(dvi.dwMajorVersion);".";str(dvi.dwMinorVersion)
  FreeLibrary(hDll)
  wc.cbSize = sizeof(WNDCLASSEX)
  wc.hbrBackground = COLOR_BTNFACE+1
  wc.hCursor = LoadCursor(0, IDC_ARROW)
  wc.hIconSm = wc.hIcon
  wc.hInstance = hInstance
  wc.lpfnWndProc = @WndProc
  wc.lpszClassName = @"FbGui"
  wc.style = CS_HREDRAW Or CS_VREDRAW
  RegisterClassEx(@wc)
  if CreateWindowEx(0, wc.lpszClassName, "Hello World",_
	WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
	(GetSystemMetrics(SM_CYSCREEN) / 2) - 150, 300, 300, 0, 0, hInstance, 0)=0 then
		    MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
		    return 0
  End If
  While GetMessage(@msg, 0, 0, 0)
      TranslateMessage(@msg)
      DispatchMessage(@msg)
  Wend
  return msg.wParam
End Function
WinMain(GetModuleHandle(NULL), NULL, COMMAND(), SW_NORMAL)
It will produce plenty of warnings, which you can ignore completely:

Code: Select all

(13) warning 2(1): Passing pointer to scalar, at parameter 3 of APPENDMENU()
(19) warning 2(1): Passing pointer to scalar, at parameter 3 of APPENDMENU()
(24) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(26) warning 1(1): Passing scalar as pointer, at parameter 10 of CREATEWINDOWEX()
(28) warning 1(1): Passing scalar as pointer, at parameter 10 of CREATEWINDOWEX()
(29) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(34) warning 2(1): Passing pointer to scalar, at parameter 4 of SENDMESSAGE()
(73) warning 1(1): Passing scalar as pointer, at parameter 2 of LOADICON()
(76) warning 4(1): Suspicious pointer assignment
(81) warning 4(1): Suspicious pointer assignment
Regarding the warnings, there are attempts to eliminate the useless ones (all 10 warnings above are in this category); see this thread.

FreeBasic has a somewhat flexible approach to passing string pointers to Windows APIs (use trial and error to find out what works, or open a new thread to ask expert forum members what is the correct way of passing strings):

Code: Select all

	SendMessage(hStatus, WM_SETTEXT, 0, @"This is the status bar")  ' works; the @ means: pass a pointer
	SendMessage(hStatus, WM_SETTEXT, 0, "This is the status bar")   ' throws an error

	SetWindowText(hStatus, @"This is my status bar")  ' works fine
	SetWindowText(hStatus, "This is my status bar")   ' works fine

	SetWindowText(hEdit, @file_char(0))  ' works fine
	SetWindowText(hEdit, file_char(0))   ' throws an error

	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", @"Hello, I'm an edit control",...  ' works fine
	hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I'm an edit control",...   ' works fine
	
	SendMessage(hEdit, WM_SETTEXT, 0, @file_char(0)) 		 ' works fine
	SendMessage(hEdit, WM_SETTEXT, 0, file_char(0))  		 ' works fine
	
	MessageBox(hWnd, @"Open not implemented", 0, MB_OK) 		' works fine
	MessageBox(hWnd, "Open not implemented", 0, MB_OK) 		 ' works fine
P.S.: If you can't yet decide which IDE to use, have a look at TinyIDE for FreeBasic
Without warnings:

Code: Select all

#include "windows.bi"   ' JJ 28.9.2020 - a WinGUI template in less than 100 lines
#include "win\commctrl.bi"   ' for CreateStatusWindow
Dim Shared As Handle hEdit, hList, hStatus   ' bat@TinyFB.bat (for use with TinyIDE)
Function WndProc(hWnd As HWND, msg As  UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
	Dim As RECT rc
	Dim As PAINTSTRUCT ps
	Dim As HANDLE PtDC
	Dim As HMENU hMenu, hPopup, hPop2
	Select Case msg
	Case WM_CREATE
		hMenu=CreateMenu()               ' create the main menu
		hPopup=CreatePopupMenu()               ' create a sub-menu
		AppendMenu(hMenu, MF_POPUP, Cast(UINT_PTR, hPopup), "&File")      ' add it to the main menu
		AppendMenu(hPopup, MF_STRING, 101, "&Open")       ' one more main item
		hPop2=CreatePopupMenu()               ' create a sub-menu
		AppendMenu(hPop2, MF_STRING, 121, "&sources")      ' fill it
		AppendMenu(hPop2, MF_STRING, 122, "&includes")      ' with various
		AppendMenu(hPop2, MF_STRING, 123, "&DLLs")      ' options
		AppendMenu(hPopup, MF_POPUP, Cast(UINT_PTR, hPop2), "&Dir")      ' and add it to the main menu as "Dir"
		AppendMenu(hPopup, MF_STRING, 102, "&Save")       ' one more main item
		AppendMenu(hPopup, MF_STRING, 103, "E&xit")       ' one more main item
		SetMenu(hWnd, hMenu)               ' attach menu to main window
		hStatus=CreateStatusWindow(WS_CHILD Or WS_VISIBLE Or WS_CLIPSIBLINGS Or SBS_SIZEGRIP, 0, hWnd, 99)
		SendMessage(hStatus, WM_SETTEXT, 0, Cast(lParam, @"This is the status bar"))
		hEdit=CreateWindowEx(WS_EX_CLIENTEDGE, "edit", "Hello, I am an edit control", WS_CHILD Or WS_VISIBLE Or ES_MULTILINE, 0, 0, 100, 100, hWnd, hMenu, 0, 0)
		hList=CreateWindowEx(WS_EX_CLIENTEDGE, "listbox", 0, WS_CHILD Or WS_VISIBLE, 0, 0, 100, 100, hWnd, hMenu, 0, 0)
		SendMessage(hList, LB_ADDSTRING, 0, Cast(lParam, @"line 1"))
		If Open(Command(1) For Binary Access Read As #1) = 0 Then
			Dim As UByte file_char ( LOF(1))
			Get #1, , file_char()
			Close #1
			SendMessage(hEdit, WM_SETTEXT, 0, Cast(lParam, @file_char(0)))
		endif
	Case WM_COMMAND
		Select Case wParam
		Case 101: MessageBox(hWnd, "Open not implemented", 0, MB_OK)
		Case 102: MessageBox(hWnd, "Save not implemented", 0, MB_OK)
		Case 121: MessageBox(hWnd, "No *.bas files found", 0, MB_OK)
		Case 122: MessageBox(hWnd, "No *.inc files found", 0, MB_OK)
		Case 123: MessageBox(hWnd, "No *.dll files found", 0, MB_OK)
		Case 103: SendMessage(hWnd, WM_CLOSE, 0, 0)
		End Select
	Case WM_PAINT
		PtDC=BeginPaint(hWnd, @ps)
		SetBkMode(PtDC, TRANSPARENT)
		TextOut(PtDC, 4, 4, "Greetings from the WM_PAINT handler", 35)
		EndPaint(hWnd, @ps)
	Case WM_KEYDOWN
		if wParam=VK_ESCAPE then SendMessage(hWnd, WM_CLOSE, 0, 0)
	Case WM_SIZE
		GetClientRect(hWnd, @rc)
		MoveWindow(hEdit, 3, 28, rc.right-66, rc.bottom-50, 0)
		MoveWindow(hList, rc.right-60, 28, rc.right-6, rc.bottom-50, 0)
	Case WM_DESTROY
		PostQuitMessage(0)
	End Select
	return DefWindowProc(hwnd, msg, wParam, lParam)
End Function
type pCall as function (xy as any ptr) as long
type DLLVERSIONINFO
	cbSize as long
	dwMajorVersion as long
	dwMinorVersion as long
	dwBuildNumber as long
	dwPlatformID as long
end type
Function WinMain(hInstance As HINSTANCE, hPrevInstance As HINSTANCE, lpCmdLine As LPSTR, nShowCmd As Integer) As Integer
	Dim wc As WNDCLASSEX, msg As MSG, hDll As HANDLE, hIconLib As HANDLE, pGetVersion as pCall, dvi As DLLVERSIONINFO
	dvi.cbSize=sizeof(DLLVERSIONINFO)
	hIconLib=LoadLibrary("shell32")
	wc.hIcon = LoadIcon(hIconLib, Cast(LPCTSTR, 239))   ' get the butterfly icon
	FreeLibrary(hIconLib)
	hDll=LoadLibrary("ComCtl32")
	pGetVersion=Cast(Any Ptr, GetProcAddress(hDll, "DllGetVersion"))
	pGetVersion(@dvi)
	If @dvi.dwMajorVersion Then Print "Using common controls version ";Str(dvi.dwMajorVersion);".";Str(dvi.dwMinorVersion)
	FreeLibrary(hDll)
	wc.cbSize = SizeOf(WNDCLASSEX)
	wc.hbrBackground = GetStockObject(COLOR_BTNFACE+1)
	wc.hCursor = LoadCursor(0, IDC_ARROW)
	wc.hIconSm = wc.hIcon
	wc.hInstance = hInstance
	wc.lpfnWndProc = @WndProc
	wc.lpszClassName = @"FbGui"
	wc.style = CS_HREDRAW Or CS_VREDRAW
	RegisterClassEx(@wc)
	If CreateWindowEx(0, wc.lpszClassName, "Hello World",_
		WS_OVERLAPPEDWINDOW Or WS_VISIBLE, (GetSystemMetrics(SM_CXSCREEN) / 2) - 150,_
		(GetSystemMetrics(SM_CYSCREEN) / 2) - 150, 300, 300, 0, 0, hInstance, 0)=0 Then
		MessageBox(0, "Creating hMain failed miserably", 0, MB_OK)
		Return 0
	End If
	While GetMessage(@msg, 0, 0, 0)
		TranslateMessage(@msg)
		DispatchMessage(@msg)
	Wend
	Return msg.wParam
End Function
WinMain(GetModuleHandle(NULL), NULL, Command(), SW_NORMAL)
;-)
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Simple template with menu, edit control, listbox and statusbar

Post by jj2007 »

UEZ wrote:Without warnings:
Your version will encourage n00bs to copy & paste to get rid of the warnings, without understanding the purpose of the casts. Is that what we want?
jj2007 wrote:We had that discussion two years ago:
jj2007 wrote:If 10% of your lines in a simple (and correctly working) Windows GUI program get criticised with warnings, then there is definitely a problem to solve.
The point is that certain Windows calls, in particular SendMessage, are not compatible with the way the compiler works. SendMessage wants integers, singles, pointers, handles - the compiler believes it needs exclusively a WPARAM and an LPARAM. The result is absolutely useless warnings.

And no, the n00b does not benefit from these warnings, the n00b gets scared away of FB because of them!

The expert who writes 1000 lines programs gets drowned in an endless flow of warnings and will therefore not see the one warning that really makes trouble. I have a source with 300 SendMessage calls. And don't tell me that casting integers, singles, pointers, handles to WPARAM is a "solution"...
Post Reply