• Welcome to PlanetSquires Forums.
 

José, if you're bored...

Started by Paul Squires, August 02, 2018, 09:19:19 PM

Previous topic - Next topic

Paul Squires

Quote from: Joerg Buckel on August 09, 2018, 08:36:00 AM
Hello José
Thank you for your tirelessness in taking up and implementing new ideas. What you do for the FreeBasic community is indescribable for me. Your WinFBX offers possibilities in programming for everyone, which are normally only available to professionals with corresponding experience. Maybe the feedback doesn't come in the crowd. Maybe it's because your level needs to be understood first. Well, I can't.
Thank you again.

My sentiments exactly Joerg!

If José had not created all of this wonderful code then I'd most likely be a C++ or C# coder by now instead of sticking with BASIC that I love more.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

CTextStream.Create

' - bOverwrite: Boolean value that indicates whether you can overwrite an existing file.
'   The value is true if the file can be overwritten, false if it can't be overwritten.
'   If omitted, existing files are not overwritten.

However, in the parameter list, bOverwrite defaults to TRUE (and not FALSE like implied by the source code comments and the Help file text).

PRIVATE FUNCTION CTextStream.Create (BYREF cbsFileName AS CBSTR, BYVAL bOverwrite AS BOOLEAN = TRUE, BYVAL bUnicode AS BOOLEAN = FALSE) AS HRESULT

Unless I'm reading this wrong, it looks like the source and help description is reverse of what it should be. For the record, I vote to keep the function declaration default as TRUE and just amend the help text.


Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

CTextStream.Open

bUnicode: One of three Tristate values used to indicate the format of the opened file. If omitted, the file is opened as ASCII

That whole "Tristate" comment seems strange? The parameter is a true/false Boolean indicating if Unicode or not.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Chris Maher

Hello José

A request for a small addition to CPrint.inc please.

I have added the lpszOutput Member of the DOCINFOW Structure to a test version of CPrint.inc and used it to create 'silent' output files from my 'Microsoft Print to PDF' printer on Windows 10.

It seems to work very well and would be very useful for all kinds of reports/bills linked to email or archive systems etc.

'#CONSOLE ON
#define UNICODE
#INCLUDE ONCE "Afx/CPrint.inc"
#INCLUDE ONCE "Afx/AfxGdiplus.inc"
USING Afx

AfxSetProcessDPIAware
DIM pPrint AS CPrint
pPrint.AttachPrinter("Microsoft Print to PDF")

DIM wszFileName AS WSTRING * MAX_PATH = ExePath & "\TestGraphic.jpg"
DIM wszOutput AS WSTRING * MAX_PATH = ExePath & "\TestFileName.pdf"

pPrint.PrintBitmap("Test Queue Name", wszOutput, AfxGdipBitmapFromFile(wszFileName))

PRINT
PRINT "Press any key..."
SLEEP


I also agree with both Joerg and Paul. These are excellent tools.

..and Paul's effort bringing all this together is truly amazing.

Many thanks to you both.

Regards,

Chris.

José Roca

#49
Using a memory bitmap doesn't seem a good idea after all because the results will depend of the resolution of the monitor and if your application is DPI aware.

The printing has to be done between StartDoc/EndDoc, StartPage/EndPage:


   StartDoc(hdcPrint, &docInfo);
   StartPage(hdcPrint);
      Graphics* graphics = new Graphics(hdcPrint);
      Pen* pen = new Pen(Color(255, 0, 0, 0));
      graphics->DrawLine(pen, 50, 50, 350, 550);
      graphics->DrawRectangle(pen, 50, 50, 300, 500);
      graphics->DrawEllipse(pen, 50, 50, 300, 500);
      delete pen;
      delete graphics;
   EndPage(hdcPrint);
   EndDoc(hdcPrint);


All graphics commands between StartDoc and EndDoc are routed to a temporary metafile. After the call to EndDoc, the printer driver converts the data in the metafile into the format required by the specific printer being used.

See: https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-sending-gdi-output-to-a-printer-use

Also worth reading: Optimizing Printing by Providing a Printer Handle
https://docs.microsoft.com/en-us/windows/desktop/gdiplus/-gdiplus-optimizing-printing-by-providing-a-printer-handle-use

I don't have expertise in printing, so I'm learning.

