Rob Garrett - Blogs

Welcome to Rob Garrett - Blogs Sign in | Join | Help
in Search
Google

Software/Technology Discussion

Software and Technology Tid-bits

Suppressing the MODI Popup using C#

For those of you who have never heard of the MODI acronym it stands for the Microsoft Office Document Image writer, which is a virtual printer driver for converting printed content into Microsoft Document Images or TIFF files. The idea for this virtual printer, shipped with Office, is to provide a means for converting output from applications with printing ability into a format that can be read by Office applications.

I am working on a project that converts known file formats into TIFF images, so MODI is ideal for this task. The project involves converting multiple files at once, using multi-threading. Converting Office type documents with MODI was easy, Word, Excel, PowerPoint etc, provide printing ability using a COM API. The method call in these application interfaces requires a printer name and filename to save to, if using virtual printers like MODI. Life is good. The problem comes about when using non-Office applications, such as Internet Explorer, to print using MODI. The print method in IE's API does not provide a way to specify the output file, as with the Office applications, so during the print request MODI pops up a helpful dialog box - great in a single thread printing environment, bad in a multi-threaded application with lots of print jobs.

I scoured the web looking for a quick fix to the MODI pop up problem but found very little help. Microsoft provides an API for MODI but it is designed for sending documents to the driver, not manipulating the driver options. The only helpful hint I came across was to post or send messages to the dialog window that MODI pops up, thus simulating a user pressing the "save" button. Using this idea I got to work on writing a class that would manipulate the MODI pop up window from C#.

I wrote a simple class that will manipulate any instance of  MODI pop up window that is found on the system. The class uses Win32 API calls to find the "Save As" window with the same characteristics used by MODI. Once found I can send Windows messages to the controls on the form to change the file name location and click the save button.
MODI typically displays the pop up window a short time after a print request has been made. This time is dependent on the sized of the data being sent to the MODI printer. Most applications use the spooler to print to MODI and the print call is asynchronous, meaning the call will return immediately after spooling before printing starts. It is not enough to detect the pop up window directly after a print method invocation because the MODI may still be busy and the pop up will be missed. So I wrote functionality into my class to wait for an expected MODI pop up window for a finite period of time.

Below is an example of how to call my class using C#. My class can also be called from VB.Net, or any other .Net language, only the syntax will change accordingly.


The code for the MODI Window class can be found Here.

Share this post: Email it! | bookmark it! | digg it! | reddit!
Published Saturday, March 05, 2005 8:19 PM by Rob Garrett

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

 

Jose Miguel said:

Check this lines. They update the windows registry to the popup never show it.

ModificarAtributo(@"Software\Microsoft\Office\11.0\MODI\MDI Writer", "PrivateFlags", 1, TypeRegistry.CurrentUser);

ModificarAtributo(@"Software\Microsoft\Office\11.0\MODI\MDI Writer", "OpenInMODI", 0, TypeRegistry.CurrentUser);

One question: do you know how i can do persistent annotations in all my documents mdi or tif?

My email is samsagaz23@wanadoo.es.

tx.
April 26, 2005 4:11 AM
 

Hank Morris said:

Amazing! How does one go about discovering obscure registry settings like PrivateFlags?!

I tried this and it works, but the file is always written as Note0001.mdi.

How would I change the type to TIFF, and the name to whatever I want?

Thanks
May 19, 2005 11:01 AM
 

Jose Miguel said:

I know, set BurnInAnnotations registry value to 5.
May 20, 2005 7:49 AM
 

John said:

Can u please give some more code how to make a print out in background with MODI, suppresing popup and tiff
September 7, 2005 9:46 AM
 

Paul said:

Thank you so much for the information. Private Key settings works grate. I was searching for this almost a day now. I could not find it any where else.

This settings copies the file in MDI. Is there any way you can do it for
TIFF?

THANK YOU :-)
March 2, 2006 2:11 PM
 

Piyush said:

Use decimal value of 35 (i.e. 1f in hexadecimal) for converting to tiff without displaying the save as dialog box.

March 2, 2006 4:15 PM
 

Rahul said:

when i try to print the PDF file using MODI printer through my class library project (dll), which is registered on the server, the MODI popup window where we can specify the output filename is suppressed. Since the popup window is not visible, FindWindowEx fails to locate the "Save As" window. Is there a way we can get around this problem.

Thanks

Rahul
April 25, 2006 6:18 PM
 

Fred said:

Here's some code I just wrote:

Using 17 for PrivateFlags gives me Note.tif in the temp directory with no save as dialog.

The DPI setting of 600 does work, although I'd suggest 200 or 300 for real code. 2400 even works, if you want a real large file.


private int iMODICOMPIMGEMF;
private string sMODIPath;
private int iMODIPrivateFlags;
private int iMODIPublic_Orientation;
private int iMODIPublic_PaperSize;
private int iMODITIFDPI;
private int iMODIOpenInMODI;

private string sMODIKey = @"HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\MODI\MDI writer";
private void SaveMODIKeys()
{
iMODICOMPIMGEMF = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "COMPIMGEMF", 0);
sMODIPath = (string) Microsoft.Win32.Registry.GetValue(sMODIKey, "DefaultFolder", @"C:\");
iMODIPrivateFlags = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "PrivateFlags", @"C:\");
iMODIPublic_Orientation = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "Public_Orientation", @"C:\");
iMODIPublic_PaperSize = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "Public_PaperSize", @"C:\");
iMODITIFDPI = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "TIFDPI", @"C:\");
iMODIOpenInMODI = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "OpenInMODI", 0);

}

