Windows GUI

New to FreeBASIC? Post your questions here.
Post Reply
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Windows GUI

Post by SARG »

Provoni wrote:Thanks SARG
You're welcome. By the way I'm just near the frontier, close Lille/Ryssel.
Provoni wrote:It works but a windows sound is heard when using the CTRL-A shortcut, like the command is not supported. This sound is also heard without your added code and with other CTRL shortcuts which have no function. Anything to do about that?
Maybe the default handle, so needed to bypass it. I'll have to check.
SARG
Posts: 1763
Joined: May 27, 2005 7:15
Location: FRANCE

Re: Windows GUI

Post by SARG »

Hi,

Unless If I mistaken, seen the way WInGui is working there is no possibility.
However you can disable the warning beep by using the sound control panel application.
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Post by Provoni »

Thanks SARG for looking into it. We are seperated by about 123 km of distance.
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Post by Provoni »

Hey all,

My program needs to color the background/text of an edit control after some original value has been altered by the user so that the user can easily see which edit control has been altered. Basically need to be able set the color of an edit control at any given point in time.

Here is an example, a grid of edit controls using Lothar's Simple GUI library:

Code: Select all

'==============================================================================
' Datagrid.bas
' Editable grid of Editboxes
' Created on July 11, 2016
' Latest change on October 18, 2016
'==============================================================================

#Include "WinGUI.bi"

Dim As HWND Window_Main, Edit_Data(20, 10), Button_GetData
Dim As MSG msg
Dim As Integer i, j,k

'Create the window with a data grid:
Window_Main = Window_New(100, 100, 500, 500, "Editable Datagrid")
For i = 0 To 20
	For j = 0 To 10
		k+=1
		Edit_Data(i, j) = EditBox_New(j * 40, i * 20, 40, 20, "abc",ES_CENTER, Window_Main)
		EditBox_SetText(Edit_Data(i, j),str(k))
	Next
Next
'Button_GetData = Button_New(350, 430, 100, 20, "GetData",, Window_Main)

'Main:
Do
	WaitEvent(Window_Main, msg)
	If msg.message = WM_LBUTTONDOWN And msg.hwnd = Button_GetData Then
		'Get data from the data grid and display them on the console:
		For i = 0 To 20
			For j = 0 To 10
				Print EditBox_GetText(Edit_Data(i, j))
			Next
		Next
	End If
Loop Until Window_Event_Close(Window_Main, msg)

End
I have found some interesting links but don't understand how to apply it to my program:

viewtopic.php?t=20703
http://www.equestionanswers.com/vcpp/ba ... static.php
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Windows GUI

Post by jj2007 »

I wish I could help you but there is a problem with this library: only a few messages pass through! Here is a simple test piece:

Code: Select all

'Main:
Do
   WaitEvent(Window_Main, msg)	' GetMessage
   If msg.message = WM_MOUSEMOVE Then Print "M";	' works fine
   If msg.message = WM_COMMAND Then Print "C";	' not seen
   If msg.message = WM_NOTIFY Then Print "N";	' not seen
   If msg.message = WM_CTLCOLOREDIT Then Print "ed ";	' not seen
   If msg.message = WM_CTLCOLORSTATIC Then Print "st ";	' not seen
You will see the 'M' but nothing else. Mysterious. No WM_COMMAND, no WM_NOTIFY, but WM_MOUSEMOVE and WM_LBUTTONDOWN work as expected. Perhaps Lothar or José could explain what is happening there...
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Post by Provoni »

Hey jj2007,

Thanks for trying to help me. Could you perhaps integrate what you are trying to do in the datagrid.bas example?

Perhaps it could work if IsDialogMessage is commented out?

Code: Select all

