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

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

概述我有一个我正在研究的可可应用程序,我在其中创建了一个我要发送到打印机的customView.在子类NSView中,我也设置了一些框架选项,代码如下.我有2个全局变量来保存在main()函数外声明的打印信息. - (id)initWithFrame:(NSRect)frame{ extern NSPrintInfo *globalPrintInfo; extern NSPrintO 我有一个我正在研究的可可应用程序,我在其中创建了一个我要发送到打印机的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;}

对于子类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,1);//black    CGContextSetRGBstrokecolor (myContext,1,1);//blue stroke    CGContextshowtextAtPoint(myContext,40,"Here is some text!",18);}

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

- (IBAction)print:(ID)sender {    NSLog(@"Testing Print");    extern nsprintoperation *globalPrintoperation;    [globalPrintoperation runoperation];}

我看到了打印窗口,我看到了我的“绿色背景”,但由于某种原因,它被拆分为2页.当我将框架的宽度和高度设置为pagesize.wIDth&时,我不确定到底发生了什么.身高,任何帮助表示赞赏.我看到的一些图像如下.

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

我的最终目标是创建一个用户选择他们想要的程序,并根据他们选择的选项打印特定页面,但首先我要弄清楚如何在“1”页面上获得我期望的“内容” ‘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=%@,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,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

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

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

解决方法 所以我改进了我的打印类,使其对许多页面更加灵活,并希望共享代码.我仍然在底部有令人讨厌的白色边框,我无法弄清楚但是当我去打印它似乎并不存在?所以我需要一些帮助来解决这个问题,但除此之外,我设计了一个类,您只需向它发送一个视图数组,它将按照您收到它们的顺序打印视图.

为此,我创建了2个类,PSPrint& PSPrintVIEw.两者都是NSVIEw的子类

这是PSPrint.h&的代码. PSPrint.m

#import <Foundation/Foundation.h>#import "PSPrintVIEw.h"@interface PSPrint : NSVIEw@property NSMutableArray *printVIEws;@property (strong) nsprintoperation *printoperation;- (voID)printTheVIEws;@end#import "PSPrint.h"#import "PSPrintVIEw.h"@implementation PSPrint- (ID)initWithFrame:(NSRect)frame{    NSLog(@"Initializing Main PSPrintVIEw");    self = [super initWithFrame:frame];    if (self) {        // Initialization code here.        _printVIEws = [[NSMutableArray alloc]initWithCapacity:1];//start it with capacity of 1    }    return self;}- (voID)drawRect:(NSRect)dirtyRect{}- (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;}- (voID)printTheVIEws{    NSLog(@"Starting printTheVIEws Function of PSPrint");    nsprintInfo *sharedPrintInfo = [nsprintInfo sharedPrintInfo];    NSUInteger numOfVIEws = _printVIEws.count;     NSLog(@"Creating %ld SubVIEws",numOfVIEws);    NSUInteger totalHeight = 0;//if not initialized to 0 weird problems occur after '3' clicks to print,Todo: Find out why? Maybe because address space in memory not guaranteed to be 0 again?    NSUInteger heightOfVIEw = 0;    PSPrintVIEw *tempVIEw;    for (NSUInteger i=0; i<numOfVIEws; i++) {        tempVIEw = [_printVIEws objectAtIndex:i];        heightOfVIEw = tempVIEw.frame.size.height;        totalHeight = totalHeight + heightOfVIEw;    }    //Change the frame size to reflect the amount of pages.    NSSize newsize;    newsize.wIDth = sharedPrintInfo.paperSize.wIDth-sharedPrintInfo.leftmargin-sharedPrintInfo.rightmargin;    newsize.height = totalHeight;    [self setFrameSize:newsize];    NSLog(@"Total Height Of Main Print VIEw Is %f",_frame.size.height);    NSInteger incrementor=-1;//default the incrementor for the loop below.  This controls what page a 'vIEw' will appear on.    //Add the vIEws in reverse,because the Y position is bottom not top.  So Page 3 will have y coordinate of 0.  Doing this so order vIEws is placed in array reflects what is printed.    for (NSInteger i=numOfVIEws-1; i>=0; i--) {        incrementor++;        tempVIEw = [_printVIEws objectAtIndex:i];//starts with the last item added to the array,in this case rectangles,and then does circle and square.        heightOfVIEw = tempVIEw.frame.size.height;        NSPoint origin;        origin.x = 0;        origin.y = heightOfVIEw*incrementor;//So for the rectangle it's placed at position '0',or the very last page.        [tempVIEw setFrameOrigin:origin];        [self addSubvIEw:tempVIEw];    }    _printoperation = [nsprintoperation printoperationWithVIEw:self printInfo:sharedPrintInfo];    [_printoperation runoperation];}// 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),pageHeight );}// Calculate the vertical size of the vIEw that fits on a single page- (float)calculatePrintHeight {    nsprintInfo *sharedPrintInfo = [nsprintInfo sharedPrintInfo];    // Obtain the print info object for the current operation    // Calculate the page height in points    NSSize paperSize = [sharedPrintInfo paperSize];    float pageHeight = paperSize.height - [sharedPrintInfo topmargin] - [sharedPrintInfo bottommargin];    // Convert height to the scaled vIEw    float scale = [[[sharedPrintInfo dictionary] objectForKey:nsprintScalingFactor]                   floatValue];    NSLog(@"Calculated Print Height:%f",(pageHeight/scale));    return (pageHeight / scale);}@end

