PlanetSquires Forums

Please login or register.

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

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

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #90 on: August 13, 2018, 03:36:06 PM »

Changed the functions AfxWindowsVersion and AfxWindowsBuild to work with Windows 10. AfxWindowsVersion will return 1000 as the version number, meaning 10.0.

Code: [Select]
' ========================================================================================
' Returns the Windows version
' Platform 1:
'   400 Windows 95
'   410 Windows 98
'   490 Windows ME
' Platform 2:
'   400 Windows NT
'   500 Windows 2000
'   501 Windows XP
'   502 Windows Server 2003
'   600 Windows Vista and Windows Server 2008
'   601 Windows 7
'   602 Windows 8
'   603 Windows 8.1
'  1000 Windows 10
' Note: As Windows 95 and Windows NT return the same version number, we also need to call
' GetWindowsPlatform to differentiate them.
' ========================================================================================
'PRIVATE FUNCTION AfxWindowsVersion () AS LONG
'   DIM dwVersion AS DWORD
'   DIM AS LONG nMajorVer, nMinorVer
'   dwVersion = GetVersion
'   nMajorVer = LOBYTE(LOWORD(dwVersion))
'   nMinorVer = HIBYTE(LOWORD(dwVersion))
'   FUNCTION = (nMajorVer + nMinorVer / 100) * 100
'END FUNCTION
' ========================================================================================
' ========================================================================================
' GetVersion returns version 6.02 (Windows 8) in Windows 10 if the application has not a
' manifest.
' ========================================================================================
PRIVATE FUNCTION AfxWindowsVersion () AS LONG
   DIM hLib AS HMODULE = LoadLibraryW("NtDll.dll")
   IF hLib = NULL THEN EXIT FUNCTION
   DIM pfnRtlGetVersion AS FUNCTION (BYVAL lpVersionInformation AS OSVERSIONINFOEXW PTR) AS LONG
   pfnRtlGetVersion = CAST(ANY PTR, GetProcAddress(hLib, "RtlGetVersion"))
   IF pfnRtlGetVersion = NULL THEN EXIT FUNCTION
   DIM osverinfo AS OSVERSIONINFOEXW
   IF pfnRtlGetVersion(@osverinfo) = 0 THEN   ' STATUS_SUCCESS
      FUNCTION = (osverinfo.dwMajorVersion + osverinfo.dwMinorVersion / 100) * 100
   END IF
   FreeLibrary hLib
END FUNCTION
' ========================================================================================

Code: [Select]
' ========================================================================================
' Returns the Windows build
' ========================================================================================
'PRIVATE FUNCTION AfxWindowsBuild () AS LONG
'   DIM dwVersion AS DWORD
'   dwVersion = GetVersion
'   IF dwVersion < &H80000000 THEN FUNCTION = HIWORD(dwVersion)
'END FUNCTION
' ========================================================================================
' ========================================================================================
PRIVATE FUNCTION AfxWindowsBuild () AS LONG
   DIM hLib AS HMODULE = LoadLibraryW("NtDll.dll")
   IF hLib = NULL THEN EXIT FUNCTION
   DIM pfnRtlGetVersion AS FUNCTION (BYVAL lpVersionInformation AS OSVERSIONINFOEXW PTR) AS LONG
   pfnRtlGetVersion = CAST(ANY PTR, GetProcAddress(hLib, "RtlGetVersion"))
   IF pfnRtlGetVersion = NULL THEN EXIT FUNCTION
   DIM osverinfo AS OSVERSIONINFOEXW
   IF pfnRtlGetVersion(@osverinfo) = 0 THEN   ' STATUS_SUCCESS
      FUNCTION = osverinfo.dwBuildNumber
   END IF
   FreeLibrary hLib
END FUNCTION
' ========================================================================================

Chris Maher

  • Little Newbie
  • *
  • Posts: 24
  • New FF3 User
Re: Josť, if you're bored...
« Reply #91 on: August 15, 2018, 05:11:30 AM »

Hi Josť,

Unless I am reading it wrong the following Methods in CPrint are being blocked by this initial m_hDC check:
Code: [Select]
IF m_hDC THEN RETURN 0
GetHorizontalUnits
GetVerticalUnits
PixelsToPointsX
PixelsToPointsY
PointsToPixelsX
PointsToPixelsY

Also a minor typo on the GitHub documentation "GetDC - Returns the name of the attached printer."
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #92 on: August 15, 2018, 08:08:33 AM »