Sub WaitEvent(ByVal hWnd As HWND, ByRef msg As MSG)
	'Wait for an event. Returns a result <> 0 if a Windows message has been received.
	'Parameters:
	'- hWnd = handle of the window
	'- msg = Message
		 
	'Note:
	'-----
	'IsDialogMessage (<> 0) supports the use of keys to change between controls.
	'Each active control in this library has the WS_TABSTOP style as a parameter 
	'"Style" so that the user can change between controls using the TAB key. If this
	'is not desired, the parameter can be set to 0.
	' 
	'Groups of controls can be defined by using the WS_GROUP style. WS_GROUP specifies
	'the first control of a group of controls. The group consists of this first control
	'and all controls defined after it, up to the next control with the WS_GROUP style. 
	'The first control in each group usually has the WS_TABSTOP style so that the user
	'can move from group to group. The user can subsequently change the keyboard focus
	'from one control in the group to the next control in the group by using the direction keys. 	
	
	If GetMessage(@msg, 0, 0, 0) <> 0 Then
		'If IsDialogMessage(hWnd, @msg) = 0 Then
			TranslateMessage(@msg )
			DispatchMessage(@msg )
		'End If
	End If
		
End Sub
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Windows GUI

Post by Josep Roca »

> Perhaps it could work if IsDialogMessage is commented out?

Probably, although you will lose tab navigation.

IMO processing windows messages in the message loop is a bad practice in a GUI application. Can be useful in a graphics application, but not in a GUI with Windows controls. I always use a Windows procedure.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Windows GUI

Post by jj2007 »

Josep Roca wrote:I always use a Windows procedure.
Me too. The problem here is that the built-in WndProc is not accessible. So the only solution would be subclassing. Here is a working example, it paints the clicked element differently:

Code: Select all

'==============================================================================
' Datagrid.bas
' Editable grid of Editboxes
' Created on July 11, 2016
' Latest change on November 17, 2018 by JJ
'==============================================================================

#Include "\AllBasics\FreeBasic\WinGUI\WinGUI.bi"

Dim shared As long opMain
Dim shared As HWND Window_Main, Edit_Data(20, 10), Button_GetData, ThisCell, hBrush
Dim As MSG msg
Dim As Integer i, j,k

Function WndProc(hWnd as HWND, uMsg as long, wParam as WPARAM, lParam as LPARAM) as integer 
  if uMsg=WM_COMMAND then
	ThisCell = lParam
	print "click or type ";
  elseif uMsg=WM_CTLCOLOREDIT then
	 if lParam=ThisCell then
	 	print "paint ";
	 	SetTextColor(wParam, &HFFFFFF)	' OK
	 	SetBkMode(wParam, TRANSPARENT) ' needed to make brush work
	 	' SetBkColor(wParam, &HFFFF00)	' no effect with transparent mode
	 	return hBrush 'GetSysColorBrush(COLOR_INFOBK)	' OK
	 endif
  endif
'   if uMsg<>15 and uMsg<>WM_MOUSEMOVE then
' 	print uMsg; " ";
'   endif
  return CallWindowProc(opMain, hwnd, uMsg, wParam, lParam)
end function

'Create the window with a data grid:
Window_Main = Window_New(700, 100, 500, 500, "Editable Datagrid")
For i = 0 To 20
   For j = 0 To 10
      k+=1
      Edit_Data(i, j) = EditBox_New(j * 40, i * 20, 40, 20, "abc",ES_CENTER, Window_Main)
      EditBox_SetText(Edit_Data(i, j),str(k))
   Next
Next
hBrush=CreateSolidBrush(&H0000E0)	' dark red
opMain=SetWindowLong(Window_Main, GWL_WNDPROC, @WndProc)
'Button_GetData = Button_New(350, 430, 100, 20, "GetData",, Window_Main)

'Main:
Do
   WaitEvent(Window_Main, msg)
Loop Until Window_Event_Close(Window_Main, msg)

End
This compiles and works fine in 32-bit but not in 64-bit mode. Don't be scared by the sheer amount of warnings it generates, they are certainly very important for a C++ coder.
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Post by Provoni »

What I don't understand is that it seems to be so complicated to change the color of something.

Suppose that you need to change whether the edit control is enabled or disabled it is simple a matter of:

Code: Select all

enablewindow(hwnd,bool)
And that actually changes the color!

My program is 64-bit only I cannot your code to work jj2007.

I am trying to work around the color problem with enabling and disabling edit control, since disabling an edit control will color it grey without the usual complications.

Is there a way to detect a click on a certain edit control or do I write code that calculates at which edit control the mouse cursor is?

Code: Select all

#include "wingui.bi"

