/*
 * COMMDLG - Print Dialog
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1996 Albrecht Kleine
 * Copyright 1999 Klaas van Gend
 * Copyright 2000 Huw D M Davies
 * Copyright 2010 Vitaly Perov
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */
#include <ctype.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winspool.h"
#include "winerror.h"

#include "wine/unicode.h"
#include "wine/debug.h"

#include "commdlg.h"
#include "dlgs.h"
#include "cderr.h"
#include "cdlg.h"

WINE_DEFAULT_DEBUG_CHANNEL(commdlg);

/* Yes these constants are the same, but we're just copying win98 */
#define UPDOWN_ID 0x270f
#define MAX_COPIES 9999

/* This PRINTDLGA internal structure stores
 * pointers to several throughout useful structures.
 */

typedef struct
{
  LPDEVMODEA        lpDevMode;
  LPPRINTDLGA       lpPrintDlg;
  LPPRINTER_INFO_2A lpPrinterInfo;
  LPDRIVER_INFO_3A  lpDriverInfo;
  UINT              HelpMessageID;
  HICON             hCollateIcon;    /* PrintDlg only */
  HICON             hNoCollateIcon;  /* PrintDlg only */
  HICON             hPortraitIcon;   /* PrintSetupDlg only */
  HICON             hLandscapeIcon;  /* PrintSetupDlg only */
  HWND              hwndUpDown;
} PRINT_PTRA;

typedef struct
{
  LPDEVMODEW        lpDevMode;
  LPPRINTDLGW       lpPrintDlg;
  LPPRINTER_INFO_2W lpPrinterInfo;
  LPDRIVER_INFO_3W  lpDriverInfo;
  UINT              HelpMessageID;
  HICON             hCollateIcon;    /* PrintDlg only */
  HICON             hNoCollateIcon;  /* PrintDlg only */
  HICON             hPortraitIcon;   /* PrintSetupDlg only */
  HICON             hLandscapeIcon;  /* PrintSetupDlg only */
  HWND              hwndUpDown;
} PRINT_PTRW;

/* Debugging info */
struct pd_flags
{
  DWORD  flag;
  LPCSTR name;
};

static const struct pd_flags psd_flags[] = {
  {PSD_MINMARGINS,"PSD_MINMARGINS"},
  {PSD_MARGINS,"PSD_MARGINS"},
  {PSD_INTHOUSANDTHSOFINCHES,"PSD_INTHOUSANDTHSOFINCHES"},
  {PSD_INHUNDREDTHSOFMILLIMETERS,"PSD_INHUNDREDTHSOFMILLIMETERS"},
  {PSD_DISABLEMARGINS,"PSD_DISABLEMARGINS"},
  {PSD_DISABLEPRINTER,"PSD_DISABLEPRINTER"},
  {PSD_NOWARNING,"PSD_NOWARNING"},
  {PSD_DISABLEORIENTATION,"PSD_DISABLEORIENTATION"},
  {PSD_RETURNDEFAULT,"PSD_RETURNDEFAULT"},
  {PSD_DISABLEPAPER,"PSD_DISABLEPAPER"},
  {PSD_SHOWHELP,"PSD_SHOWHELP"},
  {PSD_ENABLEPAGESETUPHOOK,"PSD_ENABLEPAGESETUPHOOK"},
  {PSD_ENABLEPAGESETUPTEMPLATE,"PSD_ENABLEPAGESETUPTEMPLATE"},
  {PSD_ENABLEPAGESETUPTEMPLATEHANDLE,"PSD_ENABLEPAGESETUPTEMPLATEHANDLE"},
  {PSD_ENABLEPAGEPAINTHOOK,"PSD_ENABLEPAGEPAINTHOOK"},
  {PSD_DISABLEPAGEPAINTING,"PSD_DISABLEPAGEPAINTING"},
  {-1, NULL}
};

static const struct pd_flags pd_flags[] = {
  {PD_SELECTION, "PD_SELECTION "},
  {PD_PAGENUMS, "PD_PAGENUMS "},
  {PD_NOSELECTION, "PD_NOSELECTION "},
  {PD_NOPAGENUMS, "PD_NOPAGENUMS "},
  {PD_COLLATE, "PD_COLLATE "},
  {PD_PRINTTOFILE, "PD_PRINTTOFILE "},
  {PD_PRINTSETUP, "PD_PRINTSETUP "},
  {PD_NOWARNING, "PD_NOWARNING "},
  {PD_RETURNDC, "PD_RETURNDC "},
  {PD_RETURNIC, "PD_RETURNIC "},
  {PD_RETURNDEFAULT, "PD_RETURNDEFAULT "},
  {PD_SHOWHELP, "PD_SHOWHELP "},
  {PD_ENABLEPRINTHOOK, "PD_ENABLEPRINTHOOK "},
  {PD_ENABLESETUPHOOK, "PD_ENABLESETUPHOOK "},
  {PD_ENABLEPRINTTEMPLATE, "PD_ENABLEPRINTTEMPLATE "},
  {PD_ENABLESETUPTEMPLATE, "PD_ENABLESETUPTEMPLATE "},
  {PD_ENABLEPRINTTEMPLATEHANDLE, "PD_ENABLEPRINTTEMPLATEHANDLE "},
  {PD_ENABLESETUPTEMPLATEHANDLE, "PD_ENABLESETUPTEMPLATEHANDLE "},
  {PD_USEDEVMODECOPIES, "PD_USEDEVMODECOPIES[ANDCOLLATE] "},
  {PD_DISABLEPRINTTOFILE, "PD_DISABLEPRINTTOFILE "},
  {PD_HIDEPRINTTOFILE, "PD_HIDEPRINTTOFILE "},
  {PD_NONETWORKBUTTON, "PD_NONETWORKBUTTON "},
  {-1, NULL}
};
/* address of wndproc for subclassed Static control */
static WNDPROC lpfnStaticWndProc;
static WNDPROC edit_wndproc;
/* the text of the fake document to render for the Page Setup dialog */
static WCHAR wszFakeDocumentText[1024];
static const WCHAR pd32_collateW[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
static const WCHAR pd32_nocollateW[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 };
static const WCHAR pd32_portraitW[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 };
static const WCHAR pd32_landscapeW[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 };
static const WCHAR printdlg_prop[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0};
static const WCHAR pagesetupdlg_prop[] = { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E',
                                           'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 };


static LPWSTR strdupW(LPCWSTR p)
{
    LPWSTR ret;
    DWORD len;

    if(!p) return NULL;
    len = (strlenW(p) + 1) * sizeof(WCHAR);
    ret = HeapAlloc(GetProcessHeap(), 0, len);
    memcpy(ret, p, len);
    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
 *
 * Creates an ansi copy of supplied devmode
 */
static DEVMODEA *convert_to_devmodeA(const DEVMODEW *dmW)
{
    DEVMODEA *dmA;
    DWORD size;

    if (!dmW) return NULL;
    size = dmW->dmSize - CCHDEVICENAME -
                        ((dmW->dmSize > FIELD_OFFSET(DEVMODEW, dmFormName)) ? CCHFORMNAME : 0);

    dmA = HeapAlloc(GetProcessHeap(), 0, size + dmW->dmDriverExtra);
    if (!dmA) return NULL;

    WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1,
                        (LPSTR)dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL);

    if (FIELD_OFFSET(DEVMODEW, dmFormName) >= dmW->dmSize)
    {
        memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion,
               dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmSpecVersion));
    }
    else
    {
        memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion,
               FIELD_OFFSET(DEVMODEW, dmFormName) - FIELD_OFFSET(DEVMODEW, dmSpecVersion));
        WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1,
                            (LPSTR)dmA->dmFormName, CCHFORMNAME, NULL, NULL);

        memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmLogPixels));
    }

    dmA->dmSize = size;
    memcpy((char *)dmA + dmA->dmSize, (const char *)dmW + dmW->dmSize, dmW->dmDriverExtra);
    return dmA;
}

/***********************************************************************
 *    PRINTDLG_OpenDefaultPrinter
 *
 * Returns a winspool printer handle to the default printer in *hprn
 * Caller must call ClosePrinter on the handle
 *
 * Returns TRUE on success else FALSE
 */
static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn)
{
    WCHAR buf[260];
    DWORD dwBufLen = sizeof(buf) / sizeof(buf[0]);
    BOOL res;
    if(!GetDefaultPrinterW(buf, &dwBufLen))
        return FALSE;
    res = OpenPrinterW(buf, hprn, NULL);
    if (!res)
        WARN("Could not open printer %s\n", debugstr_w(buf));
    return res;
}

/***********************************************************************
 *    PRINTDLG_SetUpPrinterListCombo
 *
 * Initializes printer list combox.
 * hDlg:  HWND of dialog
 * id:    Control id of combo
 * name:  Name of printer to select
 *
 * Initializes combo with list of available printers.  Selects printer 'name'
 * If name is NULL or does not exist select the default printer.
 *
 * Returns number of printers added to list.
 */
static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name)
{
    DWORD needed, num;
    INT i;
    LPPRINTER_INFO_2A pi;
    EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num);
    pi = HeapAlloc(GetProcessHeap(), 0, needed);
    EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed,
		  &num);

    SendDlgItemMessageA(hDlg, id, CB_RESETCONTENT, 0, 0);
    
    for(i = 0; i < num; i++) {
        SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0,
			    (LPARAM)pi[i].pPrinterName );
    }
    HeapFree(GetProcessHeap(), 0, pi);
    if(!name ||
       (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1,
				(LPARAM)name)) == CB_ERR) {

        char buf[260];
        DWORD dwBufLen = sizeof(buf);
        if (name != NULL)
            WARN("Can't find %s in printer list so trying to find default\n",
	        debugstr_a(name));
	if(!GetDefaultPrinterA(buf, &dwBufLen))
	    return num;
	i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
	if(i == CB_ERR)
	    FIXME("Can't find default printer in printer list\n");
    }
    SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0);
    return num;
}

static INT PRINTDLG_SetUpPrinterListComboW(HWND hDlg, UINT id, LPCWSTR name)
{
    DWORD needed, num;
    INT i;
    LPPRINTER_INFO_2W pi;
    EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num);
    pi = HeapAlloc(GetProcessHeap(), 0, needed);
    EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed,
		  &num);

    for(i = 0; i < num; i++) {
        SendDlgItemMessageW(hDlg, id, CB_ADDSTRING, 0,
			    (LPARAM)pi[i].pPrinterName );
    }
    HeapFree(GetProcessHeap(), 0, pi);
    if(!name ||
       (i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1,
				(LPARAM)name)) == CB_ERR) {
        WCHAR buf[260];
        DWORD dwBufLen = sizeof(buf)/sizeof(buf[0]);
        if (name != NULL)
            WARN("Can't find %s in printer list so trying to find default\n",
	        debugstr_w(name));
	if(!GetDefaultPrinterW(buf, &dwBufLen))
	    return num;
	i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
	if(i == CB_ERR)
	    TRACE("Can't find default printer in printer list\n");
    }
    SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0);
    return num;
}

/***********************************************************************
 *             PRINTDLG_CreateDevNames          [internal]
 *
 *
 *   creates a DevNames structure.
 *
 *  (NB. when we handle unicode the offsets will be in wchars).
 */
static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, const char* DeviceDriverName,
				    const char* DeviceName, const char* OutputPort)
{
    long size;
    char*   pDevNamesSpace;
    char*   pTempPtr;
    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
            + strlen(OutputPort) + 1
            + sizeof(DEVNAMES);

    if(*hmem)
        *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE);
    else
        *hmem = GlobalAlloc(GMEM_MOVEABLE, size);
    if (*hmem == 0)
        return FALSE;

    pDevNamesSpace = GlobalLock(*hmem);
    lpDevNames = (LPDEVNAMES) pDevNamesSpace;

    pTempPtr = pDevNamesSpace + sizeof(DEVNAMES);
    strcpy(pTempPtr, DeviceDriverName);
    lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;

    pTempPtr += strlen(DeviceDriverName) + 1;
    strcpy(pTempPtr, DeviceName);
    lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;

    pTempPtr += strlen(DeviceName) + 1;
    strcpy(pTempPtr, OutputPort);
    lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;

    GetDefaultPrinterA(buf, &dwBufLen);
    lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0;
    GlobalUnlock(*hmem);
    return TRUE;
}

static BOOL PRINTDLG_CreateDevNamesW(HGLOBAL *hmem, LPCWSTR DeviceDriverName,
				    LPCWSTR DeviceName, LPCWSTR OutputPort)
{
    long size;
    LPWSTR   pDevNamesSpace;
    LPWSTR   pTempPtr;
    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
            + sizeof(WCHAR)*lstrlenW(OutputPort) + 2
            + sizeof(DEVNAMES);

    if(*hmem)
        *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE);
    else
        *hmem = GlobalAlloc(GMEM_MOVEABLE, size);
    if (*hmem == 0)
        return FALSE;

    pDevNamesSpace = GlobalLock(*hmem);
    lpDevNames = (LPDEVNAMES) pDevNamesSpace;

    pTempPtr = (LPWSTR)((LPDEVNAMES)pDevNamesSpace + 1);
    lstrcpyW(pTempPtr, DeviceDriverName);
    lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace;

    pTempPtr += lstrlenW(DeviceDriverName) + 1;
    lstrcpyW(pTempPtr, DeviceName);
    lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;

    pTempPtr += lstrlenW(DeviceName) + 1;
    lstrcpyW(pTempPtr, OutputPort);
    lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;

    GetDefaultPrinterW(bufW, &dwBufLen);
    lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0;
    GlobalUnlock(*hmem);
    return TRUE;
}

/***********************************************************************
 *             PRINTDLG_UpdatePrintDlg          [internal]
 *
 *
 *   updates the PrintDlg structure for return values.
 *
 * RETURNS
 *   FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
 *   TRUE  if successful.
 */
