Numeric entry check in an EditBox control using RegEx [Windows]

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Numeric entry check in an EditBox control using RegEx [Windows]

Post by UEZ »

Here an example using regex:

Code: Select all

'Example by UEZ Using regex build 2018-08-04 beta / should work Now As x86 / x64
'You need To install the PCRE package from here: https://www.freebasic.net/forum/viewtopic.php?f=2&t=25070&p=224823&hilit=PCRE#p224823

#Include "windows.bi"
#Include "VBcompat.bi"
#Include "pcre.bi"

Declare Function StringRegEx(Byval sPattern As String, Byval sSubject As String) As String
Declare Function WndProc(hWnd As HWND, wMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
Declare Sub EditBox_SetText(Byval hWndEdit As HWND, Byval Text As String)
Declare Function EditBox_GetText(Byval hWndEdit As HWND) As String

Dim Shared As HFONT guiFont
Dim Shared As HWND hGUI, hButton_exit, hInputbox

' Create  Window Class:
Dim As WNDCLASS wcls

#Ifdef unicode
Dim szClassName As Wstring * 64
Dim szCaption   As Wstring * 64
#Else
Dim szClassName As Zstring * 64
Dim szCaption   As Zstring * 64
#Endif

szClassName = "FB_GUI"

With wcls
    .style      = CS_HREDRAW Or CS_VREDRAW
    .lpfnWndProc  = Cast(WNDPROC, @WndProc)
    .hInstance    = GetModuleHandle(NULL)
    .hIcon      = LoadIcon(NULL, IDI_APPLICATION)
    .hCursor      = LoadCursor(NULL, IDC_ARROW)
    .hbrBackground  = GetSyscolorbrush(COLOR_3DFACE) 'GetStockObject(WHITE_BRUSH)
    .lpszMenuName  = NULL
    .lpszClassName  = Strptr(szClassName)
End With

If RegisterClass(@wcls) = False Then
    MessageBox(NULL, "RegisterClass('WindowClass') FAIL!", "Error!", MB_OK Or MB_ICONERROR)
    End
End If

Dim Shared As String sText_input
sText_input = "Enter here any number"
hGUI = CreateWindowEx(NULL, szClassName, "RegEx Test", WS_OVERLAPPEDWINDOW Or WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, 300, 200, NULL, NULL, NULL, NULL)
hButton_exit = CreateWindowEx(NULL, "Button", "Exit", WS_VISIBLE Or WS_CHILD, 180, 120, 90, 24, hGUI, NULL, NULL, NULL)
hInputbox = CreateWindowEx(NULL, "Edit", sText_input, WS_BORDER Or WS_VISIBLE Or WS_CHILD Or ES_AUTOHSCROLL, 10, 40, 200, 24, hGUI, NULL, NULL, NULL)

Dim As MSG uMsg

While GetMessage(@uMsg, NULL, NULL, NULL) <> False
	TranslateMessage(@uMsg)
	DispatchMessage(@uMsg)
Wend

End

Function StringRegEx(Byval sPattern As String, Byval sSubject As String) As String
  Const OVECCOUNT = 300
  
  Dim As Zstring Ptr error1_
  Dim As Long error_offset, rc, i, ovector(OVECCOUNT - 1), result
  Dim As pcre Ptr re
  
  Dim As String aArr(), sResult
  result = 0
  
  re = pcre_compile(sPattern, 0, @error1_, @error_offset, 0)
  If re = NULL Then
    Return ""
  End If
  
  i = 0
  Do
    rc = pcre_exec(re, NULL, Strptr(sSubject), Len(sSubject), i, 0, @ovector(0), OVECCOUNT)
    If rc > 0 Then
      Redim Preserve aArr(Lbound(aArr) To Ubound(aArr) + 1)
      aArr(Ubound(aArr)) = Mid(sSubject, ovector(0) + 1, ovector(1) - ovector(0))
      result += 1
      i = ovector(1)
    End If
  Loop While rc >= 0
	For i As Integer = Lbound(aArr) To Ubound(aArr)
		sResult &= Trim(aArr(i), Any Chr(10, 13, 32))
	Next i
  
  Return sResult
End Function

Function WndProc(hWnd As HWND, wMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
    Select Case hWnd
		Case hGUI  
			Select Case wMsg				
				Case WM_DESTROY
					PostQuitMessage(NULL)
					Return 0
				Case WM_COMMAND
					Select Case Hiword(wParam)
						Case EN_CHANGE
							Dim As String sText 
							sText = EditBox_GetText(hInputbox)
							If sText <> "" Then
								Dim As String sFilter = StringRegEx("^[\d-]?\d*(?:\.\d*)?$", sText) 'check For correct Input
								If sFilter = "" Then
									EditBox_SetText(hInputbox, Rtrim(sText, Right(sText, 1)))
									SendMessage(hInputbox, EM_SETSEL, wParam, lParam) 'set the cursor To the End
								Endif
							Endif
						Case EN_SETFOCUS
							If EditBox_GetText(hInputbox) = sText_input Then EditBox_SetText(hInputbox, "")
						Case EN_KILLFOCUS
							If EditBox_GetText(hInputbox) = "" Then
								EditBox_SetText(hInputbox, sText_input)
								SendMessage(hInputbox, EM_SETSEL, wParam, lParam)
							Endif
					End Select
					Select Case lParam  
						Case hButton_exit
							DestroyWindow(hGUI)
							Return 0
					End Select
				Case WM_KEYDOWN
					If wParam = VK_ESCAPE Then
						DestroyWindow(hGUI)
						Return 0
					Endif
			End Select
    End Select
    
    Return DefWindowProc(hWnd, wMsg, wParam, lParam)
End Function

Sub EditBox_SetText(Byval hWndEdit As HWND, Byval Text As String)
	'Set text into an editbox Or an editor. Parameters:
	'- hWndEdit = handle of the edit box
	'- Text = text	
    
  SetWindowText(hWndEdit, Text)

End Sub

Function EditBox_GetText(Byval hWndEdit As HWND) As String
	'Returns the text from an editbox Or an editor. Parameter:
	'- hWndEdit = handle of the edit box
    
	Dim BufferSize As Long
	Dim Buffer As String
	
	BufferSize = GetWindowTextLength(hWndEdit)
	Buffer = Space(BufferSize)
	GetWindowText(hWndEdit, Buffer, BufferSize + 1)  
		 
	Return Rtrim(Buffer, Chr(0))
         
End Function
PCRE can be downloaded here: viewtopic.php?f=2&t=25070&p=224823&hilit=PCRE#p224823

Compiled version can be downloaded here: http://www.mediafire.com/file/nlujtz7mx ... x.zip/file
Last edited by UEZ on Aug 04, 2018 17:57, edited 5 times in total.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by jj2007 »

Same problem as before: Builds fine, at least in 32-bit Gas & Gcc, but all you can do is enter text or numbers in the box. Neither the Exit button nor Alt F4 work, but building as console and closing the console with Alt F4 works.

In 64-bit FB, the lines
re = pcre_compile(sPattern, 0, @error1_, @error_offset, NULL) and
rc = pcre_exec(re, NULL, Strptr(sSubject), Len(sSubject), i, 0, @ovector(0), OVECCOUNT)
produce the warning Passing different pointer types, and the error ld.exe: cannot find -lpcre
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by Josep Roca »

Too many missplaced PostQuitMessage. Only one is needed and in response to the WM_DESTROY message.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by jj2007 »

Right, but that is not the only problem:

Code: Select all

Function WndProc(hWnd As HWND, wMsg As UINT, wParam As WPARAM, lParam As LPARAM) As LRESULT
    MessageBox(hWnd, "Hey, I can't see this box", "Something is wrong:", MB_OK)
    Select Case hWnd

Code: Select all

    .lpszClassName  = Strptr("#32770")
What I find most mysterious is that it seems to work on UEZ's machine.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by UEZ »

@jj2007: Well, on my machine the compiled x86 working without any issue. I've uploaded the compiled version here: http://www.mediafire.com/file/nlujtz7mx ... x.zip/file
Maybe you trust me and can execute it for testing purposes.

Yes, the PCRE stuff seems not to be x64 compatible.

@Josep Roca: yes, you are right. I've updated the code.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by jj2007 »

UEZ wrote:Maybe you trust me and can execute it for testing purposes.
According to VirusTotal, Symantec says it's ransomware called ML.Attribute.HighConfidence (I checked the de-upx'ed version). Why are there numerous calls to VirtualQuery and VirtualProtect in the code?

But it works fine. The big question is now why it doesn't work on my two W7 and XP machines.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by UEZ »

jj2007 wrote:
UEZ wrote:Maybe you trust me and can execute it for testing purposes.
According to VirusTotal, Symantec says it's ransomware called ML.Attribute.HighConfidence (I checked the de-upx'ed version). Why are there numerous calls to VirtualQuery and VirtualProtect in the code?