dim as hwnd window_main, edit_data(20,10),button_getdata
dim as msg msg
dim as integer i,j,k,x,y
dim as double timer1

window_main=window_new(100,100,500,500,"editable datagrid")
for i=0 to 20
	for j=0 to 10
		k=65+int(rnd*26)
		edit_data(i,j)=editbox_new(25+j*39,25+i*19,40,20,chr(k),es_center or ws_tabstop,window_main)
		enablewindow(edit_data(i,j),int(rnd*2)-1)
	next
next

do
	waitevent(window_main,msg)
	if timer-timer1>0.1 then
		timer1=timer
		i=int(rnd*21)
		j=int(rnd*11)
		if iswindowenabled(edit_data(i,j)) then
			enablewindow(edit_data(i,j),0)
		else
			enablewindow(edit_data(i,j),-1)
		end if
	end if
loop until window_event_close(window_main, msg)

end
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Windows GUI

Post by jj2007 »

Provoni wrote:What I don't understand is that it seems to be so complicated to change the color of something.
What I don't understand is that a BASIC dialects floods the beginner with useless and confusing warnings. Oh well...
Provoni wrote:My program is 64-bit only I cannot your code to work jj2007.
Strangely enough, googling SetWindowLongPtr freebasic puts my old Simple example: Subclassing of an edit control thread on top. So I managed to convert it to 64-bit mode, which saves you the effort of trying to build it in 32-bit. Here it is:

Code: Select all

'==============================================================================
' Datagrid.bas
' Editable grid of Editboxes
' Created on July 11, 2016
' Latest change on November 17, 2018 by JJ
'==============================================================================

#Include "\AllBasics\FreeBasic\WinGUI\WinGUI.bi"

Dim shared As any ptr opMain
Dim shared As HWND Window_Main, Edit_Data(20, 10), Button_GetData, ThisCell, hBrush
Dim As Integer i, j, k
Dim As MSG msg

Function WndProc(hWnd as HWND, uMsg as long, wParam as WPARAM, lParam as LPARAM) as integer 
  Dim As Integer i, j, k
  if uMsg=WM_COMMAND then
	if lParam=Button_GetData Then
		For i = 0 To 20
			For j = 0 To 10
				Print EditBox_GetText(Edit_Data(i, j))
			Next
		Next
	else
		ThisCell = lParam
		print "click or type, value=";EditBox_GetText(ThisCell)
	endif
  elseif uMsg=WM_CTLCOLOREDIT then
	 if lParam=ThisCell then
	 	print "*"
	 	SetTextColor(wParam, &HFFFFFF)	' OK
	 	SetBkMode(wParam, TRANSPARENT)	' needed to make brush work
	 	' SetBkColor(wParam, &HFFFF00)	' no effect with transparent mode
	 	return hBrush 'GetSysColorBrush(COLOR_INFOBK)	' OK
	 endif
  endif
  return CallWindowProc(opMain, hwnd, uMsg, wParam, lParam)
end function

'Create the window with a data grid:
Window_Main = Window_New(700, 100, 500, 500, "Editable Datagrid")
For i = 0 To 20
   For j = 0 To 10
      k+=1
      Edit_Data(i, j) = EditBox_New(j * 40, i * 20, 40, 20, "abc",ES_CENTER, Window_Main)
      EditBox_SetText(Edit_Data(i, j),str(k))
   Next
Next
hBrush=CreateSolidBrush(&H0000E0)	' dark red
opMain=SetWindowLongPtr(Window_Main, GWLP_WNDPROC, @WndProc)
Button_GetData = Button_New(350, 430, 100, 20, "GetData",, Window_Main)

'Main:
Do
   WaitEvent(Window_Main, msg)
Loop Until Window_Event_Close(Window_Main, msg)
End
Is there a way to detect a click on a certain edit control or do I write code that calculates at which edit control the mouse cursor is?
Yes. See above, if uMsg=WM_COMMAND
Provoni
Posts: 513
Joined: Jan 05, 2014 12:33
Location: Belgium

Re: Windows GUI

Post by Provoni »

Wow thank you jj2007 that is working. There are indeed allot of warnings. I will try to implement it into my code and let you know how it goes.
Post Reply