Author |
Topic: Grid of Textboxes using Windows API (Read 57 times) |
|
RNBW
Full Member
member is offline
Gender:
Posts: 106
|
|
Grid of Textboxes using Windows API
« Thread started on: Jul 21st, 2016, 5:04pm » |
|
The following code sets up a grid of textboxes. in columns 1 to 4 the text should be centred an in columns 5 to 9 only numbers 0 to 9 should be accepted and should be right justified.
This works in LB, but in LBB all textboxes are left justified and will accept any characters, so it would appear that Style is not being accepted.
Code:
'===================================================
' CREATE TEXTBOX GRID CreateTextboxAPI_Grid_6.bas
' USING WINDOWS API
'===================================================
' modified from LB Newsletter API Corner
' with corrections by Cundo LB Conforum 19 July 2016
' Further modifications by RNBW 21 July 2016
'===================================================
NOMAINWIN
MENU #1, "&File","&Read", [readIt],_
"E&xit", [quit]
NOMAINWIN
[WindowSetup]
WindowWidth = 1032 : WindowHeight = 350
UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
UpperLeftY = INT((DisplayHeight-WindowHeight)/2)
' -------------------------------------------------
OPEN "API Textbox Grid" FOR WINDOW AS #1
PRINT #1, "trapclose [quit]"
' Set up the Textbox Styles as Global
Global Style, Style1
'vPos = 40 :
rowHigh = 20
' Set up the grid
DIM hT(5,9)
for row = 1 to 5
for col = 1 to 9
select case col
'First column (Reference)
case 1: xPos = 0 : width = 65
'Second Column (Description)
case 2: xPos = 65 : width = 380
'Columns 3 to 8
case 3,4,5,6,7,8: xPos = col*65+(445-65*3) : width = 65
' Column 9 (Total)
case 9: xPos = (65+380)+(col-3)*65 : width = 75
end select
if col < 5 then
Style = _WS_CHILDWINDOW OR _WS_BORDER OR _WS_VISIBLE OR _ES_CENTER
else
Style = _WS_CHILDWINDOW OR _WS_BORDER OR _WS_VISIBLE OR _ES_RIGHT OR _ES_NUMBER
end if
hT(row,col) = CreateTextbox(hwnd(#1),xPos + 20,row*rowHigh-rowHigh + rowHigh*2,width+1,rowHigh+1,Style)
next col
next row
WAIT
[quit]
CLOSE #1: END
[readIt]
handle = GetFocus()
txt$ = GetWindowText$( handle )
NOTICE txt$
WAIT
'--------------------------------------------
' SUBs and FUNCTIONs
'--------------------------------------------
' Get the focus in the Texbox
Function GetFocus()
CALLDLL #user32, "GetFocus",_
GetFocus AS uLONG
END Function
' Set the focus in the Texbox
SUB SetFocus hWnd
CALLDLL #user32, "SetFocus",_
hWnd AS uLONG,_
result AS LONG
END SUB
'Get the text entered into the Textbox
FUNCTION GetWindowText$(hWnd)
total = GetWindowTextLength(hWnd)
Title$ = SPACE$(total) + CHR$(0): l= LEN(Title$)
CALLDLL #user32, "GetWindowTextA",_
hWnd AS uLONG,_
Title$ AS PTR,_
l AS LONG,_
result AS LONG
GetWindowText$ = TRIM$(Title$)
END FUNCTION
'Get the length of the text entered into Textbox
FUNCTION GetWindowTextLength(hW)
CALLDLL #user32, "GetWindowTextLengthA",_
hW AS uLONG,_
GetWindowTextLength AS LONG
END FUNCTION
' Function to create Textbox
FUNCTION CreateTextbox(hW, x, y, w, h, Style)
Style = _WS_CHILDWINDOW OR _WS_BORDER _
OR _WS_VISIBLE
hInst = GetWindowLong(hW, _GWL_HINSTANCE)
CALLDLL #user32, "CreateWindowExA",_
0 AS LONG,_
"EDIT" AS PTR,_
"" AS PTR,_
Style AS LONG,_
x AS LONG,_
y AS LONG,_
w AS LONG,_
h AS LONG,_
hW AS uLONG,_
0 AS LONG,_
hInst AS LONG,_
0 AS LONG,_
CreateTextbox AS uLONG
END FUNCTION
FUNCTION GetWindowLong(hW, type)
CALLDLL #user32, "GetWindowLongA", _
hW AS uLONG,_
type AS LONG,_
GetWindowLong AS LONG
END FUNCTION
Has anyone any ideas?
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #1 on: Jul 21st, 2016, 9:41pm » |
|
on Jul 21st, 2016, 5:04pm, RNBW wrote:This works in LB, but in LBB all textboxes are left justified and will accept any characters, so it would appear that Style is not being accepted. |
|
You say it works in LB? It shouldn't - the code is seriously broken!
The main problem is that immediately after receiving the Style value in the CreateTextbox subroutine (it is passed as the last parameter) you replace it with a different value:
Code:FUNCTION CreateTextbox(hW, x, y, w, h, Style)
Style = _WS_CHILDWINDOW OR _WS_BORDER _
OR _WS_VISIBLE Obviously this means that whatever style value is passed to the subroutine is completely ignored, and the new style used instead. So the reason you never see the ES_CENTER, ES_RIGHT or ES_NUMBER bits take effect is that they don't go anywhere, you overwrite them.
Another fault is that having passed the Style value as a parameter to the subroutine you do not need to (and should not) also make it GLOBAL. You should decide whether you want to pass the value as a parameter (usually the better way) or by making it a global (usually not preferred) and stick to one or the other method. In fact LBB will work if you pass a global as a parameter, but LB breaks if you try to do that (it's a documented bug).
Here's the program with the two faults corrected (Style no longer GLOBAL, and the passed Style parameter not immediately replaced by a different value):
Code:'===================================================
' CREATE TEXTBOX GRID CreateTextboxAPI_Grid_6.bas
' USING WINDOWS API
'===================================================
' modified from LB Newsletter API Corner
' with corrections by Cundo LB Conforum 19 July 2016
' Further modifications by RNBW 21 July 2016
'===================================================
NOMAINWIN
MENU #1, "&File","&Read", [readIt],_
"E&xit", [quit]
NOMAINWIN
[WindowSetup]
WindowWidth = 1032 : WindowHeight = 350
UpperLeftX = INT((DisplayWidth-WindowWidth)/2)
UpperLeftY = INT((DisplayHeight-WindowHeight)/2)
' -------------------------------------------------
OPEN "API Textbox Grid" FOR WINDOW AS #1
PRINT #1, "trapclose [quit]"
' Set up the Textbox Styles as Global
' Global Style, Style1
'vPos = 40 :
rowHigh = 20
' Set up the grid
DIM hT(5,9)
for row = 1 to 5
for col = 1 to 9
select case col
'First column (Reference)
case 1: xPos = 0 : width = 65
'Second Column (Description)
case 2: xPos = 65 : width = 380
'Columns 3 to 8
case 3,4,5,6,7,8: xPos = col*65+(445-65*3) : width = 65
' Column 9 (Total)
case 9: xPos = (65+380)+(col-3)*65 : width = 75
end select
if col < 5 then
Style = _WS_CHILDWINDOW OR _WS_BORDER OR _WS_VISIBLE OR _ES_CENTER
else
Style = _WS_CHILDWINDOW OR _WS_BORDER OR _WS_VISIBLE OR _ES_RIGHT OR _ES_NUMBER
end if
hT(row,col) = CreateTextbox(hwnd(#1),xPos + 20,row*rowHigh-rowHigh + rowHigh*2,width+1,rowHigh+1,Style)
next col
next row
WAIT
[quit]
CLOSE #1: END
[readIt]
handle = GetFocus()
txt$ = GetWindowText$( handle )
NOTICE txt$
WAIT
'--------------------------------------------
' SUBs and FUNCTIONs
'--------------------------------------------
' Get the focus in the Texbox
Function GetFocus()
CALLDLL #user32, "GetFocus",_
GetFocus AS uLONG
END Function
' Set the focus in the Texbox
SUB SetFocus hWnd
CALLDLL #user32, "SetFocus",_
hWnd AS uLONG,_
result AS LONG
END SUB
'Get the text entered into the Textbox
FUNCTION GetWindowText$(hWnd)
total = GetWindowTextLength(hWnd)
Title$ = SPACE$(total) + CHR$(0): l= LEN(Title$)
CALLDLL #user32, "GetWindowTextA",_
hWnd AS uLONG,_
Title$ AS PTR,_
l AS LONG,_
result AS LONG
GetWindowText$ = TRIM$(Title$)
END FUNCTION
'Get the length of the text entered into Textbox
FUNCTION GetWindowTextLength(hW)
CALLDLL #user32, "GetWindowTextLengthA",_
hW AS uLONG,_
GetWindowTextLength AS LONG
END FUNCTION
' Function to create Textbox
FUNCTION CreateTextbox(hW, x, y, w, h, Style)
' Style = _WS_CHILDWINDOW OR _WS_BORDER _
' OR _WS_VISIBLE
hInst = GetWindowLong(hW, _GWL_HINSTANCE)
CALLDLL #user32, "CreateWindowExA",_
0 AS LONG,_
"EDIT" AS PTR,_
"" AS PTR,_
Style AS LONG,_
x AS LONG,_
y AS LONG,_
w AS LONG,_
h AS LONG,_
hW AS uLONG,_
0 AS LONG,_
hInst AS LONG,_
0 AS LONG,_
CreateTextbox AS uLONG
END FUNCTION
FUNCTION GetWindowLong(hW, type)
CALLDLL #user32, "GetWindowLongA", _
hW AS uLONG,_
type AS LONG,_
GetWindowLong AS LONG
END FUNCTION Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline
Gender:
Posts: 106
|
|
Re: Grid of Textboxes using Windows API
« Reply #2 on: Jul 22nd, 2016, 2:07pm » |
|
on Jul 21st, 2016, 9:41pm, Richard Russell wrote:You say it works in LB? It shouldn't - the code is seriously broken!
The main problem is that immediately after receiving the Style value in the CreateTextbox subroutine (it is passed as the last parameter) you replace it with a different value:
Code:FUNCTION CreateTextbox(hW, x, y, w, h, Style)
Style = _WS_CHILDWINDOW OR _WS_BORDER _
OR _WS_VISIBLE Obviously this means that whatever style value is passed to the subroutine is completely ignored, and the new style used instead. So the reason you never see the ES_CENTER, ES_RIGHT or ES_NUMBER bits take effect is that they don't go anywhere, you overwrite them.
Another fault is that having passed the Style value as a parameter to the subroutine you do not need to (and should not) also make it GLOBAL. You should decide whether you want to pass the value as a parameter (usually the better way) or by making it a global (usually not preferred) and stick to one or the other method. In fact LBB will work if you pass a global as a parameter, but LB breaks if you try to do that (it's a documented bug).
Richard |
|
You are absolutely correct in everything you say. Believe it or not, the code you provided is almost the same as one of the early options I tried, but LB threw up an error on _ES_CENTRE (by process of elimination from the whole Style parameters). That's when I moved on to the code that gave me a solution in LB. It does work in both LB 4.04 and 4.5. I know it shouldn't but I was getting desperate. Hence also the introduction of Global, which i tried both in the Function CreateTextbox() and outside it.
I can't explain why my earlier tries didn't work, but I'm pleased to say that your code does work both in LBB and LB and I am grateful to you for that.
I will post the corrected code on LB Conforums, with appropriate credit to yourself.
Thank you
Ray
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #3 on: Jul 22nd, 2016, 3:30pm » |
|
on Jul 22nd, 2016, 2:07pm, RNBW wrote:LB threw up an error on _ES_CENTRE (by process of elimination from the whole Style parameters). That's when I moved on to the code that gave me a solution in LB. |
|
The moral is: don't try to fix faults by trial and error! If something doesn't work, figure out why it doesn't work and correct whatever the mistake is. Randomly altering the code in the hope that it might help (such as making something GLOBAL when clearly it doesn't need to be) is a recipe for problems - and that's what you got.
You are not alone in automatically assuming that LBB is at fault when something doesn't work. Despite the fact that I have more than 40 years programming experience, and am a professional engineer with formal qualifications, many people are of the opinion that LBB is a 'toy' product and that LB is the 'real thing'.
Richard. M.A. C.Eng. M.I.E.T.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline
Gender:
Posts: 106
|
|
Re: Grid of Textboxes using Windows API
« Reply #4 on: Jul 22nd, 2016, 6:57pm » |
|
Hi Richard
I am a great supporter of LBB and use it by default. I didn't post the code believing that LBB was at fault, because I am well aware off the pedigree of BBC Basic that supports LBB. I was sure that your expertise, as usual, would put me right, which it did.
I have posted the corrected code on LB Conforums.
Thanks again for your help.
Ray
|
|
Logged
|
|
|
|
SarmedNafi
Junior Member
member is offline
Posts: 93
|
|
Re: Grid of Textboxes using Windows API
« Reply #5 on: Jul 23rd, 2016, 03:22am » |
|
Dear Ray,
One day we were playing a game, me and my nephew, the moment he came back from school, I said come take this game from me and cousin don't go in this street you will spend two hours then you will find it close. He was smarter than me, he was always found us solutions to save our life (inside games). After a quarter of an hour I came to found him inside all dirty of that street! In general the humans by native were not able to take experience from others. I think a grid built either by normal text boxes or by LBB loop or by one line of normal text boxes then passed to multi column ListBox are better a thousand times than a grid of API. I think you are going to west many years of your life. Please reconsider this matter.
With all respects Sarmed
|
« Last Edit: Jul 23rd, 2016, 03:24am by SarmedNafi » |
Logged
|
|
|
|
RNBW
Full Member
member is offline
Gender:
Posts: 106
|
|
Re: Grid of Textboxes using Windows API
« Reply #6 on: Jul 23rd, 2016, 09:05am » |
|
on Jul 23rd, 2016, 03:22am, SarmedNafi wrote:Dear Ray,
One day we were playing a game, me and my nephew, the moment he came back from school, I said come take this game from me and cousin don't go in this street you will spend two hours then you will find it close. He was smarter than me, he was always found us solutions to save our life (inside games). After a quarter of an hour I came to found him inside all dirty of that street! In general the humans by native were not able to take experience from others. I think a grid built either by normal text boxes or by LBB loop or by one line of normal text boxes then passed to multi column ListBox are better a thousand times than a grid of API. I think you are going to west many years of your life. Please reconsider this matter.
With all respects Sarmed |
|
Sarmed
You misunderstand my reasons for investigating using the Windows API.
If you look back through LB and LBB postings you will find that I tried to develop a grid using textboxes in LB Conforums. Without moving into the realms of graphics and other devious means involving lots of code, this could not be done because of the way LB used manhandled. Richard Russell kindly put me right providing examples of how it was done using LBB.
Since then, I have been developing code using Freebasic and in particular using a library, WinGUI.bi, which is based on the Windows GUI. It is a simple library and is aimed at providing only the basics of editboxes, statictext, listboxes, menus, and the like. This suits my purpose.
Having progressed this, my challenge was to produce a grid based on simple Windows and using simple code in LB to get over the problem. I have also thought about developing a dll. It is early days yet, but it it's coming along. At the moment I can produce a flexible grid using LB. I am now working on how to extract and manipulate data entered into the grid and producing the functions to do so. All it is, is a challenge, which to me is what coding is all about.
What would I use by choice. LBB. It is simple and, unlike LB, the code is simple and concise, but just producing a grid is no longer a challenge and I have moved on from that.
I shall continue with my challenge with LB until it is either completed or I can't progress it further. In my retirement I have the time. The question is do I have the expertise?
Ray.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #7 on: Jul 23rd, 2016, 09:59am » |
|
on Jul 23rd, 2016, 09:05am, RNBW wrote:You misunderstand my reasons for investigating using the Windows API... my challenge was to produce a grid based on simple Windows and using simple code in LB to get over the problem. |
|
Having designed LBB to overcome the problem of creating controls in a loop, there is a degree of frustration in seeing workarounds still being developed for LB (and then having them posted in this forum because they don't work in LBB!).
If LB was more competently implemented I could understand why people might not want to 'burn their boats' by committing to LBB. But really LB (4.04, and even more so 4.5.0) is awful! The slowness, the bloat, the bugs, the incompatibility with DEP, the insecurity - for me these and other shortcomings far outweigh loyalty to Carl Gundel (which I don't think he deserves anyway).
Richard.
|
|
Logged
|
|
|
|
RNBW
Full Member
member is offline
Gender:
Posts: 106
|
|
Re: Grid of Textboxes using Windows API
« Reply #8 on: Jul 23rd, 2016, 11:55am » |
|
on Jul 23rd, 2016, 09:59am, Richard Russell wrote:Having designed LBB to overcome the problem of creating controls in a loop, there is a degree of frustration in seeing workarounds still being developed for LB (and then having them posted in this forum because they don't work in LBB!).
If LB was more competently implemented I could understand why people might not want to 'burn their boats' by committing to LBB. But really LB (4.04, and even more so 4.5.0) is awful! The slowness, the bloat, the bugs, the incompatibility with DEP, the insecurity - for me these and other shortcomings far outweigh loyalty to Carl Gundel (which I don't think he deserves anyway).
Richard. |
|
Richard
The reason I did what I did was because I saw code produced by Cundo on a grid of textboxes, which whilst it did the job, produced what I considered a more complicated way off achieving the result. Because I normally work with LBB, I tried the code on LBB and it didn't work. I their posted the code on LBB and you corrected it. Your corrections were very much on lines I had tried earlier but showed up errors in LB. Having previously posted the code on LB (which strangely did work), I felt it only right to post correct code.
I have been working for several weeks on Freebasic, helping the author of WinGUI.bi (a Windows API library that can only be used for simple code - we know there are things not technically correct). Having gained this knowledge, I wanted to see if I could use it to get over some of LB's problems. You did it with LBB. Surely I should be able to do it for a particular problem also.
I am progressing it slowly. It might work. It might not.
I don't intend to use it on a permanent basis. I use LBB and see no reason to revert to LB, which doesn't provide me with the solutions I want. I will continue to use LBB, which is superior to LB in most respects. In particular, it is supported by BBC Basic that is known to be stable and more powerful than LB. It is also relatively bug free and bugs are quickly resolved (these are few and far between).
As I said, it it's a challenge to me. As always I am grateful for the help you have provided. I know how you feel about LB and it's administrators (language and forum). You could always release a new language based on LBB and BBC Basic and I am aware of some of the reasons that you don't.
My actions are not intended to be critical of LBB, yourself and all others who support LBB.
Rant over. I'm going back to watching the cricket. Woakes has just lost his wicket caught and bowled for 58.
LBB for ever!
Ray
|
|
Logged
|
|
|
|
CryptoMan
New Member
member is offline
Gender:
Posts: 46
|
|
Re: Grid of Textboxes using Windows API
« Reply #9 on: Aug 16th, 2016, 9:14pm » |
|
This is a very nice grid.
However, in order make it more usable it should move to the next cell with a TAB or with ENTER key, and able to navigate with arrow keys.
How can we do this?
Earlier grid examples was able to do this.
I remember making a grid on LB very painfully. This looks quite elegant in coding.
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #10 on: Aug 16th, 2016, 11:39pm » |
|
on Aug 16th, 2016, 9:14pm, CryptoMan wrote:However, in order make it more usable it should move to the next cell with a TAB or with ENTER key, and able to navigate with arrow keys. How can we do this? |
|
I would prefer not to discuss the LB-compatible approach here. LBB has a much easier way of creating grids of controls so can we please concentrate on that.
Richard.
|
|
Logged
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Grid of Textboxes using Windows API
« Reply #11 on: Aug 17th, 2016, 8:42pm » |
|
This code works to create grids of textboxes for one window, but I want to generalize, and use it for several windows. But it seems that the actual window name is required in the three statements containing "tmp". Is there any way around this? r.m.
Code:
call tbNumberCG "#cogs.tb", 6,185,40,10,60,25
.......
sub tbNumberCG x$,lmt,j,k,l,m,n
for x = 1 to lmt
var$ = x$ + "0"+right$(str$(x),2)
textbox #cogs.tmp, j, (k*x)+l0, m, n
stylebits #cogs.tmp, _ES_NUMBER, 0, 0, 0
maphandle #cogs.tmp, var$
next x
end sub
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #12 on: Aug 17th, 2016, 10:51pm » |
|
on Aug 17th, 2016, 8:42pm, Alincon wrote:But it seems that the actual window name is required in the three statements containing "tmp". Is there any way around this? |
|
In just the same way as you initially give your controls the same temporary name (later using maphandle to change them to the required names) you can initially give your multiple windows the same temporary name too! That should hopefully solve your problem, because now the window name you specify in your sub can be the same for all the windows. Something like this:
Code: call tbNumberCG "#cogs", 6,185,40,10,60,25
open "Window 1 (#cogs)" for window as #tmp
maphandle #tmp, #cogs
call tbNumberCG "#wheel", 6,185,40,10,60,25
open "Window 2 (#wheel)" for window as #tmp
maphandle #tmp, #wheel
#cogs.tb03 "Hello "
#wheel.tb04 "world!"
wait
sub tbNumberCG x$,lmt,j,k,l,m,n
for x = 1 to lmt
var$ = x$ + ".tb0" + right$(str$(x),2)
textbox #tmp.tmp, j, (k*x)+l0, m, n
stylebits #tmp.tmp, _ES_NUMBER, 0, 0, 0
maphandle #tmp.tmp, var$
next x
end sub Richard.
|
|
Logged
|
|
|
|
Alincon
Full Member
member is offline
Posts: 147
|
|
Re: Grid of Textboxes using Windows API
« Reply #13 on: Aug 18th, 2016, 01:48am » |
|
So the one maphandle statement takes care of several textboxes? (the '6' in the call statement below is the count of textboxes) r.m.
Code:
call tbNumberCG "#cogs", 6,185,40,10,60,25
open "Window 1 (#cogs)" for window as #tmp
maphandle #tmp, #cogs
|
|
Logged
|
|
|
|
Richard Russell
Administrator
member is offline
Posts: 1348
|
|
Re: Grid of Textboxes using Windows API
« Reply #14 on: Aug 18th, 2016, 09:37am » |
|
on Aug 18th, 2016, 01:48am, Alincon wrote:So the one maphandle statement takes care of several textboxes? |
|
No, in LBB each maphandle affects only one window or control. That's why maphandle is called 14 times in all in the code I listed (once for each textbox and once for each window).
Did you not run the code I listed? Unlike your snippet, mine was a complete self-contained program: I always prefer that complete programs be posted, rather than extracts that don't actually do anything in isolation.
Richard.
|
|
|
|
|