static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg,
				    PRINT_PTRA* PrintStructures)
{
    LPPRINTDLGA       lppd = PrintStructures->lpPrintDlg;
    PDEVMODEA         lpdm = PrintStructures->lpDevMode;
    LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo;


    if(!lpdm) {
	FIXME("No lpdm ptr?\n");
	return FALSE;
    }


    if(!(lppd->Flags & PD_PRINTSETUP)) {
        /* check whether nFromPage and nToPage are within range defined by
	 * nMinPage and nMaxPage
	 */
        if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
	    WORD nToPage;
	    WORD nFromPage;
            BOOL translated;
	    nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
	    nToPage   = GetDlgItemInt(hDlg, edt2, &translated, FALSE);

	    /* if no ToPage value is entered, use the FromPage value */
	    if(!translated) nToPage = nFromPage;

	    if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
		nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
	        WCHAR resourcestr[256];
		WCHAR resultstr[256];
		LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, resourcestr, 255);
		wsprintfW(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
		LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, resourcestr, 255);
		MessageBoxW(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING);
		return FALSE;
	    }
	    lppd->nFromPage = nFromPage;
	    lppd->nToPage   = nToPage;
	    lppd->Flags |= PD_PAGENUMS;
	}
	else
	    lppd->Flags &= ~PD_PAGENUMS;

        if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */
            lppd->Flags |= PD_SELECTION;
        else
            lppd->Flags &= ~PD_SELECTION;

	if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */
	    static char file[] = "FILE:";
	    lppd->Flags |= PD_PRINTTOFILE;
	    pi->pPortName = file;
	}

	if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */
	    FIXME("Collate lppd not yet implemented as output\n");
	}

	/* set PD_Collate and nCopies */
	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /*  The application doesn't support multiple copies or collate...
	   */
	    lppd->Flags &= ~PD_COLLATE;
	    lppd->nCopies = 1;
	  /* if the printer driver supports it... store info there
	   * otherwise no collate & multiple copies !
	   */
	    if (lpdm->dmFields & DM_COLLATE)
	        lpdm->dmCollate =
		  (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED);
	    if (lpdm->dmFields & DM_COPIES)
	        lpdm->u1.s1.dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
	} else {
            /* Application is responsible for multiple copies */
	    if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
	        lppd->Flags |= PD_COLLATE;
            else
               lppd->Flags &= ~PD_COLLATE;
            lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
            /* multiple copies already included in the document. Driver must print only one copy */
            lpdm->u1.s1.dmCopies = 1;
	}

	/* Print quality, PrintDlg16 */
	if(GetDlgItem(hDlg, cmb1))
	{
	    HWND hQuality = GetDlgItem(hDlg, cmb1);
	    int Sel = SendMessageA(hQuality, CB_GETCURSEL, 0, 0);

	    if(Sel != CB_ERR)
	    {
		LONG dpi = SendMessageA(hQuality, CB_GETITEMDATA, Sel, 0);
		lpdm->dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION;
		lpdm->u1.s1.dmPrintQuality = LOWORD(dpi);
		lpdm->dmYResolution = HIWORD(dpi);
	    }
	}
    }
    return TRUE;
}

static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg,
				    PRINT_PTRW* PrintStructures)
{
    LPPRINTDLGW       lppd = PrintStructures->lpPrintDlg;
    PDEVMODEW         lpdm = PrintStructures->lpDevMode;
    LPPRINTER_INFO_2W pi = PrintStructures->lpPrinterInfo;


    if(!lpdm) {
	FIXME("No lpdm ptr?\n");
	return FALSE;
    }


    if(!(lppd->Flags & PD_PRINTSETUP)) {
        /* check whether nFromPage and nToPage are within range defined by
	 * nMinPage and nMaxPage
	 */
        if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */
	    WORD nToPage;
	    WORD nFromPage;
            BOOL translated;
	    nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
	    nToPage   = GetDlgItemInt(hDlg, edt2, &translated, FALSE);

	    /* if no ToPage value is entered, use the FromPage value */
	    if(!translated) nToPage = nFromPage;

	    if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
		nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
	        WCHAR resourcestr[256];
		WCHAR resultstr[256];
                DWORD_PTR args[2];
		LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
			    resourcestr, 255);
                args[0] = lppd->nMinPage;
                args[1] = lppd->nMaxPage;
                FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY,
                               resourcestr, 0, 0, resultstr,
                               sizeof(resultstr)/sizeof(*resultstr),
                               (__ms_va_list*)args);
		LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE,
			    resourcestr, 255);
		MessageBoxW(hDlg, resultstr, resourcestr,
			    MB_OK | MB_ICONWARNING);
		return FALSE;
	    }
	    lppd->nFromPage = nFromPage;
	    lppd->nToPage   = nToPage;
	    lppd->Flags |= PD_PAGENUMS;
	}
	else
	    lppd->Flags &= ~PD_PAGENUMS;

        if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */
            lppd->Flags |= PD_SELECTION;
        else
            lppd->Flags &= ~PD_SELECTION;

	if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */
	    static WCHAR file[] = {'F','I','L','E',':',0};
	    lppd->Flags |= PD_PRINTTOFILE;
	    pi->pPortName = file;
	}

	if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */
	    FIXME("Collate lppd not yet implemented as output\n");
	}

	/* set PD_Collate and nCopies */
	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /*  The application doesn't support multiple copies or collate...
	   */
	    lppd->Flags &= ~PD_COLLATE;
	    lppd->nCopies = 1;
	  /* if the printer driver supports it... store info there
	   * otherwise no collate & multiple copies !
	   */
	    if (lpdm->dmFields & DM_COLLATE)
	        lpdm->dmCollate =
		  (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED);
	    if (lpdm->dmFields & DM_COPIES)
	        lpdm->u1.s1.dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
	} else {
	    if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
	        lppd->Flags |= PD_COLLATE;
            else
               lppd->Flags &= ~PD_COLLATE;
            lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
	}
    }
    return TRUE;
}

/************************************************************************
 * PRINTDLG_SetUpPaperComboBox
 *
 * Initialize either the papersize or inputslot combos of the Printer Setup
 * dialog.  We store the associated word (eg DMPAPER_A4) as the item data.
 * We also try to re-select the old selection.
 */
static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg,
					int   nIDComboBox,
					char* PrinterName,
					char* PortName,
					LPDEVMODEA dm)
{
    int     i;
    int     NrOfEntries;
    char*   Names;
    WORD*   Words;
    DWORD   Sel, old_Sel;
    WORD    oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */
    int     NamesSize;
    int     fwCapability_Names;
    int     fwCapability_Words;

    TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName,PortName,nIDComboBox);

    /* query the dialog box for the current selected value */
    Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0);
    if(Sel != CB_ERR) {
        /* we enter here only if a different printer is selected after
         * the Print Setup dialog is opened. The current settings are
         * stored into the newly selected printer.
         */
        oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA,
                                      Sel, 0);
        if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */
            oldWord = 0; /* There's no point in trying to keep custom
                            paper / bin sizes across printers */
    }

    if (dm)
        newWord = (nIDComboBox == cmb2) ? dm->u1.s1.dmPaperSize : dm->u1.s1.dmDefaultSource;

    if (nIDComboBox == cmb2) {
         NamesSize          = 64;
         fwCapability_Names = DC_PAPERNAMES;
         fwCapability_Words = DC_PAPERS;
    } else {
         nIDComboBox        = cmb3;
         NamesSize          = 24;
         fwCapability_Names = DC_BINNAMES;
         fwCapability_Words = DC_BINS;
    }

    NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
                                      fwCapability_Names, NULL, dm);
    if (NrOfEntries == 0)
         WARN("no Name Entries found!\n");
    else if (NrOfEntries < 0)
         return FALSE;

    if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm)
       != NrOfEntries) {
        ERR("Number of caps is different\n");
	NrOfEntries = 0;
    }

    Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(char)*NamesSize);
    Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD));
    NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
                                      fwCapability_Names, Names, dm);
    NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
				      fwCapability_Words, (LPSTR)Words, dm);

    /* reset any current content in the combobox */
    SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);

    /* store new content */
    for (i = 0; i < NrOfEntries; i++) {
        DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0,
					(LPARAM)(&Names[i*NamesSize]) );
	SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
			    Words[i]);
    }

    /* Look for old selection or the new default.
       Can't do this is previous loop since item order will change as more items are added */
    Sel = 0;
    old_Sel = NrOfEntries;
    for (i = 0; i < NrOfEntries; i++) {
        if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) ==
	   oldWord) {
	    old_Sel = i;
	    break;
	}
        if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord)
	    Sel = i;
    }

    if(old_Sel < NrOfEntries)
    {
        if (dm)
        {
            if(nIDComboBox == cmb2)
                dm->u1.s1.dmPaperSize = oldWord;
            else
                dm->u1.s1.dmDefaultSource = oldWord;
        }
        Sel = old_Sel;
    }

    SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0);

    HeapFree(GetProcessHeap(),0,Words);
    HeapFree(GetProcessHeap(),0,Names);
    return TRUE;
}

static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg,
					int   nIDComboBox,
					const WCHAR* PrinterName,
					const WCHAR* PortName,
					LPDEVMODEW dm)
{
    int     i;
    int     NrOfEntries;
    WCHAR*  Names;
    WORD*   Words;
    DWORD   Sel, old_Sel;
    WORD    oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */
    int     NamesSize;
    int     fwCapability_Names;
    int     fwCapability_Words;

    TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName),debugstr_w(PortName),nIDComboBox);

    /* query the dialog box for the current selected value */
    Sel = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0);
    if(Sel != CB_ERR) {
        /* we enter here only if a different printer is selected after
         * the Print Setup dialog is opened. The current settings are
         * stored into the newly selected printer.
         */
        oldWord = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA,
                                      Sel, 0);

        if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */
            oldWord = 0; /* There's no point in trying to keep custom
                            paper / bin sizes across printers */
    }

    if (dm)
        newWord = (nIDComboBox == cmb2) ? dm->u1.s1.dmPaperSize : dm->u1.s1.dmDefaultSource;

    if (nIDComboBox == cmb2) {
         NamesSize          = 64;
         fwCapability_Names = DC_PAPERNAMES;
         fwCapability_Words = DC_PAPERS;
    } else {
         nIDComboBox        = cmb3;
         NamesSize          = 24;
         fwCapability_Names = DC_BINNAMES;
         fwCapability_Words = DC_BINS;
    }

    NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName,
                                      fwCapability_Names, NULL, dm);
    if (NrOfEntries == 0)
         WARN("no Name Entries found!\n");
    else if (NrOfEntries < 0)
         return FALSE;

    if(DeviceCapabilitiesW(PrinterName, PortName, fwCapability_Words, NULL, dm)
       != NrOfEntries) {
        ERR("Number of caps is different\n");
	NrOfEntries = 0;
    }

    Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WCHAR)*NamesSize);
    Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD));
    NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName,
                                      fwCapability_Names, Names, dm);
    NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName,
                                      fwCapability_Words, Words, dm);

    /* reset any current content in the combobox */
    SendDlgItemMessageW(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0);

    /* store new content */
    for (i = 0; i < NrOfEntries; i++) {
        DWORD pos = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0,
					(LPARAM)(&Names[i*NamesSize]) );
	SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
			    Words[i]);
    }

    /* Look for old selection or the new default.
       Can't do this is previous loop since item order will change as more items are added */
    Sel = 0;
    old_Sel = NrOfEntries;
    for (i = 0; i < NrOfEntries; i++) {
        if(SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) ==
	   oldWord) {
	    old_Sel = i;
	    break;
	}
        if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord)
            Sel = i;
    }

    if(old_Sel < NrOfEntries)
    {
        if (dm)
        {
            if(nIDComboBox == cmb2)
                dm->u1.s1.dmPaperSize = oldWord;
            else
                dm->u1.s1.dmDefaultSource = oldWord;
        }
        Sel = old_Sel;
    }

    SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0);

    HeapFree(GetProcessHeap(),0,Words);
    HeapFree(GetProcessHeap(),0,Names);
    return TRUE;
}


/***********************************************************************
 *               PRINTDLG_UpdatePrinterInfoTexts               [internal]
 */
static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *pi)
{
    char   StatusMsg[256];
    char   ResourceString[256];
    int    i;

    /* Status Message */
    StatusMsg[0]='\0';

    /* add all status messages */
    for (i = 0; i < 25; i++) {
        if (pi->Status & (1<<i)) {
	    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
			ResourceString, 255);
	    strcat(StatusMsg,ResourceString);
        }
    }
    /* append "ready" */
    /* FIXME: status==ready must only be appended if really so.
              but how to detect? */
    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
		ResourceString, 255);
    strcat(StatusMsg,ResourceString);
    SetDlgItemTextA(hDlg, stc12, StatusMsg);

    /* set all other printer info texts */
    SetDlgItemTextA(hDlg, stc11, pi->pDriverName);
    
    if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
        SetDlgItemTextA(hDlg, stc14, pi->pLocation);
    else
        SetDlgItemTextA(hDlg, stc14, pi->pPortName);
    SetDlgItemTextA(hDlg, stc13, pi->pComment ? pi->pComment : "");
    return;
}

static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *pi)
{
    WCHAR   StatusMsg[256];
    WCHAR   ResourceString[256];
    static const WCHAR emptyW[] = {0};
    int    i;

    /* Status Message */
    StatusMsg[0]='\0';

    /* add all status messages */
    for (i = 0; i < 25; i++) {
        if (pi->Status & (1<<i)) {
	    LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
			ResourceString, 255);
	    lstrcatW(StatusMsg,ResourceString);
        }
    }
    /* append "ready" */
    /* FIXME: status==ready must only be appended if really so.
              but how to detect? */
    LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
		ResourceString, 255);
    lstrcatW(StatusMsg,ResourceString);
    SetDlgItemTextW(hDlg, stc12, StatusMsg);

    /* set all other printer info texts */
    SetDlgItemTextW(hDlg, stc11, pi->pDriverName);
    if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
        SetDlgItemTextW(hDlg, stc14, pi->pLocation);
    else
        SetDlgItemTextW(hDlg, stc14, pi->pPortName);
    SetDlgItemTextW(hDlg, stc13, pi->pComment ? pi->pComment : emptyW);
}


/*******************************************************************
 *
 *                 PRINTDLG_ChangePrinter
 *
 */
