Trying to get (and eventually set) the paper selection at runtime using Delphi FireMonkey for MacOS. I've substituted what I think are the correct variables and functions into a routine that I have used successfully to get the paperrect and the pagerect, as well as the orientation. But this code gives me an access error when I release FPrintInfo. I'm sure it's something simple. Hoping a kind programmer can help.
function getPaperName: string;
var
FPrintInfo: NSPrintInfo;
paper: integer;
begin
result:='';
FPrintInfo := TNSPrintInfo.Wrap(TNSPrintInfo.OCClass.sharedPrintInfo);
FPrintInfo.retain;
PMGetPageFormatPaper(FPrintInfo.PMPageFormat, @paper);
FPrintInfo.release;
result:=IntToStr(paper);
end;
Possible hint... Here is the PMGetPageFormatPaper function in the Apple documentation:
func PMGetPageFormatPaper(
_ format: PMPageFormat,
_ paper: UnsafeMutablePointer<PMPaper?>
) -> OSStatus
I notice that the pointer variable <PMPaper?> includes a question mark, while the corresponding variables in the functions that I am using successfully do not. I imagine that is telling me something important, but I don't know what.
Thanks for any help.
Scott
The second parameter for the call to PMGetPageFormatPaper
is of type PPMPaper
, not an Integer
. It is essentially a pointer to a handle that can be used to call the PMPaperXXX
functions e.g. PMPaperGetName
, PMPaperGetHeight
, PMPaperGetWidth
etc. The whole process is a bit more complicated, however this might do what you want:
uses
Macapi.PrintCore, Macapi.AppKit, Macapi.CoreFoundation, Macapi.CocoaTypes, Macapi.Helpers, Macapi.Foundation;
function getPaperName: string;
var
LPrintInfo: NSPrintInfo;
LPaper: PMPaper;
LName: CFStringRef;
LPrinter: PMPrinter;
LSession: PMPrintSession;
begin
Result := '';
if PMCreateSession(@LSession) = 0 then
begin
if PMSessionGetCurrentPrinter(LSession, @LPrinter) = 0 then
begin
LPrintInfo := TNSPrintInfo.Wrap(TNSPrintInfo.OCClass.sharedPrintInfo);
if (PMGetPageFormatPaper(LPrintInfo.PMPageFormat, @LPaper) = 0) then
begin
if PMPaperCreateLocalizedName(LPaper, LPrinter, @LName) = 0 then
try
Result := NSStrToStr(TNSString.Wrap(LName));
finally
CFRelease(LName);
end;
end;
end;
end;
end;
Ultimately, the PMPaperCreateLocalizedName
method needs to be called to get the paper name. PMPaperGetName
appears to have been removed from later macOS SDKs without Apple updating their documentation, though they do recommend using PMPaperCreateLocalizedName
anyway
This method requires a handle to the printer (of type PMPrinter
), which is obtained using PMSessionGetCurrentPrinter
, and this requires a PMPrintSession
, so this is obtained using PMCreateSession
.
The paperName
parameter of PMPaperCreateLocalizedName
is a pointer to a CFStringRef
, which can just be wrapped as an NSString
using TNSString.Wrap
and converted into a string using NSStrToStr
Since the method has the word Create
in it, the convention in Apple APIs is that if something is created, it needs to be released, hence the call to CFRelease