PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 4 5 [6] 7 8

Author Topic: Josť, if you're bored...  (Read 1343 times)

Chris Maher

  • FireFly3 Registered User
  • Little Newbie FireFly
  • *
  • Posts: 23
  • New FF3 User
Re: Josť, if you're bored...
« Reply #75 on: August 10, 2018, 08:58:50 AM »

Thank you. That amendment to PrintBitmapToFile works perfectly.

Quote
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 have been looking at the links to GDI+ that you posted. I have never used it before but it all seems familiar as most of my work in this area was via PB's GRAPHIC and XPRINT commands.

My knowledge of C and FB is a bit limited as yet to be able to convert the examples they give across to WinFBE/WinFBX but I'll keep trying and look at your templates and examples. Your various individual include files (coupled with the WinFBX Help file) are also a key learning resource. I am hoping to work through them one at a time as there is a lot to learn and I try to understand the code that I call.

Chris.
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #76 on: August 11, 2018, 01:34:00 AM »

I think that the use of GDI+ to do the drawing is one of the best options (certainly much better that the old GDI). I have been doing some tests and if using the default UnitWorld as the unit of measure, we can use the same coordinates no matter of the printer resolution. We can use other units of measure, such pixels, points, millimeters or inches, but then be will have to do scaling because the number of the units change with the resolution, whereas the world units remain the same. Therefore, I have added the GetHorizontalUnits and GetVerticalUnits methods to retrieve the number of units available for printing. I also have added PixelsToPointsX/Y and PointsToPixelsX/Y that perhaps we may need to work with fonts.

So, we can use the CPrint class to attach/choose a printer, with properties to get/set the printer values and also a method, PageSetup, to call the Page Setup Dialog if needed, and we can use GDI+ to do all the drawing. Although we can use the GDI+ Flat API, the GDI+ classes of WinFBX are more convenient.
« Last Edit: August 12, 2018, 06:02:09 AM by Josť Roca »
Logged

Chris Maher

  • FireFly3 Registered User
  • Little Newbie FireFly
  • *
  • Posts: 23
  • New FF3 User
Re: Josť, if you're bored...
« Reply #77 on: August 11, 2018, 04:58:37 AM »

That all looks good and shows direct examples of how you have translated and encapsulated the Microsoft GDI+ printer C code within FB. It really highlights the value of your classes as robust building blocks that remove the clutter and complexity without losing speed and control.

I agree the world units are really important to be device independent. I am looking forward to playing with it.
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #78 on: August 12, 2018, 06:09:32 AM »

I have made some small changes to the CPrint class and I have made a try at using GitHub and markdown for the documentation. Tell me what you think.

See: https://github.com/JoseRoca/WinFBX/blob/master/docs/CPrint%20Class.md

The advantage is that the documentation can be reviewed as soon as changes are made. without having to wait to an updated help file. If you find mistakes or have suggestions to improve it, please do it.
« Last Edit: August 12, 2018, 06:33:26 AM by Josť Roca »
Logged

Chris Maher

  • FireFly3 Registered User
  • Little Newbie FireFly
  • *
  • Posts: 23
  • New FF3 User
Re: Josť, if you're bored...
« Reply #79 on: August 12, 2018, 06:16:09 PM »

I like this GitHub and Markdown idea because it provides the ability to understand the class as a whole, as you are developing it, without initially having to decipher the code. Perhaps the uptake and response will be easier for those of us that are less used to the complexities that you are dealing with within each class.

For me it is about keying in a few lines of code and seeing what happens. This really helps with that. Code examples are good, but initially it's hard to absorb someone else's keystrokes and style.

Once it is understood then Paul's WinFBE will really make it fly!
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #80 on: August 12, 2018, 11:10:10 PM »

I have documented the other new class, CFileStream. As writing the documentation gives us the opportunity to revise the code, I have made some small changes and removed the Commit and Revert methods that are of no use unless we work with streams inside an storage file. New CStream.zip file attached.

I plan to document the available file functions and add some that are missing, such AfxCopyFile, AfxDeleteFile, AfxReplaceFile, AfxMoveFile, AfxCreateFolder or AfxDeleteFolder.