static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStructures)
{
    LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
    LPDEVMODEA lpdm = NULL;
    LONG dmSize;
    DWORD needed;
    HANDLE hprn;

    HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo);
    HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo);
    if(!OpenPrinterA(name, &hprn, NULL)) {
        ERR("Can't open printer %s\n", name);
	return FALSE;
    }
    GetPrinterA(hprn, 2, NULL, 0, &needed);
    PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed);
    GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
		&needed);
    GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed);
    PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed);
    if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo,
	    needed, &needed)) {
	ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures->lpPrinterInfo->pPrinterName);
	return FALSE;
    }
    ClosePrinter(hprn);

    PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo);

    HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
    PrintStructures->lpDevMode = NULL;

    dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0);
    if(dmSize == -1) {
        ERR("DocumentProperties fails on %s\n", debugstr_a(name));
	return FALSE;
    }
    PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize);
    dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL,
				 DM_OUT_BUFFER);
    if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) &&
			  !lstrcmpA( (LPSTR) lpdm->dmDeviceName,
				     (LPSTR) PrintStructures->lpDevMode->dmDeviceName)) {
      /* Supplied devicemode matches current printer so try to use it */
        DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm,
			    DM_OUT_BUFFER | DM_IN_BUFFER);
    }
    if(lpdm)
        GlobalUnlock(lppd->hDevMode);

    lpdm = PrintStructures->lpDevMode;  /* use this as a shortcut */

    if(!(lppd->Flags & PD_PRINTSETUP)) {
	/* Print range (All/Range/Selection) */
	if(lppd->nFromPage != 0xffff)
	    SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
	if(lppd->nToPage != 0xffff)
	    SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);

	CheckRadioButton(hDlg, rad1, rad3, rad1);		/* default */
	if (lppd->Flags & PD_NOSELECTION)
	    EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
	else
	    if (lppd->Flags & PD_SELECTION)
	        CheckRadioButton(hDlg, rad1, rad3, rad2);
	if (lppd->Flags & PD_NOPAGENUMS) {
	    EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
	    EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
	    EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
	    EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
	    EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
	} else {
	    if (lppd->Flags & PD_PAGENUMS)
	        CheckRadioButton(hDlg, rad1, rad3, rad3);
	}

	/* Collate pages
	 *
	 * FIXME: The ico3 is not displayed for some reason. I don't know why.
	 */
	if (lppd->Flags & PD_COLLATE) {
            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
				(LPARAM)PrintStructures->hCollateIcon);
	    CheckDlgButton(hDlg, chx2, 1);
	} else {
            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
				(LPARAM)PrintStructures->hNoCollateIcon);
	    CheckDlgButton(hDlg, chx2, 0);
	}

	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /* if printer doesn't support it: no Collate */
	    if (!(lpdm->dmFields & DM_COLLATE)) {
	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
		EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
	    }
	}

	/* nCopies */
	{
	  INT copies;
	  if (lppd->hDevMode == 0)
	      copies = lppd->nCopies;
	  else
	      copies = lpdm->u1.s1.dmCopies;
	  if(copies == 0) copies = 1;
	  else if(copies < 0) copies = MAX_COPIES;
	  SetDlgItemInt(hDlg, edt3, copies, FALSE);
	}

	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /* if printer doesn't support it: no nCopies */
	    if (!(lpdm->dmFields & DM_COPIES)) {
	        EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
		EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
	    }
	}

	/* print to file */
	CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
	if (lppd->Flags & PD_DISABLEPRINTTOFILE)
            EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
	if (lppd->Flags & PD_HIDEPRINTTOFILE)
            ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);

	/* Fill print quality combo, PrintDlg16 */
	if(GetDlgItem(hDlg, cmb1))
	{
	    DWORD numResolutions = DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName,
						       PrintStructures->lpPrinterInfo->pPortName,
						       DC_ENUMRESOLUTIONS, NULL, lpdm);

	    if(numResolutions != -1)
	    {
		HWND hQuality = GetDlgItem(hDlg, cmb1);
		LONG* Resolutions;
		char buf[255];
		DWORD i;
		int dpiX, dpiY;
		HDC hPrinterDC = CreateDCA(PrintStructures->lpPrinterInfo->pDriverName,
					   PrintStructures->lpPrinterInfo->pPrinterName,
					   0, lpdm);

		Resolutions = HeapAlloc(GetProcessHeap(), 0, numResolutions*sizeof(LONG)*2);
		DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName,
				    PrintStructures->lpPrinterInfo->pPortName,
				    DC_ENUMRESOLUTIONS, (LPSTR)Resolutions, lpdm);

		dpiX = GetDeviceCaps(hPrinterDC, LOGPIXELSX);
		dpiY = GetDeviceCaps(hPrinterDC, LOGPIXELSY);
		DeleteDC(hPrinterDC);

		SendMessageA(hQuality, CB_RESETCONTENT, 0, 0);
		for(i = 0; i < (numResolutions * 2); i += 2)
		{
		    BOOL IsDefault = FALSE;
		    LRESULT Index;

		    if(Resolutions[i] == Resolutions[i+1])
		    {
			if(dpiX == Resolutions[i])
			    IsDefault = TRUE;
			sprintf(buf, "%d dpi", Resolutions[i]);
		    } else
		    {
			if(dpiX == Resolutions[i] && dpiY == Resolutions[i+1])
			    IsDefault = TRUE;
			sprintf(buf, "%d dpi x %d dpi", Resolutions[i], Resolutions[i+1]);
		    }

		    Index = SendMessageA(hQuality, CB_ADDSTRING, 0, (LPARAM)buf);

		    if(IsDefault)
			SendMessageA(hQuality, CB_SETCURSEL, Index, 0);

		    SendMessageA(hQuality, CB_SETITEMDATA, Index, MAKELONG(dpiX,dpiY));
		}
		HeapFree(GetProcessHeap(), 0, Resolutions);
	    }
	}
    } else { /* PD_PRINTSETUP */
      BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT);

      PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb2,
				  PrintStructures->lpPrinterInfo->pPrinterName,
				  PrintStructures->lpPrinterInfo->pPortName,
				  lpdm);
      PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb3,
				  PrintStructures->lpPrinterInfo->pPrinterName,
				  PrintStructures->lpPrinterInfo->pPortName,
				  lpdm);
      CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2);
      SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon :
                                   PrintStructures->hLandscapeIcon));

    }

    /* help button */
    if ((lppd->Flags & PD_SHOWHELP)==0) {
        /* hide if PD_SHOWHELP not specified */
        ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
    }
    return TRUE;
}

static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
				   PRINT_PTRW *PrintStructures)
{
    LPPRINTDLGW lppd = PrintStructures->lpPrintDlg;
    LPDEVMODEW lpdm = NULL;
    LONG dmSize;
    DWORD needed;
    HANDLE hprn;

    HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo);
    HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo);
    if(!OpenPrinterW(name, &hprn, NULL)) {
        ERR("Can't open printer %s\n", debugstr_w(name));
	return FALSE;
    }
    GetPrinterW(hprn, 2, NULL, 0, &needed);
    PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed);
    GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
		&needed);
    GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
    PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed);
    if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo,
	    needed, &needed)) {
	ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures->lpPrinterInfo->pPrinterName));
	return FALSE;
    }
    ClosePrinter(hprn);

    PRINTDLG_UpdatePrinterInfoTextsW(hDlg, PrintStructures->lpPrinterInfo);

    HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
    PrintStructures->lpDevMode = NULL;

    dmSize = DocumentPropertiesW(0, 0, name, NULL, NULL, 0);
    if(dmSize == -1) {
        ERR("DocumentProperties fails on %s\n", debugstr_w(name));
	return FALSE;
    }
    PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize);
    dmSize = DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, NULL,
				 DM_OUT_BUFFER);
    if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) &&
			  !lstrcmpW(lpdm->dmDeviceName,
				  PrintStructures->lpDevMode->dmDeviceName)) {
      /* Supplied devicemode matches current printer so try to use it */
        DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, lpdm,
			    DM_OUT_BUFFER | DM_IN_BUFFER);
    }
    if(lpdm)
        GlobalUnlock(lppd->hDevMode);

    lpdm = PrintStructures->lpDevMode;  /* use this as a shortcut */

    if(!(lppd->Flags & PD_PRINTSETUP)) {
	/* Print range (All/Range/Selection) */
	if(lppd->nFromPage != 0xffff)
	    SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
	if(lppd->nToPage != 0xffff)
	    SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE);

	CheckRadioButton(hDlg, rad1, rad3, rad1);		/* default */
	if (lppd->Flags & PD_NOSELECTION)
	    EnableWindow(GetDlgItem(hDlg, rad2), FALSE);
	else
	    if (lppd->Flags & PD_SELECTION)
	        CheckRadioButton(hDlg, rad1, rad3, rad2);
	if (lppd->Flags & PD_NOPAGENUMS) {
	    EnableWindow(GetDlgItem(hDlg, rad3), FALSE);
	    EnableWindow(GetDlgItem(hDlg, stc2),FALSE);
	    EnableWindow(GetDlgItem(hDlg, edt1), FALSE);
	    EnableWindow(GetDlgItem(hDlg, stc3),FALSE);
	    EnableWindow(GetDlgItem(hDlg, edt2), FALSE);
	} else {
	    if (lppd->Flags & PD_PAGENUMS)
	        CheckRadioButton(hDlg, rad1, rad3, rad3);
	}

	/* Collate pages
	 *
	 * FIXME: The ico3 is not displayed for some reason. I don't know why.
	 */
	if (lppd->Flags & PD_COLLATE) {
            SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
				(LPARAM)PrintStructures->hCollateIcon);
	    CheckDlgButton(hDlg, chx2, 1);
	} else {
            SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
				(LPARAM)PrintStructures->hNoCollateIcon);
	    CheckDlgButton(hDlg, chx2, 0);
	}

	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /* if printer doesn't support it: no Collate */
	    if (!(lpdm->dmFields & DM_COLLATE)) {
	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
		EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
	    }
	}

	/* nCopies */
	{
	  INT copies;
	  if (lppd->hDevMode == 0)
	      copies = lppd->nCopies;
	  else
	      copies = lpdm->u1.s1.dmCopies;
	  if(copies == 0) copies = 1;
	  else if(copies < 0) copies = MAX_COPIES;
	  SetDlgItemInt(hDlg, edt3, copies, FALSE);
	}

	if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) {
	  /* if printer doesn't support it: no nCopies */
	    if (!(lpdm->dmFields & DM_COPIES)) {
	        EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
		EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
	    }
	}

	/* print to file */
	CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
	if (lppd->Flags & PD_DISABLEPRINTTOFILE)
            EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
	if (lppd->Flags & PD_HIDEPRINTTOFILE)
            ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);

    } else { /* PD_PRINTSETUP */
      BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT);

      PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2,
				  PrintStructures->lpPrinterInfo->pPrinterName,
				  PrintStructures->lpPrinterInfo->pPortName,
				  lpdm);
      PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3,
				  PrintStructures->lpPrinterInfo->pPrinterName,
				  PrintStructures->lpPrinterInfo->pPortName,
				  lpdm);
      CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2);
      SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon :
                                   PrintStructures->hLandscapeIcon));

    }

    /* help button */
    if ((lppd->Flags & PD_SHOWHELP)==0) {
        /* hide if PD_SHOWHELP not specified */
        ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
    }
    return TRUE;
}

 /***********************************************************************
 *           check_printer_setup			[internal]
 */
static LRESULT check_printer_setup(HWND hDlg)
{
    DWORD needed,num;
    WCHAR resourcestr[256],resultstr[256];

    EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num);
    if(needed == 0)
    {
          EnumPrintersW(PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &num);
    }
    if(needed > 0)
          return TRUE;
    else
    {
          LoadStringW(COMDLG32_hInstance, PD32_NO_DEVICES,resultstr, 255);
          LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE,resourcestr, 255);
          MessageBoxW(hDlg, resultstr, resourcestr,MB_OK | MB_ICONWARNING);
          return FALSE;
    }
}

/***********************************************************************
 *           PRINTDLG_WMInitDialog                      [internal]
 */
static LRESULT PRINTDLG_WMInitDialog(HWND hDlg,
				     PRINT_PTRA* PrintStructures)
{
    LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
    DEVNAMES *pdn;
    DEVMODEA *pdm;
    char *name = NULL;
    UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;

    /* load Collate ICONs */
    /* We load these with LoadImage because they are not a standard
       size and we don't want them rescaled */
    PrintStructures->hCollateIcon =
      LoadImageA(COMDLG32_hInstance, "PD32_COLLATE", IMAGE_ICON, 0, 0, 0);
    PrintStructures->hNoCollateIcon =
      LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0);

    /* These can be done with LoadIcon */
    PrintStructures->hPortraitIcon =
      LoadIconA(COMDLG32_hInstance, "PD32_PORTRAIT");
    PrintStructures->hLandscapeIcon =
      LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE");

    /* display the collate/no_collate icon */
    SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                        (LPARAM)PrintStructures->hNoCollateIcon);

    if(PrintStructures->hCollateIcon == 0 ||
       PrintStructures->hNoCollateIcon == 0 ||
       PrintStructures->hPortraitIcon == 0 ||
       PrintStructures->hLandscapeIcon == 0) {
        ERR("no icon in resourcefile\n");
	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	EndDialog(hDlg, FALSE);
    }

    /*
     * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
     * must be registered and the Help button must be shown.
     */
    if (lppd->Flags & PD_SHOWHELP) {
        if((PrintStructures->HelpMessageID =
	    RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
	    return FALSE;
	}
    } else
        PrintStructures->HelpMessageID = 0;

    if(!(lppd->Flags &PD_PRINTSETUP)) {
        PrintStructures->hwndUpDown =
	  CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER |
			      UDS_NOTHOUSANDS | UDS_ARROWKEYS |
			      UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0,
			      hDlg, UPDOWN_ID, COMDLG32_hInstance,
			      GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1);
    }

    /* FIXME: I allow more freedom than either Win95 or WinNT,
     *        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)
    	lppd->nMaxPage = lppd->nMinPage;
    if (lppd->nMinPage == lppd->nMaxPage)
    	lppd->Flags |= PD_NOPAGENUMS;
    if (lppd->nToPage < lppd->nMinPage)
        lppd->nToPage = lppd->nMinPage;
    if (lppd->nToPage > lppd->nMaxPage)
        lppd->nToPage = lppd->nMaxPage;
    if (lppd->nFromPage < lppd->nMinPage)
        lppd->nFromPage = lppd->nMinPage;
    if (lppd->nFromPage > lppd->nMaxPage)
        lppd->nFromPage = lppd->nMaxPage;

    /* if we have the combo box, fill it */
    if (GetDlgItem(hDlg,comboID)) {
	/* Fill Combobox
	 */
	pdn = GlobalLock(lppd->hDevNames);
	pdm = GlobalLock(lppd->hDevMode);
	if(pdn)
	    name = (char*)pdn + pdn->wDeviceOffset;
	else if(pdm)
	    name = (char*)pdm->dmDeviceName;
	PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name);
	if(pdm) GlobalUnlock(lppd->hDevMode);
	if(pdn) GlobalUnlock(lppd->hDevNames);

	/* Now find selected printer and update rest of dlg */
	name = HeapAlloc(GetProcessHeap(),0,256);
	if (GetDlgItemTextA(hDlg, comboID, name, 255))
	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
	HeapFree(GetProcessHeap(),0,name);
    } else {
	/* else use default printer */
	char name[200];
        DWORD dwBufLen = sizeof(name);
	BOOL ret = GetDefaultPrinterA(name, &dwBufLen);

	if (ret)
	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
	else
	    FIXME("No default printer found, expect problems!\n");
    }
    return TRUE;
}