But it works fine. The big question is now why it doesn't work on my two W7 and XP machines.
Actually, I wanted to post the Exe as Base91 code in the code box, so I tried to make the exe as small as possible using FileOptimizer, but I chose MediaFire. I cannot tell you why there are numerous calls to VirtualQuery and VirtualProtect in the code!

Usually I'm coding on Win10 x64 and I cannot tell you why Win7 and XP isn't working properly but I will test it in my VMs to reproduce the issues.
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by RNBW »

UEZ
Unfortunately, I had a similar virus check problem (ESET) with download, but I took a chance with the .exe version on MediaFire.

The code basically does the same thing as my Numeric Input Into A Textbox viewtopic.php?f=7&t=26816, setting up a single EditBox to enter a number. As far as I can see, it enables exactly the same characters in the numeric input. I think my code is simpler to understand and is only 73 lines as against RegEx with 140 lines, so I think I'll stick with it. Thank you, though, for providing an alternative. It's always good to know that there is another way of doing things.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by MrSwiss »

I don't agree, because its only good for x86, which is inacceptable, nowadays ...
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by RNBW »

MrSwiss wrote:I don't agree, because its only good for x86, which is inacceptable, nowadays ...
I'm only concerned with X86 and Windows. I've only coded for use with one library, but I'm sure that the code could be used with library specific modifications for other libraries. As far as I can see UEZ's code is also for X86 Windows. I'm sure that there are more people out there in the hobbyist world who work with a single platform, rather than multiple platforms.

