Thursday, May 14, 2009

Powerbuilder Print PDF

I discovered the ever so useful DDE today.


type process_information from structure
long hprocess
long hthread
long dwprocessid
long dwthreadid
end type

type startupinfo from structure
long cb
string lpreserved
string lpdesktop
string lptitle
long dwx
long dwy
long dwxsize
long dwysize
long dwxcountchars
long dwycountchars
long dwfillattribute
long dwflags
long wshowwindow
long cbreserved2
long lpreserved2
long hstdinput
long hstdoutput
long hstderror
end type

function boolean CreateProcess ( &
string lpApplicationName, &
string lpCommandLine, &
long lpProcessAttributes, &
long lpThreadAttributes, &
boolean bInheritHandles, &
long dwCreationFlags, &
long lpEnvironment, &
string lpCurrentDirectory, &
STARTUPINFO lpStartupInfo, &
ref PROCESS_INFORMATION lpProcessInformation &
) library "kernel32.dll" alias for "CreateProcessW"

function boolean CloseHandle(ulong hObject) library "kernel32.dll"
function long WaitForInputIdle(ulong hProcess, long dwMilliseconds) library "user32.dll"



STARTUPINFO lstr_si
PROCESS_INFORMATION lstr_pi
long ll_null, ll_CreationFlags, ll_dde
string ls_null, ls_adobe, ls_pdf_path

ls_pdf_path = 'C:\test.pdf'

If RegistryGet("HKEY_CLASSES_ROOT\Applications\AcroRD32.exe\shell\Read\command", "", ls_adobe) = 1 Then

ls_adobe = Mid( ls_adobe, 2, Len(ls_adobe) - 7 )

// initialize arguments
SetNull(ll_null)
SetNull(ls_null)

//Structure Size
lstr_si.cb = 72

lstr_si.dwFlags = STARTF_USESHOWWINDOW
lstr_si.wShowWindow = 0
ll_CreationFlags = CREATE_NEW_CONSOLE + NORMAL_PRIORITY_CLASS

//Start Adobe Reader
If CreateProcess(ls_null, ls_adobe, ll_null, ll_null, False, ll_CreationFlags, ll_null, ls_null, lstr_si, lstr_pi) Then

//Wait a tic
WaitForInputIdle(lstr_pi.hprocess, 60000)

//Connect to Adobe via DDE
//Note 'parent' at this point is the window object. (code resides in a button)
//I havent tested this, but i imagine you could create a window in memory just for
//passing to this function in order to move it into a generic function.
ll_dde = OpenChannel("Acroview", "Control", Handle( parent ) )

//Do magic
If ll_dde > 0 Then
ExecRemote('[DocOpen("' + ls_pdf_path + '")]', ll_dde)
ExecRemote('[FilePrintSilent("' + ls_pdf_path + '")]', ll_dde)
ExecRemote('[DocClose("' + ls_pdf_path + '")]', ll_dde)
ExecRemote('[AppExit]', ll_dde)

CloseChannel(ll_dde)
End If

//Clean up
CloseHandle(lstr_pi.hprocess)
CloseHandle(lstr_pi.hthread)
End If

End If