Update for Quricol library from Krzysztof Michalowski
Krzysztof Michalowski modified the code to load library dynamically. This allows you to run a program when there is no library. Here is the code provided to me by Krzysztof.
unit QuricolCode; interface uses Windows, SysUtils, Classes, Graphics, Dialogs; type TQRCode = class public class procedure GenerateBitmap(const FileName : string; const Text : string; Margin : integer = 4; PixelSize : integer = 3); class procedure GeneratePng(const FileName : string; const Text : string; Margin : integer = 4; PixelSize : integer = 3); class function GetBitmap(const Text : string; Margin : integer = 4; PixelSize : integer = 3) : TBitmap; class procedure GetPng(Stream : TStream; const Text : string; Margin : integer = 4; PixelSize : integer = 3); end; implementation { TQRCode } class procedure TQRCode.GenerateBitmap(const FileName, Text: string; Margin, PixelSize: integer); type TGenerateBMPWProc = procedure (fileName: PWChar; text : PWChar; margin : integer; size : integer); stdcall; var dllHandle : cardinal; generateBMPWProc : TGenerateBMPWProc; begin dllHandle := LoadLibrary('quricol32.dll'); if dllHandle <> 0 then begin try @generateBMPWProc := GetProcAddress(dllHandle, 'GenerateBMPW'); if Assigned (generateBMPWProc) then generateBMPWProc(PWChar(FileName), PWChar(Text), Margin, PixelSize) else ShowMessage('"GenerateBMPW" procedure not found'); finally FreeLibrary(dllHandle); end; end else begin ShowMessage('quricol32.dll not found / not loaded'); end; end; class procedure TQRCode.GeneratePng(const FileName, Text: string; Margin, PixelSize: integer); type TGeneratePNGWProc = procedure (fileName: PWChar; text : PWChar; margin : integer; size : integer); stdcall; var dllHandle : cardinal; generatePNGWProc : TGeneratePNGWProc; begin dllHandle := LoadLibrary('quricol32.dll'); if dllHandle <> 0 then begin try @generatePNGWProc := GetProcAddress(dllHandle, 'GeneratePNGW'); if Assigned (generatePNGWProc) then generatePNGWProc(PWChar(FileName), PWChar(Text), Margin, PixelSize) else ShowMessage('"GeneratePNGW" procedure not found'); finally FreeLibrary(dllHandle); end; end else begin ShowMessage('quricol32.dll not found / not loaded'); end; end; class function TQRCode.GetBitmap(const Text: string; Margin, PixelSize: integer): TBitmap; type TGetHBitmapW = function (text : PWChar; margin : integer; size : integer): HBITMAP; stdcall; var Bmp : HBITMAP; DIB: TDIBSection; ScreenDC : THandle; DC : THandle; dllHandle : cardinal; GetHBitmapWFunc : TGetHBitmapW; begin dllHandle := LoadLibrary('quricol32.dll'); if dllHandle <> 0 then begin try @GetHBitmapWFunc := GetProcAddress(dllHandle, 'GetHBitmapW'); if Assigned (GetHBitmapWFunc) then Bmp := GetHBitmapWFunc(PWChar(Text), Margin, PixelSize) else ShowMessage('"GetHBitmapW" function not found'); finally FreeLibrary(dllHandle); end; end else begin ShowMessage('quricol32.dll not found / not loaded'); end; GetObject(Bmp, SizeOf(DIB), @DIB); Result := TBitmap.Create(); Result.Width := DIB.dsBmih.biWidth; Result.Height := DIB.dsBmih.biHeight; Result.PixelFormat := pf32bit; ScreenDC := GetDC(0); DC := CreateCompatibleDC(ScreenDC); SelectObject(DC, Bmp); ReleaseDC(0, ScreenDC); BitBlt(Result.Canvas.Handle, 0, 0, Result.Width, Result.Height, DC, 0, 0, SRCCOPY); DeleteDC(DC); DeleteObject(Bmp); end; class procedure TQRCode.GetPng(Stream: TStream; const Text: string; Margin, PixelSize: integer); type TGetPNGW = procedure (text : PWChar; margin : integer; size : integer; var bufSize : integer; out ppvBits : PByte); stdcall; TDestroyBuffer = procedure(Buffer : PByte); stdcall; var size : integer; i : integer; buffer : PByte; ps : PByte; dllHandle : cardinal; GetPNGWProc : TGetPNGW; DestroyBufferProc : TDestroyBuffer; begin size := 0; dllHandle := LoadLibrary('quricol32.dll'); if dllHandle <> 0 then begin try @GetPNGWProc := GetProcAddress(dllHandle, 'GetPNGW'); if Assigned (GetPNGWProc) then GetPNGWProc(PWChar(Text), Margin, PixelSize, size, buffer) else ShowMessage('"GetPNGW" procedure not found'); if (size > 0) then begin ps := buffer; for I := 0 to size - 1 do begin Stream.Write(ps^, 1); inc(ps); end; @DestroyBufferProc := GetProcAddress(dllHandle, 'DestroyBuffer'); if Assigned (DestroyBufferProc) then DestroyBufferProc(buffer) else ShowMessage('"DestroyBuffer" procedure not found'); end; finally FreeLibrary(dllHandle); end; end else begin ShowMessage('quricol32.dll not found / not loaded'); end; end; end.
nice job you've done Serhiy Perevoznyk with quricol, but what about decoding the qr code? Do you know how to do this with delphi?
ReplyDeleteI will add this possibility to the library later
ReplyDeletegreat, looking forward to it
ReplyDeleteThank you for these very useful postings. I happened to notice a memory leak but only when when the call to GetBitmap is made and in tracking that down, it appears that it just needs a Result.free after DeleteObject(Bmp)line.
ReplyDeleteI spoke too soon regarding Result.free as that leads to an exception and it may have something to do with something on my end, but am still seeing a memory leak in GetBitmap. It isn't something critical since I'm not planning to use that particular routine. Thanks again.
ReplyDeleteI updated Quricol library and fixed the bug reported in the previous comment. Download: http://users.telenet.be/ws36637/download/quricol.zip
ReplyDelete