static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg,
				     PRINT_PTRW* PrintStructures)
{
    LPPRINTDLGW lppd = PrintStructures->lpPrintDlg;
    DEVNAMES *pdn;
    DEVMODEW *pdm;
    WCHAR *name = NULL;
    UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;

    /* load Collate ICONs */
    /* We load these with LoadImage because they are not a standard
       size and we don't want them rescaled */
    PrintStructures->hCollateIcon =
      LoadImageW(COMDLG32_hInstance, pd32_collateW, IMAGE_ICON, 0, 0, 0);
    PrintStructures->hNoCollateIcon =
      LoadImageW(COMDLG32_hInstance, pd32_nocollateW, IMAGE_ICON, 0, 0, 0);

    /* These can be done with LoadIcon */
    PrintStructures->hPortraitIcon =
      LoadIconW(COMDLG32_hInstance, pd32_portraitW);
    PrintStructures->hLandscapeIcon =
      LoadIconW(COMDLG32_hInstance, pd32_landscapeW);

    /* display the collate/no_collate icon */
    SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                        (LPARAM)PrintStructures->hNoCollateIcon);

    if(PrintStructures->hCollateIcon == 0 ||
       PrintStructures->hNoCollateIcon == 0 ||
       PrintStructures->hPortraitIcon == 0 ||
       PrintStructures->hLandscapeIcon == 0) {
        ERR("no icon in resourcefile\n");
	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	EndDialog(hDlg, FALSE);
    }

    /*
     * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message
     * must be registered and the Help button must be shown.
     */
    if (lppd->Flags & PD_SHOWHELP) {
        if((PrintStructures->HelpMessageID =
	    RegisterWindowMessageW(HELPMSGSTRINGW)) == 0) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
	    return FALSE;
	}
    } else
        PrintStructures->HelpMessageID = 0;

    if(!(lppd->Flags &PD_PRINTSETUP)) {
        PrintStructures->hwndUpDown =
	  CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER |
			      UDS_NOTHOUSANDS | UDS_ARROWKEYS |
			      UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0,
			      hDlg, UPDOWN_ID, COMDLG32_hInstance,
			      GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1);
    }

    /* FIXME: I allow more freedom than either Win95 or WinNT,
     *        which do not agree to what errors should be thrown or not
     *        in case nToPage or nFromPage is out-of-range.
     */
    if (lppd->nMaxPage < lppd->nMinPage)
    	lppd->nMaxPage = lppd->nMinPage;
    if (lppd->nMinPage == lppd->nMaxPage)
    	lppd->Flags |= PD_NOPAGENUMS;
    if (lppd->nToPage < lppd->nMinPage)
        lppd->nToPage = lppd->nMinPage;
    if (lppd->nToPage > lppd->nMaxPage)
        lppd->nToPage = lppd->nMaxPage;
    if (lppd->nFromPage < lppd->nMinPage)
        lppd->nFromPage = lppd->nMinPage;
    if (lppd->nFromPage > lppd->nMaxPage)
        lppd->nFromPage = lppd->nMaxPage;

    /* if we have the combo box, fill it */
    if (GetDlgItem(hDlg,comboID)) {
	/* Fill Combobox
	 */
	pdn = GlobalLock(lppd->hDevNames);
	pdm = GlobalLock(lppd->hDevMode);
	if(pdn)
	    name = (WCHAR*)pdn + pdn->wDeviceOffset;
	else if(pdm)
	    name = pdm->dmDeviceName;
	PRINTDLG_SetUpPrinterListComboW(hDlg, comboID, name);
	if(pdm) GlobalUnlock(lppd->hDevMode);
	if(pdn) GlobalUnlock(lppd->hDevNames);

	/* Now find selected printer and update rest of dlg */
	/* ansi is ok here */
	name = HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR));
	if (GetDlgItemTextW(hDlg, comboID, name, 255))
	    PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures);
	HeapFree(GetProcessHeap(),0,name);
    } else {
	/* else use default printer */
	WCHAR name[200];
        DWORD dwBufLen = sizeof(name) / sizeof(WCHAR);
	BOOL ret = GetDefaultPrinterW(name, &dwBufLen);

	if (ret)
	    PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures);
	else
	    FIXME("No default printer found, expect problems!\n");
    }
    return TRUE;
}

/***********************************************************************
 *                              PRINTDLG_WMCommand               [internal]
 */
static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam,
                                   PRINT_PTRA* PrintStructures)
{
    LPPRINTDLGA lppd = PrintStructures->lpPrintDlg;
    UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
    LPDEVMODEA lpdm = PrintStructures->lpDevMode;

    switch (LOWORD(wParam))  {
    case IDOK:
        TRACE(" OK button was hit\n");
        if (!PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)) {
	    FIXME("Update printdlg was not successful!\n");
	    return(FALSE);
	}
	EndDialog(hDlg, TRUE);
	return(TRUE);

    case IDCANCEL:
        TRACE(" CANCEL button was hit\n");
        EndDialog(hDlg, FALSE);
	return(FALSE);

     case pshHelp:
        TRACE(" HELP button was hit\n");
        SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
        			(WPARAM) hDlg, (LPARAM) lppd);
        break;

     case chx2:                         /* collate pages checkbox */
        if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                                    (LPARAM)PrintStructures->hCollateIcon);
        else
            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                                    (LPARAM)PrintStructures->hNoCollateIcon);
        break;
     case edt1:                         /* from page nr editbox */
     case edt2:                         /* to page nr editbox */
        if (HIWORD(wParam)==EN_CHANGE) {
	    WORD nToPage;
	    WORD nFromPage;
	    nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
	    nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
            if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
	        CheckRadioButton(hDlg, rad1, rad3, rad3);
	}
        break;

    case edt3:
        if(HIWORD(wParam) == EN_CHANGE) {
	    INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
	    if(copies <= 1)
	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
	    else
	        EnableWindow(GetDlgItem(hDlg, chx2), TRUE);
	}
	break;

     case psh2:                       /* Properties button */
       {
         HANDLE hPrinter;
         char   PrinterName[256];

         GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255);
         if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) {
	     FIXME(" Call to OpenPrinter did not succeed!\n");
	     break;
	 }
	 DocumentPropertiesA(hDlg, hPrinter, PrinterName,
			     PrintStructures->lpDevMode,
			     PrintStructures->lpDevMode,
			     DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
	 ClosePrinter(hPrinter);
         break;
       }

    case rad1: /* Paperorientation */
        if (lppd->Flags & PD_PRINTSETUP)
        {
              lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
              SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(PrintStructures->hPortraitIcon));
        }
        break;

    case rad2: /* Paperorientation */
        if (lppd->Flags & PD_PRINTSETUP)
        {
              lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
              SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(PrintStructures->hLandscapeIcon));
        }
        break;

    case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */
	 if (PrinterComboID != LOWORD(wParam)) {
	     break;
	 }
	 /* FALLTHROUGH */
    case cmb4:                         /* Printer combobox */
         if (HIWORD(wParam)==CBN_SELCHANGE) {
	     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;

    case cmb2: /* Papersize */
      {
	  DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
	  if(Sel != CB_ERR)
	      lpdm->u1.s1.dmPaperSize = SendDlgItemMessageA(hDlg, cmb2,
							    CB_GETITEMDATA,
							    Sel, 0);
      }
      break;

    case cmb3: /* Bin */
      {
	  DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0);
	  if(Sel != CB_ERR)
	      lpdm->u1.s1.dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3,
							  CB_GETITEMDATA, Sel,
							  0);
      }
      break;
    }
    if(lppd->Flags & PD_PRINTSETUP) {
        switch (LOWORD(wParam)) {
	case rad1:                         /* orientation */
	case rad2:
	    if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) {
	        if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) {
		    lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
                    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hPortraitIcon);
                    SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hPortraitIcon);
		}
	    } else {
	        if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) {
	            lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
                    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hLandscapeIcon);
                    SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hLandscapeIcon);
		}
	    }
	    break;
	}
    }
    return FALSE;
}

static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam,
			           PRINT_PTRW* PrintStructures)
{
    LPPRINTDLGW lppd = PrintStructures->lpPrintDlg;
    UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4;
    LPDEVMODEW lpdm = PrintStructures->lpDevMode;

    switch (LOWORD(wParam))  {
    case IDOK:
        TRACE(" OK button was hit\n");
        if (!PRINTDLG_UpdatePrintDlgW(hDlg, PrintStructures)) {
	    FIXME("Update printdlg was not successful!\n");
	    return(FALSE);
	}
	EndDialog(hDlg, TRUE);
	return(TRUE);

    case IDCANCEL:
        TRACE(" CANCEL button was hit\n");
        EndDialog(hDlg, FALSE);
	return(FALSE);

     case pshHelp:
        TRACE(" HELP button was hit\n");
        SendMessageW(lppd->hwndOwner, PrintStructures->HelpMessageID,
        			(WPARAM) hDlg, (LPARAM) lppd);
        break;

     case chx2:                         /* collate pages checkbox */
        if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
            SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                                    (LPARAM)PrintStructures->hCollateIcon);
        else
            SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON,
                                    (LPARAM)PrintStructures->hNoCollateIcon);
        break;
     case edt1:                         /* from page nr editbox */
     case edt2:                         /* to page nr editbox */
        if (HIWORD(wParam)==EN_CHANGE) {
	    WORD nToPage;
	    WORD nFromPage;
	    nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
	    nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
            if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage)
	        CheckRadioButton(hDlg, rad1, rad3, rad3);
	}
        break;

    case edt3:
        if(HIWORD(wParam) == EN_CHANGE) {
	    INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE);
	    if(copies <= 1)
	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
	    else
                EnableWindow(GetDlgItem(hDlg, chx2), TRUE);
        }
        break;

     case psh2:                       /* Properties button */
       {
         HANDLE hPrinter;
         WCHAR  PrinterName[256];

         if (!GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255)) break;
         if (!OpenPrinterW(PrinterName, &hPrinter, NULL)) {
	     FIXME(" Call to OpenPrinter did not succeed!\n");
	     break;
	 }
	 DocumentPropertiesW(hDlg, hPrinter, PrinterName,
			     PrintStructures->lpDevMode,
			     PrintStructures->lpDevMode,
			     DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
	 ClosePrinter(hPrinter);
         break;
       }

    case rad1: /* Paperorientation */
        if (lppd->Flags & PD_PRINTSETUP)
        {
              lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
              SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(PrintStructures->hPortraitIcon));
        }
        break;

    case rad2: /* Paperorientation */
        if (lppd->Flags & PD_PRINTSETUP)
        {
              lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
              SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
                          (LPARAM)(PrintStructures->hLandscapeIcon));
        }
        break;

    case cmb1: /* Printer Combobox in PRINT SETUP */
	 /* FALLTHROUGH */
    case cmb4:                         /* Printer combobox */
         if (HIWORD(wParam)==CBN_SELCHANGE) {
	     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;

    case cmb2: /* Papersize */
      {
	  DWORD Sel = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0);
	  if(Sel != CB_ERR)
	      lpdm->u1.s1.dmPaperSize = SendDlgItemMessageW(hDlg, cmb2,
							    CB_GETITEMDATA,
							    Sel, 0);
      }
      break;

    case cmb3: /* Bin */
      {
	  DWORD Sel = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0);
	  if(Sel != CB_ERR)
	      lpdm->u1.s1.dmDefaultSource = SendDlgItemMessageW(hDlg, cmb3,
							  CB_GETITEMDATA, Sel,
							  0);
      }
      break;
    }
    if(lppd->Flags & PD_PRINTSETUP) {
        switch (LOWORD(wParam)) {
	case rad1:                         /* orientation */
	case rad2:
	    if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) {
	        if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) {
		    lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
                    SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hPortraitIcon);
                    SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hPortraitIcon);
		}
	    } else {
	        if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) {
	            lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
                    SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hLandscapeIcon);
                    SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON,
					(LPARAM)PrintStructures->hLandscapeIcon);
		}
	    }
	    break;
	}
    }
    return FALSE;
}

/***********************************************************************
 *           PrintDlgProcA			[internal]
 */
static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
                                      LPARAM lParam)
{
    PRINT_PTRA* PrintStructures;
    INT_PTR res = FALSE;

    if (uMsg!=WM_INITDIALOG) {
        PrintStructures = GetPropW(hDlg, printdlg_prop);
	if (!PrintStructures)
	    return FALSE;
    } else {
        PrintStructures = (PRINT_PTRA*) lParam;
        SetPropW(hDlg, printdlg_prop, PrintStructures);
        if(!check_printer_setup(hDlg))
        {
            EndDialog(hDlg,FALSE);
            return FALSE;
        }
	res = PRINTDLG_WMInitDialog(hDlg, PrintStructures);

	if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK)
	    res = PrintStructures->lpPrintDlg->lpfnPrintHook(
		hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg
	    );
	return res;
    }

    if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
        res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam,
							 lParam);
	if(res) return res;
    }

    switch (uMsg) {
    case WM_COMMAND:
        return PRINTDLG_WMCommandA(hDlg, wParam, PrintStructures);

    case WM_DESTROY:
	DestroyIcon(PrintStructures->hCollateIcon);
	DestroyIcon(PrintStructures->hNoCollateIcon);
        DestroyIcon(PrintStructures->hPortraitIcon);
        DestroyIcon(PrintStructures->hLandscapeIcon);
	if(PrintStructures->hwndUpDown)
	    DestroyWindow(PrintStructures->hwndUpDown);
        return FALSE;
    }
    return res;
}

static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
                                      LPARAM lParam)
{
    PRINT_PTRW* PrintStructures;
    INT_PTR res = FALSE;

    if (uMsg!=WM_INITDIALOG) {
        PrintStructures = GetPropW(hDlg, printdlg_prop);
	if (!PrintStructures)
	    return FALSE;
    } else {
        PrintStructures = (PRINT_PTRW*) lParam;
        SetPropW(hDlg, printdlg_prop, PrintStructures);
        if(!check_printer_setup(hDlg))
        {
            EndDialog(hDlg,FALSE);
            return FALSE;
        }
	res = PRINTDLG_WMInitDialogW(hDlg, PrintStructures);

	if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK)
	    res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg);
	return res;
    }

    if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
        res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, lParam);
	if(res) return res;
    }

    switch (uMsg) {
    case WM_COMMAND:
        return PRINTDLG_WMCommandW(hDlg, wParam, PrintStructures);

    case WM_DESTROY:
	DestroyIcon(PrintStructures->hCollateIcon);
	DestroyIcon(PrintStructures->hNoCollateIcon);
        DestroyIcon(PrintStructures->hPortraitIcon);
        DestroyIcon(PrintStructures->hLandscapeIcon);
	if(PrintStructures->hwndUpDown)
	    DestroyWindow(PrintStructures->hwndUpDown);
        return FALSE;
    }
    return res;
}

/************************************************************
 *
 *      PRINTDLG_GetDlgTemplate
 *
 */