CFileStream documentation: https://github.com/JoseRoca/WinFBX/blob/master/docs/CFileStream%20Class.md

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #81 on: August 13, 2018, 04:31:04 AM »

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #82 on: August 13, 2018, 09:54:16 AM »

This is a replacement for the GB's FileDateTime function, that uses the obsolete Visual Basic's DATE format.

Code: [Select]
' ========================================================================================
' * Unicode replacement for Free Basic's FileDateTime.
' Returns the file's last modified date and time as Date Serial.
' wszFileName : Filename to retrieve date and time for.
' Return Value : Returns a Date Serial.
' Example:
' #include "windows.bi"
' #include "vbcompat.bi"
' #include "win/ole2.bi"
' DIM wszFileName AS WSTRING * MAX_PATH = ExePath & "\test.bas"
' DIM dt AS DOUBLE = AfxFileDateTime(wszFileName)
' PRINT Format(dt, "yyyy-mm-dd hh:mm AM/PM")
' ========================================================================================
PRIVATE FUNCTION AfxFileDateTime (BYREF wszFileName AS WSTRING) AS DOUBLE
   DIM fd AS WIN32_FIND_DATAW
   DIM hFind AS HANDLE = FindFirstFileW(wszFileName, @fd)
   IF hFind = INVALID_HANDLE_VALUE THEN RETURN 0
   FindClose hFind
   DIM ft AS FILETIME
   FileTimeToLocalFileTime(@fd.ftLastWriteTime, @ft)
   DIM st AS SYSTEMTIME
   FileTimeToSystemTime(@ft, @st)
   DIM dt AS DOUBLE
   SystemTimeToVariantTime @st, @dt
   RETURN dt
END FUNCTION
' ========================================================================================

FileLen replaced with
#define AfxFileLen AfxGetFileSize
« Last Edit: August 13, 2018, 10:09:28 AM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #83 on: August 13, 2018, 10:29:45 AM »

AfxChDir: Replacement for Free Basic's ChDir.

Code: [Select]
' ========================================================================================
' Changes the current directory for the current process.
' lpPathName : The path to the new current directory. This parameter may specify a relative
'              path or a full path. In either case, the full path of the specified directory
'              is calculated and stored as the current directory.
' Return value:
'   If the function succeeds, the return value is TRUE.
'   If the function fails, the return value is FALSE.
'   To get extended error information, call GetLastError.
' ========================================================================================
PRIVATE FUNCTION AfxSetCurDir (BYVAL pwszPathName AS LPCWSTR) AS BOOLEAN
   RETURN SetCurrentDirectory(pwszPathName)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Unicode replacement for Free Basic's ChDir.
' Return value: Returns 0 on success, or -1 on failure.
' ========================================================================================
PRIVATE FUNCTION AfxChDir (BYVAL pwszPathName AS LPCWSTR) AS BOOLEAN
   RETURN NOT SetCurrentDirectory(pwszPathName)
END FUNCTION
' ========================================================================================
« Last Edit: August 13, 2018, 11:37:28 AM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #84 on: August 13, 2018, 11:12:22 AM »

Unicode replacements for Environ and SetEnviron.

Code: [Select]
' ========================================================================================
' Retrieves the contents of the specified variable from the environment block of the
' calling process.
' - pwszName : The name of the environment variable.
' Return value: The contents of the specified environment variable.
' Example: DIM cws AS CWSTR = AfxEnviron("path")
' ========================================================================================
PRIVATE FUNCTION AfxEnviron (BYVAL pwszName AS LPCWSTR) AS CWSTR
   DIM wszBuffer AS WSTRING * 32767
   DIM cb AS DWORD = GetEnvironmentVariable(pwszName, @wszBuffer, 32767)
   RETURN LEFT(wszBuffer, cb)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Sets the contents of the specified environment variable for the current process.