Yes, it should be IF m_hDC = NULL THEN RETURN 0. I noticed that there was not check and added one (unfortunately wrong) and copy pasted it to the other functions. These are the kind of silly mistakes that I'm trying to avoid by having the code being checked by others.

I also have modified the GtHub documentation, which I plan to arrange by groups:
https://github.com/JoseRoca/WinFBX/tree/master/docs

Thanks very much. It is the first time that somebody, except Paul, has collaborated. GitHub it's a great way to keep the code and documentation up to date. I have added to the File Management group the documentation for CFindFile, CFileStream and CTextStream, and I'm preparing the one for CFileSys. I also have added to the Strings group documentation for the String Procedures. Later, I will add documentation for CWSTR and CBSTR.


Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #93 on: August 15, 2018, 08:37:09 AM »

The available Free Basic classes, implemented as types, are fast and lightweight, yet powerful because you can have several constructors and overloading of methods and operators. The available classes in WinFBX are a great way to learn how to use them. True classes will support interfaces. Now, is like we had a class with only one interface, but are a great way to encapsulate code and make it reusable. I'm very happy with them. They allow to make complex things simpler to use.
« Last Edit: September 18, 2018, 04:55:30 AM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #94 on: August 15, 2018, 11:26:39 AM »

I'm making changes to CFileSys and CTextStream to allow to work with the standard StdIn, StdErr and StdOut using the methods of the CTextStream class.

First working test:

Code: [Select]
'#CONSOLE ON
#include "Afx/AfxFile.inc"
using Afx

' // Create an instance of the CFileSys class
DIM pFileSys AS CFileSys
' // Create an instance of the CTextStream class initialized
' // with a pointer to the standard StdOut stream
DIM pTxtStm AS CTextStream = pFileSys.GetStdOutStream
' // Write a string and an end of line to the stream
pTxtStm.WriteLine "This is a test."

PRINT "Press any key to end..."
SLEEP

The default is ansi, but we can also work with unicode passing TRUE to GetStdOutStream.

Code: [Select]
DIM pTxtStm AS CTextStream = pFileSys.GetStdOutStream(TRUE)

Alternative syntax:

Code: [Select]
'#CONSOLE ON
#include "Afx/AfxFile.inc"
using Afx

' // Create an instance of the CTextStream class initialized
' // with a pointer to the standard StdOut stream
DIM pTxtStm AS CTextStream = CFileSys().GetStdOutStream(TRUE)
' // Write a string and an end of line to the stream
pTxtStm.WriteLine "This is a test."

PRINT "Press any key to end..."
SLEEP

Isn't it cool?
« Last Edit: August 15, 2018, 11:34:02 AM by Josť Roca »
Logged

Paul Squires

  • Administrator
  • Guru Member
  • *****
  • Posts: 9287
  • Windows 10
    • PlanetSquires Software
Re: Josť, if you're bored...
« Reply #95 on: August 15, 2018, 11:31:32 AM »

I'm making changes to CFileSys and CTextStream to allow to work with the standard StdIn, StdErr and StdOut using the methods of the CTextStream class.

First working test:

Code: [Select]
'#CONSOLE ON
#include "Afx/AfxFile.inc"
using Afx

' // Create an instance of the CFileSys class
DIM pFileSys AS CFileSys
' // Create an instance of the CTextStream class initialized
' // with a pointer to the standard StdOut stream
DIM pTxtStm AS CTextStream = pFileSys.GetStdOutStream
' // Write a string and an end of line to the stream
pTxtStm.WriteLine "This is a test."

PRINT "Press any key to end..."
SLEEP

The default is ansi, but we can also work with unicode passing TRUE to GetStdOutStream.

Code: [Select]
DIM pTxtStm AS CTextStream = pFileSys.GetStdOutStream(TRUE)


Well, that's interesting!
Logged
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer

Chris Maher

  • Little Newbie
  • *
  • Posts: 24
  • New FF3 User
Re: Josť, if you're bored...
« Reply #96 on: August 15, 2018, 11:37:13 AM »

Hi Josť,

1.) I am pretty sure that using your WinFBX Classes is a key skill that needs to be learned to produce fast, solid and reliable FB Windows code based upon a great framework.

It certainly isn't the simple text output that I used when I was first learning BASIC, but the power of the windows and the additional tools it gives me are fascinating (and 64 bit). I am finding that I am slowly understanding more and more of CPrint just by playing with the code and reading your GitHub documentation (I really like the new format and further short examples in FB echoing the Microsoft Docs could be really valuable).

