in

Blog By Bob

Blog by Bob

February 2005 - Posts

  • New IE on the Way!

    Well, it looks like steveb may not have been ignoring me after all. Billg announced that there will be an Internet Explorer 7 beta, most likely by May. I cross my fingers and hope for security, but we know they aren't rewriting anything so I am not holding my breath. I want to see a full rewrite running in managed code...maybe by 2113...
  • The Lone Gunmen - Geek Fashion

    Way back in the day...a few friends of mine from Team-SciFi.com decided to join together and see how many 'Work Units' we could process for the SETI project. For those who don't know, SETI. also known as http://setiathome.ssl.berkeley.edu/, is an organization at Berkley that searches for possible extraterrestrial radio signals, looking for aliens you might say. Anyhow, for anyone who *does* do SETI, below is a copy of our certificate, granted I was definitely the lowliest contributor.

  • The Weather by Seinfeld

    Last night I went and saw Seinfield, and I highly recommend going if you get the opportunity. One thing I find I still remember (had a couple drinks and all) was Seinfeld commenting on 5 day forcasts...

    “And what about the 5 day forcast? How long have they been yanking our chain with this tidbit? If they *really* had a 5 day forecast, they would only have to do the weather once every 5 days...”

  • System.Drawing.Printing Oh My!

    In a previous article, I was discussing the err of my ways in trying to to take the easy (lazy) way out and use Word for my mail merge needs in ASP.NET. Some of the reason for my rewrite has been nothing more than 'Not built here' syndrome, but I like to think the current configuration is much cleaner than what I would have had finishing the project automating Word, with the whole interop thing thrown in there.

    I started to research the System.Drawing.Printing namespace and either the documentation is lacking, or I am not nearly as bright as I think I am. Granted, that would be saying alot, considering how lowly I think of myself. This actually turned out to be a plus though, since normally when a deadline is rapidly approaching, we tend to learn just enough to write the snippet we need and roll with it, but with the documentation I had, it was necessary to dig quite a bit deeper to build a truly workable solution.

    The System.Drawing.Printing namespace radiates out from the PrintDocument object, and the print process follows a pretty basic flow.

    Create a PrintDocument object
    PrintDocument cardDocument = new PrintDocument();

    If you want to use the 'Print Dialog' to choose a printer,etc, create an PrintDialog object as well
    PrintDialog dlg = new PrintDialog();

    Tie the PrintDocument to the PrintDialog
    dlg.Document=cardDocument;

    Using the PrintDialog is not manditory, if you leave it out, it acts just like Office, it prints to the default printer.

    For the project I was working on, I was printing to post cards instead of normal paper, hence the document object being called cardDocument. After some looking around at how to choose the paper type I was using, I found out something interesting.

    Paper types are kept as an enumeration that can, and most likely is, different from printer to printer. So enum value 9 might be A6 on one printer, and Japanese PostCard on another printer. What you need is a routing to enumerate the paper types and choose the one you want, after you have displayed the PrintDialog, if you are going to, and selected a printer.

    I found a nice article that has the following code that does just that.

    void ForcePageSize(System.Drawing.Printing.PrintDocument MyPrintDocument, System.Drawing.Printing.PaperKind MyPaperKind)
    {
        for (int i = 0; i < MyPrintDocument.PrinterSettings.PaperSizes.Count; ++i)
        {
            if(MyPrintDocument.PrinterSettings.PaperSizes[i].Kind == PaperKind.MyPaperKind)
            {
                MyPrintDocument.DefaultPageSettings.PaperSize = MyPrintDocument.PrinterSettings.PaperSizes[i];
            }
        }
        return;
    }

    So, at this point we've created a blank document, decided what printer to print to and selected the paper we are going to print on. Now we just need something to print. This is one place where things are 'odd' in a way.

    The first thing we need is a “Print” event. Once we build the page, to get it printed, we will call the cardDocument.Print() method that fires the PrintPage event. So we add

    this.cardDocument.PrintPage += new PrintPageEventHandler(this.cardDocument_PrintPage);

    So, in a basic event, we'll print a page, after picking a font and choosing a format, which lets you do things like printing vertically. You will notice we are using the Grpahics.DrawString method just like if we were printing to the screen. The line I used for printing really brings this to the forefront, since you will notice I am passing in x and y coordinates for where we want to print on the paper. This works exceptionally well, since you can just 'do the math' to place tables or groups of text together anywhere you want on the paper.

    private void cardDocument_PrintPage(object sender, PrintPageEventArgs e)
    {
        Font cardFont = new Font(“Arial“,12);
        StringFormat cardFormat = new StringFormat();
        cardFormat.FormatFlags=StringFormatFlags.DirectionVertical;
        e.Graphics.DrawString(“Hello!“,cardFont,Brushes.Black,(float)220,(float)20,cardFormat);
    }

    So, now we have a routine to print out or page which we call by allowing the framework to fire the PrintPage event.

    cardDocument.Print();

    Ok...we printed a page, but Houston, we seem to have a problem. How do we print more than one page? We could change the document and call the Print() method again, but then it would repetitively tell me it is printing Page 1 for each page.

    What I come across is adding a section to out PrintPage event that says

    if (checkSomething)
    {
        e.HasMorePages=
    true;
    }
    else
    {
        e.HasMorePages=
    false;
    }

    The only *issue* I have with this is that the PrintPage event is immediately fired as soon as you leave the PrintPage event, so your logic to get the data for the next page has to be called from the event itself, but I guess that is a small price to pay for the flexibility you get with this solution.

    Another thing I noticed, the hard way, is in the PrintDialog object there is no option to print from page x to page x, since the pages are created on the fly, the PrintDialog object has no way to know how many pages there are, so if you print 100 pages and page 86 messes up....

    There is another object in the Printing namespace that may provide a solution, the PrintController object, it is one item I did not have the opportunity to touch during my research.

    As you will recall from the previous article, the issue I ended up having with the Word mail merge solution was a security issue in CAS(Code Access Security) in .NET since it doesnt allow the facility to write to the client drive from a web page. Well the same thing happened when trying to print from this clientside WinControl. I was eventually able to host it in the browser and do what I wanted to do, but that will wait till next article, considering that story is nearly as long as this one...

  • :Bows to Google:

    If you havent seen the new Google Maps, head over and check it out. It is amazing what Google has been able to do in the browser, grab the picture and you can 'drag' yourself around the countryside...some right click or mousewheel functionality would be nice, but nicely done all the same.
  • A Bit of Browser Irony

    Some of you may remember that a previous exploit in IE had me somewhat perturbed, even to the point that I temporarily switched to Foxfire. Needless to say, my experience with Foxfire was less than satisfactory, so I switched back to IE and just cranked the security settings all up as high as they would go.

    Skip forward a month and a half and I find this interesting article explaining the same type of exploit, but IE is pretty much the only current browser that *isn't* affected by it.

    <---Quote--->
    Vulnerable browsers include (but are not limited to):

    Most mozilla-based browsers (Firefox 1.0, Camino .8.5, Mozilla 1.6, etc)
    Safari 1.2.5
    Opera 7.54
    Omniweb 5
    <---Quote--->

    This list includes the “we don't have any security problems“ people at Apple as well...

  • The Longest Journey Down the Wrong Path

    Recently at work I was tasked with coding a solution for an interesting problem. I was pretty excited about it since most of my work is centered around database work and data analysis, and this would be 'real' coding in ASP.NET.

    The specifics of this stage of the project were to create a web page that accessed server side data and allowed them to click a button in the browser and print out a selected group of post cards, which may number in the 1000's. This instantly brings up the thought of a couple of things. First, this is a web page accessing the client's printer, which can be ugly after Service Pack 2's 'hardening' (I use that term loosely when talking about IE) of Internet Explorer, and it brings up the thought of the easiest way of doing a mail merge, which one would assume would mean word.

    This is definitely a doable project, especially if this part of the project will have a very limited number of controllable end user machines. I *know* the machines are all Windows XP SP2 and Word 2003. I found an awesome KB article on automating Word in C# and starting coding. In retrospect, the *easiest* way to do a mail merge is no such thing when you actually get down to it.

    Before we get into the details, the first thing you will notice about the KB article is there interesting way you add a using statement for Word 2003.

    using Word = Microsoft.Office.Interop.Word;

    Definitely a little different than I am used to seeing. So, I add my using statement and get all my code going. I've decided to use a WinControl hosted in IE to do the automation instead of trying to automate Word in clientside script (ick). I get the WinControl working great in a WinForm application, and move the assembly into the folder that contains my ASP.NET app. The control comes up and renders correctly, and then issue number one comes up.

    To do a mail merge, Word needs to use something as a data source. Our SQL Server is buried behind ISA server and not accessable from the web, as it should be so I can't query SQL directly. Word won't take a reader or a data set as a data source, but it will take a csv file or a table in a Word document among other things. The example in the article had used a table in another Word document as an example, so I figured that was the best place to start. My WinControl was calling a Web Service and building a new Word document on the fly for the data source. Well, once I hosted this in IE, a caveat came into view. For word to use the new Word document as the data source, it needed to be saved to disk first. The framework was not pleased with this and threw a huge security error.

    After doing some research the 'solution' I find is that in order to access the hard drive I need to first strongly name and sign my assemble. I run sn.exe on it, generate the keys, but find out something more interesting when I try to host it after it is signed. It no longer even renders in the browser.

    At this point, I've decided 'Fine, I don't want to write to their drive anyhow, let's find a new solution.' My next thought is, why don't I write a csv file onto the server, named with a unique identifier and kill it when I am done. Not the best solution by far, but I want to get something working until I can find a better solution. Well, I come to find out, this is 2005 and I am using Word 2003, but there is no support for using a URI path as a data source...

    At this point, I decided that I wasn't going to use Word at all, and was going to pursue writing my own routines to create a maiol merge template. That article will have to be tomorrow's agenda, my fingers are tired...And I know there are better things I could have done with the Word portion and could have even gotten it to work, so remember that if you comment, but I wanted to go into the solution I ended up with, as it is much nicer and cleaner, even though it is lacking in its own rights. Till tomorrow.

  • Death of the Internet...

    If it isn't bad enough that 80% of daily email is now Spam, almost all of my comments are Spam too. I am not going to lie, I barely get enough hits to consider myself as having a readership, and I got 19 Spam comments yesterday. I don't know how you 'big bloggers' handle that. We need to all sit down collectively and find a solution.
More Posts
Copyright © :: BlogByBob.com
Powered by Community Server (Non-Commercial Edition), by Telligent Systems