NSPrintOperation上下文始终为零,从而导致崩溃。打印时如何设置上下文?

时间:2019-03-15 21:40:06

标签: macos printing nsprintoperation

我有一个要打印的自定义NSView。在使用NSView和打印选项进行设置之后,我将进行以下调用:

    ui_print("***************************************");
ui_print("*          ______________             *");
ui_print("*         / ___/ . /  . /             *");
ui_print("*        / /_ /  _/  _ /              *");
ui_print("*       /  _//  \/  /                 *");
ui_print("*      /__/_/_^__\_/DESTROYER         *");
ui_print("*                                     *");
ui_print("***************************************");
ui_print(" ");
ui_print("     **********************************");
ui_print("     *     Software Edition:  1.1     *");
ui_print("     **********************************");
sleep(5);
ui_print(" ");
ui_print("******************************");
ui_print("* Reformatting FRP Partition *");
ui_print("******************************");
ui_print(getprop("ro.frp.pst"));
ui_print("******************************");
format("ext4″, "EMMC",""+(getprop("ro.frp.pst")), "0″);
sleep(1);
ui_print(" ");
ui_print("******************************");
ui_print("*         COMPLETED          *");
ui_print("******************************");
sleep(2);
ui_print(" ");
ui_print("***************************************");
ui_print("*          ______________             *");
ui_print("*         / ___/ . /  . /             *");
ui_print("*        / /_ /  _/  _ /              *");
ui_print("*       /  _//  \/  /                 *");
ui_print("*      /__/_/_^__\_/DESTROYER         *");
ui_print("*                      by Zillinium   *");
ui_print("*   _______________________________   *");
ui_print("*     You MUST do a Factory Reset     *");
ui_print("*     and remove the SIM Card Now.    *");
ui_print("* ___________________________________ *");
ui_print("* Do not connect to WiFi during setup *");
ui_print("***************************************");
ui_print(" ");
ui_print(" ");
set_progress(1.000000);
sleep(10);

“ theContext”始终为零。如果我忽略了这个,在我打电话时:

NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView: printView printInfo: printInfo];

[NSPrintOperation setCurrentOperation: printOperation];
[printView beginDocument];

NSGraphicsContext* theContext = printOperation.context;

我得到一个例外,说:“ [常规] lockFocus / unlockFocus发送到不在窗口中的视图”

如果我对此予以评论,则会收到大约十亿条消息,内容如下:“ CGContextDrawPath:无效上下文0x0。如果要查看回溯,请设置CG_CONTEXT_SHOW_BACKTRACE环境变量。”启用回溯功能仅显示我的所有绘图都是引起该绘图的原因。

如果我在视图的“ DrawRect:”函数中查看图形上下文:

[printView beginPageInRect: rect atPlacement: location];

graphicsContext和context均为零。

那么,我该怎么做才能获得有效的打印环境?我看到有一个NSPrintOperation方法createContext,但是文档说不要直接调用它,如果我忽略它,它就无济于事,并向打印机发射了大约八个空作业。

最新版本的代码,仍会导致空上下文:

NSGraphicsContext *graphicsContext = [NSGraphicsContext currentContext];
CGContextRef      context = [[NSGraphicsContext currentContext] graphicsPort];

2 个答案:

答案 0 :(得分:0)

beginDocumentbeginPageInRect:atPlacement:在打印会话的开始和每页的开始被调用。如果需要,请覆盖这些方法,但不要调用它们。不要呼叫setCurrentOperation,只需创建一个NSPrintOperation并呼叫runOperationrunOperationModalForWindow:delegate:didRunSelector:contextInfo:

请参见Printing Programming Guide for Mac

编辑,例如:

PrintView.h

@interface PrintView : NSView

@property (strong) NSArray *forms;

@end

PrintView.m

@interface PrintView ()

@property (weak) NSTextField *titleField;
@property (weak) NSDictionary *currentForm;

@end


@implementation PrintView

- (instancetype)initWithFrame:(NSRect)frameRect {
    if (self = [super initWithFrame:frameRect]) {
        // add a title text field
        NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(25.0, 225.0, 250.0, 25.0)];
        textField.alignment = NSTextAlignmentCenter;
        [self addSubview:textField];
        self.titleField = textField;
    }
    return self;
}

- (BOOL)knowsPageRange:(NSRangePointer)range {
    range->location = 1;
    range->length = self.forms.count;
    return YES;
}

- (NSRect)rectForPage:(NSInteger)page {
    return self.bounds;
}

- (void)beginPageInRect:(NSRect)rect atPlacement:(NSPoint)location {
    [super beginPageInRect:rect atPlacement:location];
    NSPrintOperation *printOperation = [NSPrintOperation currentOperation];
    self.currentForm = self.forms[printOperation.currentPage - 1];
    // set the title
    [self.titleField setStringValue:
        [NSString stringWithFormat:@"Form ‘%@’ page %li",
            self.currentForm[@"title"], (long)printOperation.currentPage]];
}

- (void)drawRect:(NSRect)dirtyRect {
    [super drawRect:dirtyRect];
    // Drawing code here.
    // draw a colored frame
    NSColor *formColor = self.currentForm[@"color"];
    NSRect rect = self.bounds;
    NSInsetRect(rect, 20.0, 20.0);
    [formColor set];
    NSFrameRect(rect);
}

@end

其他地方

- (IBAction)printAction:(id)sender {
    PrintView *printView = [[PrintView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300.0, 300.0)];
    printView.forms = @[
            @{@"title":@"Form A", @"color":[NSColor redColor]},
            @{@"title":@"Form B", @"color":[NSColor greenColor]},
            @{@"title":@"Form C", @"color":[NSColor blueColor]},
        ];
    NSPrintOperation *printOperation = [NSPrintOperation printOperationWithView:printView];
    [printOperation setShowsPrintPanel:YES];
    [printOperation runOperationModalForWindow:[self window] delegate:nil didRunSelector:NULL contextInfo:NULL];
}

答案 1 :(得分:-1)

一个Swift例子,出现在您的NSView子类中。如果没有帮助,我深表歉意:

         func letsPrint() {
             let pInfo = NSPrintInfo.shared
             let d = pInfo.dictionary()
             d["NSLastPage"] = 1
             super.printView(self)
         }
         override func knowsPageRange(_ range: NSRangePointer) -> Bool {
             return true
         }
         override func rectForPage(_ page: Int) -> NSRect {
             if page > 1 { return NSZeroRect }
             return NSRect(x: 0, y: 0, width: 612, height: 792)
         }

此示例打印1页,即8.5 x 11,因此rectForPage中的常量

letsPrint已连接到应用程序菜单的第一响应者。