wait until MS-Word finished printing

Scenario:

* You have created an RTF file, c:\temp\test.rtf
* You want MS-Word to print this RTF file, but you don't want to use OLE Automation. In other words: you want to call ShellExecute(..., "print", "c:\temp\test.rtf", .....).
* You want to wait until MS-Word has finished printing.

Why:

OLE Automation would be fine but the OLE commands are application specific (and perhaps even version/translation specific) so you rather rely on the Shell "print"-verb.
You can not easily use CreateProcess and WaitForSingleObject, because MS-Word (and many other word-processors) has an MDI-interface. This means MS-Word (the process) will not terminate if it was already opened before you issued the "print"-request.

Solution:

Knowing that the Shell's "print"-verb executes a DDE-conversation with MS-Word, you can use ShellExecuteEx with the option to wait until the DDE conversation terminates.
Procedure PrintAndWait in this example uses the ShellExecuteEx function. I did not include any error-handling.

RUN PrintAndWait ("c:\temp\test.rtf").
 
{windows.i}
 
PROCEDURE PrintAndWait :
  define INPUT PARAMETER FILENAME AS CHARACTER NO-UNDO.
 
  DEFINE VARIABLE lpVerb AS MEMPTR.
  DEFINE VARIABLE lpFile AS MEMPTR.
  DEFINE VARIABLE lpExecInfo AS MEMPTR.
  DEFINE VARIABLE ReturnValue AS INTEGER NO-UNDO.
 
  SET-SIZE(lpVerb)         = LENGTH("print") + 1.
  PUT-STRING(lpVerb,1)     = "print".
 
  SET-SIZE(lpFile)         = LENGTH (FILENAME) + 1.
  PUT-STRING(lpFile,1)     = FILENAME.
 
  SET-SIZE (lpExecInfo)    = 60.
  PUT-LONG (lpExecInfo, 1) = GET-SIZE(lpExecInfo).
  PUT-LONG (lpExecInfo, 5) = 256. /* = SEE_MASK_FLAG_DDEWAIT */
  PUT-LONG (lpExecInfo, 9) = 0.   /* hwnd                    */
  PUT-LONG (lpExecInfo,13) = GET-POINTER-VALUE(lpVerb).
  PUT-LONG (lpExecInfo,17) = GET-POINTER-VALUE(lpFile).
  PUT-LONG (lpExecInfo,21) = 0.   /* commandline             */
  PUT-LONG (lpExecInfo,25) = 0.   /* current directory       */
  PUT-LONG (lpExecInfo,29) = 2.   /* wCmdShow                */
 
  RUN ShellExecuteExA IN hpApi(GET-POINTER-VALUE(lpExecInfo),
                               OUTPUT ReturnValue).
 
  SET-SIZE (lpExecInfo)    = 0.
  SET-SIZE (lpFile)        = 0.
  SET-SIZE (lpverb)        = 0.
 
END PROCEDURE.