PSPrintVIEw.h的代码& PSPrintVIEw.m如下

#import <Cocoa/Cocoa.h>@interface PSPrintVIEw : NSVIEwenum optionsForVIEw{drawRectangle,drawCircle,drawSquare};@property enum optionsForVIEw myOptions;- (voID)drawSquare;- (voID)drawCircle;- (voID)drawRectangle;@end#import "PSPrintVIEw.h"@implementation PSPrintVIEw- (ID)initWithFrame:(NSRect)frame{    self = [super initWithFrame:frame];    if (self) {        // Initialization code here.    }    return self;}- (voID)drawRect:(NSRect)dirtyRect{    NSLog(@"Drawing Green VIEw BoundarIEs");    nsprintInfo *sharedPrintInfo = [nsprintInfo sharedPrintInfo];    //So we kNow the boundarIEs for the page. Remove in actual application.    [[NScolor greencolor] setFill];    NSRectFill(dirtyRect);    Nsstring *drawType;    const char *cString;    if(sharedPrintInfo.orIEntation == NSPortraitOrIEntation){        drawType = @"Portrait";    }else{        drawType = @"Landscape";    }    cString = [drawType cStringUsingEnCoding:NSASCIIStringEnCoding];    //Draw the print mode for reference.    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];    CGContextSelectFont(myContext,30,kCGTextFillstroke);    CGContextSetRGBFillcolor(myContext,1);//white stroke    CGContextshowtextAtPoint(myContext,cString,drawType.length);    //Control what type of page is drawn.    switch (_myOptions){        case drawSquare:            [self drawSquare];            break;        case drawCircle:            [self drawCircle];            break;        case drawRectangle:            [self drawRectangle];            break;    }}- (voID)drawSquare{    NSLog(@"Drawing Square");    //Because this function can only be called from drawRect we are guaranteed with the function below to be in the correct graphics context    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];    NSRect redSquare = CGRectMake (0,200,200 );    redSquare.origin.y = self.bounds.size.height-redSquare.size.height;//move it to the top of the page.    CGContextSetRGBFillcolor (myContext,1);//set to red color    CGContextFillRect (myContext,redSquare);//Y coordinate set to height to put it in upper left,200 is total height of the vIEw.}-(voID)drawCircle{    NSLog(@"Drawing Circle");    //Because this function can only be called from drawRect we are guaranteed with the function below to be in the correct graphics context    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];    CGContextSetRGBFillcolor (myContext,1);//set to red color    NSRect ovalFrame = CGRectMake (0,200 );    ovalFrame.origin.x=0;//from within the vIEw it's self.    ovalFrame.origin.y=0;//at the top of the page.    CGContextFillEllipseInRect(myContext,ovalFrame);}-(voID)drawRectangle{    NSLog(@"Drawing Rectangle");    //Because this function can only be called from drawRect we are guaranteed with the function below to be in the correct graphics context    CGContextRef myContext = [[NSGraphicsContext currentContext] graphicsPort];    NSRect redRectangle = CGRectMake (0,300,100 );    redRectangle.origin.y = self.bounds.size.height-redRectangle.size.height-(self.bounds.size.height/2);//move it to the top of the page.    CGContextSetRGBFillcolor (myContext,redRectangle);//Y coordinate set to height to put it in upper left,200 is total height of the vIEw.}@end