José Roca

#50
Quote from: Paul Squires on August 09, 2018, 09:46:38 AM
CTextStream.Open

bUnicode: One of three Tristate values used to indicate the format of the opened file. If omitted, the file is opened as ASCII

That whole "Tristate" comment seems strange? The parameter is a true/false Boolean indicating if Unicode or not.

For the documentation, I do a lot of copy and paste and this leads to mistakes. The scarce documentation talks about a third available value, TriState_UseDefault (aka TriState_Mixed), but it is not very explanatory. It only says: "Opens the file using the system default."

I will change the documentation to remove the reference to TriState and only say that TRUE opens the file as unicode and FALSE as ASCII.

In fact, in the code source file I have it right:
bUnicode: TRUE or FALSE. Indicates the format of the opened file. If omitted, the file is opened as ASCII.

I will change it to:
bUnicode: Boolean value indicating the format of the opened file. True to open the file as unicode, False to open it as ASCII. If omitted, the file is opened as ASCII.

José Roca

#51
Quote from: Paul Squires on August 09, 2018, 08:55:59 AM
CTextStream.Create

' - bOverwrite: Boolean value that indicates whether you can overwrite an existing file.
'   The value is true if the file can be overwritten, false if it can't be overwritten.
'   If omitted, existing files are not overwritten.

However, in the parameter list, bOverwrite defaults to TRUE (and not FALSE like implied by the source code comments and the Help file text).

PRIVATE FUNCTION CTextStream.Create (BYREF cbsFileName AS CBSTR, BYVAL bOverwrite AS BOOLEAN = TRUE, BYVAL bUnicode AS BOOLEAN = FALSE) AS HRESULT

Unless I'm reading this wrong, it looks like the source and help description is reverse of what it should be. For the record, I vote to keep the function declaration default as TRUE and just amend the help text.

Yet another copy and paste problem. In the original interface, the default is False, but apparently I thought that it was better if it was True. I will remove the "not" from "If omitted, existing files are not overwritten."

Not only the code has to be tried, but the documentation has also to be reviewed.

José Roca

#52
Quote
A request for a small addition to CPrint.inc please.

I have added the lpszOutput Member of the DOCINFOW Structure to a test version of CPrint.inc and used it to create 'silent' output files from my 'Microsoft Print to PDF' printer on Windows 10.

It seems to work very well and would be very useful for all kinds of reports/bills linked to email or archive systems etc.

Interesting suggestion. This is why I want participation.

I have added a new method called PrintBitmapToFile. Works like the existing PrintBitmap method but instead of the document name you will pass the output file name.

BTW I wasn't aware of the existence of the "Microsoft Print to PDF" driver. I did not exist in my previous Windows 7 system. I will use it instead of Bullzip.

José Roca

#53
Quote from: Paul Squires on August 09, 2018, 08:39:14 AM
I'm working on doing the conversion of the FB file handling routines to your stream classes. Not sure if I'll get to the print class today but I'll try.

Using the WinFBX help file, I'm thinking that you might need to explain what the HRESULT code is. I remember it from your COM programming but I'm not sure if others would readily identify it. Maybe put a hyperlink in the help file to a general page that describes HRESULT and lists some common codes like are specified at https://docs.microsoft.com/en-us/windows/desktop/seccrypto/common-hresult-values

I realize that your GetErrorInfo will return an empty string if no error but it is cleaner to do an inline error result check when opening a file. Like this:

   dim pStream AS CTextStream
   if pStream.OpenUnicode(wszFileName, IOMode_ForReading) <> S_OK then exit function

Maybe even if you indicate that the Return Value of Open/OpenUnicode is a non-zero HRESULT value. At least then users can do this:

   if pStream.OpenUnicode(wszFileName, IOMode_ForReading) <> 0 then exit function

Just a suggestion... as I think of stuff when I'm working through the conversion, I'll post them for you to consider.

The problem with hyperlinks is that they die very often. Microsoft is moving all the documentation to Microsoft Docs and it is a mess until they finish it, since the documentation for many of the parameters is still lacking and replaced with TBD.

Besides, the help file is intended as a reference, not as a tutorial. We have also to explain what is a bitmap, a handle, a stream...?

