From 3b77de9cac9e23be33e820b5f1c04269fa57f245 Mon Sep 17 00:00:00 2001 From: Huw Davies Date: Fri, 22 Jul 2005 18:28:12 +0000 Subject: [PATCH] Implement the undocumented StartDocDlg[A|W]. These will be used by StartDoc. --- dlls/winspool/info.c | 112 ++++++++++++++++++++++++++++++-- dlls/winspool/winspool.drv.spec | 4 +- include/winspool.h | 4 ++ 3 files changed, 114 insertions(+), 6 deletions(-) diff --git a/dlls/winspool/info.c b/dlls/winspool/info.c index d7c18b4e61f..7f99b959534 100644 --- a/dlls/winspool/info.c +++ b/dlls/winspool/info.c @@ -5153,12 +5153,12 @@ INT_PTR CALLBACK file_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam if(LOWORD(wparam) == IDOK) { HANDLE hf; - DWORD len = SendDlgItemMessageW(hwnd, 201, WM_GETTEXTLENGTH, 0, 0); + DWORD len = SendDlgItemMessageW(hwnd, EDITBOX, WM_GETTEXTLENGTH, 0, 0); LPWSTR *output; filename = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR)); GetDlgItemTextW(hwnd, EDITBOX, filename, len + 1); - + if(GetFileAttributesW(filename) != INVALID_FILE_ATTRIBUTES) { WCHAR caption[200], message[200]; @@ -5202,6 +5202,15 @@ INT_PTR CALLBACK file_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam return FALSE; } +/***************************************************************************** + * get_filename + */ +static BOOL get_filename(LPWSTR *filename) +{ + return DialogBoxParamW(WINSPOOL_hInstance, MAKEINTRESOURCEW(FILENAME_DIALOG), GetForegroundWindow(), + file_dlg_proc, (LPARAM)filename) == IDOK; +} + /***************************************************************************** * schedule_file */ @@ -5209,8 +5218,7 @@ static BOOL schedule_file(LPCWSTR filename) { LPWSTR output = NULL; - if(DialogBoxParamW(WINSPOOL_hInstance, MAKEINTRESOURCEW(FILENAME_DIALOG), GetForegroundWindow(), - file_dlg_proc, (LPARAM)&output) == IDOK) + if(get_filename(&output)) { TRACE("copy to %s\n", debugstr_w(output)); CopyFileW(filename, output, FALSE); @@ -5404,3 +5412,99 @@ end: LeaveCriticalSection(&printer_handles_cs); return ret; } + +/***************************************************************************** + * StartDocDlgA [WINSPOOL.@] + */ + LPSTR WINAPI StartDocDlgA( HANDLE hPrinter, DOCINFOA *doc ) +{ + UNICODE_STRING usBuffer; + DOCINFOW docW; + LPWSTR retW; + LPSTR ret = NULL; + + docW.cbSize = sizeof(docW); + docW.lpszDocName = asciitounicode(&usBuffer, doc->lpszDocName); + docW.lpszOutput = asciitounicode(&usBuffer, doc->lpszOutput); + docW.lpszDatatype = asciitounicode(&usBuffer, doc->lpszDatatype); + docW.fwType = doc->fwType; + + retW = StartDocDlgW(hPrinter, &docW); + + if(retW) + { + DWORD len = WideCharToMultiByte(CP_ACP, 0, retW, -1, NULL, 0, NULL, NULL); + ret = HeapAlloc(GetProcessHeap(), 0, len); + WideCharToMultiByte(CP_ACP, 0, retW, -1, ret, len, NULL, NULL); + HeapFree(GetProcessHeap(), 0, retW); + } + + HeapFree(GetProcessHeap(), 0, (LPWSTR)docW.lpszDatatype); + HeapFree(GetProcessHeap(), 0, (LPWSTR)docW.lpszOutput); + HeapFree(GetProcessHeap(), 0, (LPWSTR)docW.lpszDocName); + + return ret; +} + +/***************************************************************************** + * StartDocDlgW [WINSPOOL.@] + * + * Undocumented: Apparently used by gdi32:StartDocW() to popup the file dialog + * when lpszOutput is "FILE:" or if lpszOutput is NULL and the default printer + * port is "FILE:". Also returns the full path if passed a relative path. + * + * The caller should free the returned string from the process heap. + */ +LPWSTR WINAPI StartDocDlgW( HANDLE hPrinter, DOCINFOW *doc ) +{ + LPWSTR ret = NULL; + DWORD len, attr; + + if(doc->lpszOutput == NULL) /* Check whether default port is FILE: */ + { + PRINTER_INFO_5W *pi5; + GetPrinterW(hPrinter, 5, NULL, 0, &len); + if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return NULL; + pi5 = HeapAlloc(GetProcessHeap(), 0, len); + GetPrinterW(hPrinter, 5, (LPBYTE)pi5, len, &len); + if(!pi5->pPortName || strcmpW(pi5->pPortName, FILE_Port)) + { + HeapFree(GetProcessHeap(), 0, pi5); + return NULL; + } + HeapFree(GetProcessHeap(), 0, pi5); + } + + if(doc->lpszOutput == NULL || !strcmpW(doc->lpszOutput, FILE_Port)) + { + LPWSTR name; + get_filename(&name); + if(name) + { + if(!(len = GetFullPathNameW(name, 0, NULL, NULL))) + { + HeapFree(GetProcessHeap(), 0, name); + return NULL; + } + ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + GetFullPathNameW(name, len, ret, NULL); + HeapFree(GetProcessHeap(), 0, name); + } + return ret; + } + + if(!(len = GetFullPathNameW(doc->lpszOutput, 0, NULL, NULL))) + return NULL; + + ret = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + GetFullPathNameW(doc->lpszOutput, len, ret, NULL); + + attr = GetFileAttributesW(ret); + if(attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY)) + { + HeapFree(GetProcessHeap(), 0, ret); + ret = NULL; + } + return ret; +} diff --git a/dlls/winspool/winspool.drv.spec b/dlls/winspool/winspool.drv.spec index b0c6d6a3ad5..5f714eba3ef 100644 --- a/dlls/winspool/winspool.drv.spec +++ b/dlls/winspool/winspool.drv.spec @@ -130,8 +130,8 @@ @ stdcall SetPrinterW(long long ptr long) @ stub SpoolerDevQueryPrintW @ stub SpoolerInit -@ stub StartDocDlgA -@ stub StartDocDlgW +@ stdcall StartDocDlgA(ptr ptr) +@ stdcall StartDocDlgW(ptr ptr) @ stdcall StartDocPrinterA(long long ptr) @ stdcall StartDocPrinterW(long long ptr) @ stdcall StartPagePrinter(long) diff --git a/include/winspool.h b/include/winspool.h index e9f9b33018b..6099a56be54 100644 --- a/include/winspool.h +++ b/include/winspool.h @@ -1160,6 +1160,10 @@ LONG WINAPI ExtDeviceMode( HWND hWnd, HANDLE hInst, LPDEVMODEA pDevModeOutput, LPSTR pDeviceName, LPSTR pPort, LPDEVMODEA pDevModeInput, LPSTR pProfile, DWORD fMode); +LPSTR WINAPI StartDocDlgA(HANDLE hPrinter, DOCINFOA *doc); +LPWSTR WINAPI StartDocDlgW(HANDLE hPrinter, DOCINFOW *doc); +#define StartDocDlg WINELIB_NAME_AW(StartDocDlg) + #ifdef __cplusplus } /* extern "C" */ #endif