' - pwszName : The name of the environment variable.
'              The name of the environment variable.
'              The operating system creates the environment variable if it does not exist
'              and pwszValue is not NULL.
' - pszValue : The contents of the environment variable.
'              The maximum size of a user-defined environment variable is 32,767 characters.
' Return value:
'   If the function succeeds, the return value is TRUE.
'   If the function fails, the return value is FALSE.
'   To get extended error information, call GetLastError.
' Example: AfxSetEnviron("path", "c:")
' ========================================================================================
PRIVATE FUNCTION AfxSetEnviron OVERLOAD (BYVAL pwszName AS LPCWSTR, BYVAL pwszValue AS LPCWSTR) AS BOOLEAN
   RETURN SetEnvironmentVariable(pwszName, pwszValue)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Sets the contents of the specified environment variable for the current process.
' - varexpr = Name and setting of an environment variable in the following (or equivalent)
'   form: varname=varstring. (varname being the name of the environment variable, and
'   varstring being its text value to set).
' Returns 0 on success, or -1 on failure.
' Example: AfxSetEnviron "path=c:"
' ========================================================================================
PRIVATE FUNCTION AfxSetEnviron OVERLOAD (BYREF varexp AS WSTRING) AS BOOLEAN
   DIM cwsName AS CWSTR = AfxStrExtract(1, varexp, "=")
   IF LEN(cwsName) = 0 THEN RETURN TRUE
   cwsName = TRIM(**cwsName)
   DIM cwsValue AS CWSTR
   DIM p AS LONG = INSTR(varexp, "=")
   IF p = 0 THEN RETURN TRUE
   cwsValue = MID(varexp, p + 1)
   cwsValue = TRIM(**cwsValue)
   IF LEN(cwsValue) = 0 THEN RETURN TRUE
   RETURN NOT SetEnvironmentVariable(cwsName, cwsValue)
END FUNCTION
' ========================================================================================

For Kill, #define AfxKill AfxDeleteFile.
« Last Edit: August 13, 2018, 11:37:09 AM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #85 on: August 13, 2018, 11:33:48 AM »

Replacement for Free Basic's MkDir.

Code: [Select]
' ========================================================================================
' Creates a new directory.
' - lpPathName : The path of the directory to be created.
'   To extend the limit to 32,767 wide characters, prepend "\?" to the path.
' Return value:
'   If the function succeeds, the return value is TRUE.
'   If the function fails, the return value is FALSE.
'   To get extended error information, call GetLastError.
'   Possible errors include the following.
'   - ERROR_ALREADY_EXISTS
'     The specified directory already exists.
'   - ERROR_PATH_NOT_FOUND
'     One or more intermediate directories do not exist; this function will only create
'     the final directory in the path.
' ========================================================================================
PRIVATE FUNCTION AfxCreateDirectory (BYVAL lpPathName AS LPCWSTR) AS BOOLEAN
   RETURN CreateDirectory(lpPathName, NULL)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Returns 0 on success, or -1 on failure.
' ========================================================================================
PRIVATE FUNCTION AfxMkDir (BYVAL lpPathName AS LPCWSTR) AS BOOLEAN
   RETURN NOT CreateDirectory(lpPathName, NULL)
END FUNCTION
' ========================================================================================

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #86 on: August 13, 2018, 12:05:57 PM »

FreeBasic's replacement for RmDir.

Code: [Select]
' ========================================================================================
' Deletes an existing empty directory.
' - lpPathName : The path of the directory to be removed. This path must specify an empty
'   directory, and the calling process must have delete access to the directory.
' To extend the MAX_PATH limit to 32,767 wide characters prepend "\?" to the path.
' If the function succeeds, the return value is TRUE.
' If the function fails, the return value is FALSE.
' To get extended error information, call GetLastError.
' The RemoveDirectory function marks a directory for deletion on close. Therefore, the
' directory is not removed until the last handle to the directory is closed.
' To recursively delete the files in a directory, use the SHFileOperation function.
' RemoveDirectory removes a directory junction, even if the contents of the target are not
' empty; the function removes directory junctions regardless of the state of the target object.
' ========================================================================================
PRIVATE FUNCTION AfxRemoveDir (BYVAL lpPathName AS LPCWSTR) AS BOOLEAN
   RETURN RemoveDirectoryW(lpPathName)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Unicode replacement for Free Basic's RmDir.
