Printing multiply copies of Word document from WPF/C# .NET 4 - wpf

I'm building an WPF application in C# and .NET 4 and need to print out two copies of the same file.
I have the following code, which gets the job done, but it's not that pretty as Word opens up twice.
Process myProcess = new Process();
myProcess.StartInfo.FileName = invoiceFileAbsoluteStoreagePath;
myProcess.StartInfo.Verb = "Print";
myProcess.StartInfo.CreateNoWindow = true;
//Print out two copies - ugly! - no better way apparently
myProcess.Start();
myProcess.WaitForExit();
//Let's do it again... there need to be a better way :(
myProcess.Start();
myProcess.WaitForExit();
Can't I somehow send an argument to Word letting it know that I want X copies from this document?

I usually do my printing via WPF flow documents. From there you can just create the WPF page, invoke the print command on it, auto fill the number of copies and execute the print job. If you only have a few documents you can recreate them in XAML and even inject data into them. It is a little time consuming to start, but once implemented, it is quite fast. No opening word. Just opening a xml file as a XamlDocument, inject data via ViewModel, and printing.
While this is not specifically about flow documents, it will get you there.

Related

Appending a big number of nodes to an xml tree

I'm using libxml via C, to work with xml file creation and parsing. Until recently everything worked smoothly, but a case emerged where a single tree has a subnode, lets call it S, with approximately 200,000 children. This case works surprisingly slow and I suspect the function :
xmlNewChild(/**/);
which I'm using to build the tree, has to iterate over every child of S to add one more child. Since a function that also accepts a hint (a pointer to the last added function) doesn't seem to exist, is there a better way to build the tree (maybe a batch build method) ? In case such numbers are insignificant and I should search for deficiencies elsewhere, please let me know.
Yeah, rather than keeping the entire XML in memory with xmlTree, you may want to use a combination of libxml's xmlReader and xmlWriter APIs. They're both streaming, so it won't have to keep the entire document in memory and won't have any scaling problems based on the number of elements.
Examples of both xmlReader and xmlWriter can be found here:
http://www.xmlsoft.org/examples/index.html

The Basics of Parse Blocks in Swift

I'm having a little issue on understanding how exactly blocks work.
for x in self.activerestaurantIDArray
{
let namelabel = x.0
self.activenameArray.append(namelabel)
let distancelabel = x.1
self.activedistanceArray.append(distancelabel)
let imageFile = x.2
imageFile.getDataInBackgroundWithBlock({ (imageData: NSData?, error: NSError?) -> Void in
if error == nil {
let realimage = UIImage(data: imageData!)
self.activeimageArray.append(realimage!)
}
println(self.activenameArray)
println(self.activedistanceArray)
println(self.activeimageArray)
})
}
In the code above, I am appending information to an array from the tuple (named: activerestaurantIDArray) so that I will get separate arrays of name, distance and image. As for the image, I can only retrieve a PFFile from parse so I will have to transform the file into a UIImage.
However, when I do this, the appends for the activeImageArray is in effect only when the println() is within the Block (imageFile.getDataInBackgroundWithBlock).
If I were to println(self.activeimageArray) at any place outside of the box, the array will turn out nil. I am not really sure why that happens or how I should go about ensuring that the appended values carry out beyond the Block{}. Any help would be greatly appreciated.
Closures (also known as yes, blocks) are pieces of code that can be called later, they are essentially functions.
What you are doing in imageFile.getDataInBackgroundWithBlock is to download the data, and when the data is downloaded, imageFile.getDataInBackgroundWithBlock will call your block, passing you the contents of the thing it just downloaded.
It is done this way because downloading must take place in a separate thread. Otherwise your main thread will freeze, and not only will it cause annoyances for the user, but after 5 seconds of non-responsiveness, the OS will kill your app. getDataInBackgroundWithBlock spawns a different thread for the download operation, and then it lets you know by calling your block. This allows you to download anything without "freezing" or "hanging" your app.
So imageData, when outside the block, is nil because you are trying to use it before the block has completed the download operation. Your code will never run slower than a download operation, so you must use the block to implement the code you want to use when an operation finishes downloading, in this case, setting the imageData.
Edit to add, this is not exclusive to Parse. Almost any framework that can freeze your UI will do those operations and implement the notifications using blocks. It's still possible to be notified by using delegates, but ever since blocks were introduces in Objective-C, people have been moving away from that pattern.

Download Files using a For Each Loop