static HGLOBAL PRINTDLG_GetDlgTemplateA(const PRINTDLGA *lppd)
{
    HRSRC hResInfo;
    HGLOBAL hDlgTmpl;

    if (lppd->Flags & PD_PRINTSETUP) {
	if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) {
	    hDlgTmpl = lppd->hSetupTemplate;
	} else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
	    hResInfo = FindResourceA(lppd->hInstance,
				     lppd->lpSetupTemplateName, (LPSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
	} else {
	    hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP",
				     (LPSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
	}
    } else {
	if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) {
	    hDlgTmpl = lppd->hPrintTemplate;
	} else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) {
	    hResInfo = FindResourceA(lppd->hInstance,
				     lppd->lpPrintTemplateName,
				     (LPSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
	} else {
	    hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32",
				     (LPSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
	}
    }
    return hDlgTmpl;
}

static HGLOBAL PRINTDLG_GetDlgTemplateW(const PRINTDLGW *lppd)
{
    HRSRC hResInfo;
    HGLOBAL hDlgTmpl;
    static const WCHAR xpsetup[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
    static const WCHAR xprint[] = { 'P','R','I','N','T','3','2',0};

    if (lppd->Flags & PD_PRINTSETUP) {
	if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) {
	    hDlgTmpl = lppd->hSetupTemplate;
	} else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
	    hResInfo = FindResourceW(lppd->hInstance,
				     lppd->lpSetupTemplateName, (LPWSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
	} else {
	    hResInfo = FindResourceW(COMDLG32_hInstance, xpsetup, (LPWSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
	}
    } else {
	if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) {
	    hDlgTmpl = lppd->hPrintTemplate;
	} else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) {
	    hResInfo = FindResourceW(lppd->hInstance,
				     lppd->lpPrintTemplateName,
				     (LPWSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
	} else {
	    hResInfo = FindResourceW(COMDLG32_hInstance, xprint, (LPWSTR)RT_DIALOG);
	    hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
	}
    }
    return hDlgTmpl;
}

/***********************************************************************
 *
 *      PRINTDLG_CreateDC
 *
 */
static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd)
{
    DEVNAMES *pdn = GlobalLock(lppd->hDevNames);
    DEVMODEA *pdm = GlobalLock(lppd->hDevMode);

    if(lppd->Flags & PD_RETURNDC) {
        lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset,
			      (char*)pdn + pdn->wDeviceOffset,
			      (char*)pdn + pdn->wOutputOffset,
			      pdm );
    } else if(lppd->Flags & PD_RETURNIC) {
        lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset,
			      (char*)pdn + pdn->wDeviceOffset,
			      (char*)pdn + pdn->wOutputOffset,
			      pdm );
    }
    GlobalUnlock(lppd->hDevNames);
    GlobalUnlock(lppd->hDevMode);
    return lppd->hDC ? TRUE : FALSE;
}

static BOOL PRINTDLG_CreateDCW(LPPRINTDLGW lppd)
{
    DEVNAMES *pdn = GlobalLock(lppd->hDevNames);
    DEVMODEW *pdm = GlobalLock(lppd->hDevMode);

    if(lppd->Flags & PD_RETURNDC) {
        lppd->hDC = CreateDCW((WCHAR*)pdn + pdn->wDriverOffset,
			      (WCHAR*)pdn + pdn->wDeviceOffset,
			      (WCHAR*)pdn + pdn->wOutputOffset,
			      pdm );
    } else if(lppd->Flags & PD_RETURNIC) {
        lppd->hDC = CreateICW((WCHAR*)pdn + pdn->wDriverOffset,
			      (WCHAR*)pdn + pdn->wDeviceOffset,
			      (WCHAR*)pdn + pdn->wOutputOffset,
			      pdm );
    }
    GlobalUnlock(lppd->hDevNames);
    GlobalUnlock(lppd->hDevMode);
    return lppd->hDC ? TRUE : FALSE;
}

/***********************************************************************
 *           PrintDlgA   (COMDLG32.@)
 *
 *  Displays the PRINT dialog box, which enables the user to specify
 *  specific properties of the print job.
 *  
 * PARAMS
 *  lppd  [IO] ptr to PRINTDLG32 struct
 * 
 * RETURNS
 *  nonzero if the user pressed the OK button
 *  zero    if the user cancelled the window or an error occurred
 *  
 * BUGS
 *  PrintDlg:
 *  * The Collate Icons do not display, even though they are in the code.
 *  * The Properties Button(s) should call DocumentPropertiesA().
 */

BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd)
{
    BOOL      bRet = FALSE;
    LPVOID    ptr;
    HINSTANCE hInst;

    if (!lppd)
    {
        COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION);
        return FALSE;
    }

    if(TRACE_ON(commdlg)) {
        char flagstr[1000] = "";
	const struct pd_flags *pflag = pd_flags;
	for( ; pflag->name; pflag++) {
	    if(lppd->Flags & pflag->flag)
	        strcat(flagstr, pflag->name);
	}
	TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
              "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
              "flags %08x (%s)\n",
	      lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames,
	      lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage,
	      lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr);
    }

    if(lppd->lStructSize != sizeof(PRINTDLGA)) {
        WARN("structure size failure !!!\n");
	COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
	return FALSE;
    }

    if(lppd->Flags & PD_RETURNDEFAULT) {
        PRINTER_INFO_2A *pbuf;
	DRIVER_INFO_3A	*dbuf;
	HANDLE hprn;
	DWORD needed;

	if(lppd->hDevMode || lppd->hDevNames) {
	    WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
	    return FALSE;
	}
        if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
	    WARN("Can't find default printer\n");
	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
	    return FALSE;
	}

	GetPrinterA(hprn, 2, NULL, 0, &needed);
	pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
	GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed);

	GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed);
	dbuf = HeapAlloc(GetProcessHeap(),0,needed);
	if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) {
	    ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
	        GetLastError(),pbuf->pPrinterName);
	    HeapFree(GetProcessHeap(), 0, dbuf);
	    HeapFree(GetProcessHeap(), 0, pbuf);
	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
	    return FALSE;
	}
	ClosePrinter(hprn);

	PRINTDLG_CreateDevNames(&(lppd->hDevNames),
				  dbuf->pDriverPath,
				  pbuf->pPrinterName,
				  pbuf->pPortName);
	lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
				     pbuf->pDevMode->dmDriverExtra);
	ptr = GlobalLock(lppd->hDevMode);
	memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
	       pbuf->pDevMode->dmDriverExtra);
	GlobalUnlock(lppd->hDevMode);
	HeapFree(GetProcessHeap(), 0, pbuf);
	HeapFree(GetProcessHeap(), 0, dbuf);
	bRet = TRUE;
    } else {
	HGLOBAL hDlgTmpl;
	PRINT_PTRA *PrintStructures;

    /* load Dialog resources,
     * depending on Flags indicates Print32 or Print32_setup dialog
     */
	hDlgTmpl = PRINTDLG_GetDlgTemplateA(lppd);
	if (!hDlgTmpl) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	    return FALSE;
	}
	ptr = LockResource( hDlgTmpl );
	if (!ptr) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	    return FALSE;
	}

        PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
				    sizeof(PRINT_PTRA));
	PrintStructures->lpPrintDlg = lppd;

	/* and create & process the dialog .
	 * -1 is failure, 0 is broken hwnd, everything else is ok.
	 */
        hInst = COMDLG32_hInstance;
	if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance;
	bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner,
					   PrintDlgProcA,
					   (LPARAM)PrintStructures));

	if(bRet) {
	    DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn;
	    PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo;
	    DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo;

	    if (lppd->hDevMode == 0) {
	        TRACE(" No hDevMode yet... Need to create my own\n");
		lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE,
					lpdm->dmSize + lpdm->dmDriverExtra);
	    } else {
		lppd->hDevMode = GlobalReAlloc(lppd->hDevMode,
					       lpdm->dmSize + lpdm->dmDriverExtra,
					       GMEM_MOVEABLE);
	    }
	    lpdmReturn = GlobalLock(lppd->hDevMode);
	    memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra);

	    PRINTDLG_CreateDevNames(&(lppd->hDevNames),
		    di->pDriverPath,
		    pi->pPrinterName,
		    pi->pPortName
	    );
	    GlobalUnlock(lppd->hDevMode);
	}
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo);
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo);
	HeapFree(GetProcessHeap(), 0, PrintStructures);
    }
    if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC))
        bRet = PRINTDLG_CreateDCA(lppd);

    TRACE("exit! (%d)\n", bRet);
    return bRet;
}

/***********************************************************************
 *           PrintDlgW   (COMDLG32.@)
 *
 * See PrintDlgA.
 */
BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd)
{
    BOOL      bRet = FALSE;
    LPVOID    ptr;
    HINSTANCE hInst;

    if (!lppd)
    {
        COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION);
        return FALSE;
    }

    if(TRACE_ON(commdlg)) {
        char flagstr[1000] = "";
	const struct pd_flags *pflag = pd_flags;
	for( ; pflag->name; pflag++) {
	    if(lppd->Flags & pflag->flag)
	        strcat(flagstr, pflag->name);
	}
	TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
              "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n"
              "flags %08x (%s)\n",
	      lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames,
	      lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage,
	      lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr);
    }

    if(lppd->lStructSize != sizeof(PRINTDLGW)) {
        WARN("structure size failure !!!\n");
	COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
	return FALSE;
    }

    if(lppd->Flags & PD_RETURNDEFAULT) {
        PRINTER_INFO_2W *pbuf;
	DRIVER_INFO_3W	*dbuf;
	HANDLE hprn;
	DWORD needed;

	if(lppd->hDevMode || lppd->hDevNames) {
	    WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
	    return FALSE;
	}
        if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
	    WARN("Can't find default printer\n");
	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
	    return FALSE;
	}

	GetPrinterW(hprn, 2, NULL, 0, &needed);
	pbuf = HeapAlloc(GetProcessHeap(), 0, needed);
	GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);

	GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
	dbuf = HeapAlloc(GetProcessHeap(),0,needed);
	if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) {
	    ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",
	        GetLastError(),debugstr_w(pbuf->pPrinterName));
	    HeapFree(GetProcessHeap(), 0, dbuf);
	    HeapFree(GetProcessHeap(), 0, pbuf);
	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
	    return FALSE;
	}
	ClosePrinter(hprn);

	PRINTDLG_CreateDevNamesW(&(lppd->hDevNames),
				  dbuf->pDriverPath,
				  pbuf->pPrinterName,
				  pbuf->pPortName);
	lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize +
				     pbuf->pDevMode->dmDriverExtra);
	ptr = GlobalLock(lppd->hDevMode);
	memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize +
	       pbuf->pDevMode->dmDriverExtra);
	GlobalUnlock(lppd->hDevMode);
	HeapFree(GetProcessHeap(), 0, pbuf);
	HeapFree(GetProcessHeap(), 0, dbuf);
	bRet = TRUE;
    } else {
	HGLOBAL hDlgTmpl;
	PRINT_PTRW *PrintStructures;

    /* load Dialog resources,
     * depending on Flags indicates Print32 or Print32_setup dialog
     */
	hDlgTmpl = PRINTDLG_GetDlgTemplateW(lppd);
	if (!hDlgTmpl) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	    return FALSE;
	}
	ptr = LockResource( hDlgTmpl );
	if (!ptr) {
	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
	    return FALSE;
	}

        PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
				    sizeof(PRINT_PTRW));
	PrintStructures->lpPrintDlg = lppd;

	/* and create & process the dialog .
	 * -1 is failure, 0 is broken hwnd, everything else is ok.
	 */
        hInst = COMDLG32_hInstance;
	if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance;
	bRet = (0<DialogBoxIndirectParamW(hInst, ptr, lppd->hwndOwner,
					   PrintDlgProcW,
					   (LPARAM)PrintStructures));

	if(bRet) {
	    DEVMODEW *lpdm = PrintStructures->lpDevMode, *lpdmReturn;
	    PRINTER_INFO_2W *pi = PrintStructures->lpPrinterInfo;
	    DRIVER_INFO_3W *di = PrintStructures->lpDriverInfo;

	    if (lppd->hDevMode == 0) {
	        TRACE(" No hDevMode yet... Need to create my own\n");
		lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE,
					lpdm->dmSize + lpdm->dmDriverExtra);
	    } else {
	        WORD locks;
		if((locks = (GlobalFlags(lppd->hDevMode) & GMEM_LOCKCOUNT))) {
		    WARN("hDevMode has %d locks on it. Unlocking it now\n", locks);
		    while(locks--) {
		        GlobalUnlock(lppd->hDevMode);
			TRACE("Now got %d locks\n", locks);
		    }
		}
		lppd->hDevMode = GlobalReAlloc(lppd->hDevMode,
					       lpdm->dmSize + lpdm->dmDriverExtra,
					       GMEM_MOVEABLE);
	    }
	    lpdmReturn = GlobalLock(lppd->hDevMode);
	    memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra);

	    if (lppd->hDevNames != 0) {
	        WORD locks;
		if((locks = (GlobalFlags(lppd->hDevNames) & GMEM_LOCKCOUNT))) {
		    WARN("hDevNames has %d locks on it. Unlocking it now\n", locks);
		    while(locks--)
		        GlobalUnlock(lppd->hDevNames);
		}
	    }
	    PRINTDLG_CreateDevNamesW(&(lppd->hDevNames),
		    di->pDriverPath,
		    pi->pPrinterName,
		    pi->pPortName
	    );
	    GlobalUnlock(lppd->hDevMode);
	}
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode);
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo);
	HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo);
	HeapFree(GetProcessHeap(), 0, PrintStructures);
    }
    if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC))
        bRet = PRINTDLG_CreateDCW(lppd);

    TRACE("exit! (%d)\n", bRet);
    return bRet;
}

/***********************************************************************
 *
 *          PageSetupDlg
 * rad1 - portrait
 * rad2 - landscape
 * cmb1 - printer select (not in standard dialog template)
 * cmb2 - paper size
 * cmb3 - source (tray?)
 * edt4 - border left
 * edt5 - border top
 * edt6 - border right
 * edt7 - border bottom
 * psh3 - "Printer..."
 */

typedef struct
{
    BOOL unicode;
    union
    {
        LPPAGESETUPDLGA dlga;
        LPPAGESETUPDLGW dlgw;
    } u;
    HWND hDlg;                /* Page Setup dialog handle */
    RECT rtDrawRect;          /* Drawing rect for page */
} pagesetup_data;

static inline DWORD pagesetup_get_flags(const pagesetup_data *data)
{
    return data->u.dlgw->Flags;
}

static inline BOOL is_metric(const pagesetup_data *data)
{
    return pagesetup_get_flags(data) & PSD_INHUNDREDTHSOFMILLIMETERS;
}

static inline LONG tenths_mm_to_size(const pagesetup_data *data, LONG size)
{
    if (is_metric(data))
        return 10 * size;
    else
        return 10 * size * 100 / 254;
}

static inline LONG thousandths_inch_to_size(const pagesetup_data *data, LONG size)
{
    if (is_metric(data))
        return size * 254 / 100;
    else
        return size;
}

static WCHAR get_decimal_sep(void)
{
    static WCHAR sep;

    if(!sep)
    {
        WCHAR buf[] = {'.', 0};
        GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buf, sizeof(buf) / sizeof(buf[0]));
        sep = buf[0];
    }
    return sep;
}

static void size2str(const pagesetup_data *data, DWORD size, LPWSTR strout)
{
    WCHAR integer_fmt[] = {'%','d',0};
    WCHAR hundredths_fmt[] = {'%','d','%','c','%','0','2','d',0};
    WCHAR thousandths_fmt[] = {'%','d','%','c','%','0','3','d',0};

    /* FIXME use LOCALE_SDECIMAL when the edit parsing code can cope */

    if (is_metric(data))
    {
        if(size % 100)
            wsprintfW(strout, hundredths_fmt, size / 100, get_decimal_sep(), size % 100);
        else
            wsprintfW(strout, integer_fmt, size / 100);
    }
    else
    {
        if(size % 1000)
            wsprintfW(strout, thousandths_fmt, size / 1000, get_decimal_sep(), size % 1000);
        else
            wsprintfW(strout, integer_fmt, size / 1000);

    }
}

static inline BOOL is_default_metric(void)
{
    DWORD system;
    GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER,
                   (LPWSTR)&system, sizeof(system));
    return system == 0;
}

/**********************************************
 *           rotate_rect
 * Cyclically permute the four members of rc
 * If sense is TRUE l -> t -> r -> b
 * otherwise        l <- t <- r <- b
 */
