* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#define WIN32_NO_STATUS
-#define _INC_WINDOWS
-#define COM_NO_WINDOWS_H
//#include <ctype.h>
//#include <stdlib.h>
//#include <string.h>
#include <assert.h>
+#define COBJMACROS
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include <windef.h>
#include <winbase.h>
-#include <wingdi.h>
#include <winuser.h>
+#include <wingdi.h>
#include <winspool.h>
//#include "winerror.h"
+#include <objbase.h>
+#include <commdlg.h>
#include <wine/unicode.h>
#include <wine/debug.h>
-#include <commdlg.h>
//#include "dlgs.h"
#include <cderr.h>
#include "cdlg.h"
return ret;
}
+/***********************************************************************
+ * get_driver_info [internal]
+ *
+ * get DRIVER_INFO_3W for the current printer handle,
+ * alloc the buffer, when needed
+ */
+static DRIVER_INFO_3W * get_driver_infoW(HANDLE hprn)
+{
+ DRIVER_INFO_3W *di3 = NULL;
+ DWORD needed = 0;
+ BOOL res;
+
+ res = GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
+ if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+ di3 = HeapAlloc(GetProcessHeap(), 0, needed);
+ res = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)di3, needed, &needed);
+ }
+
+ if (res)
+ return di3;
+
+ TRACE("GetPrinterDriverW failed with %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, di3);
+ return NULL;
+}
+
+static DRIVER_INFO_3A * get_driver_infoA(HANDLE hprn)
+{
+ DRIVER_INFO_3A *di3 = NULL;
+ DWORD needed = 0;
+ BOOL res;
+
+ res = GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed);
+ if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+ di3 = HeapAlloc(GetProcessHeap(), 0, needed);
+ res = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)di3, needed, &needed);
+ }
+
+ if (res)
+ return di3;
+
+ TRACE("GetPrinterDriverA failed with %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, di3);
+ return NULL;
+}
+
+
+/***********************************************************************
+ * get_printer_info [internal]
+ *
+ * get PRINTER_INFO_2W for the current printer handle,
+ * alloc the buffer, when needed
+ */
+static PRINTER_INFO_2W * get_printer_infoW(HANDLE hprn)
+{
+ PRINTER_INFO_2W *pi2 = NULL;
+ DWORD needed = 0;
+ BOOL res;
+
+ res = GetPrinterW(hprn, 2, NULL, 0, &needed);
+ if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+ pi2 = HeapAlloc(GetProcessHeap(), 0, needed);
+ res = GetPrinterW(hprn, 2, (LPBYTE)pi2, needed, &needed);
+ }
+
+ if (res)
+ return pi2;
+
+ TRACE("GetPrinterW failed with %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, pi2);
+ return NULL;
+}
+
+static PRINTER_INFO_2A * get_printer_infoA(HANDLE hprn)
+{
+ PRINTER_INFO_2A *pi2 = NULL;
+ DWORD needed = 0;
+ BOOL res;
+
+ res = GetPrinterA(hprn, 2, NULL, 0, &needed);
+ if (!res && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
+ pi2 = HeapAlloc(GetProcessHeap(), 0, needed);
+ res = GetPrinterA(hprn, 2, (LPBYTE)pi2, needed, &needed);
+ }
+
+ if (res)
+ return pi2;
+
+ TRACE("GetPrinterA failed with %u\n", GetLastError());
+ HeapFree(GetProcessHeap(), 0, pi2);
+ return NULL;
+}
+
+
+/***********************************************************************
+ * update_devmode_handle [internal]
+ *
+ * update a devmode handle for the given DEVMODE, alloc the buffer, when needed
+ */
+static HGLOBAL update_devmode_handleW(HGLOBAL hdm, DEVMODEW *dm)
+{
+ SIZE_T size = GlobalSize(hdm);
+ LPVOID ptr;
+
+ /* Increase / alloc the global memory block, when needed */
+ if ((dm->dmSize + dm->dmDriverExtra) > size) {
+ if (hdm)
+ hdm = GlobalReAlloc(hdm, dm->dmSize + dm->dmDriverExtra, 0);
+ else
+ hdm = GlobalAlloc(GMEM_MOVEABLE, dm->dmSize + dm->dmDriverExtra);
+ }
+
+ if (hdm) {
+ ptr = GlobalLock(hdm);
+ if (ptr) {
+ memcpy(ptr, dm, dm->dmSize + dm->dmDriverExtra);
+ GlobalUnlock(hdm);
+ }
+ else
+ {
+ GlobalFree(hdm);
+ hdm = NULL;
+ }
+ }
+ return hdm;
+}
+
+static HGLOBAL update_devmode_handleA(HGLOBAL hdm, DEVMODEA *dm)
+{
+ SIZE_T size = GlobalSize(hdm);
+ LPVOID ptr;
+
+ /* Increase / alloc the global memory block, when needed */
+ if ((dm->dmSize + dm->dmDriverExtra) > size) {
+ if (hdm)
+ hdm = GlobalReAlloc(hdm, dm->dmSize + dm->dmDriverExtra, 0);
+ else
+ hdm = GlobalAlloc(GMEM_MOVEABLE, dm->dmSize + dm->dmDriverExtra);
+ }
+
+ if (hdm) {
+ ptr = GlobalLock(hdm);
+ if (ptr) {
+ memcpy(ptr, dm, dm->dmSize + dm->dmDriverExtra);
+ GlobalUnlock(hdm);
+ }
+ else
+ {
+ GlobalFree(hdm);
+ hdm = NULL;
+ }
+ }
+ return hdm;
+}
+
/***********************************************************
* convert_to_devmodeA
*
LPDEVNAMES lpDevNames;
char buf[260];
DWORD dwBufLen = sizeof(buf);
+ const char *p;
+
+ p = strrchr( DeviceDriverName, '\\' );
+ if (p) DeviceDriverName = p + 1;
size = strlen(DeviceDriverName) + 1
+ strlen(DeviceName) + 1
LPDEVNAMES lpDevNames;
WCHAR bufW[260];
DWORD dwBufLen = sizeof(bufW) / sizeof(WCHAR);
+ const WCHAR *p;
+
+ p = strrchrW( DeviceDriverName, '\\' );
+ if (p) DeviceDriverName = p + 1;
size = sizeof(WCHAR)*lstrlenW(DeviceDriverName) + 2
+ sizeof(WCHAR)*lstrlenW(DeviceName) + 2
}
/* FIXME: I allow more freedom than either Win95 or WinNT,
- * which do not agree to what errors should be thrown or not
+ * which do not agree on what errors should be thrown or not
* in case nToPage or nFromPage is out-of-range.
*/
if (lppd->nMaxPage < lppd->nMinPage)
/* FALLTHROUGH */
case cmb4: /* Printer combobox */
if (HIWORD(wParam)==CBN_SELCHANGE) {
- char PrinterName[256];
- GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255);
+ char *PrinterName;
+ INT index = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0);
+ INT length = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0);
+ PrinterName = HeapAlloc(GetProcessHeap(),0,length+1);
+ SendDlgItemMessageA(hDlg, LOWORD(wParam), CB_GETLBTEXT, index, (LPARAM)PrinterName);
PRINTDLG_ChangePrinterA(hDlg, PrinterName, PrintStructures);
+ HeapFree(GetProcessHeap(),0,PrinterName);
}
break;
/* FALLTHROUGH */
case cmb4: /* Printer combobox */
if (HIWORD(wParam)==CBN_SELCHANGE) {
- WCHAR PrinterName[256];
- GetDlgItemTextW(hDlg, LOWORD(wParam), PrinterName, 255);
+ WCHAR *PrinterName;
+ INT index = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETCURSEL, 0, 0);
+ INT length = SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXTLEN, index, 0);
+
+ PrinterName = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(length+1));
+ SendDlgItemMessageW(hDlg, LOWORD(wParam), CB_GETLBTEXT, index, (LPARAM)PrinterName);
PRINTDLG_ChangePrinterW(hDlg, PrinterName, PrintStructures);
+ HeapFree(GetProcessHeap(),0,PrinterName);
}
break;
}
GlobalUnlock(lppd->hDevNames);
GlobalUnlock(lppd->hDevMode);
- return lppd->hDC ? TRUE : FALSE;
+ return lppd->hDC != NULL;
}
static BOOL PRINTDLG_CreateDCW(LPPRINTDLGW lppd)
}
GlobalUnlock(lppd->hDevNames);
GlobalUnlock(lppd->hDevMode);
- return lppd->hDC ? TRUE : FALSE;
+ return lppd->hDC != NULL;
}
/***********************************************************************
case cmb1: /* Printer combo */
if(msg == CBN_SELCHANGE)
{
- WCHAR name[256];
- GetDlgItemTextW(hDlg, id, name, sizeof(name) / sizeof(name[0]));
+ WCHAR *name;
+ INT index = SendDlgItemMessageW(hDlg, id, CB_GETCURSEL, 0, 0);
+ INT length = SendDlgItemMessageW(hDlg, id, CB_GETLBTEXTLEN, index, 0);
+ name = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(length+1));
+ SendDlgItemMessageW(hDlg, id, CB_GETLBTEXT, index, (LPARAM)name);
pagesetup_change_printer(name, data);
pagesetup_init_combos(hDlg, data);
+ HeapFree(GetProcessHeap(),0,name);
}
break;
case cmb2: /* Paper combo */
return pagesetup_common(&data);
}
+static void pdlgex_to_pdlg(const PRINTDLGEXW *pdlgex, PRINTDLGW *pdlg)
+{
+ pdlg->lStructSize = sizeof(*pdlg);
+ pdlg->hwndOwner = pdlgex->hwndOwner;
+ pdlg->hDevMode = pdlgex->hDevMode;
+ pdlg->hDevNames = pdlgex->hDevNames;
+ pdlg->hDC = pdlgex->hDC;
+ pdlg->Flags = pdlgex->Flags;
+ if ((pdlgex->Flags & PD_NOPAGENUMS) || !pdlgex->nPageRanges || !pdlgex->lpPageRanges)
+ {
+ pdlg->nFromPage = 0;
+ pdlg->nToPage = 65534;
+ }
+ else
+ {
+ pdlg->nFromPage = pdlgex->lpPageRanges[0].nFromPage;
+ pdlg->nToPage = pdlgex->lpPageRanges[0].nToPage;
+ }
+ pdlg->nMinPage = pdlgex->nMinPage;
+ pdlg->nMaxPage = pdlgex->nMaxPage;
+ pdlg->nCopies = pdlgex->nCopies;
+ pdlg->hInstance = pdlgex->hInstance;
+ pdlg->lCustData = 0;
+ pdlg->lpfnPrintHook = NULL;
+ pdlg->lpfnSetupHook = NULL;
+ pdlg->lpPrintTemplateName = pdlgex->lpPrintTemplateName;
+ pdlg->lpSetupTemplateName = NULL;
+ pdlg->hPrintTemplate = NULL;
+ pdlg->hSetupTemplate = NULL;
+}
+
+/* Only copy fields that are supposed to be changed. */
+static void pdlg_to_pdlgex(const PRINTDLGW *pdlg, PRINTDLGEXW *pdlgex)
+{
+ pdlgex->hDevMode = pdlg->hDevMode;
+ pdlgex->hDevNames = pdlg->hDevNames;
+ pdlgex->hDC = pdlg->hDC;
+ if (!(pdlgex->Flags & PD_NOPAGENUMS) && pdlgex->nPageRanges && pdlgex->lpPageRanges)
+ {
+ pdlgex->lpPageRanges[0].nFromPage = pdlg->nFromPage;
+ pdlgex->lpPageRanges[0].nToPage = pdlg->nToPage;
+ }
+ pdlgex->nMinPage = pdlg->nMinPage;
+ pdlgex->nMaxPage = pdlg->nMaxPage;
+ pdlgex->nCopies = pdlg->nCopies;
+}
+
+struct callback_data
+{
+ IPrintDialogCallback *callback;
+ IObjectWithSite *object;
+};
+
+static UINT_PTR CALLBACK pdlgex_hook_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
+{
+ if (msg == WM_INITDIALOG)
+ {
+ PRINTDLGW *pd = (PRINTDLGW *)lp;
+ struct callback_data *cb = (struct callback_data *)pd->lCustData;
+
+ if (cb->callback)
+ {
+ cb->callback->lpVtbl->SelectionChange(cb->callback);
+ cb->callback->lpVtbl->InitDone(cb->callback);
+ }
+ }
+ else
+ {
+/* FIXME: store interface pointer somewhere in window properties and call it
+ HRESULT hres;
+ cb->callback->lpVtbl->HandleMessage(cb->callback, hwnd, msg, wp, lp, &hres);
+*/
+ }
+
+ return 0;
+}
+
/***********************************************************************
* PrintDlgExA (COMDLG32.@)
*
*/
HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd)
{
- DWORD ret = E_FAIL;
- LPVOID ptr;
+ PRINTER_INFO_2A *pbuf;
+ DRIVER_INFO_3A *dbuf;
+ DEVMODEA *dm;
+ HRESULT hr = S_OK;
+ HANDLE hprn;
- FIXME("(%p) not fully implemented\n", lppd);
if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA)))
return E_INVALIDARG;
if (!IsWindow(lppd->hwndOwner))
return E_HANDLE;
- if (lppd->Flags & PD_RETURNDEFAULT)
+ if (lppd->nStartPage != START_PAGE_GENERAL)
{
- PRINTER_INFO_2A *pbuf;
- DRIVER_INFO_2A *dbuf;
- HANDLE hprn;
- DWORD needed = 1024;
- BOOL bRet;
+ if (!lppd->nPropertyPages)
+ return E_INVALIDARG;
+
+ FIXME("custom property sheets (%d at %p) not supported\n", lppd->nPropertyPages, lppd->lphPropertyPages);
+ }
+
+ /* Use PD_NOPAGENUMS or set nMaxPageRanges and lpPageRanges */
+ if (!(lppd->Flags & PD_NOPAGENUMS) && (!lppd->nMaxPageRanges || !lppd->lpPageRanges))
+ {
+ return E_INVALIDARG;
+ }
+ if (lppd->Flags & PD_RETURNDEFAULT)
+ {
if (lppd->hDevMode || lppd->hDevNames)
{
WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
return E_FAIL;
}
- pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed);
- if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
- {
- HeapFree(GetProcessHeap(), 0, pbuf);
- pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed);
- }
- if (!bRet)
+ pbuf = get_printer_infoA(hprn);
+ if (!pbuf)
{
- HeapFree(GetProcessHeap(), 0, pbuf);
ClosePrinter(hprn);
return E_FAIL;
}
- needed = 1024;
- dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
- if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
- {
- HeapFree(GetProcessHeap(), 0, dbuf);
- dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
- }
- if (!bRet)
+ dbuf = get_driver_infoA(hprn);
+ if (!dbuf)
{
- ERR("GetPrinterDriverŠ failed, last error %d, fix your config for printer %s!\n",
- GetLastError(), pbuf->pPrinterName);
- HeapFree(GetProcessHeap(), 0, dbuf);
HeapFree(GetProcessHeap(), 0, pbuf);
COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
ClosePrinter(hprn);
return E_FAIL;
}
- ClosePrinter(hprn);
-
- PRINTDLG_CreateDevNames(&(lppd->hDevNames),
- dbuf->pDriverPath,
- pbuf->pPrinterName,
- pbuf->pPortName);
- lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
- pbuf->pDevMode->dmDriverExtra);
- if (lppd->hDevMode)
+ dm = pbuf->pDevMode;
+ }
+ else
+ {
+ PRINTDLGA pdlg;
+ struct callback_data cb_data = { 0 };
+
+ FIXME("(%p) semi-stub\n", lppd);
+
+ if (lppd->lpCallback)
+ {
+ IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IPrintDialogCallback, (void **)&cb_data.callback);
+ IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IObjectWithSite, (void **)&cb_data.object);
+ }
+
+ /*
+ * PRINTDLGEXA/W and PRINTDLGA/W layout is the same for A and W variants.
+ */
+ pdlgex_to_pdlg((const PRINTDLGEXW *)lppd, (PRINTDLGW *)&pdlg);
+ pdlg.Flags |= PD_ENABLEPRINTHOOK;
+ pdlg.lpfnPrintHook = pdlgex_hook_proc;
+ pdlg.lCustData = (LPARAM)&cb_data;
+
+ if (PrintDlgA(&pdlg))
{
- ptr = GlobalLock(lppd->hDevMode);
- if (ptr)
- {
- memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
- pbuf->pDevMode->dmDriverExtra);
- GlobalUnlock(lppd->hDevMode);
- ret = S_OK;
- }
+ pdlg_to_pdlgex((const PRINTDLGW *)&pdlg, (PRINTDLGEXW *)lppd);
+ lppd->dwResultAction = PD_RESULT_PRINT;
}
- HeapFree(GetProcessHeap(), 0, pbuf);
- HeapFree(GetProcessHeap(), 0, dbuf);
+ else
+ lppd->dwResultAction = PD_RESULT_CANCEL;
+
+ if (cb_data.callback)
+ cb_data.callback->lpVtbl->Release(cb_data.callback);
+ if (cb_data.object)
+ cb_data.object->lpVtbl->Release(cb_data.object);
+
+ return S_OK;
+ }
+
+ ClosePrinter(hprn);
+
+ PRINTDLG_CreateDevNames(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName);
+ if (!lppd->hDevNames)
+ hr = E_FAIL;
- return ret;
+ lppd->hDevMode = update_devmode_handleA(lppd->hDevMode, dm);
+ if (!hr && lppd->hDevMode) {
+ if (lppd->Flags & PD_RETURNDC) {
+ lppd->hDC = CreateDCA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm);
+ if (!lppd->hDC)
+ hr = E_FAIL;
+ }
+ else if (lppd->Flags & PD_RETURNIC) {
+ lppd->hDC = CreateICA(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm);
+ if (!lppd->hDC)
+ hr = E_FAIL;
+ }
}
+ else
+ hr = E_FAIL;
+
+ HeapFree(GetProcessHeap(), 0, pbuf);
+ HeapFree(GetProcessHeap(), 0, dbuf);
- return E_NOTIMPL;
+ return hr;
}
/***********************************************************************
*/
HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lppd)
{
- DWORD ret = E_FAIL;
- LPVOID ptr;
-
- FIXME("(%p) not fully implemented\n", lppd);
+ PRINTER_INFO_2W *pbuf;
+ DRIVER_INFO_3W *dbuf;
+ DEVMODEW *dm;
+ HRESULT hr = S_OK;
+ HANDLE hprn;
if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXW))) {
return E_INVALIDARG;
return E_HANDLE;
}
+ if (lppd->nStartPage != START_PAGE_GENERAL)
+ {
+ if (!lppd->nPropertyPages)
+ return E_INVALIDARG;
+
+ FIXME("custom property sheets (%d at %p) not supported\n", lppd->nPropertyPages, lppd->lphPropertyPages);
+ }
+
+ /* Use PD_NOPAGENUMS or set nMaxPageRanges and lpPageRanges */
+ if (!(lppd->Flags & PD_NOPAGENUMS) && (!lppd->nMaxPageRanges || !lppd->lpPageRanges))
+ {
+ return E_INVALIDARG;
+ }
+
if (lppd->Flags & PD_RETURNDEFAULT) {
- PRINTER_INFO_2W *pbuf;
- DRIVER_INFO_2W *dbuf;
- HANDLE hprn;
- DWORD needed = 1024;
- BOOL bRet;
if (lppd->hDevMode || lppd->hDevNames) {
WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
return E_FAIL;
}
- pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
- if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
- HeapFree(GetProcessHeap(), 0, pbuf);
- pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
- }
- if (!bRet) {
- HeapFree(GetProcessHeap(), 0, pbuf);
+ pbuf = get_printer_infoW(hprn);
+ if (!pbuf)
+ {
ClosePrinter(hprn);
return E_FAIL;
}
- needed = 1024;
- dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
- if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) {
- HeapFree(GetProcessHeap(), 0, dbuf);
- dbuf = HeapAlloc(GetProcessHeap(), 0, needed);
- bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed);
- }
- if (!bRet) {
- ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n",
- GetLastError(), debugstr_w(pbuf->pPrinterName));
- HeapFree(GetProcessHeap(), 0, dbuf);
+ dbuf = get_driver_infoW(hprn);
+ if (!dbuf)
+ {
HeapFree(GetProcessHeap(), 0, pbuf);
COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
ClosePrinter(hprn);
return E_FAIL;
}
- ClosePrinter(hprn);
-
- PRINTDLG_CreateDevNamesW(&(lppd->hDevNames),
- dbuf->pDriverPath,
- pbuf->pPrinterName,
- pbuf->pPortName);
- lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
- pbuf->pDevMode->dmDriverExtra);
- if (lppd->hDevMode) {
- ptr = GlobalLock(lppd->hDevMode);
- if (ptr) {
- memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
- pbuf->pDevMode->dmDriverExtra);
- GlobalUnlock(lppd->hDevMode);
- ret = S_OK;
- }
+ dm = pbuf->pDevMode;
+ }
+ else
+ {
+ PRINTDLGW pdlg;
+ struct callback_data cb_data = { 0 };
+
+ FIXME("(%p) semi-stub\n", lppd);
+
+ if (lppd->lpCallback)
+ {
+ IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IPrintDialogCallback, (void **)&cb_data.callback);
+ IUnknown_QueryInterface((IUnknown *)lppd->lpCallback, &IID_IObjectWithSite, (void **)&cb_data.object);
+ }
+
+ pdlgex_to_pdlg(lppd, &pdlg);
+ pdlg.Flags |= PD_ENABLEPRINTHOOK;
+ pdlg.lpfnPrintHook = pdlgex_hook_proc;
+ pdlg.lCustData = (LPARAM)&cb_data;
+
+ if (PrintDlgW(&pdlg))
+ {
+ pdlg_to_pdlgex(&pdlg, lppd);
+ lppd->dwResultAction = PD_RESULT_PRINT;
}
- HeapFree(GetProcessHeap(), 0, pbuf);
- HeapFree(GetProcessHeap(), 0, dbuf);
+ else
+ lppd->dwResultAction = PD_RESULT_CANCEL;
+
+ if (cb_data.callback)
+ cb_data.callback->lpVtbl->Release(cb_data.callback);
+ if (cb_data.object)
+ cb_data.object->lpVtbl->Release(cb_data.object);
+
+ return S_OK;
+ }
+
+ ClosePrinter(hprn);
+
+ PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName);
+ if (!lppd->hDevNames)
+ hr = E_FAIL;
- return ret;
+ lppd->hDevMode = update_devmode_handleW(lppd->hDevMode, dm);
+ if (!hr && lppd->hDevMode) {
+ if (lppd->Flags & PD_RETURNDC) {
+ lppd->hDC = CreateDCW(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm);
+ if (!lppd->hDC)
+ hr = E_FAIL;
+ }
+ else if (lppd->Flags & PD_RETURNIC) {
+ lppd->hDC = CreateICW(dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, dm);
+ if (!lppd->hDC)
+ hr = E_FAIL;
+ }
}
+ else
+ hr = E_FAIL;
+
+ HeapFree(GetProcessHeap(), 0, pbuf);
+ HeapFree(GetProcessHeap(), 0, dbuf);
- return E_NOTIMPL;
+ return hr;
}