' Returns 0 on success and -1 on failure.
' ========================================================================================
PRIVATE FUNCTION AfxRmDir (BYVAL lpPathName AS LPCWSTR) AS BOOLEAN
   RETURN NOT RemoveDirectoryW(lpPathName)
END FUNCTION
' ========================================================================================

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #87 on: August 13, 2018, 12:24:53 PM »

Replacement for Free Basic's function FileCopy.

Code: [Select]
' ========================================================================================
' Copies an existing file to a new file.
' - lpExistingFileName : The name of an existing file.
'   To extend the limit of MAX_PATH characters to 32,767 wide characters prepend "\?" to the path.
'   If lpExistingFileName does not exist, CopyFile fails, and GetLastError returns ERROR_FILE_NOT_FOUND.
' - lpNewFileName : The name of the new file.
'   To extend the limit of MAX_PATH characters to 32,767 wide characters prepend "\?" to the path.
' bFailIfExists
' If this parameter is TRUE and the new file specified by lpNewFileName already exists, the
' function fails. If this parameter is FALSE and the new file already exists, the function
' overwrites the existing file and succeeds.
' If the function succeeds, the return value is nonzero.
' If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
' ========================================================================================
PRIVATE FUNCTION AfxCopyFile (BYVAL lpExistingFileName AS LPCWSTR, BYVAL lpNewFileName AS LPCWSTR, BYVAL bFailIfExists AS BOOLEAN = FALSE) AS BOOLEAN
   RETURN CopyFile(lpExistingFileName, lpNewFileName, bFailIfExists)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Unicode replacement for Free Basic's FileCopy.
' Returns 0 on success, or 1 if an error occurred.
' ========================================================================================
PRIVATE FUNCTION AfxFilecopy (BYVAL lpExistingFileName AS LPCWSTR, BYVAL lpNewFileName AS LPCWSTR) AS LONG
   DIM nRet AS LONG = IIF(CopyFile(lpExistingFileName, lpNewFileName, FALSE) = 0, 1, 0)
   RETURN nRet
END FUNCTION
' ========================================================================================

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #88 on: August 13, 2018, 12:40:01 PM »

Unicode replacement for Free Basic's Name function.

Code: [Select]
' ========================================================================================
' Moves an existing file or a directory, including its children.
' - lpExistingFileName : The name of an existing file.
'   To extend the limit of MAX_PATH characters to 32,767 wide characters prepend "\?" to the path.
'   If lpExistingFileName does not exist, CopyFile fails, and GetLastError returns ERROR_FILE_NOT_FOUND.
' - lpNewFileName : The name of the new file.
'   To extend the limit of MAX_PATH characters to 32,767 wide characters prepend "\?" to the path.
' Return value:
'   If the function succeeds, the return value is nonzero.
'   If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
' ========================================================================================
PRIVATE FUNCTION AfxMoveFile (BYVAL lpExistingFileName AS LPCWSTR, BYVAL lpNewFileName AS LPCWSTR) AS BOOLEAN
   RETURN MoveFile(lpExistingFileName, lpNewFileName)
END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION AfxRenameFile (BYVAL lpExistingFileName AS LPCWSTR, BYVAL lpNewFileName AS LPCWSTR) AS BOOLEAN
   RETURN MoveFile(lpExistingFileName, lpNewFileName)
END FUNCTION
' ========================================================================================
' ========================================================================================
' Unicode replacement for Free Basic's Name function.
' Returns 0 on success, or non-zero on failure.
' ========================================================================================
PRIVATE FUNCTION AfxName (BYVAL lpExistingFileName AS LPCWSTR, BYVAL lpNewFileName AS LPCWSTR) AS LONG
   RETURN NOT AfxMoveFile(lpExistingFileName, lpNewFileName)
END FUNCTION
' ========================================================================================

Josť Roca

  • Moderator
  • Master Member
  • *****
  • Posts: 3028
    • Jos
Re: Josť, if you're bored...
« Reply #89 on: August 13, 2018, 12:44:22 PM »

If I'm not wrong, we already have unicode replacements for all the FB file functions.

Curiously, the FB versions return inverse values that the API ones for success and failure.
Pages: 1 ... 4 5 [6] 7 8