static inline void rotate_rect(RECT *rc, BOOL sense)
{
    INT tmp;
    if(sense)
    {
        tmp        = rc->bottom;
        rc->bottom = rc->right;
        rc->right  = rc->top;
        rc->top    = rc->left;
        rc->left   = tmp;
    }
    else
    {
        tmp        = rc->left;
        rc->left   = rc->top;
        rc->top    = rc->right;
        rc->right  = rc->bottom;
        rc->bottom = tmp;
    }
}

static void pagesetup_set_orientation(pagesetup_data *data, WORD orient)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);

    assert(orient == DMORIENT_PORTRAIT || orient == DMORIENT_LANDSCAPE);

    if(data->unicode)
        dm->u1.s1.dmOrientation = orient;
    else
    {
        DEVMODEA *dmA = (DEVMODEA *)dm;
        dmA->u1.s1.dmOrientation = orient;
    }
    GlobalUnlock(data->u.dlgw->hDevMode);
}

static WORD pagesetup_get_orientation(const pagesetup_data *data)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);
    WORD orient;

    if(data->unicode)
        orient = dm->u1.s1.dmOrientation;
    else
    {
        DEVMODEA *dmA = (DEVMODEA *)dm;
        orient = dmA->u1.s1.dmOrientation;
    }
    GlobalUnlock(data->u.dlgw->hDevMode);
    return orient;
}

static void pagesetup_set_papersize(pagesetup_data *data, WORD paper)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);

    if(data->unicode)
        dm->u1.s1.dmPaperSize = paper;
    else
    {
        DEVMODEA *dmA = (DEVMODEA *)dm;
        dmA->u1.s1.dmPaperSize = paper;
    }
    GlobalUnlock(data->u.dlgw->hDevMode);
}

static WORD pagesetup_get_papersize(const pagesetup_data *data)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);
    WORD paper;

    if(data->unicode)
        paper = dm->u1.s1.dmPaperSize;
    else
    {
        DEVMODEA *dmA = (DEVMODEA *)dm;
        paper = dmA->u1.s1.dmPaperSize;
    }
    GlobalUnlock(data->u.dlgw->hDevMode);
    return paper;
}

static void pagesetup_set_defaultsource(pagesetup_data *data, WORD source)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);

    if(data->unicode)
        dm->u1.s1.dmDefaultSource = source;
    else
    {
        DEVMODEA *dmA = (DEVMODEA *)dm;
        dmA->u1.s1.dmDefaultSource = source;
    }
    GlobalUnlock(data->u.dlgw->hDevMode);
}

typedef enum
{
    devnames_driver_name,
    devnames_device_name,
    devnames_output_name
} devnames_name;


static inline WORD get_devname_offset(const DEVNAMES *dn, devnames_name which)
{
    switch(which)
    {
    case devnames_driver_name: return dn->wDriverOffset;
    case devnames_device_name: return dn->wDeviceOffset;
    case devnames_output_name: return dn->wOutputOffset;
    }
    ERR("Shouldn't be here\n");
    return 0;
}

static WCHAR *pagesetup_get_a_devname(const pagesetup_data *data, devnames_name which)
{
    DEVNAMES *dn;
    WCHAR *name;

    dn = GlobalLock(data->u.dlgw->hDevNames);
    if(data->unicode)
        name = strdupW((WCHAR *)dn + get_devname_offset(dn, which));
    else
    {
        int len = MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, NULL, 0);
        name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, name, len);
    }
    GlobalUnlock(data->u.dlgw->hDevNames);
    return name;
}

static WCHAR *pagesetup_get_drvname(const pagesetup_data *data)
{
    return pagesetup_get_a_devname(data, devnames_driver_name);
}

static WCHAR *pagesetup_get_devname(const pagesetup_data *data)
{
    return pagesetup_get_a_devname(data, devnames_device_name);
}

static WCHAR *pagesetup_get_portname(const pagesetup_data *data)
{
    return pagesetup_get_a_devname(data, devnames_output_name);
}

static void pagesetup_release_a_devname(const pagesetup_data *data, WCHAR *name)
{
    HeapFree(GetProcessHeap(), 0, name);
}

static void pagesetup_set_devnames(pagesetup_data *data, LPCWSTR drv, LPCWSTR devname, LPCWSTR port)
{
    DEVNAMES *dn;
    WCHAR def[256];
    DWORD len = sizeof(DEVNAMES), drv_len, dev_len, port_len;

    if(data->unicode)
    {
        drv_len  = (strlenW(drv) + 1) * sizeof(WCHAR);
        dev_len  = (strlenW(devname) + 1) * sizeof(WCHAR);
        port_len = (strlenW(port) + 1) * sizeof(WCHAR);
    }
    else
    {
        drv_len = WideCharToMultiByte(CP_ACP, 0, drv, -1, NULL, 0, NULL, NULL);
        dev_len = WideCharToMultiByte(CP_ACP, 0, devname, -1, NULL, 0, NULL, NULL);
        port_len = WideCharToMultiByte(CP_ACP, 0, port, -1, NULL, 0, NULL, NULL);
    }
    len += drv_len + dev_len + port_len;

    if(data->u.dlgw->hDevNames)
        data->u.dlgw->hDevNames = GlobalReAlloc(data->u.dlgw->hDevNames, len, GMEM_MOVEABLE);
    else
        data->u.dlgw->hDevNames = GlobalAlloc(GMEM_MOVEABLE, len);

    dn = GlobalLock(data->u.dlgw->hDevNames);

    if(data->unicode)
    {
        WCHAR *ptr = (WCHAR *)(dn + 1);
        len = sizeof(DEVNAMES) / sizeof(WCHAR);
        dn->wDriverOffset = len;
        strcpyW(ptr, drv);
        ptr += drv_len / sizeof(WCHAR);
        len += drv_len / sizeof(WCHAR);
        dn->wDeviceOffset = len;
        strcpyW(ptr, devname);
        ptr += dev_len / sizeof(WCHAR);
        len += dev_len / sizeof(WCHAR);
        dn->wOutputOffset = len;
        strcpyW(ptr, port);
    }
    else
    {
        char *ptr = (char *)(dn + 1);
        len = sizeof(DEVNAMES);
        dn->wDriverOffset = len;
        WideCharToMultiByte(CP_ACP, 0, drv, -1, ptr, drv_len, NULL, NULL);
        ptr += drv_len;
        len += drv_len;
        dn->wDeviceOffset = len;
        WideCharToMultiByte(CP_ACP, 0, devname, -1, ptr, dev_len, NULL, NULL);
        ptr += dev_len;
        len += dev_len;
        dn->wOutputOffset = len;
        WideCharToMultiByte(CP_ACP, 0, port, -1, ptr, port_len, NULL, NULL);
    }

    dn->wDefault = 0;
    len = sizeof(def) / sizeof(def[0]);
    GetDefaultPrinterW(def, &len);
    if(!lstrcmpW(def, devname))
        dn->wDefault = 1;

    GlobalUnlock(data->u.dlgw->hDevNames);
}

static DEVMODEW *pagesetup_get_devmode(const pagesetup_data *data)
{
    DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode);
    DEVMODEW *ret;

    if(data->unicode)
    {
        /* We make a copy even in the unicode case because the ptr
           may get passed back to us in pagesetup_set_devmode. */
        ret = HeapAlloc(GetProcessHeap(), 0, dm->dmSize + dm->dmDriverExtra);
        memcpy(ret, dm, dm->dmSize + dm->dmDriverExtra);
    }
    else
        ret = GdiConvertToDevmodeW((DEVMODEA *)dm);

    GlobalUnlock(data->u.dlgw->hDevMode);
    return ret;
}

static void pagesetup_release_devmode(const pagesetup_data *data, DEVMODEW *dm)
{
    HeapFree(GetProcessHeap(), 0, dm);
}

static void pagesetup_set_devmode(pagesetup_data *data, DEVMODEW *dm)
{
    DEVMODEA *dmA = NULL;
    void *src, *dst;
    DWORD size;

    if(data->unicode)
    {
        size = dm->dmSize + dm->dmDriverExtra;
        src = dm;
    }
    else
    {
        dmA = convert_to_devmodeA(dm);
        size = dmA->dmSize + dmA->dmDriverExtra;
        src = dmA;
    }

    if(data->u.dlgw->hDevMode)
        data->u.dlgw->hDevMode = GlobalReAlloc(data->u.dlgw->hDevMode, size,
                                               GMEM_MOVEABLE);
    else
        data->u.dlgw->hDevMode = GlobalAlloc(GMEM_MOVEABLE, size);

    dst = GlobalLock(data->u.dlgw->hDevMode);
    memcpy(dst, src, size);
    GlobalUnlock(data->u.dlgw->hDevMode);
    HeapFree(GetProcessHeap(), 0, dmA);
}

static inline POINT *pagesetup_get_papersize_pt(const pagesetup_data *data)
{
    return &data->u.dlgw->ptPaperSize;
}

static inline RECT *pagesetup_get_margin_rect(const pagesetup_data *data)
{
    return &data->u.dlgw->rtMargin;
}

typedef enum
{
    page_setup_hook,
    page_paint_hook
} hook_type;

static inline LPPAGESETUPHOOK pagesetup_get_hook(const pagesetup_data *data, hook_type which)
{
    switch(which)
    {
    case page_setup_hook: return data->u.dlgw->lpfnPageSetupHook;
    case page_paint_hook: return data->u.dlgw->lpfnPagePaintHook;
    }
    return NULL;
}

/* This should only be used in calls to hook procs so we return the ptr
   already cast to LPARAM */
static inline LPARAM pagesetup_get_dlg_struct(const pagesetup_data *data)
{
    return (LPARAM)data->u.dlgw;
}

static inline void swap_point(POINT *pt)
{
    LONG tmp = pt->x;
    pt->x = pt->y;
    pt->y = tmp;
}

static BOOL pagesetup_update_papersize(pagesetup_data *data)
{
    DEVMODEW *dm;
    LPWSTR devname, portname;
    int i, num;
    WORD *words = NULL, paperword;
    POINT *points = NULL;
    BOOL retval = FALSE;

    dm       = pagesetup_get_devmode(data);
    devname  = pagesetup_get_devname(data);
    portname = pagesetup_get_portname(data);

    num = DeviceCapabilitiesW(devname, portname, DC_PAPERS, NULL, dm);
    if (num <= 0)
    {
        FIXME("No papernames found for %s/%s\n", debugstr_w(devname), debugstr_w(portname));
        goto end;
    }

    words = HeapAlloc(GetProcessHeap(), 0, num * sizeof(WORD));
    points = HeapAlloc(GetProcessHeap(), 0, num * sizeof(POINT));

    if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERS, (LPWSTR)words, dm))
    {
        FIXME("Number of returned words is not %d\n", num);
        goto end;
    }

    if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERSIZE, (LPWSTR)points, dm))
    {
        FIXME("Number of returned sizes is not %d\n", num);
        goto end;
    }

    paperword = pagesetup_get_papersize(data);

    for (i = 0; i < num; i++)
        if (words[i] == paperword)
            break;

    if (i == num)
    {
        FIXME("Papersize %d not found in list?\n", paperword);
        goto end;
    }

    /* this is _10ths_ of a millimeter */
    pagesetup_get_papersize_pt(data)->x = tenths_mm_to_size(data, points[i].x);
    pagesetup_get_papersize_pt(data)->y = tenths_mm_to_size(data, points[i].y);

    if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE)
        swap_point(pagesetup_get_papersize_pt(data));

    retval = TRUE;

end:
    HeapFree(GetProcessHeap(), 0, words);
    HeapFree(GetProcessHeap(), 0, points);
    pagesetup_release_a_devname(data, portname);
    pagesetup_release_a_devname(data, devname);
    pagesetup_release_devmode(data, dm);

    return retval;
}

/**********************************************************************************************
 * pagesetup_change_printer
 *
 * Redefines hDevMode and hDevNames HANDLES and initialises it.
 * 
 */
static BOOL pagesetup_change_printer(LPWSTR name, pagesetup_data *data)
{
    HANDLE hprn;
    DWORD needed;
    PRINTER_INFO_2W *prn_info = NULL;
    DRIVER_INFO_3W *drv_info = NULL;
    DEVMODEW *dm = NULL;
    BOOL retval = FALSE;

    if(!OpenPrinterW(name, &hprn, NULL))
    {
        ERR("Can't open printer %s\n", debugstr_w(name));
        goto end;
    }

    GetPrinterW(hprn, 2, NULL, 0, &needed);
    prn_info = HeapAlloc(GetProcessHeap(), 0, needed);
    GetPrinterW(hprn, 2, (LPBYTE)prn_info, needed, &needed);
    GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
    drv_info = HeapAlloc(GetProcessHeap(), 0, needed);
    if(!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)drv_info, needed, &needed))
    {
        ERR("GetPrinterDriverA failed for %s, fix your config!\n", debugstr_w(prn_info->pPrinterName));
        goto end;
    }
    ClosePrinter(hprn);

    needed = DocumentPropertiesW(0, 0, name, NULL, NULL, 0);
    if(needed == -1)
    {
        ERR("DocumentProperties fails on %s\n", debugstr_w(name));
        goto end;
    }

    dm = HeapAlloc(GetProcessHeap(), 0, needed);
    DocumentPropertiesW(0, 0, name, dm, NULL, DM_OUT_BUFFER);

    pagesetup_set_devmode(data, dm);
    pagesetup_set_devnames(data, drv_info->pDriverPath, prn_info->pPrinterName,
                           prn_info->pPortName);

    retval = TRUE;
end:
    HeapFree(GetProcessHeap(), 0, dm);
    HeapFree(GetProcessHeap(), 0, prn_info);
    HeapFree(GetProcessHeap(), 0, drv_info);
    return retval;
}

/****************************************************************************************
 *  pagesetup_init_combos
 *
 *  Fills Printers, Paper and Source combos
 *
 */
static void pagesetup_init_combos(HWND hDlg, pagesetup_data *data)
{
    DEVMODEW *dm;
    LPWSTR devname, portname;

    dm       = pagesetup_get_devmode(data);
    devname  = pagesetup_get_devname(data);
    portname = pagesetup_get_portname(data);

    PRINTDLG_SetUpPrinterListComboW(hDlg, cmb1, devname);
    PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, devname, portname, dm);
    PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, devname, portname, dm);

    pagesetup_release_a_devname(data, portname);
    pagesetup_release_a_devname(data, devname);
    pagesetup_release_devmode(data, dm);
}


/****************************************************************************************
 *  pagesetup_change_printer_dialog
 *
 *  Pops up another dialog that lets the user pick another printer.
 *
 *  For now we display the PrintDlg, this should display a striped down version of it.
 */
