Currently, using the Wine supplied print dialog, printing to a file
results in a file named "FILE:". In Windows (at least Win2k) a simple
one line dialog box is put up where the filename can be typed in. I
don't see a reason why a full Save As dialog would not be preferable;
some programs override the standard dialog with a full Save As dialog.
It looks to me like the correct place to do this is in gdi/printdrv.c
CreateSpoolFile(). So I have tried adding the attached patch to the
function to play with, adding comdlg32 to the libraries in the makefile.
But the call to GetSaveFileNameW(&ofn) crashes. I guess the first
question is whether it is ok to call that from printdrv. And if so, is
there an example of how to do it correctly?
Index: dlls/gdi/printdrv.c
===================================================================
RCS file: /home/wine/wine/dlls/gdi/printdrv.c,v
retrieving revision 1.47
diff -u -p -r1.47 printdrv.c
--- dlls/gdi/printdrv.c 23 May 2006 12:47:58 -0000 1.47
+++ dlls/gdi/printdrv.c 16 Jul 2006 22:43:03 -0000
@@ -50,6 +50,7 @@
#include "wine/debug.h"
#include "gdi.h"
#include "gdi_private.h"
+#include <commdlg.h>
WINE_DEFAULT_DEBUG_CHANNEL(print);
@@ -470,6 +471,26 @@ static int CreateSpoolFile(LPCSTR pszOut
}
if (!psCmd[0] && !strncmp("LPR:",pszOutput,4))
sprintf(psCmd,"|lpr -P%s",pszOutput+4);
+ else if (!psCmd[0] && !strncmp("FILE:",pszOutput,5)) {
+ OPENFILENAMEW ofn;
+ WCHAR szFile[MAX_PATH];
+ WCHAR szDir[MAX_PATH];
+ static const WCHAR ps_files[] = { '*','.','p','s',0 };
+
+ ZeroMemory(&ofn, sizeof(ofn));
+ GetCurrentDirectoryW(sizeof(szDir)/ sizeof(*szDir), szDir);
+ lstrcpyW(szFile, ps_files);
+ ofn.lStructSize = sizeof(OPENFILENAMEW);
+ ofn.lpstrFile = szFile;
+ ofn.nMaxFile = sizeof(szFile)/ sizeof(*szFile);
+ ofn.lpstrInitialDir = szDir;
+ ofn.Flags = OFN_OVERWRITEPROMPT;
+ if (GetSaveFileNameW(&ofn)) {
+ WideCharToMultiByte(CP_ACP, 0, szFile, -1, psCmd, 1024, NULL, NULL);
+ TRACE("Save to filename %s\n", psCmd);
+ }
+
+ }
TRACE("Got printerSpoolCommand '%s' for output device '%s'\n",
psCmd, pszOutput);