2.) I also have a small request. I am not sure if you left PaperLength and PaperWidth out of CPrint for a reason but they are vital for thermal label printers using a windows driver where the page size is almost never standard.

Code: [Select]
' ========================================================================================
' Returns the printer paper length in units of 1/10 of a millimeter.
' ========================================================================================
PRIVATE PROPERTY CPrint.PaperLength () AS LONG
   RETURN this.GetDocumentProperties(DM_PAPERLENGTH)
END PROPERTY
' ========================================================================================
' ========================================================================================
' Sets the printer paper length in units of 1/10 of a millimeter. This value overrides the
' length of the paper specified by PaperSize, and is used if the paper is of a custom size,
' or if the device is a dot matrix printer, which can print a page of arbitrary length.
' ========================================================================================
PRIVATE PROPERTY CPrint.PaperLength (BYVAL nSize AS LONG)
   this.SetPrinterInfo(DM_PAPERLENGTH, nSize)
END PROPERTY
' ========================================================================================

' ========================================================================================
' Returns the printer paper width in units of 1/10 of a millimeter.
' ========================================================================================
PRIVATE PROPERTY CPrint.PaperWidth () AS LONG
   RETURN this.GetDocumentProperties(DM_PAPERWIDTH)
END PROPERTY
' ========================================================================================
' ========================================================================================
' Sets the printer paper width in units of 1/10 of a millimeter. This value overrides the
' width of the paper specified by PaperSize. This MUST be used if PaperLength is used.
' ========================================================================================
PRIVATE PROPERTY CPrint.PaperWidth (BYVAL nSize AS LONG)
   this.SetPrinterInfo(DM_PAPERWIDTH, nSize)
END PROPERTY
' ========================================================================================

These are my versions based upon your work - please feel free to use and tidy these up as you see fit.

3.) It would also be useful for all printer types to Get and Set the non-printing margin widths at the Top, Bottom, Left and Right of a page. This could/would be affected by orientation and very often they are non-symmetrical due to mechanical limitations. Currently I don't know where to start with this.

Chris.
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #97 on: August 15, 2018, 11:47:15 AM »

> I am not sure if you left PaperLength and PaperWidth out of CPrint for a reason

Just an oversight. This is why I want some collaboration to help with testing and suggestions. Much more with CPrint, since I don't even have a printer.

> It would also be useful for all printer types to Get and Set the non-printing margin widths at the Top, Bottom, Left and Right of a page.

Currently, you can set them with calling the SetPageSetup method, that activates the Set Page Setup dialog. I have yet to find if there is a way to do it programatically.

« Last Edit: August 15, 2018, 11:49:26 AM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #98 on: August 15, 2018, 12:54:38 PM »

I have added the suggested properties and also the SetPageSize function, that allows to set both the length and width with one call.

The GitHub repository and documentation has been updated.
« Last Edit: August 15, 2018, 01:36:40 PM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #99 on: August 15, 2018, 01:05:49 PM »

> I am finding that I am slowly understanding more and more of CPrint just by playing with the code

This is the way to do it. With practice, it will become second nature. I started using Free Basic not very long ago and now I feel like I have been using it all my life. As it uses many C conventions, probably the most important skill is to be proficient with the use of pointers.

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #100 on: August 15, 2018, 01:41:53 PM »

Modified CFileSys and CTextStream to allow to use the methods of the CTextStream class with the standard StdErr, StdIn and StdOut streams. It works with ansi and unicode.

- CFileSys.inc: Added the GetStdErrStream, GetStdInStream and GetStdOutStream methods.
- CTextStream.inc: Added a new constructor and the LET and CAST operators. The new constructor and the LET operator allow to initialize the class by passing a pointer to an existing TextStream interface.

Example:

Code: [Select]
'#CONSOLE ON
#include "Afx/AfxFile.inc"
using Afx

' // Create an instance of the CTextStream class initialized
' // with a pointer to the standard StdOut stream
DIM pTxtStm AS CTextStream = CFileSys().GetStdOutStream(TRUE)
' // Write a string and an end of line to the stream
pTxtStm.WriteLine "This is a test."

PRINT "Press any key to end..."
SLEEP

The GitHub repository and documentation have been updated.
« Last Edit: August 15, 2018, 04:22:29 PM by Josť Roca »
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #101 on: August 16, 2018, 02:09:21 AM »

Hi Chris,

Regarding the margins, I have found a way to get them:

Code: [Select]
DIM totalWidth AS LONG = GetDeviceCaps(m_hdc, PHYSICALWIDTH)
DIM printWidth AS LONG = GetDeviceCaps(m_hdc, HORZRES)
DIM leftMargin AS LONG = GetDeviceCaps(m_hdc, PHYSICALOFFSETX)
DIM rightMargin AS LONG = totalWidth - printWidth - leftMargin

DIM totalHeight AS LONG = GetDeviceCaps(m_hdc, PHYSICALHEIGHT)
DIM printHeight AS LONG = GetDeviceCaps(m_hdc, VERTRES)
DIM topMargin AS LONG = GetDeviceCaps(m_hdc, PHYSICALOFFSETY)
DIM bottomMargin AS LONG = totalHeight - printHeight - topMargin

I will add properties to the CPrint class.

But setting the margins is a different question. Even PowerBasic provides a XPRINT GET MARGIN statement, but not a XPRINT SET MARGIN.

Chris Maher

  • Little Newbie
  • *
  • Posts: 24
  • New FF3 User
Re: Josť, if you're bored...
« Reply #102 on: August 16, 2018, 04:13:12 AM »

Hi Josť,

Brilliant. I am sure I looked at GetDeviceCaps but just didn't see them!

As for setting the margins, I suppose that makes sense if the margins are mechanical limitations they could not be made smaller.

I think what I was looking for can be done in code as virtual margins (or an offset) that may be wider than these minimums.

Thanks for spending the time to find them. Also I keep forgetting what a massive resource the PB code base is in pointing to some of the answers.
Logged

Chris Maher

  • Little Newbie
  • *
  • Posts: 24
  • New FF3 User
Re: Josť, if you're bored...
« Reply #103 on: August 16, 2018, 06:58:54 AM »

Hi Josť,

I guess I am doing it wrong but I can't seem to set any properties in CPrint. Here's a sample of me trying to set Paper Size and Orientation but it is the same for everything I have tried.

Code: [Select]
'#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 HRX as long = pPrint.GetHorizontalResolution()
DIM HRY as long = pPrint.GetVerticalResolution ()
Print "Print Area pix:", HRX, HRY
DIM PPIX as long = pPrint.GetPPIX()
DIM PPIY as long = pPrint.GetPPIY()
Print "Resolution dpi:", PPIX, PPIY
DIM PWmm as long = (HRX/PPIX)*25.4
DIM PHmm as long = (HRY/PPIY)*25.4
Print "Print Area mm:", PWmm,PHmm
Dim WX as long = pPrint.GetHorizontalUnits()
Dim WY as long = pPrint.GetVerticalUnits()
Print "World Units:",, WX,WY
Dim PaperW as long = pPrint.PaperWidth
Dim PaperL as long = pPrint.PaperLength
Print "Paper Size 0.1 mm:", PaperW,PaperL
Dim PO as long = pPrint.Orientation
Print "Orientation:",, PO

DIM wszOutput AS WSTRING * MAX_PATH = ExePath & "\GdiplusPrint.pdf"
DIM hdcPrint AS HDC = pPrint.GetDC
DIM docInfo AS DOCINFOW
docInfo.cbSize = SIZEOF(DOCINFOW)
docInfo.lpszDocName = CAST(LPCWSTR, @"GdiplusPrint")
docInfo.lpszOutput = @wszOutput

dim PaperSet as boolean = pPrint.SetPaperSize (2800, 1900)
Print "Paper Size set:", PaperSet
pPrint.Orientation = DMORIENT_LANDSCAPE
Print "Orientation:",, pPrint.Orientation

StartDocW(hdcPrint, @docInfo)
StartPage(hdcPrint)
SCOPE
   DIM graphics AS CGpGraphics = hdcPrint
   DIM pen AS CGpPen = GDIP_ARGB(255, 255, 0, 0)
   graphics.DrawLine(@pen, 0, 0, WX, WY)
   graphics.DrawRectangle(@pen, 0, 0, WX-2, WY-2)
   graphics.DrawEllipse(@pen, 0, 0, WX-1, WY-1)
END SCOPE
EndPage(hdcPrint)
EndDoc(hdcPrint)

PRINT "Press any key to end..."
SLEEP

Any help would be greatly appreciated..
Logged

Josť Roca

  • Moderator
  • Guru Member
  • *****
  • Posts: 3268
Re: Josť, if you're bored...
« Reply #104 on: August 16, 2018, 04:26:47 PM »

Try with a real printer. With Microsoft PDF printer OpenPrinterW fails with an access denied error.
Pages: 1 ... 5 6 [7] 8 9 ... 12