static void pagesetup_change_printer_dialog(HWND hDlg, pagesetup_data *data)
{
    PRINTDLGW prnt;
    LPWSTR drvname, devname, portname;
    DEVMODEW *tmp_dm, *dm;

    memset(&prnt, 0, sizeof(prnt));
    prnt.lStructSize = sizeof(prnt);
    prnt.Flags     = 0;
    prnt.hwndOwner = hDlg;

    drvname = pagesetup_get_drvname(data);
    devname = pagesetup_get_devname(data);
    portname = pagesetup_get_portname(data);
    prnt.hDevNames = 0;
    PRINTDLG_CreateDevNamesW(&prnt.hDevNames, drvname, devname, portname);
    pagesetup_release_a_devname(data, portname);
    pagesetup_release_a_devname(data, devname);
    pagesetup_release_a_devname(data, drvname);

    tmp_dm = pagesetup_get_devmode(data);
    prnt.hDevMode = GlobalAlloc(GMEM_MOVEABLE, tmp_dm->dmSize + tmp_dm->dmDriverExtra);
    dm = GlobalLock(prnt.hDevMode);
    memcpy(dm, tmp_dm, tmp_dm->dmSize + tmp_dm->dmDriverExtra);
    GlobalUnlock(prnt.hDevMode);
    pagesetup_release_devmode(data, tmp_dm);

    if (PrintDlgW(&prnt))
    {
        DEVMODEW *dm = GlobalLock(prnt.hDevMode);
        DEVNAMES *dn = GlobalLock(prnt.hDevNames);

        pagesetup_set_devnames(data, (WCHAR*)dn + dn->wDriverOffset,
                               (WCHAR*)dn + dn->wDeviceOffset, (WCHAR *)dn + dn->wOutputOffset);
        pagesetup_set_devmode(data, dm);
        GlobalUnlock(prnt.hDevNames);
        GlobalUnlock(prnt.hDevMode);
        pagesetup_init_combos(hDlg, data);
    }

    GlobalFree(prnt.hDevMode);
    GlobalFree(prnt.hDevNames);

}

/******************************************************************************************
 * pagesetup_change_preview
 *
 * Changes paper preview size / position
 *
 */
static void pagesetup_change_preview(const pagesetup_data *data)
{
    LONG width, height, x, y;
    RECT tmp;
    const int shadow = 4;

    if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE)
    {
        width  = data->rtDrawRect.right - data->rtDrawRect.left;
        height = pagesetup_get_papersize_pt(data)->y * width / pagesetup_get_papersize_pt(data)->x;
    }
    else
    {
        height = data->rtDrawRect.bottom - data->rtDrawRect.top;
        width  = pagesetup_get_papersize_pt(data)->x * height / pagesetup_get_papersize_pt(data)->y;
    }
    x = (data->rtDrawRect.right + data->rtDrawRect.left - width) / 2;
    y = (data->rtDrawRect.bottom + data->rtDrawRect.top - height) / 2;
    TRACE("draw rect %s x=%d, y=%d, w=%d, h=%d\n",
          wine_dbgstr_rect(&data->rtDrawRect), x, y, width, height);

    MoveWindow(GetDlgItem(data->hDlg, rct2), x + width, y + shadow, shadow, height, FALSE);
    MoveWindow(GetDlgItem(data->hDlg, rct3), x + shadow, y + height, width, shadow, FALSE);
    MoveWindow(GetDlgItem(data->hDlg, rct1), x, y, width, height, FALSE);

    tmp = data->rtDrawRect;
    tmp.right  += shadow;
    tmp.bottom += shadow;
    InvalidateRect(data->hDlg, &tmp, TRUE);
}

static inline LONG *element_from_margin_id(RECT *rc, WORD id)
{
    switch(id)
    {
    case edt4: return &rc->left;
    case edt5: return &rc->top;
    case edt6: return &rc->right;
    case edt7: return &rc->bottom;
    }
    return NULL;
}

static void update_margin_edits(HWND hDlg, const pagesetup_data *data, WORD id)
{
    WCHAR str[100];
    WORD idx;

    for(idx = edt4; idx <= edt7; idx++)
    {
        if(id == 0 || id == idx)
        {
            size2str(data, *element_from_margin_id(pagesetup_get_margin_rect(data), idx), str);
            SetDlgItemTextW(hDlg, idx, str);
        }
    }
}

static void margin_edit_notification(HWND hDlg, const pagesetup_data *data, WORD msg, WORD id)
{
    switch (msg)
    {
    case EN_CHANGE:
      {
        WCHAR buf[10];
        LONG val = 0;
        LONG *value = element_from_margin_id(pagesetup_get_margin_rect(data), id);

        if (GetDlgItemTextW(hDlg, id, buf, sizeof(buf) / sizeof(buf[0])) != 0)
        {
            WCHAR *end;
            WCHAR decimal = get_decimal_sep();

            val = strtolW(buf, &end, 10);
            if(end != buf || *end == decimal)
            {
                int mult = is_metric(data) ? 100 : 1000;
                val *= mult;
                if(*end == decimal)
                {
                    while(mult > 1)
                    {
                        end++;
                        mult /= 10;
                        if(isdigitW(*end))
                            val += (*end - '0') * mult;
                        else
                            break;
                    }
                }
            }
        }
        *value = val;
        return;
      }

    case EN_KILLFOCUS:
        update_margin_edits(hDlg, data, id);
        return;
    }
}

static void set_margin_groupbox_title(HWND hDlg, const pagesetup_data *data)
{
    WCHAR title[256];

    if(LoadStringW(COMDLG32_hInstance, is_metric(data) ? PD32_MARGINS_IN_MILLIMETERS : PD32_MARGINS_IN_INCHES,
                   title, sizeof(title)/sizeof(title[0])))
        SetDlgItemTextW(hDlg, grp4, title);
}

static void pagesetup_update_orientation_buttons(HWND hDlg, const pagesetup_data *data)
{
    if (pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE)
        CheckRadioButton(hDlg, rad1, rad2, rad2);
    else
        CheckRadioButton(hDlg, rad1, rad2, rad1);
}

/****************************************************************************************
 *  pagesetup_printer_properties
 *
 *  Handle invocation of the 'Properties' button (not present in the default template).
 */
static void pagesetup_printer_properties(HWND hDlg, pagesetup_data *data)
{
    HANDLE hprn;
    LPWSTR devname;
    DEVMODEW *dm;
    LRESULT count;
    int i;

    devname = pagesetup_get_devname(data);

    if (!OpenPrinterW(devname, &hprn, NULL))
    {
        FIXME("Call to OpenPrinter did not succeed!\n");
        pagesetup_release_a_devname(data, devname);
        return;
    }

    dm = pagesetup_get_devmode(data);
    DocumentPropertiesW(hDlg, hprn, devname, dm, dm, DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT);
    pagesetup_set_devmode(data, dm);
    pagesetup_release_devmode(data, dm);
    pagesetup_release_a_devname(data, devname);
    ClosePrinter(hprn);

    /* Changing paper */
    pagesetup_update_papersize(data);
    pagesetup_update_orientation_buttons(hDlg, data);

    /* Changing paper preview */
    pagesetup_change_preview(data);

    /* Selecting paper in combo */
    count = SendDlgItemMessageW(hDlg, cmb2, CB_GETCOUNT, 0, 0);
    if(count != CB_ERR)
    {
        WORD paperword = pagesetup_get_papersize(data);
        for(i = 0; i < count; i++)
        {
            if(SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0) == paperword) {
                SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0);
                break;
            }
        }
    }
}

/********************************************************************************
 * pagesetup_wm_command
 * process WM_COMMAND message for PageSetupDlg
 *
 * PARAMS
 *  hDlg 	[in] 	Main dialog HANDLE 
 *  wParam 	[in]	WM_COMMAND wParam
 *  lParam	[in]	WM_COMMAND lParam
 *  pda		[in/out] ptr to PageSetupDataA
 */

static BOOL pagesetup_wm_command(HWND hDlg, WPARAM wParam, LPARAM lParam, pagesetup_data *data)
{
    WORD msg = HIWORD(wParam);
    WORD id  = LOWORD(wParam);

    TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n",
	    LOWORD(lParam),wParam,lParam);
    switch (id)  {
    case IDOK:
	EndDialog(hDlg, TRUE);
	return TRUE ;

    case IDCANCEL:
        EndDialog(hDlg, FALSE);
	return FALSE ;

    case psh3: /* Printer... */
        pagesetup_change_printer_dialog(hDlg, data);
        return TRUE;

    case rad1: /* Portrait */
    case rad2: /* Landscape */
        if((id == rad1 && pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) ||
           (id == rad2 && pagesetup_get_orientation(data) == DMORIENT_PORTRAIT))
	{
            pagesetup_set_orientation(data, (id == rad1) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE);
            pagesetup_update_papersize(data);
            rotate_rect(pagesetup_get_margin_rect(data), (id == rad2));
            update_margin_edits(hDlg, data, 0);
            pagesetup_change_preview(data);
	}
	break;
    case cmb1: /* Printer combo */
        if(msg == CBN_SELCHANGE)
        {
            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 */
        if(msg == CBN_SELCHANGE)
        {
            DWORD paperword = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA,
                                                  SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0);
            if (paperword != CB_ERR)
            {
                pagesetup_set_papersize(data, paperword);
                pagesetup_update_papersize(data);
                pagesetup_change_preview(data);
	    } else
                FIXME("could not get dialog text for papersize cmbbox?\n");
        }
        break;
    case cmb3: /* Paper Source */
        if(msg == CBN_SELCHANGE)
        {
            WORD source = SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA,
                                              SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0), 0);
            pagesetup_set_defaultsource(data, source);
        }
        break;
    case psh2: /* Printer Properties button */
        pagesetup_printer_properties(hDlg, data);
        break;
    case edt4:
    case edt5:
    case edt6:
    case edt7:
        margin_edit_notification(hDlg, data, msg, id);
        break;
    }
    InvalidateRect(GetDlgItem(hDlg, rct1), NULL, TRUE);
    return FALSE;
}

/***********************************************************************
 *           default_page_paint_hook
 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box 
 * whenever the sample page is redrawn.
 */
static UINT_PTR default_page_paint_hook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam,
                                        const pagesetup_data *data)
{
    LPRECT lprc = (LPRECT) lParam;
    HDC hdc = (HDC) wParam;
    HPEN hpen, holdpen;
    LOGFONTW lf;
    HFONT hfont, holdfont;
    INT oldbkmode;
    TRACE("uMsg: WM_USER+%d\n",uMsg-WM_USER);
    /* Call user paint hook if enable */
    if (pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK)
        if (pagesetup_get_hook(data, page_paint_hook)(hwndDlg, uMsg, wParam, lParam))
            return TRUE;

    switch (uMsg) {
       /* LPPAGESETUPDLG in lParam */
       case WM_PSD_PAGESETUPDLG:
       /* Inform about the sample page rectangle */
       case WM_PSD_FULLPAGERECT:
       /* Inform about the margin rectangle */
       case WM_PSD_MINMARGINRECT:
            return FALSE;

        /* Draw dashed rectangle showing margins */
        case WM_PSD_MARGINRECT:
            hpen = CreatePen(PS_DASH, 1, GetSysColor(COLOR_3DSHADOW));
            holdpen = SelectObject(hdc, hpen);
            Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom);
            DeleteObject(SelectObject(hdc, holdpen));
            return TRUE;
        /* Draw the fake document */
        case WM_PSD_GREEKTEXTRECT:
            /* select a nice scalable font, because we want the text really small */
            SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0);
            lf.lfHeight = 6; /* value chosen based on visual effect */
            hfont = CreateFontIndirectW(&lf);
            holdfont = SelectObject(hdc, hfont);

            /* if text not loaded, then do so now */
            if (wszFakeDocumentText[0] == '\0')
                 LoadStringW(COMDLG32_hInstance,
                        IDS_FAKEDOCTEXT,
                        wszFakeDocumentText,
                        sizeof(wszFakeDocumentText)/sizeof(wszFakeDocumentText[0]));

            oldbkmode = SetBkMode(hdc, TRANSPARENT);
            DrawTextW(hdc, wszFakeDocumentText, -1, lprc, DT_TOP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK);
            SetBkMode(hdc, oldbkmode);

            DeleteObject(SelectObject(hdc, holdfont));
            return TRUE;

        /* Envelope stamp */
        case WM_PSD_ENVSTAMPRECT:
        /* Return address */
        case WM_PSD_YAFULLPAGERECT:
            FIXME("envelope/stamp is not implemented\n");
            return FALSE;
        default:
            FIXME("Unknown message %x\n",uMsg);
            return FALSE;
    }
    return TRUE;
}

/***********************************************************************
 *           PagePaintProc
 * The main paint procedure for the PageSetupDlg function.
 * The Page Setup dialog box includes an image of a sample page that shows how
 * the user's selections affect the appearance of the printed output.
 * The image consists of a rectangle that represents the selected paper
 * or envelope type, with a dotted-line rectangle representing
 * the current margins, and partial (Greek text) characters
 * to show how text looks on the printed page. 
 *
 * The following messages in the order sends to user hook procedure:
 *   WM_PSD_PAGESETUPDLG    Draw the contents of the sample page
 *   WM_PSD_FULLPAGERECT    Inform about the bounding rectangle
 *   WM_PSD_MINMARGINRECT   Inform about the margin rectangle (min margin?)
 *   WM_PSD_MARGINRECT      Draw the margin rectangle
 *   WM_PSD_GREEKTEXTRECT   Draw the Greek text inside the margin rectangle
 * If any of first three messages returns TRUE, painting done.
 *
 * PARAMS:
 *   hWnd   [in] Handle to the Page Setup dialog box
 *   uMsg   [in] Received message
 *
 * TODO:
 *   WM_PSD_ENVSTAMPRECT    Draw in the envelope-stamp rectangle (for envelopes only)
 *   WM_PSD_YAFULLPAGERECT  Draw the return address portion (for envelopes and other paper sizes)
 *
 * RETURNS:
 *   FALSE if all done correctly
 *
 */


