Cocoa(Mac Os X)打印多页,为什么预览窗口显示2页而不是1页?

Jos*_*han 5 printing macos cocoa objective-c

我有一个我正在研究的可可应用程序,我在其中创建了一个我要发送到打印机的customView.在子类NSView中,我也设置了一些框架选项,代码如下.我有2个全局变量来保存在main()函数外声明的打印信息.

- (id)initWithFrame:(NSRect)frame
{
    extern NSPrintInfo *globalPrintInfo;
    extern NSPrintOperation *globalPrintOperation;

    //Modify the frame before it's sent to it's super method.  Also set the global variables to there default values.
    globalPrintOperation = [NSPrintOperation printOperationWithView:self];
    globalPrintInfo = [globalPrintOperation printInfo];//Get the print information from it.

    [globalPrintInfo setBottomMargin:0.0];
    [globalPrintInfo setLeftMargin:0.0];
    [globalPrintInfo setTopMargin:0.0];
    [globalPrintInfo setRightMargin:0.0];

    [globalPrintOperation setPrintInfo:globalPrintInfo];//save the printInfo changes.

    //modify the frame to reflect the correct height & width of the paper.
    frame.size.height = globalPrintInfo.paperSize.height-globalPrintInfo.topMargin-globalPrintInfo.bottomMargin;
    frame.size.width = globalPrintInfo.paperSize.width-globalPrintInfo.leftMargin-globalPrintInfo.rightMargin;
    frame.origin.x=0;
    frame.origin.y=0;

    NSLog(@"Printer Name=%@, Printer Type=%@",globalPrintInfo.printer.name,globalPrintInfo.printer.type);

    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.

    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

对于子类NSView,我可以看到它的边界,我在下面的代码中添加了以下代码的drawRect方法.

- (void)drawRect:(NSRect)dirtyRect
{
    if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
        NSLog(@"Drawing To Screen");
    } else {
        NSLog(@"Drawing To Printer");
    }

    // Draw common elements here

    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];

    //Set color of drawing to green, and fill the rectangle green, so we can see it's boundaries.
    [[NSColor greenColor] setFill];
    NSRectFill(dirtyRect);

    CGContextSelectFont(myContext, "Helvetica-Bold", 18, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(myContext, 10);
    CGContextSetTextDrawingMode(myContext, kCGTextFillStroke);

    CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);//black
    CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);//blue stroke
    CGContextShowTextAtPoint(myContext, 40, 0, "Here is some text!", 18);

}
Run Code Online (Sandbox Code Playgroud)

当我使用全局变量运行打印操作时,就像这样......

- (IBAction)print:(id)sender {
    NSLog(@"Testing Print");

    extern NSPrintOperation *globalPrintOperation;

    [globalPrintOperation runOperation];
}
Run Code Online (Sandbox Code Playgroud)

我看到了打印窗口,我看到了我的"绿色背景",但由于某种原因,它被拆分为2页.我不确定究竟发生了什么,因为我将框架的宽度和高度设置为pagesize.width和height,任何帮助都是值得赞赏的.我看到的一些图像如下.

我的猜测是,页面大小的宽度和高度与用于定义视图框架的像素单位类型的单位不同.

我的最终目标是创建一个用户选择他们想要的程序,并根据他们选择的选项打印特定页面,但首先我要弄清楚如何在"1"页面上获得我期望的"内容" '2'.我可以通过实验手动找出宽度和高度,但对于我假设的不同纸张尺寸,这不会是非常动态的.

提前致谢.

此搜索

镜像2

编辑***

我刚刚为下面的NSVIEW编辑了我的代码到下面的代码

