Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Programmatically Convert PDF to XPS Document Using MXDW

0.00/5 (No votes)
12 Mar 2015 1  
Programmatically Convert PDF-To-XPS Document

Introduction

This is a hack to programmatically convert PDF documents to XPS documents using Microsoft XPS Document Writer (MXDW).

Using the Code

This approach can be used to convert almost any document to XPS document, provided the 'ProcessStartInfo::Verbs' property of the file supports 'print' or 'printto'. The trick here is to perform UI automation, that's it.

MC++
ProcessStartInfo^ info = gcnew ProcessStartInfo( gcnew String(sourcefile));
info->Arguments = "Microsoft XPS Document Writer";
info->UseShellExecute = true;
info->WindowStyle = ProcessWindowStyle::Hidden;
info->CreateNoWindow = false;

for( int i = 0; i < info->Verbs->Length ; i++)
{
    if(info->Verbs[i]->ToString()->Equals("print",StringComparison::OrdinalIgnoreCase))
    {
        info->Verb="print";
        IsPrintable =true;
        break;
    }
}

/* --- Set MXDW as default printer --- */

Process ^ process =  gcnew Process();
process->Start(info);
Edit(targetfile);

/* --- Reset to the original default printer --- */

Some PDF apps exit after issuing print job, few don't. The following must be considered for such a scenario.

MC++
/*  wait for 20 sec */
    process->WaitForExit(20000);

/*  commented 'wait for infinite time'.
    since some application don't exit,
    even after they are done.
*/

//  process->WaitForExit();

This is where the UI automation is done. Editing the Text box and mimicking the save button key press.

MC++
//edits the filename in text box automatically
void Edit(char * pFileName)
{
    HWND hWnd =0;
    try
    {
        // Find Save File Dialog Box
        do{

            Sleep(1000);
            hWnd = FindWindow(DialogClass, "Save the file as");

        }while(!hWnd);

        GetWnd(hWnd,"Edit","");

    }catch(HWND hChild)
    {
        // Enter file name and mimic key press:
        if(SendMessage(hChild, WM_SETTEXT,NULL, (LPARAM) pFileName) !=0)
        {
            hChild = FindWindowEx(hWnd, NULL, NULL, "&Save");
            SendMessage (hChild, WM_IME_KEYDOWN, 'S', NULL);
        }
    }
    return;
}

Given the parent window handle, GetWnd function traverses through all of its child windows until it finds the one which matches classname and caption provided.

MC++
//throws an exception if match is found
void GetWnd( HWND hWnd,char * classname,char * caption)
{
    if( hWnd ==0 || classname[0] == '\0' || caption == '\0')
        return;

    GetWnd ( GetWindow(hWnd,GW_CHILD),classname,caption );
    char Class[50],Text[50];
    GetClassName(hWnd,Class,50);
    GetWindowText(hWnd,Text,50);
    /* throw exception to come out of recursion */
    if ( !strcmp(Class,classname) && !strcmp(Text,caption) )
        throw hWnd;
    GetWnd ( GetWindow(hWnd,GW_HWNDNEXT),classname,caption);
    return;
}

Fixes

Few PDF applications don't close even after issuing print job, causing pdftoxps to wait for infinite time, this was the main intent in commenting 'process.WaitForExit()' earlier. The source code has been modified a bit to address this issue.

Reference

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here