static LRESULT CALLBACK
PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    RECT rcClient, rcMargin;
    HPEN hpen, holdpen;
    HDC hdc;
    HBRUSH hbrush, holdbrush;
    pagesetup_data *data;
    int papersize=0, orientation=0; /* FIXME: set these values for the user paint hook */
    double scalx, scaly;

    if (uMsg != WM_PAINT)
        return CallWindowProcA(lpfnStaticWndProc, hWnd, uMsg, wParam, lParam);

    /* Processing WM_PAINT message */
    data = GetPropW(hWnd, pagesetupdlg_prop);
    if (!data) {
        WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
        return FALSE;
    }
    if (default_page_paint_hook(hWnd, WM_PSD_PAGESETUPDLG, MAKELONG(papersize, orientation),
                                pagesetup_get_dlg_struct(data), data))
        return FALSE;

    hdc = BeginPaint(hWnd, &ps);
    GetClientRect(hWnd, &rcClient);
    
    scalx = rcClient.right  / (double)pagesetup_get_papersize_pt(data)->x;
    scaly = rcClient.bottom / (double)pagesetup_get_papersize_pt(data)->y;
    rcMargin = rcClient;

    rcMargin.left   += pagesetup_get_margin_rect(data)->left   * scalx;
    rcMargin.top    += pagesetup_get_margin_rect(data)->top    * scaly;
    rcMargin.right  -= pagesetup_get_margin_rect(data)->right  * scalx;
    rcMargin.bottom -= pagesetup_get_margin_rect(data)->bottom * scaly;

    /* if the space is too small then we make sure to not draw anything */
    rcMargin.left = min(rcMargin.left, rcMargin.right);
    rcMargin.top = min(rcMargin.top, rcMargin.bottom);

    if (!default_page_paint_hook(hWnd, WM_PSD_FULLPAGERECT, (WPARAM)hdc, (LPARAM)&rcClient, data) &&
        !default_page_paint_hook(hWnd, WM_PSD_MINMARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data) )
    {
        /* fill background */
        hbrush = GetSysColorBrush(COLOR_3DHIGHLIGHT);
        FillRect(hdc, &rcClient, hbrush);
        holdbrush = SelectObject(hdc, hbrush);

        hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW));
        holdpen = SelectObject(hdc, hpen);
        
        /* paint left edge */
        MoveToEx(hdc, rcClient.left, rcClient.top, NULL);
        LineTo(hdc, rcClient.left, rcClient.bottom-1);

        /* paint top edge */
        MoveToEx(hdc, rcClient.left, rcClient.top, NULL);
        LineTo(hdc, rcClient.right, rcClient.top);

        hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW));
        DeleteObject(SelectObject(hdc, hpen));

        /* paint right edge */
        MoveToEx(hdc, rcClient.right-1, rcClient.top, NULL);
        LineTo(hdc, rcClient.right-1, rcClient.bottom);

        /* paint bottom edge */
        MoveToEx(hdc, rcClient.left, rcClient.bottom-1, NULL);
        LineTo(hdc, rcClient.right, rcClient.bottom-1);

        DeleteObject(SelectObject(hdc, holdpen));
        DeleteObject(SelectObject(hdc, holdbrush));

        default_page_paint_hook(hWnd, WM_PSD_MARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data);

        /* give text a bit of a space from the frame */
        rcMargin.left += 2;
        rcMargin.top += 2;
        rcMargin.right -= 2;
        rcMargin.bottom -= 2;
        
        /* if the space is too small then we make sure to not draw anything */
        rcMargin.left = min(rcMargin.left, rcMargin.right);
        rcMargin.top = min(rcMargin.top, rcMargin.bottom);

        default_page_paint_hook(hWnd, WM_PSD_GREEKTEXTRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data);
    }

    EndPaint(hWnd, &ps);
    return FALSE;
}

/*******************************************************
 * The margin edit controls are subclassed to filter
 * anything other than numbers and the decimal separator.
 */
static LRESULT CALLBACK pagesetup_margin_editproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if (msg == WM_CHAR)
    {
        WCHAR decimal = get_decimal_sep();
        WCHAR wc = (WCHAR)wparam;
        if(!isdigitW(wc) && wc != decimal && wc != VK_BACK) return 0;
    }
    return CallWindowProcW(edit_wndproc, hwnd, msg, wparam, lparam);
}

static void subclass_margin_edits(HWND hDlg)
{
    int id;
    WNDPROC old_proc;

    for(id = edt4; id <= edt7; id++)
    {
        old_proc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hDlg, id),
                                              GWLP_WNDPROC,
                                              (ULONG_PTR)pagesetup_margin_editproc);
        InterlockedCompareExchangePointer((void**)&edit_wndproc, old_proc, NULL);
    }
}

/***********************************************************************
 *           pagesetup_dlg_proc
 *
 * Message handler for PageSetupDlg
 */
static INT_PTR CALLBACK pagesetup_dlg_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    pagesetup_data *data;
    INT_PTR		res = FALSE;
    HWND 		hDrawWnd;

    if (uMsg == WM_INITDIALOG) { /*Init dialog*/
        data = (pagesetup_data *)lParam;
        data->hDlg = hDlg;

	hDrawWnd = GetDlgItem(hDlg, rct1); 
        TRACE("set property to %p\n", data);
        SetPropW(hDlg, pagesetupdlg_prop, data);
        SetPropW(hDrawWnd, pagesetupdlg_prop, data);
        GetWindowRect(hDrawWnd, &data->rtDrawRect); /* Calculating rect in client coordinates where paper draws */
        MapWindowPoints( 0, hDlg, (LPPOINT)&data->rtDrawRect, 2 );
        lpfnStaticWndProc = (WNDPROC)SetWindowLongPtrW(
            hDrawWnd,
            GWLP_WNDPROC,
            (ULONG_PTR)PRINTDLG_PagePaintProc);
	
	/* FIXME: Paint hook. Must it be at begin of initialization or at end? */
	res = TRUE;
        if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK)
        {
            if (!pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam,
                                                           pagesetup_get_dlg_struct(data)))
		FIXME("Setup page hook failed?\n");
	}

	/* if printer button disabled */
        if (pagesetup_get_flags(data) & PSD_DISABLEPRINTER)
            EnableWindow(GetDlgItem(hDlg, psh3), FALSE);
	/* if margin edit boxes disabled */
        if (pagesetup_get_flags(data) & PSD_DISABLEMARGINS)
        {
            EnableWindow(GetDlgItem(hDlg, edt4), FALSE);
            EnableWindow(GetDlgItem(hDlg, edt5), FALSE);
            EnableWindow(GetDlgItem(hDlg, edt6), FALSE);
            EnableWindow(GetDlgItem(hDlg, edt7), FALSE);
	}

        /* Set orientation radiobuttons properly */
        pagesetup_update_orientation_buttons(hDlg, data);

	/* if orientation disabled */
        if (pagesetup_get_flags(data) & PSD_DISABLEORIENTATION)
        {
	    EnableWindow(GetDlgItem(hDlg,rad1),FALSE);
	    EnableWindow(GetDlgItem(hDlg,rad2),FALSE);
	}

	/* We fill them out enabled or not */
        if (!(pagesetup_get_flags(data) & PSD_MARGINS))
        {
            /* default is 1 inch */
            LONG size = thousandths_inch_to_size(data, 1000);
            SetRect(pagesetup_get_margin_rect(data), size, size, size, size);
        }
        update_margin_edits(hDlg, data, 0);
        subclass_margin_edits(hDlg);
        set_margin_groupbox_title(hDlg, data);

	/* if paper disabled */
        if (pagesetup_get_flags(data) & PSD_DISABLEPAPER)
        {
	    EnableWindow(GetDlgItem(hDlg,cmb2),FALSE);
	    EnableWindow(GetDlgItem(hDlg,cmb3),FALSE);
	}

	/* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */
        pagesetup_init_combos(hDlg, data);
        pagesetup_update_papersize(data);
        pagesetup_set_defaultsource(data, DMBIN_FORMSOURCE); /* FIXME: This is the auto select bin. Is this correct? */

	/* Drawing paper prev */
        pagesetup_change_preview(data);
	return TRUE;
    } else {
        data = GetPropW(hDlg, pagesetupdlg_prop);
        if (!data)
        {
	    WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
	    return FALSE;
	}
        if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK)
        {
            res = pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam, lParam);
	    if (res) return res;
	}
    }
    switch (uMsg) {
    case WM_COMMAND:
        return pagesetup_wm_command(hDlg, wParam, lParam, data);
    }
    return FALSE;
}

static WCHAR *get_default_printer(void)
{
    WCHAR *name = NULL;
    DWORD len = 0;

    GetDefaultPrinterW(NULL, &len);
    if(len)
    {
        name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
        GetDefaultPrinterW(name, &len);
    }
    return name;
}

static void pagesetup_dump_dlg_struct(const pagesetup_data *data)
{
    if(TRACE_ON(commdlg))
    {
        char flagstr[1000] = "";
	const struct pd_flags *pflag = psd_flags;
        for( ; pflag->name; pflag++)
        {
            if(pagesetup_get_flags(data) & pflag->flag)
            {
                strcat(flagstr, pflag->name);
                strcat(flagstr, "|");
            }
        }
        TRACE("%s: (%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n"
              "hinst %p, flags %08x (%s)\n",
              data->unicode ? "unicode" : "ansi",
              data->u.dlgw, data->u.dlgw->hwndOwner, data->u.dlgw->hDevMode,
              data->u.dlgw->hDevNames, data->u.dlgw->hInstance,
              pagesetup_get_flags(data), flagstr);
    }
}

static void *pagesetup_get_template(pagesetup_data *data)
{
    HRSRC res;
    HGLOBAL tmpl_handle;

    if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATEHANDLE)
    {
	tmpl_handle = data->u.dlgw->hPageSetupTemplate;
    }
    else if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATE)
    {
        if(data->unicode)
            res = FindResourceW(data->u.dlgw->hInstance,
                                data->u.dlgw->lpPageSetupTemplateName, MAKEINTRESOURCEW(RT_DIALOG));
        else
            res = FindResourceA(data->u.dlga->hInstance,
                                data->u.dlga->lpPageSetupTemplateName, MAKEINTRESOURCEA(RT_DIALOG));
        tmpl_handle = LoadResource(data->u.dlgw->hInstance, res);
    }
    else
    {
        res = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(PAGESETUPDLGORD),
                            MAKEINTRESOURCEW(RT_DIALOG));
        tmpl_handle = LoadResource(COMDLG32_hInstance, res);
    }
    return LockResource(tmpl_handle);
}

static BOOL pagesetup_common(pagesetup_data *data)
{
    BOOL ret;
    void *tmpl;

    if(!pagesetup_get_dlg_struct(data))
    {
        COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION);
        return FALSE;
    }

    pagesetup_dump_dlg_struct(data);

    if(data->u.dlgw->lStructSize != sizeof(PAGESETUPDLGW))
    {
        COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
        return FALSE;
    }

    if ((pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK) &&
        (pagesetup_get_hook(data, page_paint_hook) == NULL))
    {
        COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK);
        return FALSE;
    }

    if(!(pagesetup_get_flags(data) & (PSD_INTHOUSANDTHSOFINCHES | PSD_INHUNDREDTHSOFMILLIMETERS)))
        data->u.dlgw->Flags |= is_default_metric() ?
            PSD_INHUNDREDTHSOFMILLIMETERS : PSD_INTHOUSANDTHSOFINCHES;

    if (!data->u.dlgw->hDevMode || !data->u.dlgw->hDevNames)
    {
        WCHAR *def = get_default_printer();
        if(!def)
        {
            if (!(pagesetup_get_flags(data) & PSD_NOWARNING))
            {
                WCHAR errstr[256];
                LoadStringW(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255);
                MessageBoxW(data->u.dlgw->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR);
            }
            COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
            return FALSE;
        }
        pagesetup_change_printer(def, data);
        HeapFree(GetProcessHeap(), 0, def);
    }

    if (pagesetup_get_flags(data) & PSD_RETURNDEFAULT)
    {
        pagesetup_update_papersize(data);
        return TRUE;
    }

    tmpl = pagesetup_get_template(data);

    ret = DialogBoxIndirectParamW(data->u.dlgw->hInstance, tmpl,
                                  data->u.dlgw->hwndOwner,
                                  pagesetup_dlg_proc, (LPARAM)data) > 0;
    return ret;
}

/***********************************************************************
 *            PageSetupDlgA  (COMDLG32.@)
 *
 *  Displays the PAGE SETUP dialog box, which enables the user to specify
 *  specific properties of a printed page such as
 *  size, source, orientation and the width of the page margins.
 *
 * PARAMS
 *  setupdlg [IO] PAGESETUPDLGA struct
 *
 * RETURNS
 *  TRUE    if the user pressed the OK button
 *  FALSE   if the user cancelled the window or an error occurred
 *
 * NOTES
 *    The values of hDevMode and hDevNames are filled on output and can be
 *    changed in PAGESETUPDLG when they are passed in PageSetupDlg.
 *
 */
BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg)
{
    pagesetup_data data;

    data.unicode = FALSE;
    data.u.dlga  = setupdlg;

    return pagesetup_common(&data);
}

/***********************************************************************
 *            PageSetupDlgW  (COMDLG32.@)
 *
 * See PageSetupDlgA.
 */
BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg)
{
    pagesetup_data data;

    data.unicode = TRUE;
    data.u.dlgw  = setupdlg;

    return pagesetup_common(&data);
}

/***********************************************************************
 * PrintDlgExA (COMDLG32.@)
 *
 * See PrintDlgExW.
 *
 * BUGS
 *   Only a Stub
 *
 */
HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd)
{
    PRINTER_INFO_2A *pbuf;
    DRIVER_INFO_3A *dbuf;
    DEVMODEA *dm;
    HRESULT hr = S_OK;
    HANDLE hprn;

    if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA)))
        return E_INVALIDARG;

    if (!IsWindow(lppd->hwndOwner))
        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)
    {
        if (lppd->hDevMode || lppd->hDevNames)
        {
            WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
            return E_INVALIDARG;
        }
        if (!PRINTDLG_OpenDefaultPrinter(&hprn))
        {
            WARN("Can't find default printer\n");
            COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
            return E_FAIL;
        }

        pbuf = get_printer_infoA(hprn);
        if (!pbuf)
        {
            ClosePrinter(hprn);
            return E_FAIL;
        }

        dbuf = get_driver_infoA(hprn);
        if (!dbuf)
        {
            HeapFree(GetProcessHeap(), 0, pbuf);
            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
            ClosePrinter(hprn);
            return E_FAIL;
        }
        dm = pbuf->pDevMode;
    }
    else
    {
        FIXME("(%p) dialog not implemented\n", lppd);
        return E_NOTIMPL;

    }

    ClosePrinter(hprn);

    PRINTDLG_CreateDevNames(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName);
    if (!lppd->hDevNames)
        hr = E_FAIL;

    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 hr;
}

/***********************************************************************
 * PrintDlgExW (COMDLG32.@)
 *
 * Display the property sheet style PRINT dialog box
 *  
 * PARAMS
 *  lppd  [IO] ptr to PRINTDLGEX struct
 * 
 * RETURNS
 *  Success: S_OK
 *  Failure: One of the following COM error codes:
 *    E_OUTOFMEMORY Insufficient memory.
 *    E_INVALIDARG  One or more arguments are invalid.
 *    E_POINTER     Invalid pointer.
 *    E_HANDLE      Invalid handle.
 *    E_FAIL        Unspecified error.
 *  
 * NOTES
 * This Dialog enables the user to specify specific properties of the print job.
 * The property sheet can also have additional application-specific and
 * driver-specific property pages.
 *
 * BUGS
 *   Not fully implemented
 *
 */
HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW 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;
    }

    if (!IsWindow(lppd->hwndOwner)) {
        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) {

        if (lppd->hDevMode || lppd->hDevNames) {
            WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
            return E_INVALIDARG;
        }
        if (!PRINTDLG_OpenDefaultPrinter(&hprn)) {
            WARN("Can't find default printer\n");
            COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
            return E_FAIL;
        }

        pbuf = get_printer_infoW(hprn);
        if (!pbuf)
        {
            ClosePrinter(hprn);
            return E_FAIL;
        }

        dbuf = get_driver_infoW(hprn);
        if (!dbuf)
        {
            HeapFree(GetProcessHeap(), 0, pbuf);
            COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
            ClosePrinter(hprn);
            return E_FAIL;
        }
        dm = pbuf->pDevMode;
    }
    else
    {
        FIXME("(%p) dialog not implemented\n", lppd);
        return E_NOTIMPL;

    }

    ClosePrinter(hprn);

    PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName);
    if (!lppd->hDevNames)
        hr = E_FAIL;

    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 hr;
}
