User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active

QRCoder is an open source .Net assembly for creating QR Codes.  What we're going to do is wrap that with an assembly in SnapDevelop we can use from PowerBuilder.  First thing we need to do is create a .Net standard Class Library project in SnapDevelop.

Once we've done that we go into the Nuget Package Manager and install the QRCoder library.

In our wrapper assembly, we just need to add a few lines of code 

 public string GenerateQRCode(string qrText)   
       QRCodeGenerator qRCodeGenerator = new QRCodeGenerator();  
       QRCodeData qRCodeData = qRCodeGenerator.CreateQrCode(qrText, QRCodeGenerator.ECCLevel.Q);  
       PngByteQRCode pngByteQRCode = new PngByteQRCode(qRCodeData);  
       byte[] qrCodeBytes = pngByteQRCode.GetGraphic(20);  
       string qrCodeString = Convert.ToBase64String(qrCodeBytes);  
       return qrCodeString;  

A couple of things to note here.  first, if you look at the QRCoder documentation the sample they give involves the base QRCode class and converts the result to a bitmap.  Since I want to pass this back to PowerBuilder as a byte array or, as I've done here, as a Base64 encoded string, converting the result is a bitmap first is an intermediate step I don't want or need.  So I used the PngByteQRCode class instead to get a byte array   Second, I am converting the byte array to a Base64 string.  You can return a byte array directly from the assembly, and the .Net Importer will convert it to a blob automatically.  The issue is that for debugging purposes I can't see inside of a blob variable in the PowerBuilder debugger.  So if something goes wrong I'm not sure what I got back.  By passing back a Base64 encoded string to PowerBuilder and then converting it to a blob in PowerScript I have better insight when debugging.

After you've compiled that, lets switch over to PowerBuilder 2019 R3 and use it.  I created an target that contains a window that has a single line edit (sle_1) to enter text, a picture control (p_1_ to display the bitmap and a command button to run the script needed to generate the QR code image using the assembly.  Now we need to run the .Net Assembly importer to import our wrapper assembly.

As usual with a window this is going to call a .net assembly using the importer I do the following in order to facilitate error handling.

1.  Declare the .net assembly wrapper object as an instance variable on the window 

 nvo_qrgenerator inv_generator  

 2.  Instantiate the wrapper object in the open event and register the error handler to an event on the window 

 inv_generator = Create nvo_qrgenerator  
 inv_generator.of_seterrorhandler( this, 'assemblyerror')  

 3.  Destroy the instance variable in the close event of the window 

 Destroy inv_generator   

 4.  Create a custom event on the window to use as the error handler, and display any error messages relayed by the .net assembly wrapper 

 MessageBox ( "Error", inv_generator.is_errortext )  

 With that done we're ready to add the code to call the wrapper object and put the generated QR code in the picture control: 

 string          ls_text  
 string          ls_base64  
 blob          lblb_qrcode  
 CoderObject          co  
 p_1.visible = FALSE  
 ls_text = sle_1.Text  
 ls_base64 = inv_generator.of_generateqrcode( ls_text )  
 co = create CoderObject  
 lblb_qrcode = co.base64decode(ls_base64)  
 destroy co  
 p_1.setpicture( lblb_qrcode )  
 p_1.visible = TRUE  

 That's it.  Enter some text, click the command button and you've got a QR code

There's a bunch of options that I haven't touched on such as generating the QR code in color or adding a custom image to the center of the QR code.  I'll let you explore those on your own.   If you want to skip performing all these steps and just get started with the code, I've uploaded it to CodeXchange.


Comments (7)

  1. Eduardo Adriano

Hi Bruce,
Thank you very much for the code.

I'm trying to use the "qrcodedemo" api with PB 2019 R3. I changed the path of the dll file to my personal folder. Clicking to generate the QRCode that would run the DLL gives the error:

"Call GerenateQRCode failed.
Error Text: Error calling external object function generatedqrcode. Do not possible load the file or assembly 'QRCoder, Version = ... "

I'm using Windows 10.
dotnet: 5.0.5 5.0.5 5.0.5

dotnet sdk 5.0.202

I would like a help to resolve the error please.

Your account does not have privileges to view attachments in the comment
  1. Bruce Armstrong

I'm not sure what you mean by "I changed the path of the dll file to my personal folder". Do you mean you changed the location that was included in the nvo_qrgenerator object?

Also, the QRCodeGenerator.dll file is just a wrapper around the QRCoder.dll. Do you have both in the location where you are attempting to load the assembly?

Your account does not have privileges to view attachments in the comment

Hai Bruce,
What is the reason for the below error message?
I completed this route as save you explained at the top...
but, getting error...

"Could not load file or assembly 'netstandard Version=, Culture-neutral,PublicKeyToken=cc7b13ffcd2ddd51' or one of its dependencies. The system cannot find the file specified"

Your account does not have privileges to view attachments in the comment
  1. Bruce Armstrong    SHAMEEM KAKKAD

Generally this means your project is targeting one version of the .net framework and you've reference a library that targets a different version.

Your account does not have privileges to view attachments in the comment
  1. SHAMEEM KAKKAD    Bruce Armstrong

Let me check and thanks for your reply...

Your account does not have privileges to view attachments in the comment
  1. Ramón San Félix Ramón

Great Bruce, thanks for your contributions to the community.

I have recently created a .Net library based on Zxing for the generation of barcodes of different types, including Qr.

The difference is that in addition to generating codes, it has the interesting option of reading them.

You can see my example here:

Your account does not have privileges to view attachments in the comment
  1. Tomas Beran

This is my first attempt to use SnapDevelop and here's my experience with this example. Information here may help beginners to avoid some try and fail attempts.
I use PB 2021
1. Create a new project based on Class Library .NET Standard as it's mentioned above.
2. In menu "Tools - Nuget Package Manager" -> "Manage Nuget Package for Solution" look for package "QRCoder". On the right side click the checkbox left to your project. Then click Install.
3. In menu "Project" -> "<your project> Properites" switch "Target framework" to ".NET Standard 2.0"
3. In your already generated .cs file insert row "using QRCoder;" at the end of the using block.
4. Put the code mentioned in the article into the pre-generated class.
5. Click menu Build -> Build Solution.
6. Create an export folder (somewhere, doesn't matter).
7. In Solution Explorer rclick the project, choose "Publish". Select a proper "target location", "configuration", "target framework" (again ".NET Standard 2.0"). Then follow the wizard. This step helps you solve dependencies.
8. Take all the files newly generated in the export folder from step 6. and copy them to the folder with your PB project.
9. Start PB. In menu Tools select ".NET DLL importer". Choose your DLL. Check whole DLL, click Import.
10. Move your newly created nvo from the app (project) library to a different library.
11. Remove the absolute path from the nvo instance variable named "is_assemblypath". Only filename must stay here for correct deployment.
11. Comment //inv_generator.of_seterrorhandler( this, 'assemblyerror') from the code in the article because there's no such method.
12. Open your PowerClient project. Go to 'External files' tab. Add all exported files here.

Don't use p_1.OriginalSize attribute because picture object gets crazy after loading from blob through p_1.setpicture(lblb_blb).
Once you touch the .NET DLL in PB the DLL and the folder containing this DLL is being locked until you close PB. Never start SnapDevelop directly from PB because if you close PB it closes SnapDevelop.

Your account does not have privileges to view attachments in the comment
There are no comments posted here yet