I'm not going to make any apology for coding for X86 and Windows. If anyone wants to code the exercise for other platforms I would be happy to see their code. It is quite accceptable to code for a specific platform. I think most people do. I don't see much code in the FreeBasic forum (or any other BASIC forum) which is written for multiple platforms.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by MrSwiss »

While I also agree on platform (WIN / LIN ...), I'll never accept "further limits" as: i.e. 32 bit only ...
The two are decidedly different!
I would be happy to see their code.
Feel free. All code of mine is with both compilers checked ... (32/64).
(32 bit, only for backwards compatibility of course, because I live in: 2018!)
RNBW
Posts: 267
Joined: Apr 11, 2015 11:06
Location: UK

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by RNBW »

MrSwiss wrote:While I also agree on platform (WIN / LIN ...), I'll never accept "further limits" as: i.e. 32 bit only ...
The two are decidedly different!
I would be happy to see their code.
Feel free. All code of mine is with both compilers checked ... (32/64).
(32 bit, only for backwards compatibility of course, because I live in: 2018!)
I think we are at cross purposes. I was using the term X86 generically. To be exact, I normally code in X86_64 and my code is compiled in 64bit. My compiler is set up to compile in Win64. I usually only compile in Win64 and only use Win32 when necessary. So I do live in 2018.
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by UEZ »

RNBW wrote:UEZ
Unfortunately, I had a similar virus check problem (ESET) with download, but I took a chance with the .exe version on MediaFire.

The code basically does the same thing as my Numeric Input Into A Textbox viewtopic.php?f=7&t=26816, setting up a single EditBox to enter a number. As far as I can see, it enables exactly the same characters in the numeric input. I think my code is simpler to understand and is only 73 lines as against RegEx with 140 lines, so I think I'll stick with it. Thank you, though, for providing an alternative. It's always good to know that there is another way of doing things.
I just wanted to show a different approach (PCRE) for the same "challenge" and that's the reason why I used same GUI and some functions from WinGUI.bi.
I know it is very hard to learn regular expression but it can a mighty tool to have a simpler solution especially with string manipulation.

Counting lines with includes at the top makes not really sense as they are not visible.
MrSwiss
Posts: 3910
Joined: Jun 02, 2013 9:27
Location: Switzerland

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by MrSwiss »

I think we are at cross purposes.
Yes, seems that way ...

However, there are some <specialists> in this forum, that really seem to still live
in the 20th century, claiming nostalgic reasons (which I call "cheap excuses") even
for coding libraries ... (I'm not going to call names ...)!
UEZ
Posts: 972
Joined: May 05, 2017 19:59
Location: Germany

Re: Numeric entry check in an EditBox control using RegEx [Windows]

Post by UEZ »

MrSwiss wrote:
I think we are at cross purposes.
Yes, seems that way ...

However, there are some <specialists> it this forum, that really seem to still live
in the 20th century, claiming nostalgic reasons (which I call "cheap excuses") even
for coding libraries ... (I'm not going to call names ...)!
Even if you are partial correct with your statements, how you are communicating sucks and usually I'm ignoring such guys.
Post Reply