MAP
CyberSource:GenerateHeader PROCEDURE (*typCCRetailMsg ccMsg, *NetWebClient pWeb, STRING PostString)
END
CyberSource:GenerateSignatureFromParams PROCEDURE (STRING signatureParams,STRING secretKey)
strParams StringTheory
strKey StringTheory
CODE
strParams.SetValue(signatureParams,st:clip)
strKey.SetValue(secretKey,st:clip)
strKey.Base64Decode()
! strParams.ToUnicode()
strParams.SetValue(NetMakeHMAC(strParams.GetValuePtr(), strParams.Length(), strKey.GetValue(), net:CALG_SHA_256))
strParams.Base64Encode()
return strParams.GetValue()
CyberSource:GenerateHeader PROCEDURE (*typCCRetailMsg ccMsg, *NetWebClient pWeb, STRING PostString)
lSecretKey STRING(100)
KeyId STRING(100)
MerchantId STRING(100)
HostName STRING(100)
HostTarget STRING(100)
strPost StringTheory
strHost StringTheory
strURL StringTheory
sGMTDate STRING(64)
lstart LONG
lend LONG
CODE
MerchantId = ccMsg.AcctNo
KeyId = ccMsg.Key
lSecretKey = ccMsg.PW
strURL.SetValue(ccMsg.TxnURL)
lstart = 0
lend = 0
HostName = CLIP(strURL.FindBetween('https://', '.com', lstart, lend)) & '.com'
lstart = 0
lend = 0
HostTarget = 'post /' & CLIP(strURL.FindBetween('.com/', '', lstart, lend))
strPost.SetValue(CLIP(PostString))
strPost.SetValue(NetMakeHash(strPost.GetValuePtr(),strPost.Length(),net:CALG_SHA_256))
strPost.Base64Encode()
sGMTDate = pWeb.CreateGMTDate()
strHost.SetValue('host: ' & CLIP(HostName) & '<10>' &|
'v-c-date: ' & CLIP(sGMTDate) & '<10>' & |
'request-target: ' & CLIP(HostTarget) & '<10>' &|
'digest: SHA-256=' & strPost.GetValue() & '<10>' &|
'v-c-merchant-id: ' & CLIP(MerchantId) & '')
pWeb.CustomHeader = |
'v-c-merchant-id: ' & CLIP(MerchantId) & '<13,10>' &|
'v-c-date: ' & CLIP(sGMTDate) & '' & '<13,10>' &|
'digest: SHA-256=' & strPost.GetValue() & '<13,10>' &|
'Signature: keyid="' & CLIP(KeyId) & '", algorithm="HmacSHA256",' &|
' headers="host v-c-date request-target digest v-c-merchant-id", signature="' &|
CyberSource:GenerateSignatureFromParams(strHost.GetValue(), lSecretKey) & '"'
1 post - 1 participant
]]>I have a NT button and i want to execute the move() javascript function when the button is pressed.
I have tried multiple permutations and this is my current permutation for the button embed. However, it is not correct as the function does not execute.
This is the current iteration:
p_web.script(‘$(’‘[“move()”]’‘).call();’)
Can someone help me with the correct syntax to call this function from a NT button?
THanks,
Ron
5 posts - 2 participants
]]>IF UserType1 = TRUE
START(Browse1, 25000)
ELSE
START(Browse2, 25000)
END
This works as expected EXCEPT when that procedure is closed and I re-select the log button, the Select embed doesn’t run a second time. (I have to select some other button/procedure then when I reselect the log button, it seems to have reset itself?)
I moved my code to the Accept embed point, and that works without having to select a different button/procedure. When I close the log procedure and re-press the log button, it opens the appropriate procedure that was “de-activated” using the Select embed.
HOWEVER, using the Accept embed point, bypasses the Browse “run only one” code. Pressing it three times opens 3 copies of the procedure.
My work around is to leave the button embed points empty and have the button call a “Source Procedure” with the same code I had in the embed points.
Any info/ideas on why the Accept embed bypasses the run only one code in the Browse Procedure?
14 posts - 6 participants
]]>Guide:
https://askgoodquestions.dev/guides/the-hidden-cost-of-magic
Field note:
https://askgoodquestions.dev/field-notes/when-working-code-isnt-enough
The idea is simple, but I think it’s important:
AI makes it easier than ever to get working code. But that doesn’t automatically mean you have something you can safely own.
The moment where things get interesting is not when the code first works. It’s when something needs to change.
That’s where lack of understanding shows up, and where the real cost starts to become visible.
I’d be interested to hear how others are handling this. Are you finding that AI-generated code is holding up well over time, or are you seeing friction when it comes to maintenance and changes?
26 posts - 11 participants
]]>I’m looking for developer feedback on a new Windows desktop tool I’ve been
building called bsQuery: www.datafortress.app/bsquery
bsQuery is a focused SQL query, data inspection, reporting, and
troubleshooting utility currently aimed at Microsoft SQL Server. It is
designed for developers, support teams, consultants, software vendors, and
trusted power users who want a faster, cleaner workspace for day-to-day
database work without the overhead of launching a full IDE every time.
I personally use bsQuery every day in my own software development projects
and for end-user support, so this is a tool being shaped by real-world daily
use rather than just theory. I simply got tired of waiting for SSMS to load
and wanted something that works the way I want it to work after 26 years of
SQL Server development.
A few of the things it includes:
I’m also exploring OEM / embedded use for software vendors that want to
include it with their vertical applications.
For more details, screenshots, and a printable one-page overview, please
take a look here:
www.datafortress.app/bsquery
The page is easy to share internally with a manager, product owner, business
owner, or anyone involved in purchase approval. They can also print it or
forward the link to others who need to review the product.
At this stage, I’m mainly trying to gauge interest and hear what other
developers think:
I’m also considering two possible editions:
bsQuery Standard - SQL Server only
bsQuery Pro - All engines (PostgreSQL, MySQL, Oracle added)
I’d genuinely appreciate any feedback, criticism, feature requests, or
thoughts on positioning.
Thanks for your interest!
Greg Berthume
www.datafortress.app
11 posts - 5 participants
]]>8 posts - 5 participants
]]>I’m Jacques Ooms from Brackenfell South Africa. I’ve been a Clarion Developer for many years, starting in Clarion 2.1 for DOS. The majority of my experience has been in Clarion. I have used all versions for Windows up to the current Clarion 10 and 11.
I got experience in many fields.
I’m looking for remote work.
I am available from end of May 2026. Please contact me at : [email protected]
1 post - 1 participant
]]>12 posts - 4 participants
]]>askgoodquestions.dev
I’ve cleaned up the layout, made it easier to read, and added an email signup option for anyone who wants a notice when I post something new.
The focus of the site is still the same: practical thinking about how to use AI well in real work, without hype and without losing control of the process.
If you’d rather subscribe directly, you can do that here:
1 post - 1 participant
]]>If Access:table:Whatever <> Level:Benign
lastError = Errorcode()
End
This is because the ABC Methods explicitly do not preserve the actual ErrorCode et al from the file driver operation. So you cannot test ErrorCode(), Error(), FileErrorCode() or FileError() after an ABC call.
The Errors are however pushed into the GlobalErrors object, and hence can be queried. So the following code works;
If Access:table:Whatever <> Level:Benign
lastError = GlobalErrors.GetError(ErrClarion)
lastErrorCode = GlobalErrors.GetErrorCode(ErrClarion)
lastFileError = GlobalErrors.GetError(ErrFile)
lastFileErrorCode = GlobalErrors.GetErrorCode(ErrFile)
End
3 posts - 2 participants
]]>Syntax error: Parameter type has wrong scope: DATAGROUP
Syntax error: No matching prototype available
I am attaching a zip file containing a small VC6 DLL file that only returns a messagebox when calling a function. In addition, there is a CW6 hand-coded example that works ok and an app made with an IDE that gives the above-mentioned errors when compiled. The template file I’m struggling with is also included.
If anyone would be willing to take a look at this, I would be really grateful.
Best regards,
-Ville Vahtera
CW6_TEST.zip (30.7 KB)
3 posts - 2 participants
]]>I need to position an SDI window at runtime (center horizontally and above the taskbar)
I use the GetPosition(myWindow, x, y, w ,h) but missing how to get the total width/height of the desktop and the height of the taskbar?
TIA
5 posts - 4 participants
]]>Guide:
The AI Junk Drawer Problem
https://askgoodquestions.dev/guides/the-ai-junk-drawer-problem/
Field note:
When our AI workflow became a junk drawer
https://askgoodquestions.dev/field-notes/the-day-our-ai-workflow-became-a-junk-drawer/
The central idea is simple: more context is not always better context. Rules, notes, reminders, and examples can help, but after a certain point they can also start competing with each other and making the AI less precise.
In practical terms, the AI is no longer just doing the task. It is also sorting through the pile around the task.
That seems especially relevant for Clarion developers, where existing constraints, working patterns, version realities, and compatibility concerns often matter more than shiny rewrites or modern-looking substitutions.
I’ll be exploring this idea further in the upcoming book, Real Programmers Use AI.
1 post - 1 participant
]]>Just a quick note to let everyone know that I’ve set up a simple way to support ClarionHub, if anyone wishes to (see the coffee cup in the header).
ClarionHub was originally created and run by Brahn, and after his passing in 2021, Rebecca, Brahn’s wife, very kindly helped keep things running behind the scenes. I’ve since taken over the hosting and ongoing management to keep the site available for the community.
There are ongoing costs involved in running the site, so I’ve added a “buy me a coffee” link for anyone who would like to contribute.
https://buymeacoffee.com/clarionhub
This is completely optional — the site will remain free to use as always — but I wanted to make the option available.
Thanks,
Mark
7 posts - 5 participants
]]>Exception occurred at address 01022AA9
Exception code C0000005: Access Violation
Process PID=19320 Image: C:\KeyProj\Clarion8\Municipal\run\kf80.exe
Thread 1 Handle=00000244 TID=14864
Exception parameters:
00000000
00000070
EAX=00000000 EBX=00000001 ECX=0112F148 EDX=00458100
ESI=03630ED8 EDI=0019FE2F EBP=0019FEC4 ESP=0019FDCC
EIP=01022AA9 FLG=00010246
Call Stack:
01022AA9
010BDA03
76F2839E
76F2836E
Clarion modules:
01000000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaRUN.dll
00A70000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaDOS.dll
04A00000 08.00:9661 C:\KeyProj\Clarion8\Municipal\run\ClaIP.dll
13000000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\CLAnet.dll
04800000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\cwhhla.dll
00EE0000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaBAS.dll
00F00000 07.03:7900 C:\KeyProj\Clarion8\Municipal\run\claelp.dll
00F30000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaOLE.dll
01D20000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaASC.dll
00FE0000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaTPS.dll
01A80000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\CYBER80.dll
00F50000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ELPSETUP.dll
01B40000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\KFMAIL80.dll
01CD0000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaDB3.dll
01C80000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\ClaMSS.dll
05C00000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\TC80QWX.dll
01540000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\MTFILE80.dll
01180000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\KFGBL80.dll
00400000 08.00:9759 C:\KeyProj\Clarion8\Municipal\run\kf80.exe
Thread stack:
0019FDC0: 00 81 45 00 48 F1 12 01 9C 2A 02 01 2F FE 19 00
0019FDD0: 00 00 00 00 C4 FE 19 00 EC FD 19 00 D8 0E 63 03
0019FDE0: 00 81 45 00 08 81 45 00 2F FE 19 00 00 FE 19 00
0019FDF0: 01 00 00 00 2F FE 19 00 50 2A 00 08 64 3E 00 08
0019FE00: 00 00 00 00 0F E4 01 01 00 00 00 00 64 F1 42 00
0019FE10: C4 FE 19 00 28 FE 19 00 08 81 45 00 D8 0E 63 03
0019FE20: 00 00 00 00 D8 0E 63 03 64 F1 42 08 81 45 00 BC
0019FE30: FB 12 01 00 00 00 00 00 FF FF FF 01 50 2A 00 08
0019FE40: 64 3E 00 08 E2 B9 01 01 0C 83 42 00 17 FF 19 00
0019FE50: DB 7E 42 00 00 00 00 00 48 E8 42 00 C4 FE 19 00
0019FE60: 74 FE 19 00 A8 EC 42 00 0C 83 42 00 17 FF 19 00
0019FE70: 64 F1 42 00 1B 1F 40 00 C7 DB 0B 01 CC FF 19 00
0019FE80: 03 DA 0B 01 C4 FE 19 00 9C FE 19 00 13 4A 13 01
0019FE90: 0C 83 42 00 17 FF 19 00 0C 83 42 00 00 50 02 05
0019FEA0: 00 00 00 0C 83 42 00 13 00 00 00 13 2A DA 0B 01
0019FEB0: BC 4A 13 01 2A 6F 11 01 17 FF 19 00 DC F2 19 00
0019FEC0: 2C F3 19 00 80 FF 19 00 03 DA 0B 01 CC FF 19 00
0019FED0: CC FF 19 00 45 6F 11 01 17 FF 19 00 17 FF 19 00
0019FEE0: 08 DB 0B 01 38 96 AE 00 03 DA 0B 01 17 FF 19 00
0019FEF0: 5C ED 42 00 0C 83 42 00 80 FF 19 00 10 FF 19 00
0019FF00: 01 00 00 00 20 B9 45 00 00 70 45 00 0C 83 42 00
0019FF10: FF 3D 0B 17 FF 19 00 BC 4A 13 01 BC FE 19 00 04
0019FF20: 00 00 00 3C 4B 13 01 38 96 AE 00 78 93 12 01 8C
0019FF30: 93 12 01 A8 93 12 01 9C 93 12 01 C4 93 12 01 B8
0019FF40: 93 12 01 00 00 00 00 08 DB 0B 01 0C 83 42 00 13
0019FF50: 7C D6 0B 01 58 1E 40 00 58 1E 40 00 58 1E 40 00
0019FF60: 00 00 00 00 0C 83 42 00 01 00 00 00 5C ED 42 00
0019FF70: 68 1E 40 00 C9 FC 02 75 00 40 2D 00 B0 FC 02 75
0019FF80: DC FF 19 00 9E 83 F2 76 00 40 2D 00 C9 71 B4 C2
0019FF90: 00 00 00 00 00 00 00 00 00 40 2D 00 00 00 00 00
0019FFA0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0019FFB0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0019FFC0: 00 00 00 00 8C FF 19 00 00 00 00 00 E4 FF 19 00
0019FFD0: 60 B6 F3 76 8D 45 51 B4 00 00 00 00 EC FF 19 00
0019FFE0: 6E 83 F2 76 FF FF FF FF 4D 95 F4 76 00 00 00 00
0019FFF0: 00 00 00 00 58 1E 40 00 00 40 2D 00 00 00 00 00
12 posts - 6 participants
]]>HELP? What is this PHP stuff. Did malicious actor do something or did WIndows update and create this mess?
THanks,
ROn
5 posts - 3 participants
]]>It’s been a while since my last update, with features and improvements added incrementally over several releases. Below is a summary of what’s new since then. This doesn’t cover everything, so please check the changelogs on the repo for full details.
Numerous fixes across parsing, navigation, and folding
Examples include:
GitHub: GitHub - msarson/Clarion-Extension: VS Code Extension for Clarion · GitHub
Feedback welcome ![]()
1 post - 1 participant
]]>5 posts - 4 participants
]]>net.Start()
net.SetValue('', '{"program_id":"xxx","client_id":"xxx","api_key":"xxx"}', |
net:NoUrlEncode, 'application/json', '')
net.ContentType = 'application/json'
net.Post('https://licentio.dev/validate')
The response is a simple JSON that you parse with jFiles:
{
"valid": true,
"message": "License valid",
"license_type": "EXPIRY_DATE",
"days_remaining": 18,
"warning": true,
"warning_message": "License expires in 18 days"
}
Free plan available — no credit card required.
I’ll be doing a live demo this Saturday at the Clarion webinar (Spanish version). Happy to answer any questions here.
licentio.dev
1 post - 1 participant
]]>7 posts - 5 participants
]]>Its like the internal counter gets messed up after the delete, ie record 2, delete record 2, record 3 becomes record 2 and then the #For fetches record 3, skipping the replacement record 2.
As #For is mainly used with builtin symbols which cant be deleted, this might explain why it exists.
#For(%MultiSymbol)
#Delete(%MultiSymbol)
#EndFor
Wont delete all instances of the %MultiSymbol.
11 posts - 3 participants
]]>I tried importing the key but I’m getting “Error in Cryptonite.ImportKey.2(): Could not import the key onto the machine, CryptImportKey API failed. [1628]
Windows CryptoAPI error -2146893817: 80090007h: Bad Version of provider.”. Unfortunately I have to use that specific key.
My Clarion code:
PublicKeyLen LONG !
PublicKey STRING(4096) !
PublicKey64 STRING(4096) !
CODE
! Import Public Key
PublicKey64 = 'MII....iL5l1VxbU=' ! This is the whole key from url above
str.SetValue(PublicKey64,st:clip)
str.Base64Decode()
PublicKeyLen = str.Length()
PublicKey = str.GetValue()
If Crypto.ImportKey(PublicKey, PublicKeyLen, Crypto.hExchangeKey) <> Crypto:OK
stop('Import Failed')
End
I have this working Python script that does that
import base64
import hashlib
import logging
import os
import time
from dataclasses import dataclass
import requests
from typing import Optional
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding as asym_padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
def _get_encryption_public_key(self):
"""
Returns:
RSA key (cryptography).
Raises:
RuntimeError: Przy błędzie HTTP lub braku certyfikatu.
"""
url = f"{self.base_url}/security/public-key-certificates"
response = requests.get(url, headers={"Accept": "application/json"}, timeout=30)
if response.status_code != 200:
raise RuntimeError(
f"Błąd pobierania certyfikatów: HTTP {response.status_code} – {response.text}"
)
certs = response.json()
try:
token_cert = next(c for c in certs if "KsefTokenEncryption" in c["usage"])
except StopIteration:
raise RuntimeError("Brak certyfikatu KsefTokenEncryption w odpowiedzi API")
cert_der = base64.b64decode(token_cert["certificate"])
cert = x509.load_der_x509_certificate(cert_der, default_backend())
return cert.public_key()
def _encrypt_token(self, timestamp_ms: int, public_key) -> str:
"""
Encrypts token in format "{token}|{timestampMs}" with RSA-OAEP SHA-256 key.
Args:
timestamp_ms: Timestamp from challenge response (Unix ms).
public_key: public key RSA MF.
Returns:
str: Encrypted Base64 encoded token.
"""
token_string = f"{self.api_token}|{timestamp_ms}"
encrypted = public_key.encrypt(
token_string.encode("utf-8"),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None,
),
)
return base64.b64encode(encrypted).decode("ascii")```
How can this be accomplished in Clarion? Any syggestions?
5 posts - 2 participants
]]>127.0.0.1 as ProxyServer and 8000 as ProxyPort, also setting SSLCertificateOptions.DontVerifyRemoteCertificateCommonName and SSLCertificateOptions.DontVerifyRemoteCertificateWithCARoot to true - but inside the Demo application it does send and receive the request - but in my own application, it just straight goes from GET to PageReceived with no error and no data - doesn’t even make the call at all.
Now the only difference I can still find is my application is Legacy and the Demo is ABC - this can’t be it, can it? The reason it works in one and not the other?
5 posts - 2 participants
]]>Or is it just because they’re so awfully bad at maintaining their website?
Their timeline under updates has been down since February 2024, their documentation under support has been saying “Articles coming soon” for years - and the latest news is ANN : noyantis ReportGrid Wrapper Template : v25.11.12 from November 12, 2025?
//Peter
6 posts - 5 participants
]]>Only this report is customized for each client.
I would like a way to compile only this report, so that when I update the layout I don’t have to compile the entire system.
Which is what I do today.
thanks.
17 posts - 5 participants
]]>Guide:
When AI Defaults to Newer, Better, Faster
https://askgoodquestions.dev/guides/when-ai-defaults-to-newer-better-faster/
Field note:
The Moment I Realized the AI Needed the Rules First
https://askgoodquestions.dev/field-notes/the-moment-i-realized-the-ai-needed-the-rules-first/
One of the patterns I keep seeing is that if you let AI move into implementation without first loading the real project constraints, it tends to start “helping” by leaning toward newer libraries, cleaner rewrites, more modern approaches, and other things that may be completely wrong for the actual environment.
That is fine in theory. In real projects, especially older or mixed environments, it can get you into trouble fast.
This will also be part of my upcoming book, Real Programmers Use AI.
15 posts - 4 participants
]]>How do I know from inside a regular non-elevated exe clarion program, to which program is associated a given file extension? For example, I want to use Shellexecute to open a JPG, but before that I want to know if the JPG extension is associated with MSPaint or any other program, to execute different code previous to the call.
Kind regards,
Jorge Lavera
6 posts - 3 participants
]]>Thanks,
Keith Ferguson
5 posts - 2 participants
]]>I’m implementing FTP in my system using the FTP Manager from our friend Mike Duglas.
Everything seems to be working fine.
But when I try to delete a directory, I get an error.
I’ve tried to fix it but haven’t been able to.
Does anyone have a solution?
The error message is below.
Thanks everyone.
Log libCurl:
. . . .
HEADER_OUT: LIST
HEADER_IN: 150 Opening ASCII mode data connection for file list
TEXT: Maxdownload = -1
TEXT: abort upload
TEXT: Remembering we are in dir "www/usuarios/ftp/Ana_Lara_Cristo-00272/"
HEADER_IN: 226 Transfer complete
TEXT: Connection #0 to host ftp.softjep.com left intact
TEXT: Re-using existing connection with host ftp.softjep.com
HEADER_OUT: DELE /www/usuarios/ftp/Ana_Lara_Cristo-00272
HEADER_IN: 550 /www/usuarios/ftp/Ana_Lara_Cristo-00272: Is a directory
TEXT: QUOT command failed with 550
TEXT: shutting down connection #0
I did some research and it might be that the command to delete an empty directory needs to be
ftp .... -Q RMD dirToDelete
But I don’t know how to implement that in Mike’s code.
4 posts - 3 participants
]]>It supports secure SMTP, POP3, Microsoft OAuth, Google OAuth, built-in autodetect, and a guided Setup Wizard designed to make account setup dramatically easier for both developers and end users.
This is especially relevant for three groups of Clarion developers:
One of the features we are emphasizing is Zero Code OAuth. The developer does not have to write OAuth code. The wizard handles the user-facing flow, and the DLL handles the OAuth implementation behind the scenes.
We also published the docs and a dedicated OAuth setup guide that shows developers where to go to get their credentials, what to enter, and where to put it in the product.
There is also a downloadable demo that lets you:
So whether you want to test a standard email account, Gmail / Google OAuth, or Microsoft OAuth, you can see it working for yourself.
Pricing
Links:
5 posts - 3 participants
]]>