Please keep in mind that I am a TOTAL NOOB. I am not asking anyone to code my entire project, but I am easily lost in many cases. Your help and patience is much appreciated ...
My AS3 code looks something like this:
var totalFeatureImageDownloads:Number = 0; //total file size of all feature images, in bytes
var totalFeatureImageDownloaded:Number = 0; //total downloaded of all feature images, in bytes
for each(var featureimage:XML in xml.featureimages.imgurl)
{
trace(featureimage);
var featureImageRequest:URLRequest = new URLRequest(featureimage);
var featureImageLoader:URLLoader = new URLLoader(featureImageRequest);
totalFeatureImageDownloads = totalFeatureImageDownloads + featureImageLoader.bytesTotal;
trace(featureImageLoader.bytesTotal);
}
Currently I have 3 images in the XML file, and their URL's are traced properly. However, bytesTotal always equals 0. Also, I know that this loop creates 3 identically named URLRequest's and 3 identically named URLLoaders. I probably need to create 3 differently named ones.
I would like all the images to be downloaded simultaneously, and I need to calculate the combined file size for all three, along with the download status as a fraction (bytesLoaded / bytesTotal).
I have multiple scenarios like this, and am stuck until I get this finished. Your help is much appreciated. Cheers.
It is not possible to read the bytesTotal from a newly created URLLoader, because the client needs to connect to the web server first to get the size of the file to be downloaded. You need to listen for the first ProgressEvent.PROGRESS event sent by the URLLoader, once that event is sent the bytesTotal property is more likely to be accurate. I say "more likely" because it is not possible to get a total file size if the data is dynamically generated on the server, but in the general case where you download a file from the server it works.
I recognize the general scenario. There are libraries to aid with this, such as LoaderMax or BulkLoader. I personally use BulkLoader: https://github.com/arthur-debert/BulkLoader

How do I find a item in ListView control?

My list view contains 3 columns Name, address and phone number.
I want to retrieve an index for a particular name.
I'm using ListView_FindItem macro to find the index number but when my code comes to this line it crashes the program.
It just says Payroll has stopped working. Windows can check online for a solution to the problem.
I'm sure I have passed right handle to the ListView_FindItem macro but I'm not sure about the LVFINDINFO structure.
Here's my code
WCHAR szProcess[80] = {0};
LVFINDINFO item = {LVFI_STRING, (LPCTSTR) szProcess};
//code to find parent handles
...
//code to find index
index = ListView_FindItem(hwndListView, -1, &item);
I'm not sure about the LVFI_STRING flag and I have even tried passing a constant LVFINDINFO structure to ListView_FindItem macro still my program crashes.
Note : The above code is not part of
the payroll application. I mean to say
the payroll application has the
listview and I'm trying to search the
item from other application.
Can some one point me in a right direction ?
Thanks.
Your description is a little unclear, but I interpret it that you are sending LVM_FINDITEM message (via the ListView_FindItem() macro) to a window in a different process.
This simply does not work for this particular Windows message since it passes a pointer to a struct in the calling process which is meaningless when interpreted in the context of the other process (the payroll app that owns the list view).
To solve your problem you could allocate memory in the other process although this is quite a complex task. A commonly cited example of the technique is to be found in the Code Project article, Stealing Program's Memory.
Perhaps a simpler approach would be to use WM_COPYDATA which will marshal string data between processes. If that doesn't have enough flexibility then you'd need to find another IPC mechanism, e.g. named pipes.

Why does silverlight run into an endless loop when printing document longer than 1 page? .HasMorePages = true

My 1st question here on stackoverflow.
I am trying to print a long grid, which was dynamically generated.
pdoc.PrintPage += (p, args) =>
{
args.PageVisual = myGrid;
args.HasMorePages = false;
};
When I use args.HasMorePages = false;, it prints the first page of the grid as it should (although it takes some time, since it sends a 123MB big bitmap to the poor printer - thanks for silverlight 4's print feature implementation.).
However, when I enable printing more pages withargs.HasMorePages = true;, the printing job runs amok on the memory and sends endless copies of the first printing page of the document - effectively disabling my developer machine. Even if the grid is only 2 pages long.
Why does this happen?
What is a possible workaround here? All I found on the net is that SL handles printing badly, but not a real solution.
The HasMorePages property indicates to silverlight printing that you have a least one more page to print. The PrintPage page event fires for each page to be printed.
Hence when you set HasMorePages to true you will get another PrintPage event, if you always set it true (as your code appears to be doing) you are creating an infinite loop.
At some point the code has to leave HasMorePages set to false.
Ultimately its up to you the developer to perform all the pagination logic and decide what appears on each page, Silverlight does not automagically do that for you.

Resources