下面在我的AppController中使用这些类的示例.我只是创建了一个按钮,屏幕上有3个复选框,用于显示矩形,圆形和方形.

这是appController.h和appController.m

#import <Foundation/Foundation.h>#import "PSPrint.h"#import "PSPrintVIEw.h"@interface AppController : NSObject- (IBAction)printResultsbutton:(ID)sender;@property (weak) IBOutlet NSbutton *squareCheckBox;@property (weak) IBOutlet NSbutton *circleCheckBox;@property (weak) IBOutlet NSbutton *rectangleCheckBox;@property (strong) PSPrint *PSPrintObject;- (IBAction)pageSetup:(ID)sender;@end#import "AppController.h"#import "PSPrint.h"#import "PSPrintVIEw.h"@implementation AppController- (IBAction)printResultsbutton:(ID)sender {    NSLog(@"Print button pressed");    //First get the shared print info object so we kNow page sizes.  The shared print info object acts like a global variable.    nsprintInfo *sharedPrintInfo = [nsprintInfo sharedPrintInfo];    //initialize it's base values.    sharedPrintInfo.leftmargin = 0;    sharedPrintInfo.rightmargin = 0;    sharedPrintInfo.topmargin = 0;    sharedPrintInfo.bottommargin = 0;    PSPrintVIEw *printPageVIEw;    NSRect frame;    frame.size.height = sharedPrintInfo.paperSize.height-sharedPrintInfo.topmargin-sharedPrintInfo.bottommargin;    frame.size.wIDth = sharedPrintInfo.paperSize.wIDth-sharedPrintInfo.leftmargin-sharedPrintInfo.rightmargin;    //Initiate the printObject without a frame,it's frame will be decIDed later.    _PSPrintObject = [[PSPrint alloc]init];    //[_PSPrintObject.printVIEws initWithCapacity:1];//start it off with a capacity of '1'    if(_squareCheckBox.state == NSOnState){        //Allocate a new instance of NSVIEw into the variable printPageVIEw        printPageVIEw =[[PSPrintVIEw alloc] initWithFrame:frame];        //Set the option for the printVIEw for what it should draw.        printPageVIEw.myOptions=drawSquare;        //Finally append the vIEw to the PSPrint Object.        [_PSPrintObject.printVIEws addobject:printPageVIEw];        NSLog(@"Added Square Print VIEw To Mutable Array");    }    if(_circleCheckBox.state == NSOnState){        //Allocate a new instance of NSVIEw into the variable printPageVIEw        printPageVIEw =[[PSPrintVIEw alloc] initWithFrame:frame];        //Set the option for the printVIEw for what it should draw.        printPageVIEw.myOptions=drawCircle;        //Finally append the vIEw to the PSPrint Object.        [_PSPrintObject.printVIEws addobject:printPageVIEw];        NSLog(@"Added Circle Print VIEw To Mutable Array");    }    if(_rectangleCheckBox.state == NSOnState){        //Allocate a new instance of NSVIEw into the variable printPageVIEw        printPageVIEw =[[PSPrintVIEw alloc] initWithFrame:frame];        //Set the option for the printVIEw for what it should draw.        printPageVIEw.myOptions=drawRectangle;        //Finally append the vIEw to the PSPrint Object.        [_PSPrintObject.printVIEws addobject:printPageVIEw];        NSLog(@"Added Rectangle Print VIEw To Mutable Array");    }    NSLog(@"Attempting to print all vIEws...");    [_PSPrintObject printTheVIEws];//print all the vIEws,each vIEw being a 'page'.}- (IBAction)pageSetup:(ID)sender {    NSPageLayout *pageLayout = [NSPageLayout pageLayout];    [pageLayout runModal];//runs the model for the page layout UI.  It saves the global copy of printInfo in printoperation,which can be used to make decisions}@end

我希望这可以帮助你们中的一些人在打印中挣扎,花了一些时间来做这件事,但是这些课程让打印变得更容易.

总结

以上是内存溢出为你收集整理的objective-c – Cocoa(Mac Os X)打印多页,为什么预览窗口显示2页而不是1页?全部内容,希望文章能够帮你解决objective-c – Cocoa(Mac Os X)打印多页,为什么预览窗口显示2页而不是1页?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/web/1013508.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-22
下一篇 2022-05-22

发表评论

登录后才能评论

评论列表(0条)

保存