Error Handling in COM:
https://docs.microsoft.com/en-us/windows/desktop/com/error-handling-in-com

Structure of COM Error Codes
https://docs.microsoft.com/en-us/windows/desktop/com/structure-of-com-error-codes

I doubt that a novice to COM will understand anything posted in these links.

Maybe I can change "An HRESULT code" to "S_OK (0) on success, or an HRESULT error code on failure."

The GetErrorInfo function is only intended to provide a little help because, apart from some standard HRESULT codes, they aren't unique, i.e. the same HRESULT can mean different things depending of the COM server that returns it. In the AfxCOM.inc file, I provide the AfxGetOleErrorInfo function, that returns a description (sometimes localized) of the error, but unfortunately it will only work if the COM server supports the IErrorInfo interface, and most don't.

That said, any suggestion to improve the documentation is welcome. Currently it has more than four thousand entries and it must contain many mistakes and many things should be better explained.

Paul Squires

QuoteMaybe I can change "An HRESULT code" to "S_OK (0) on success, or an HRESULT error code on failure."

I agree with you regarding links and explanations, and I think the short sentence above is sufficient. :)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Paul Squires

Hi José,

Can you run the following code? I get a GPF when the code finishes. A problem with the DESTRUCTOR maybe?

Quote
#include once "\afx\AfxFile.inc"

dim pStream as CFileStream

if pStream.Open("_binary.txt", STGM_CREATE or STGM_WRITE) = S_OK then
   'dim as string pBuffer = string(65, 10)
   'pStream.Write strptr(pBuffer), len(pBuffer)
   'pStream.Close
end if

I had no problems at all with the CTextStream class. I was able to convert every instance of FB file handling commands over to CTextStream without any trouble at all. I have two areas in WinFBE that deal with binary files so I tried to change that code to use CFileStream. I noticed that it correctly created the file with correct contents but it would GPF the editor. I then wrote a simple test file (the code I posted above) and that code also GPF's. Maybe I am not correctly understand the CFileStream syntax.

Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

Something as stupid as forgetting to set m_pStream to NULL.


' ========================================================================================
' Releases the stream object.
' ========================================================================================
PRIVATE SUB CFileStream.Close
   ' // Release the IStrean interface
   IF m_pStream THEN m_pStream->lpvtbl->Release(m_pStream)
   m_pStream = NULL
   m_Result = 0
END SUB
' ========================================================================================

José Roca

#57
Well, I have succesfully written a working test.


'#CONSOLE ON
#define UNICODE
#INCLUDE ONCE "Afx/CPrint.inc"
#INCLUDE ONCE "Afx/CGdiplus/CGdiplus.inc"
USING Afx

DIM pPrint AS CPrint
pPrint.AttachPrinter("Microsoft Print to PDF")
DIM hdcPrint AS HDC = pPrint.GetDC
DIM docInfo AS DOCINFOW
StartDocW(hdcPrint, @docInfo)
StartPage(hdcPrint)
SCOPE
   DIM graphics AS CGpGraphics = hdcPrint
   DIM pen AS CGpPen = GDIP_ARGB(255, 0, 0, 0)
   graphics.DrawLine(@pen, 50, 50, 350, 550)
   graphics.DrawRectangle(@pen, 50, 50, 300, 500)
   graphics.DrawEllipse(@pen, 50, 50, 300, 500)
END SCOPE
EndPage(hdcPrint)
EndDoc(hdcPrint)

PRINT
PRINT "Press any key..."
SLEEP


It's time to learn how to use my GDI+ classes :) Fortunately, there are several hundred examples available.


Paul Squires

That fix didn't seem to stop the GPF.... I will check more tonight but the sample code I posted seems to GPF even after the m_pStream = NULL fix.
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

José Roca

#59
It works in my computer. Try adding using Afx after #include once "\afx\AfxFile.inc", although in my computer it works even without adding it.


'#CONSOLE ON
#define UNICODE
#include once "\afx\AfxFile.inc"
using Afx

dim pStream as CFileStream

if pStream.Open("_binary.txt", STGM_CREATE or STGM_WRITE) = S_OK then
   dim as string pBuffer = string(65, 10)
   pStream.Write strptr(pBuffer), len(pBuffer)
   pStream.Close
end if

PRINT
PRINT "Press any key..."
SLEEP