private void SetMyMODIKeys()
{
Microsoft.Win32.Registry.SetValue(sMODIKey, "COMPIMGEMF", 1);
Microsoft.Win32.Registry.SetValue(sMODIKey, "DefaultFolder", @"C:\temp");
Microsoft.Win32.Registry.SetValue(sMODIKey, "PrivateFlags", 17);
Microsoft.Win32.Registry.SetValue(sMODIKey, "Public_PaperSize", 1);
Microsoft.Win32.Registry.SetValue(sMODIKey, "Public_Orientation", 1);
Microsoft.Win32.Registry.SetValue(sMODIKey, "TIFDPI", 600);
Microsoft.Win32.Registry.SetValue(sMODIKey, "OpenInMODI", 0);
}

private void RestoreMODIKeys()
{
Microsoft.Win32.Registry.SetValue(sMODIKey, "COMPIMGEMF", iMODICOMPIMGEMF);
Microsoft.Win32.Registry.SetValue(sMODIKey, "DefaultFolder", sMODIPath);
Microsoft.Win32.Registry.SetValue(sMODIKey, "Public_Orientation", iMODIPrivateFlags);
Microsoft.Win32.Registry.SetValue(sMODIKey, "Public_PaperSize", iMODIPublic_Orientation);
Microsoft.Win32.Registry.SetValue(sMODIKey, "Public_PaperSize", iMODIPublic_PaperSize);
Microsoft.Win32.Registry.SetValue(sMODIKey, "TIFDPI", iMODITIFDPI);
Microsoft.Win32.Registry.SetValue(sMODIKey, "OpenInMODI", iMODIOpenInMODI);
}
May 5, 2006 7:08 PM
 

Fred said:

Oops, wrong default values there

private void SaveMODIKeys()
{
iMODICOMPIMGEMF = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "COMPIMGEMF", 0);
sMODIPath = (string) Microsoft.Win32.Registry.GetValue(sMODIKey, "DefaultFolder", @"C:\");
iMODIPrivateFlags = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "PrivateFlags", 0);
iMODIPublic_Orientation = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "Public_Orientation", 1);
iMODIPublic_PaperSize = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "Public_PaperSize", 1);
iMODITIFDPI = (int) Microsoft.Win32.Registry.GetValue(sMODIKey, "TIFDPI", 300);
iMODIOpenInMODI = (int)Microsoft.Win32.Registry.GetValue(sMODIKey, "OpenInMODI", 1);
}
May 5, 2006 7:10 PM
 

Rob Garrett said:

Awesome, thanks Fred.
May 6, 2006 9:38 PM
 

Berto said:

Hey guys, thanks for this thread!! It has been a great reference point!  However I am having one problem.  

I am writing an automation application for IBM's content manager, in which I would like to print to a .tif file, then send to our Fax printer.  (I cannot directly print to the fax printer, because I am going some database work in between).  Anyhow, through IBM's automation API's, even if I have OpenInMODI=0, it still pops up when its done printing.  

Has anyone else had this type of issue (where MODI is popping up, even though OpenInMODI=0)?

Thanks!!
May 23, 2006 9:40 AM
 

Berto said:

Note: I've temporarily solved my problem by spawning a process that looks for instances of "mspview.exe" and kills them ;), cheap, but for now it works.

I'm guessing that IBM's API's are, for some reason trying to open the document upon a successful print.
May 23, 2006 12:46 PM
 

Yolanda said:

Fred said: Using 17 for PrivateFlags gives me Note.tif in the temp directory with no save as dialog. A perfect tip. Does anybody know how I can change the file name automatically. E.g. I like to create a MDI with file name Invoice_12345.mdi when I am printing the invoice Any help will help me Yolanda
May 25, 2007 8:53 AM
 

Brian said:

I have been looking for this information for some time now. I was trying to print a large amount of TEXT files through MODI to TIF format. Using 17 for PrivateFlags gives Note.tif in the temp directory with no save as dialog will be a big help for me. However, like Yolanda mentioned, it would be great if one can specify the output file name. Since no one has found a way to do that yet, I guess one solution would be to rename/copy the Note.tif to youfilename.tif after the printing finishes. So my question is how you can detect that the printing has finished and Note.tif has been closed before I do the rename? I have been using window scripting to print thousands of text files, it worked most of the time. I'd like to impement a more reliable solution in C#. Any help will be really appreciated.
July 7, 2007 1:31 AM
 

Raju E said:

private void convertToTiff(object sfile, object dfile) { object o_null = System.Reflection.Missing.Value; object missingValue = System.Reflection.Missing.Value; object bak = true; Word.Document doc = null; object myTrue = true; object myFalse = false; try { doc = wordApp.Documents.OpenOld(ref sfile,ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue); doc.PrintOutOld(ref myTrue,ref myFalse, ref missingValue,ref dfile, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref myTrue, ref missingValue, ref missingValue, ref missingValue); } finally { if (doc != null) doc.Close(ref o_null,ref o_null,ref o_null); } }
August 10, 2007 7:03 AM

Leave a Comment

(required) 
(optional)
(required) 
Submit

Blurb


Head Shot
Rob Garrett is a British Expat living in Maryland USA. Rob is a trained software engineer and experienced in Windows .NET development.

Rob enjoys listening to Rock music, posting to blogs, driving in the country with the sunroof open, beer (not in conjunction with country driving) and spending time with his family.

This Blog

Syndication

Powered by Community Server, by Telligent Systems