//METHOD OVERIDES
- (id)initWithFrame:(NSRect)frame
{
    extern NSPrintInfo *globalPrintInfo;
    extern NSPrintOperation *globalPrintOperation;

    //Modify the frame before it's sent to it's super method.  Also set the global variables to there default values.
    globalPrintOperation = [NSPrintOperation printOperationWithView:self];//use whatever is currently there as the default print operation.
    globalPrintInfo = [globalPrintOperation printInfo];//Get the print information from it.

    [globalPrintInfo setBottomMargin:0.0];
    [globalPrintInfo setLeftMargin:0.0];
    [globalPrintInfo setTopMargin:0.0];
    [globalPrintInfo setRightMargin:0.0];

    [globalPrintOperation setPrintInfo:globalPrintInfo];//save the printInfo changes.

    //modify the frame to reflect the correct height & width of the paper.
    frame.size.height = (globalPrintInfo.paperSize.height-globalPrintInfo.topMargin-globalPrintInfo.bottomMargin);
    frame.size.width = globalPrintInfo.paperSize.width-globalPrintInfo.leftMargin-globalPrintInfo.rightMargin;
    frame.origin.x=0;
    frame.origin.y=0;

    NSLog(@"Printer Name=%@, Printer Type=%@",globalPrintInfo.printer.name,globalPrintInfo.printer.type);

    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.

    }

    return self;
}

- (void)drawRect:(NSRect)dirtyRect
{
    if ( [NSGraphicsContext currentContextDrawingToScreen] ) {
        NSLog(@"Drawing To Screen");
    } else {
        NSLog(@"Drawing To Printer");
    }

    // Draw common elements here

    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];

    //Set color of drawing to green, and fill the rectangle green, so we can see it's boundaries.
    [[NSColor greenColor] setFill];
    NSRectFill(dirtyRect);

    CGContextSelectFont(myContext, "Helvetica-Bold", 18, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(myContext, 10);
    CGContextSetTextDrawingMode(myContext, kCGTextFillStroke);

    CGContextSetRGBFillColor(myContext, 0, 0, 0, 1);//black
    CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);//blue stroke
    CGContextShowTextAtPoint(myContext, 40, 0, "Here is some text!", 18);

}


- (BOOL)knowsPageRange:(NSRangePointer)range {
    NSRect bounds = [self bounds];
    float printHeight = [self calculatePrintHeight];

    range->location = 1;
    range->length = NSHeight(bounds) / printHeight + 1;

    NSLog(@"Calculated Page Range");
    return YES;
}

// Return the drawing rectangle for a particular page number
- (NSRect)rectForPage:(int)page {
    NSRect bounds = [self bounds];
    float pageHeight = [self calculatePrintHeight];
    NSLog(@"Created Rect For View");
    return NSMakeRect( NSMinX(bounds), NSMaxY(bounds) - page * pageHeight,
                      NSWidth(bounds), pageHeight );
}

//CUSTOM METHODS

// Calculate the vertical size of the view that fits on a single page
- (float)calculatePrintHeight {

    extern NSPrintInfo *globalPrintInfo;
    extern NSPrintOperation *globalPrintOperation;

    // Obtain the print info object for the current operation

    // Calculate the page height in points
    NSSize paperSize = [globalPrintInfo paperSize];
    float pageHeight = paperSize.height - [globalPrintInfo topMargin] - [globalPrintInfo bottomMargin];

    // Convert height to the scaled view
    float scale = [[[globalPrintInfo dictionary] objectForKey:NSPrintScalingFactor]
                   floatValue];

    NSLog(@"Calculated Print Height:%f",(pageHeight/scale));
    return (pageHeight / scale);
}

@end
Run Code Online (Sandbox Code Playgroud)

我能够得到我现在想要的东西,接受当我去打印预览时它仍然认为出于某种原因有第二页?现在不确定为什么.我会上传我看到的内容......

请注意它是如何说2?第二页只是空白.

在此输入图像描述

Jos*_*han 1

我不完全确定,但我在某种程度上回答了我的问题。在我的代码中(大部分是我从苹果打印示例代码中获得的,有这样的部分:

- (BOOL)knowsPageRange:(NSRangePointer)range {
    NSRect bounds = [self bounds];
    float printHeight = [self calculatePrintHeight];

    range->location = 1;
    range->length = NSHeight(bounds) / printHeight + 0;

    NSLog(@"Calculated Page Range");
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

这是子类 NSView 的重写方法之一,在苹果代码中它说 printHeight + 1,所以我将其更改为 printHeight + 0,现在页面只显示 1 of 1。

然而,我仍然有一个奇怪的问题,它下面似乎仍然有一些白色边框,我不确定它的用途。如果有人能弄清楚那是什么,请告诉我。它与问题中发布的图像中的白色边框相同,正上方写着 1 of 1 或 1 of 2,正下方写着“这里有一些文字!”