-
Jun 28th, 2024, 04:15 AM
#1
[twinBASIC] gPdfMerge - A GUI-based PDF merger
gPdfMerge v1.2
Latest version: v1.2.14, 07 Jul 2024
gPdfMerge is a simple utility written in twinBASIC mainly for me to try out using pdfium.dll, Google's open source PDF utility. It will merge the selected PDFs together, either into a new file, or into the first file on the list. You can optionally specify which pages in each document should be merged, and if you're appending the first in list, where to insert them at. That's all there is to it right now; just a brief experiment before I make a 64bit version of a more complex PDF control.
Updates:
Important: Starting with version 1.2, newer builds of pdfium.dll are used. These are obtained from https://github.com/bblanchon/pdfium-binaries/releases. Version 1.2 was tested with 128.0.6569.0 (01 Jul 2024), but newer versions should continue to work fine. Click 'Show all .. assets' to find the Windows versions; the file names you need are pdfium-win-x86.tgz and pdfium-win-x64.tgz. gPdfMerge v1.2+ will not work with the 2018-era original DLLs used with version 1.0.
(Version 1.2 - 07 Jul 2024)
-Adds a 'Search for pages' function which opens a new dialog you can use to search for a range of pages to merge:
(Version 1.1)
-Range entry textbox now only enabled if an item is selected.
-Specifying a single pdf with page range to trim it now supported.
Build notes:
The project is configured as follows:
-The project's root folder should contain the .twinproj file, and folders win32 and win64 with the respective bitness version of pdfium.dll
-The compiled project must have pdfium.dll in the same folder with the .exe (the build output is set to \win32 and \win64).
One thing of interest, all the VB6 samples didn't have save functionality. I wasn't positive on how to implement it at first; it uses a very VB/tB unfriendly method:
Code:
typedef struct FPDF_FILEWRITE_ {
int version;
int (*WriteBlock)(struct FPDF_FILEWRITE_* pThis,
const void* pData,
unsigned long size);
} FPDF_FILEWRITE;
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SaveAsCopy(FPDF_DOCUMENT document,
FPDF_FILEWRITE* pFileWrite,
FPDF_DWORD flags);
Functions in UDTs defined like that isn't something you usually see. pdfium makes you write your own write function. Other languages weren't helpful here... it seems all the ones I looked at had a built in class that somehow worked with this layout. We're not so lucky. It looked like a simple function pointer to a routine with a file write would work, and it did with one caveat: Despite the DLL's 32bit export calling convention being _stdcall, this callback had to be _cdecl, which might explain why nobody had done it in VB6 before. While there were solutions for APIs, afaik it wasn't until 2021 CDecl functions became practical with The trick's VBCDeclFix, an amazing piece of work that actually seems to finish VB6's incomplete CDecl support.
twinBASIC, of course, supports CDecl natively, so no hacks are needed.
The code opens for write the output using CreateFile prior to calling FPDF_SaveAsCopy, then fills in a copy of the UDT with AddressOf WriteBlock
Code:
Private Type FPDF_FILEWRITE
version As Long
WriteBlock As LongPtr
End Type
Dim tWrite As FPDF_FILEWRITE
tWrite.version = 1
tWrite.WriteBlock = AddressOf WriteBlock
Private Function WriteBlock CDecl(ByVal pThis As LongPtr, ByVal pData As LongPtr, ByVal size As Long) As Long
If hFileOut Then
Dim cbRet As Long
Return WriteFile(hFileOut, ByVal pData, size, cbRet, vbNullPtr)
End If
End Function
Et voilà.
Thanks and Notes
Developed using pdfium builds from https://github.com/bblanchon/pdfium-binaries/releases
Merge routine based on pdfium-cli: https://github.com/klippa-app/pdfium-cli
Also special thanks to tB Discord user mike webb for getting me interested in this and helping test the program while under development. mike also contributed the code for the CompressRange function in v1.2-- very good work, I was having trouble getting my head around it!
Command line
Command line usage:
Merge: gPdfMerge.exe /i "C:...\Input1.pdf" "C:...\Input2.pdf" /o "C:\path\Output.pdf"
Append: gPdfMerge.exe /i "C:...\Input1.pdf" "C:...\Input2.pdf"
Append or merge with ranges and/or insert idx not support via command line in v1.0
Download from GitHub
Repo includes browsable source and binary builds.
(Project use my WinDevLib package for Windows APIs; since all files are built into a .twinproj right now, it's too big to attach to this post even if I wanted to-- that's also why the source is so large)
Last edited by fafalone; Jul 7th, 2024 at 03:19 AM.
-
Jun 28th, 2024, 04:44 AM
#2
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
You should make a link to this in the VB6 getting the ball rolling thread. You are coming up with some great utils.
Spurred on by the new life in TB64?
https://github.com/yereverluvinunclebert
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
-
Jun 28th, 2024, 05:46 AM
#3
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Originally Posted by fafalone
One thing of interest, all the VB6 samples didn't have save functionality. I wasn't positive on how to implement it at first; it uses a very VB/tB unfriendly method:
Code:
typedef struct FPDF_FILEWRITE_ {
int version;
int (*WriteBlock)(struct FPDF_FILEWRITE_* pThis,
const void* pData,
unsigned long size);
} FPDF_FILEWRITE;
FPDF_EXPORT FPDF_BOOL FPDF_CALLCONV FPDF_SaveAsCopy(FPDF_DOCUMENT document,
FPDF_FILEWRITE* pFileWrite,
FPDF_DWORD flags);
Functions in UDTs defined like that isn't something you usually see. pdfium makes you write your own write function.
Would have to disagree on this.
Any C-Sourcecode i've seen had those.
In a nutshell: It's C's "try" to "offer" something like Class-Methods we're used to from vb6, with one difference:
It allows you to write your own Procedure/Function, and as you pointed out: pdfium EXPECTS you to do that, which in the end "translates" to a callback, since you're just passing a pointer to the function
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Jun 28th, 2024, 06:32 AM
#4
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
It's unusual in structure in terms of what I'm normally porting to VB/tB, the Windows API. The few places a callback is used in UDTs, the function is defined separately and the UDT definition makes it clear it's a function pointer to that definition, not just putting the definition in the UDT.
Like take the GetOpenFileName API; the callback entry is LPOFNHOOKPROC lpfnHook;, then elsewhere is the typedef UINT_PTR (CALLBACK *LPOFNHOOKPROC) (HWND, UINT, WPARAM, LPARAM);; that's just a lot more clear to me what is expected, and pretty much without exception how the Windows API is done.
I got it right on my first guess how to do it (other than initially not realizing it was CDecl and trying other things for 2-3 minutes before trying that), so it's not like I was lost for hours, just a little different than my own experience.
----------------
You should make a link to this in the VB6 getting the ball rolling thread. You are coming up with some great utils.
Spurred on by the new life in TB64?
I used to do lots of VB6 code bank projects. I've been wanting so many of the features tB offers for so many years... 64bit support, more language features, etc. Having those is so great I'm ok with the bugs and unimplemented stuff during beta, so tB is now my daily driver, and yes the new features do open up a few more options and reasons to do 64bit conversions, but mainly it's just replaced VB6 for me. If I use VB6 now, it's to test compatibility or backport something I think is so cool the people who haven't yet embraced tB should get to use it too
-
Jun 28th, 2024, 06:44 AM
#5
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Originally Posted by fafalone
It's unusual in structure in terms of what I'm normally porting to VB/tB, the Windows API. The few places a callback is used in UDTs, the function is defined separately and the UDT definition makes it clear it's a function pointer to that definition, not just putting the definition in the UDT.
Like take the GetOpenFileName API; the callback entry is LPOFNHOOKPROC lpfnHook;, then elsewhere is the typedef UINT_PTR (CALLBACK *LPOFNHOOKPROC) (HWND, UINT, WPARAM, LPARAM);; that's just a lot more clear to me what is expected, and pretty much without exception how the Windows API is done.
I got it right on my first guess how to do it (other than initially not realizing it was CDecl and trying other things for 2-3 minutes before trying that), so it's not like I was lost for hours, just a little different than my own experience.
Faf, maybe i wasn't clear enough or you misunderstood: I'm NOT critisizing you or your knowledge. On the contrary, you probably have more expierence than me with stuff like that.
All said: Nicely done tool.
The only thing weirding me out at first look was the listbox top-right, being alphanumerically sorted, which probably was pure happenstance that it was the correct order.
It took me a few minutes to spot the "up"/"Down"-Buttons on the left of the Listbox...
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
-
Jun 28th, 2024, 06:51 AM
#6
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
No worries I hadn't taken it as a criticism, was just clarifying why I said it.
The ListBox's initial order is just whatever the file dialog returns... if you sorted your open dialog by date, they'd be in that order. Windows defaults to sort by name, so it would be that unless you changed it.
-
Jun 28th, 2024, 07:12 AM
#7
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Originally Posted by fafalone
I think is so cool the people who haven't yet embraced tB should get to use it too
Agreed. When I am familiar and confident using TB64 generated utils. then ultimately I will eventually migrate myself, lock, stock and barrel. At the moment though I am in a great migration of my own, from javascript to VB6 along with a leap into getting my head around RC6. When that is finally complete I will take small steps toward TB64.
https://github.com/yereverluvinunclebert
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
-
Jun 28th, 2024, 08:20 AM
#8
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Just a heads up, you can use RC6 in tB, but Olaf hasn't and is very unlikely to make a 64bit version even if tB made it possible, so any RC6 project would be limited to 32bit in tB.
tB has so, so much more to offer than 64bit, but just to let you know.
-
Jun 28th, 2024, 08:43 AM
#9
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Btw, RC6 recompile in TB could also get rid of all support DLLs baggage (sqlite, cairo) by embedding OBJ/LIB files directly into final Ax-DLL.
cheers,
</wqw>
-
Jun 29th, 2024, 07:34 AM
#10
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Originally Posted by fafalone
Just a heads up, you can use RC6 in tB, but Olaf hasn't and is very unlikely to make a 64bit version even if tB made it possible, so any RC6 project would be limited to 32bit in tB.
tB has so, so much more to offer than 64bit, but just to let you know.
I suppose it is time to ask Olaf some questions on his roadmap. I'll try that and see how that goes. I am assuming that a 64bit version of RC6 will be on the cards especially when TB64 can be used to recompile his code. I can't see a technical reason why he wouldn't use it. I always assume he has his own plans and that he will eventually come up with something to surprise us all. He certainly has the brains.
I have to move away from .js if I want to retain my 'widget' designs as working entities. I see 32bit VB6 with RC6 as an enabler to keep my graphical 'stuff' going. The resulting 32bit binaries are for me, no problem for the moment, I now call them WoW64! (sounds good, almost exciting, to the great unwashed).
Ultimately though, I do want to build using TB64 to achieve a 64 bit binary, if that is possible by some sort of linking/embedding 32bit DLLs to produce 64 binaries - then that would be acceptable. IF not, then Olaf must know that he has to eventually come up with a 64bit set of DLLs. Possibly, he will come to the acceptance that TB64's workable existence meets his criteria for releasing his code as FOSS.
Something will come along, I am sure of that. I am positive.
I do have a TwinBasic 'question' that needs to be answered regarding transparent forms and click-through PNGs, what I have seen so far is basic legacy-style Windows forms and I would like to know whether TB64 has suitability for creation of non-standard, form less applications, graphical applications using partly transparent graphical controls with associated events and proper handling of click-throughs &c. My 'sort' of application that you have already seen. I am not expecting you to answer this question, I need to dig into TB64 myself and determine this.
RC6 handles it well. Not perfectly in the way I have grown accustomed, but it does it. One just has to know how and realise that there are limitations/characteristics that have to be overcome using methods to which I have been previously unfamiliar. I'm getting there.
https://github.com/yereverluvinunclebert
Skillset: VMS,DOS,Windows Sysadmin from 1985, fault-tolerance, VaxCluster, Alpha,Sparc. DCL,QB,VBDOS- VB6,.NET, PHP,NODE.JS, Graphic Design, Project Manager, CMS, Quad Electronics. classic cars & m'bikes. Artist in water & oils. Historian.
By the power invested in me, all the threads I start are battle free zones - no arguing about the benefits of VB6 over .NET here please. Happiness must reign.
-
Jun 29th, 2024, 07:54 AM
#11
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
There's no built in help for it but you could implement it the same way RC6 does. Or use OpenGL/DirectX. tB did however add a lot more transparency-related stuff lately; child control transparency and alpha blending taking advantage of Windows 8+ APIs.
Olaf has the brains but he's not the most personable sort... seems quite unhappy Wayne didn't sign on to his vision and build tB's UI around RC6, so I wouldn't hold out much hope for 64bit RC6 until OlafBasic or whatever in 2050+. And then it probably won't be a standalone DLL that can be called from anywhere but built into his compiler/IDE.
-
Jul 2nd, 2024, 06:28 AM
#12
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Critical update: Please download v1.0.6.2. The initial release contains a bug that truncates the last 2 bytes of PDFs read. This didn't result in any corrupt files in my tests, but it's highly likely to at some point. I apologize for the inconvenience.
https://github.com/fafalone/gPdfMerge
-
Jul 7th, 2024, 03:20 AM
#13
Re: [twinBASIC] gPdfMerge - A GUI-based PDF merger
Project updated: v1.2
Important: Starting with version 1.2, newer builds of pdfium.dll are used. These are obtained from https://github.com/bblanchon/pdfium-binaries/releases. Version 1.2 was tested with 128.0.6569.0 (01 Jul 2024), but newer versions should continue to work fine. Click 'Show all .. assets' to find the Windows versions; the file names you need are pdfium-win-x86.tgz and pdfium-win-x64.tgz. gPdfMerge v1.2+ will not work with the 2018-era original DLLs used with version 1.0.
(Version 1.2 - 07 Jul 2024)
-Adds a 'Search for pages' function which opens a new dialog you can use to search for a range of pages to merge:
(Version 1.1)
-Range entry textbox now only enabled if an item is selected.
-Specifying a single pdf with page range to trim it now supported.
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|