Index: trunk/src/comdlg32/makefile
===================================================================
--- trunk/src/comdlg32/makefile	(revision 9363)
+++ trunk/src/comdlg32/makefile	(revision 9364)
@@ -1,3 +1,3 @@
-# $Id: makefile,v 1.31 2001-11-19 12:32:00 sandervl Exp $
+# $Id: makefile,v 1.32 2002-10-28 17:55:09 sandervl Exp $
 
 #
@@ -36,7 +36,7 @@
 $(OBJDIR)\filedlg.obj \
 $(OBJDIR)\filedlg95.obj \
-$(OBJDIR)\comdlg32.obj \
+##$(OBJDIR)\comdlg32.obj \
 $(OBJDIR)\filedlgbrowser.obj \
-##$(OBJDIR)\printdlg.obj \
+$(OBJDIR)\printdlg.obj \
 $(OBJDIR)\rsrc.obj
 
Index: trunk/src/comdlg32/printdlg.c
===================================================================
--- trunk/src/comdlg32/printdlg.c	(revision 9363)
+++ trunk/src/comdlg32/printdlg.c	(revision 9364)
@@ -6,4 +6,18 @@
  * Copyright 1999 Klaas van Gend
  * Copyright 2000 Huw D M Davies
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 #include <ctype.h>
@@ -19,10 +33,10 @@
 #include "commdlg.h"
 #include "dlgs.h"
-#include "debugtools.h"
+#include "wine/debug.h"
 #include "cderr.h"
 #include "winspool.h"
 #include "winerror.h"
 
-DEFAULT_DEBUG_CHANNEL(commdlg);
+WINE_DEFAULT_DEBUG_CHANNEL(commdlg);
 
 #include "cdlg.h"
@@ -30,7 +44,7 @@
 /* This PRINTDLGA internal structure stores
  * pointers to several throughout useful structures.
- * 
+ *
  */
-typedef struct  
+typedef struct
 {
   LPDEVMODEA        lpDevMode;
@@ -48,4 +62,20 @@
   HWND              hwndUpDown;
 } PRINT_PTRA;
+
+typedef struct
+{
+  LPDEVMODEW        lpDevMode;
+  struct {
+      LPPRINTDLGW       lpPrintDlg;
+  } dlg;
+  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 */
@@ -108,10 +138,10 @@
  *
  * Returns the default printer name in buf.
- * Even under WinNT/2000 default printer is retrieved via GetProfileString - 
+ * Even under WinNT/2000 default printer is retrieved via GetProfileString -
  * these entries are mapped somewhere in the registry rather than win.ini.
  *
  * Returns TRUE on success else FALSE
  */
-static BOOL PRINTDLG_GetDefaultPrinterName(LPSTR buf, DWORD len)
+static BOOL PRINTDLG_GetDefaultPrinterNameA(LPSTR buf, DWORD len)
 {
     char *ptr;
@@ -129,4 +159,25 @@
 }
 
+static BOOL PRINTDLG_GetDefaultPrinterNameW(LPWSTR buf, DWORD len)
+{
+    LPSTR ptr, bufA = (LPSTR)HeapAlloc(GetProcessHeap(),0,len+1);
+
+
+    if(!GetProfileStringA("windows", "device", "", bufA, len)) {
+	TRACE("No profile entry for default printer found.\n");
+        HeapFree(GetProcessHeap(),0,bufA);
+	return FALSE;
+    }
+    if((ptr = strchr(bufA, ',')) == NULL) {
+	FIXME("bad format for default printer (%s)!\n",bufA);
+        HeapFree(GetProcessHeap(),0,bufA);
+	return FALSE;
+    }
+    *ptr = '\0';
+    MultiByteToWideChar( CP_ACP, 0, bufA, -1, buf, len );
+    HeapFree(GetProcessHeap(),0,bufA);
+    return TRUE;
+}
+
 /***********************************************************************
  *    PRINTDLG_OpenDefaultPrinter
@@ -141,5 +192,5 @@
     char buf[260];
     BOOL res;
-    if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
+    if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)))
         return FALSE;
     res = OpenPrinterA(buf, hprn, NULL);
@@ -162,5 +213,5 @@
  * Returns number of printers added to list.
  */
-static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name)
+static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name)
 {
     DWORD needed, num;
@@ -169,5 +220,5 @@
     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, 
+    EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed,
 		  &num);
 
@@ -184,5 +235,5 @@
         FIXME("Can't find '%s' in printer list so trying to find default\n",
 	      name);
-	if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)))
+	if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)))
 	    return num;
 	i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf);
@@ -194,4 +245,37 @@
 }
 
+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) {
+
+	/* ansi is ok */
+        char buf[260];
+        FIXME("Can't find '%s' in printer list so trying to find default\n",
+	      debugstr_w(name));
+	if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)))
+	    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");
+    }
+    SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0);
+    return num;
+}
+
 /***********************************************************************
  *             PRINTDLG_CreateDevNames          [internal]
@@ -202,5 +286,5 @@
  *  (NB. when we handle unicode the offsets will be in wchars).
  */
-static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, char* DeviceDriverName, 
+static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, char* DeviceDriverName,
 				    char* DeviceName, char* OutputPort)
 {
@@ -215,5 +299,5 @@
             + strlen(OutputPort) + 1
             + sizeof(DEVNAMES);
-            
+
     if(*hmem)
         *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE);
@@ -233,16 +317,62 @@
     strcpy(pTempPtr, DeviceName);
     lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
-        
+
     pTempPtr += strlen(DeviceName) + 1;
     strcpy(pTempPtr, OutputPort);
     lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
 
-    PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf));
+    PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf));
     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];
+    char buf[260];
+
+    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;
+
+    PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf));
+    MultiByteToWideChar(CP_ACP, 0, buf, -1, bufW, -1);
+    lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0;
+    GlobalUnlock(*hmem);
+    return TRUE;
+}
+
+
 #ifndef __WIN32OS2__
-static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName, 
+static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName,
 				      char* DeviceName, char* OutputPort)
 {
@@ -257,5 +387,5 @@
             + strlen(OutputPort) + 1
             + sizeof(DEVNAMES);
-            
+
     if(*hmem)
         *hmem = GlobalReAlloc16(*hmem, size, GMEM_MOVEABLE);
@@ -275,10 +405,10 @@
     strcpy(pTempPtr, DeviceName);
     lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace;
-        
+
     pTempPtr += strlen(DeviceName) + 1;
     strcpy(pTempPtr, OutputPort);
     lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace;
 
-    PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf));
+    PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf));
     lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0;
     GlobalUnlock16(*hmem);
@@ -292,10 +422,10 @@
  *
  *   updates the PrintDlg structure for returnvalues.
- *      
+ *
  * RETURNS
  *   FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values)
  *   TRUE  if succesful.
  */
-static BOOL PRINTDLG_UpdatePrintDlg(HWND hDlg, 
+static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg,
 				    PRINT_PTRA* PrintStructures)
 {
@@ -324,8 +454,8 @@
 	        char resourcestr[256];
 		char resultstr[256];
-		LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, 
+		LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
 			    resourcestr, 255);
 		sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
-		LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE, 
+		LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
 			    resourcestr, 255);
 		MessageBoxA(hDlg, resultstr, resourcestr,
@@ -335,5 +465,8 @@
 	    lppd->nFromPage = nFromPage;
 	    lppd->nToPage   = nToPage;
-	}
+	    lppd->Flags |= PD_PAGENUMS;
+	}
+	else
+	    lppd->Flags &= ~PD_PAGENUMS;
 
 	if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */
@@ -356,5 +489,5 @@
 	   */
 	    if (lpdm->dmFields & DM_COLLATE)
-	        lpdm->dmCollate = 
+	        lpdm->dmCollate =
 		  (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED);
 	    if (lpdm->dmFields & DM_COPIES)
@@ -371,5 +504,80 @@
 }
 
-static BOOL PRINTDLG_PaperSize(
+static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg,
+				    PRINT_PTRW* PrintStructures)
+{
+    LPPRINTDLGW       lppd = PrintStructures->dlg.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;
+	    nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE);
+	    nToPage   = GetDlgItemInt(hDlg, edt2, NULL, FALSE);
+	    if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage ||
+		nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) {
+	        char resourcestr[256];
+		char resultstr[256];
+		LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE,
+			    resourcestr, 255);
+		sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage);
+		LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE,
+			    resourcestr, 255);
+		MessageBoxA(hDlg, resultstr, resourcestr,
+			    MB_OK | MB_ICONWARNING);
+		return FALSE;
+	    }
+	    lppd->nFromPage = nFromPage;
+	    lppd->nToPage   = nToPage;
+	}
+
+	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->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;
+}
+
+static BOOL PRINTDLG_PaperSizeA(
 	PRINTDLGA	*pdlga,const char *PaperSize,LPPOINT size
 ) {
@@ -378,9 +586,9 @@
     LPSTR	devname,portname;
     int		i;
-    DWORD	NrOfEntries,ret;
+    INT		NrOfEntries,ret;
     char	*Names = NULL;
     POINT	*points = NULL;
     BOOL	retval = FALSE;
-    
+
     dn = GlobalLock(pdlga->hDevNames);
     dm = GlobalLock(pdlga->hDevMode);
@@ -394,7 +602,12 @@
 	goto out;
     }
+    if (NrOfEntries == -1) {
+	ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
+	goto out;
+    }
+
     Names = (char*)HeapAlloc(GetProcessHeap(),0,NrOfEntries*64);
     if (NrOfEntries != (ret=DeviceCapabilitiesA(devname,portname,DC_PAPERNAMES,Names,dm))) {
-	FIXME("Number of returned vals %ld is not %ld\n",NrOfEntries,ret);
+	FIXME("Number of returned vals %d is not %d\n",NrOfEntries,ret);
 	goto out;
     }
@@ -409,5 +622,5 @@
     points = HeapAlloc(GetProcessHeap(),0,sizeof(points[0])*NrOfEntries);
     if (NrOfEntries!=(ret=DeviceCapabilitiesA(devname,portname,DC_PAPERSIZE,(LPBYTE)points,dm))) {
-	FIXME("Number of returned sizes %ld is not %ld?\n",NrOfEntries,ret);
+	FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries,ret);
 	goto out;
     }
@@ -415,5 +628,4 @@
     size->x=points[i].x;
     size->y=points[i].y;
-    FIXME("papersize is %ld x %ld\n",size->x,size->y);
     retval = TRUE;
 out:
@@ -425,4 +637,62 @@
 }
 
+static BOOL PRINTDLG_PaperSizeW(
+	PRINTDLGW	*pdlga,const WCHAR *PaperSize,LPPOINT size
+) {
+    DEVNAMES	*dn;
+    DEVMODEW	*dm;
+    LPWSTR	devname,portname;
+    int		i;
+    INT		NrOfEntries,ret;
+    WCHAR	*Names = NULL;
+    POINT	*points = NULL;
+    BOOL	retval = FALSE;
+
+    dn = GlobalLock(pdlga->hDevNames);
+    dm = GlobalLock(pdlga->hDevMode);
+    devname	= ((WCHAR*)dn)+dn->wDeviceOffset;
+    portname	= ((WCHAR*)dn)+dn->wOutputOffset;
+
+
+    NrOfEntries = DeviceCapabilitiesW(devname,portname,DC_PAPERNAMES,NULL,dm);
+    if (!NrOfEntries) {
+	FIXME("No papernames found for %s/%s\n",debugstr_w(devname),debugstr_w(portname));
+	goto out;
+    }
+    if (NrOfEntries == -1) {
+	ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n");
+	goto out;
+    }
+
+    Names = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*NrOfEntries*64);
+    if (NrOfEntries != (ret=DeviceCapabilitiesW(devname,portname,DC_PAPERNAMES,Names,dm))) {
+	FIXME("Number of returned vals %d is not %d\n",NrOfEntries,ret);
+	goto out;
+    }
+    for (i=0;i<NrOfEntries;i++)
+	if (!lstrcmpW(PaperSize,Names+(64*i)))
+	    break;
+    HeapFree(GetProcessHeap(),0,Names);
+    if (i==NrOfEntries) {
+	FIXME("Papersize %s not found in list?\n",debugstr_w(PaperSize));
+	goto out;
+    }
+    points = HeapAlloc(GetProcessHeap(),0,sizeof(points[0])*NrOfEntries);
+    if (NrOfEntries!=(ret=DeviceCapabilitiesW(devname,portname,DC_PAPERSIZE,(LPWSTR)points,dm))) {
+	FIXME("Number of returned sizes %d is not %d?\n",NrOfEntries,ret);
+	goto out;
+    }
+    /* this is _10ths_ of a millimeter */
+    size->x=points[i].x;
+    size->y=points[i].y;
+    retval = TRUE;
+out:
+    GlobalUnlock(pdlga->hDevNames);
+    GlobalUnlock(pdlga->hDevMode);
+    if (Names) HeapFree(GetProcessHeap(),0,Names);
+    if (points) HeapFree(GetProcessHeap(),0,points);
+    return retval;
+}
+
 
 /************************************************************************
@@ -433,12 +703,12 @@
  * We also try to re-select the old selection.
  */
-static BOOL PRINTDLG_SetUpPaperComboBox(HWND hDlg,
+static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg,
 					int   nIDComboBox,
-					char* PrinterName, 
+					char* PrinterName,
 					char* PortName,
 					LPDEVMODEA dm)
 {
     int     i;
-    DWORD   NrOfEntries;
+    int     NrOfEntries;
     char*   Names;
     WORD*   Words;
@@ -448,7 +718,7 @@
     int     fwCapability_Names;
     int     fwCapability_Words;
-    
-    TRACE(" Printer: %s, ComboID: %d\n",PrinterName,nIDComboBox);
-    
+
+    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);
@@ -462,9 +732,5 @@
         if (dm) {
             if (nIDComboBox == cmb2)
-#ifdef __WIN32OS2__
-                dm->dmPaperSize = oldWord;
-#else
                 dm->u1.s1.dmPaperSize = oldWord;
-#endif
             else
                 dm->dmDefaultSource = oldWord;
@@ -478,9 +744,5 @@
         if (dm) {
             if (nIDComboBox == cmb2)
-#ifdef __WIN32OS2__
-                oldWord = dm->dmPaperSize;
-#else
                 oldWord = dm->u1.s1.dmPaperSize;
-#endif
             else
                 oldWord = dm->dmDefaultSource;
@@ -498,6 +760,6 @@
          fwCapability_Words = DC_BINS;
     }
-    
-    /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the 
+
+    /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
      * paper settings. As Wine doesn't allow VXDs, this results in a crash.
      */
@@ -507,4 +769,6 @@
     if (NrOfEntries == 0)
          WARN("no Name Entries found!\n");
+    else if (NrOfEntries < 0)
+         return FALSE;
 
     if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm)
@@ -514,5 +778,5 @@
     }
 
-    Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*NamesSize);
+    Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(char)*NamesSize);
     Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD));
     NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName,
@@ -523,10 +787,10 @@
     /* 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, 
+	SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
 			    Words[i]);
     }
@@ -549,8 +813,119 @@
 }
 
+static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg,
+					int   nIDComboBox,
+					WCHAR* PrinterName,
+					WCHAR* PortName,
+					LPDEVMODEW dm)
+{
+    int     i;
+    int     NrOfEntries;
+    WCHAR*  Names;
+    WORD*   Words;
+    DWORD   Sel;
+    WORD    oldWord = 0;
+    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 = 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 (dm) {
+            if (nIDComboBox == cmb2)
+                dm->u1.s1.dmPaperSize = oldWord;
+            else
+                dm->dmDefaultSource = oldWord;
+        }
+    }
+    else {
+        /* we enter here only when the Print setup dialog is initially
+         * opened. In this case the settings are restored from when
+         * the dialog was last closed.
+         */
+        if (dm) {
+            if (nIDComboBox == cmb2)
+                oldWord = dm->u1.s1.dmPaperSize;
+            else
+                oldWord = dm->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;
+    }
+
+    /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the
+     * paper settings. As Wine doesn't allow VXDs, this results in a crash.
+     */
+    WARN(" if your printer driver uses VXDs, expect a crash now!\n");
+    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, (LPWSTR)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 = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0,
+					(LPARAM)(&Names[i*NamesSize]) );
+	SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos,
+			    Words[i]);
+    }
+
+    /* Look for old selection - can't do this is previous loop since
+       item order will change as more items are added */
+    Sel = 0;
+    for (i = 0; i < NrOfEntries; i++) {
+        if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) ==
+	   oldWord) {
+	    Sel = i;
+	    break;
+	}
+    }
+    SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0);
+
+    HeapFree(GetProcessHeap(),0,Words);
+    HeapFree(GetProcessHeap(),0,Names);
+    return TRUE;
+}
+
+
 /***********************************************************************
  *               PRINTDLG_UpdatePrinterInfoTexts               [internal]
  */
-static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, LPPRINTER_INFO_2A pi)
+static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, LPPRINTER_INFO_2A pi)
 {
     char   StatusMsg[256];
@@ -564,5 +939,5 @@
     for (i = 0; i < 25; i++) {
         if (pi->Status & (1<<i)) {
-	    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, 
+	    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i,
 			ResourceString, 255);
 	    strcat(StatusMsg,ResourceString);
@@ -570,10 +945,10 @@
     }
     /* append "ready" */
-    /* FIXME: status==ready must only be appended if really so. 
+    /* FIXME: status==ready must only be appended if really so.
               but how to detect? */
-    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, 
+    LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY,
 		ResourceString, 255);
     strcat(StatusMsg,ResourceString);
-  
+
     SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
 
@@ -589,4 +964,41 @@
 }
 
+static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, LPPRINTER_INFO_2W pi)
+{
+    WCHAR   StatusMsg[256];
+    WCHAR   ResourceString[256];
+    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);
+
+    SendDlgItemMessageW(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg);
+
+    /* set all other printer info texts */
+    SendDlgItemMessageW(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)pi->pDriverName);
+    if (pi->pLocation != NULL && pi->pLocation[0] != '\0')
+        SendDlgItemMessageW(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation);
+    else
+        SendDlgItemMessageW(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName);
+    SendDlgItemMessageW(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)(pi->pComment ?
+			pi->pComment : (LPCWSTR)"\0\0"));
+    return;
+}
+
 
 /*******************************************************************
@@ -595,5 +1007,5 @@
  *
  */
-static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name,
+static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name,
 				   PRINT_PTRA *PrintStructures)
 {
@@ -625,5 +1037,5 @@
     ClosePrinter(hprn);
 
-    PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures->lpPrinterInfo);
+    PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo);
 
     if(PrintStructures->lpDevMode) {
@@ -676,20 +1088,20 @@
 	    char        resourcestr[64];
 	    char        result[64];
-	    LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES, 
+	    LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
 			resourcestr, 49);
 	    sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
 	    SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
 	}
-        
-	/* Collate pages 
+
+	/* 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, (WPARAM) IMAGE_ICON, 
+	    SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
 				(LPARAM)PrintStructures->hCollateIcon);
 	    CheckDlgButton(hDlg, chx2, 1);
 	} else {
-	    SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
+	    SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
 				(LPARAM)PrintStructures->hNoCollateIcon);
 	    CheckDlgButton(hDlg, chx2, 0);
@@ -699,6 +1111,6 @@
 	  /* if printer doesn't support it: no Collate */
 	    if (!(lpdm->dmFields & DM_COLLATE)) {
-	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);    
-		EnableWindow(GetDlgItem(hDlg, ico3), FALSE);    
+	        EnableWindow(GetDlgItem(hDlg, chx2), FALSE);
+		EnableWindow(GetDlgItem(hDlg, ico3), FALSE);
 	    }
 	}
@@ -719,6 +1131,6 @@
 	  /* if printer doesn't support it: no nCopies */
 	    if (!(lpdm->dmFields & DM_COPIES)) {
-	        EnableWindow(GetDlgItem(hDlg, edt3), FALSE);    
-		EnableWindow(GetDlgItem(hDlg, stc5), FALSE);    
+	        EnableWindow(GetDlgItem(hDlg, edt3), FALSE);
+		EnableWindow(GetDlgItem(hDlg, stc5), FALSE);
 	    }
 	}
@@ -727,20 +1139,16 @@
 	CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0);
 	if (lppd->Flags & PD_DISABLEPRINTTOFILE)
-            EnableWindow(GetDlgItem(hDlg, chx1), FALSE);    
+            EnableWindow(GetDlgItem(hDlg, chx1), FALSE);
 	if (lppd->Flags & PD_HIDEPRINTTOFILE)
             ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE);
 
     } else { /* PD_PRINTSETUP */
-#ifdef __WIN32OS2__
-      BOOL bPortrait = (lpdm->dmOrientation == DMORIENT_PORTRAIT);
-#else
       BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT);
-#endif
-
-      PRINTDLG_SetUpPaperComboBox(hDlg, cmb2,
+
+      PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb2,
 				  PrintStructures->lpPrinterInfo->pPrinterName,
 				  PrintStructures->lpPrinterInfo->pPortName,
 				  lpdm);
-      PRINTDLG_SetUpPaperComboBox(hDlg, cmb3,
+      PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb3,
 				  PrintStructures->lpPrinterInfo->pPrinterName,
 				  PrintStructures->lpPrinterInfo->pPortName,
@@ -750,5 +1158,5 @@
                           (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon :
                                    PrintStructures->hLandscapeIcon));
-      
+
     }
 
@@ -756,5 +1164,168 @@
     if ((lppd->Flags & PD_SHOWHELP)==0) {
         /* hide if PD_SHOWHELP not specified */
-        ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);         
+        ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE);
+    }
+    return TRUE;
+}
+
+static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name,
+				   PRINT_PTRW *PrintStructures)
+{
+    LPPRINTDLGW lppd = PrintStructures->dlg.lpPrintDlg;
+    LPDEVMODEW lpdm = NULL;
+    LONG dmSize;
+    DWORD needed;
+    HANDLE hprn;
+
+    if(PrintStructures->lpPrinterInfo)
+        HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo);
+    if(PrintStructures->lpDriverInfo)
+        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,sizeof(WCHAR)*needed);
+    GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed,
+		&needed);
+    GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
+    PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*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);
+
+    if(PrintStructures->lpDevMode) {
+        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) */
+        SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE);
+	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);
+	}
+	/* "All xxx pages"... */
+	{
+	    /* ansi is ok */
+	    char        resourcestr[64];
+	    char        result[64];
+	    LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES,
+			resourcestr, 49);
+	    sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1);
+	    SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result);
+	}
+
+	/* 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, (WPARAM) IMAGE_ICON,
+				(LPARAM)PrintStructures->hCollateIcon);
+	    CheckDlgButton(hDlg, chx2, 1);
+	} else {
+	    SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) 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->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);
+      SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) 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;
@@ -774,9 +1345,9 @@
 
     /* load Collate ICONs */
-    /* We load these with LoadImage becasue they are not a standard
+    /* 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 = 
+    PrintStructures->hNoCollateIcon =
       LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0);
 
@@ -801,5 +1372,5 @@
      */
     if (lppd->Flags & PD_SHOWHELP) {
-        if((PrintStructures->HelpMessageID = 
+        if((PrintStructures->HelpMessageID =
 	    RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) {
 	    COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
@@ -824,6 +1395,6 @@
     if (lppd->nMaxPage < lppd->nMinPage)
     	lppd->nMaxPage = lppd->nMinPage;
-    if (lppd->nMinPage == lppd->nMaxPage) 
-    	lppd->Flags |= PD_NOPAGENUMS;        
+    if (lppd->nMinPage == lppd->nMaxPage)
+    	lppd->Flags |= PD_NOPAGENUMS;
     if (lppd->nToPage < lppd->nMinPage)
         lppd->nToPage = lppd->nMinPage;
@@ -837,5 +1408,5 @@
     /* if we have the combo box, fill it */
     if (GetDlgItem(hDlg,comboID)) {
-	/* Fill Combobox 
+	/* Fill Combobox
 	 */
 	pdn = GlobalLock(lppd->hDevNames);
@@ -845,5 +1416,5 @@
 	else if(pdm)
 	    name = pdm->dmDeviceName;
-	PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name);
+	PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name);
 	if(pdm) GlobalUnlock(lppd->hDevMode);
 	if(pdn) GlobalUnlock(lppd->hDevNames);
@@ -852,13 +1423,117 @@
 	name = HeapAlloc(GetProcessHeap(),0,256);
 	if (GetDlgItemTextA(hDlg, comboID, name, 255))
-	    PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
+	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
 	HeapFree(GetProcessHeap(),0,name);
     } else {
 	/* else use default printer */
 	char name[200];
-	BOOL ret = PRINTDLG_GetDefaultPrinterName(name, sizeof(name));
+	BOOL ret = PRINTDLG_GetDefaultPrinterNameA(name, sizeof(name));
 
 	if (ret)
-	    PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
+	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
+	else
+	    FIXME("No default printer found, expect problems!\n");
+    }
+    return TRUE;
+}
+
+static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam,
+				     PRINT_PTRW* PrintStructures)
+{
+    LPPRINTDLGW lppd = PrintStructures->dlg.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 =
+      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");
+
+    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 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];
+	BOOL ret = PRINTDLG_GetDefaultPrinterNameW(name, sizeof(name));
+
+	if (ret)
+	    PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures);
 	else
 	    FIXME("No default printer found, expect problems!\n");
@@ -883,5 +1558,5 @@
     PrintStructures->hCollateIcon =
       LoadIconA(COMDLG32_hInstance, "PD32_COLLATE");
-    PrintStructures->hNoCollateIcon = 
+    PrintStructures->hNoCollateIcon =
       LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE");
     if(PrintStructures->hCollateIcon == 0 ||
@@ -900,5 +1575,5 @@
      */
     if (lppd->Flags & PD_SHOWHELP) {
-        if((PrintStructures->HelpMessageID = 
+        if((PrintStructures->HelpMessageID =
 	    RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) {
 	    COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL);
@@ -926,5 +1601,5 @@
 		}
 	        GlobalUnlock16(lppd->hDevMode);
-	    } else 
+	    } else
 		strcpy(buf,"Default");
 	    SendDlgItemMessageA(hDlg,cmb1,CB_ADDSTRING,0,(LPARAM)buf);
@@ -940,6 +1615,6 @@
     if (lppd->nMaxPage < lppd->nMinPage)
     	lppd->nMaxPage = lppd->nMinPage;
-    if (lppd->nMinPage == lppd->nMaxPage) 
-    	lppd->Flags |= PD_NOPAGENUMS;        
+    if (lppd->nMinPage == lppd->nMaxPage)
+    	lppd->Flags |= PD_NOPAGENUMS;
     if (lppd->nToPage < lppd->nMinPage)
         lppd->nToPage = lppd->nMinPage;
@@ -953,5 +1628,5 @@
     /* If the printer combo box is in the dialog, fill it */
     if (GetDlgItem(hDlg,comboID)) {
-	/* Fill Combobox 
+	/* Fill Combobox
 	 */
 	pdn = GlobalLock16(lppd->hDevNames);
@@ -961,5 +1636,5 @@
 	else if(pdm)
 	    name = pdm->dmDeviceName;
-	PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name);
+	PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name);
 	if(pdm) GlobalUnlock16(lppd->hDevMode);
 	if(pdn) GlobalUnlock16(lppd->hDevNames);
@@ -968,12 +1643,12 @@
 	name = HeapAlloc(GetProcessHeap(),0,256);
 	if (GetDlgItemTextA(hDlg, comboID, name, 255))
-	    PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
+	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
     } else {
 	/* else just use default printer */
 	char name[200];
-	BOOL ret = PRINTDLG_GetDefaultPrinterName(name, sizeof(name));
+	BOOL ret = PRINTDLG_GetDefaultPrinterNameA(name, sizeof(name));
 
 	if (ret)
-	    PRINTDLG_ChangePrinter(hDlg, name, PrintStructures);
+	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures);
 	else
 	    FIXME("No default printer found, expect problems!\n");
@@ -984,9 +1659,8 @@
 }
 #endif
-
 /***********************************************************************
  *                              PRINTDLG_WMCommand               [internal]
  */
-static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, 
+static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam,
 			LPARAM lParam, PRINT_PTRA* PrintStructures)
 {
@@ -998,5 +1672,5 @@
     case IDOK:
         TRACE(" OK button was hit\n");
-        if (PRINTDLG_UpdatePrintDlg(hDlg, PrintStructures)!=TRUE) {
+        if (PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)!=TRUE) {
 	    FIXME("Update printdlg was not successful!\n");
 	    return(FALSE);
@@ -1012,5 +1686,5 @@
      case pshHelp:
         TRACE(" HELP button was hit\n");
-        SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, 
+        SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID,
         			(WPARAM) hDlg, (LPARAM) lppd);
         break;
@@ -1018,10 +1692,10 @@
      case chx2:                         /* collate pages checkbox */
         if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED)
-            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
+            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
                                     (LPARAM)PrintStructures->hCollateIcon);
         else
-            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, 
+            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
                                     (LPARAM)PrintStructures->hNoCollateIcon);
-        break;        
+        break;
      case edt1:                         /* from page nr editbox */
      case edt2:                         /* to page nr editbox */
@@ -1050,5 +1724,5 @@
 	{
 	    PRINTDLG16	pdlg;
-	    
+
 	    if (!PrintStructures->dlg.lpPrintDlg16) {
 		FIXME("The 32bit print dialog does not have this button!?\n");
@@ -1058,5 +1732,5 @@
 	    memcpy(&pdlg,PrintStructures->dlg.lpPrintDlg16,sizeof(pdlg));
 	    pdlg.Flags |= PD_PRINTSETUP;
-	    pdlg.hwndOwner = hDlg;
+	    pdlg.hwndOwner = HWND_16(hDlg);
 	    if (!PrintDlg16(&pdlg))
 		break;
@@ -1075,5 +1749,5 @@
 	     break;
 	 }
-	 DocumentPropertiesA(hDlg, hPrinter, PrinterName, 
+	 DocumentPropertiesA(hDlg, hPrinter, PrinterName,
 			     PrintStructures->lpDevMode,
 			     PrintStructures->lpDevMode,
@@ -1086,27 +1760,19 @@
         if (lppd->Flags & PD_PRINTSETUP)
         {
-#ifdef __WIN32OS2__
-              lpdm->dmOrientation = DMORIENT_PORTRAIT;
-#else
               lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
-#endif
               SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
                           (LPARAM)(PrintStructures->hPortraitIcon));
         }
         break;
-            
+
     case rad2: /* Paperorientation */
         if (lppd->Flags & PD_PRINTSETUP)
         {
-#ifdef __WIN32OS2__
-              lpdm->dmOrientation = DMORIENT_LANDSCAPE;
-#else
               lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
-#endif
               SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
                           (LPARAM)(PrintStructures->hLandscapeIcon));
         }
         break;
-            
+
     case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT */
 	 if (PrinterComboID != wParam) {
@@ -1119,5 +1785,5 @@
 	     char   PrinterName[256];
 	     GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255);
-	     PRINTDLG_ChangePrinter(hDlg, PrinterName, PrintStructures);
+	     PRINTDLG_ChangePrinterA(hDlg, PrinterName, PrintStructures);
 	 }
 	 break;
@@ -1127,9 +1793,5 @@
 	  DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0);
 	  if(Sel != CB_ERR)
-#ifdef __WIN32OS2__
-	      lpdm->dmPaperSize = SendDlgItemMessageA(hDlg, cmb2,
-#else
 	      lpdm->u1.s1.dmPaperSize = SendDlgItemMessageA(hDlg, cmb2,
-#endif
 							    CB_GETITEMDATA,
 							    Sel, 0);
@@ -1145,5 +1807,5 @@
 							  0);
       }
-      break; 
+      break;
     }
     if(lppd->Flags & PD_PRINTSETUP) {
@@ -1152,11 +1814,6 @@
 	case rad2:
 	    if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) {
-#ifdef __WIN32OS2__
-	        if(lpdm->dmOrientation != DMORIENT_PORTRAIT) {
-		    lpdm->dmOrientation = DMORIENT_PORTRAIT;
-#else
 	        if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) {
 		    lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT;
-#endif
 		    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE,
 					(WPARAM)IMAGE_ICON,
@@ -1167,11 +1824,6 @@
 		}
 	    } else {
-#ifdef __WIN32OS2__
-	        if(lpdm->dmOrientation != DMORIENT_LANDSCAPE) {
-		    lpdm->dmOrientation = DMORIENT_LANDSCAPE;
-#else
 	        if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) {
 	            lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
-#endif
 		    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE,
 					(WPARAM)IMAGE_ICON,
@@ -1186,16 +1838,175 @@
     }
     return FALSE;
-}    
+}
+
+static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam,
+			LPARAM lParam, PRINT_PTRW* PrintStructures)
+{
+    LPPRINTDLGW lppd = PrintStructures->dlg.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)!=TRUE) {
+	    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)
+            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON,
+                                    (LPARAM)PrintStructures->hCollateIcon);
+        else
+            SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) 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 psh1:                       /* Print Setup */
+	{
+		ERR("psh1 is called from 16bit code only, we should not get here.\n");
+	}
+	break;
+     case psh2:                       /* Properties button */
+       {
+         HANDLE hPrinter;
+         WCHAR  PrinterName[256];
+
+         GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255);
+         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;
+              SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (WPARAM) 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, (WPARAM) IMAGE_ICON,
+                          (LPARAM)(PrintStructures->hLandscapeIcon));
+        }
+        break;
+
+    case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT */
+	 if (PrinterComboID != wParam) {
+	     FIXME("No handling for print quality combo box yet.\n");
+	     break;
+	 }
+	 /* FALLTHROUGH */
+    case cmb4:                         /* Printer combobox */
+         if (HIWORD(wParam)==CBN_SELCHANGE) {
+	     WCHAR   PrinterName[256];
+	     GetDlgItemTextW(hDlg, LOWORD(wParam), PrinterName, 255);
+	     PRINTDLG_ChangePrinterW(hDlg, PrinterName, PrintStructures);
+	 }
+	 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->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;
+		    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE,
+					(WPARAM)IMAGE_ICON,
+					(LPARAM)PrintStructures->hPortraitIcon);
+		    SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE,
+					(WPARAM)IMAGE_ICON,
+					(LPARAM)PrintStructures->hPortraitIcon);
+		}
+	    } else {
+	        if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) {
+	            lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE;
+		    SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE,
+					(WPARAM)IMAGE_ICON,
+					(LPARAM)PrintStructures->hLandscapeIcon);
+		    SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE,
+					(WPARAM)IMAGE_ICON,
+					(LPARAM)PrintStructures->hLandscapeIcon);
+		}
+	    }
+	    break;
+	}
+    }
+    return FALSE;
+}
 
 /***********************************************************************
  *           PrintDlgProcA			[internal]
  */
-#ifdef __WIN32OS2__
-LRESULT WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
-   	  	  	     LPARAM lParam)
-#else
 BOOL WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam,
 			  LPARAM lParam)
-#endif
 {
     PRINT_PTRA* PrintStructures;
@@ -1203,10 +2014,10 @@
 
     if (uMsg!=WM_INITDIALOG) {
-        PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);   
+        PrintStructures = (PRINT_PTRA*)GetPropA(hDlg,"__WINE_PRINTDLGDATA");
 	if (!PrintStructures)
 	    return FALSE;
     } else {
         PrintStructures = (PRINT_PTRA*) lParam;
-	SetWindowLongA(hDlg, DWL_USER, lParam); 
+	SetPropA(hDlg,"__WINE_PRINTDLGDATA",lParam);
 	res = PRINTDLG_WMInitDialog(hDlg, wParam, PrintStructures);
 
@@ -1214,8 +2025,8 @@
 	    res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook(
 		hDlg, uMsg, wParam, (LPARAM)PrintStructures->dlg.lpPrintDlg
-	    ); 
+	    );
 	return res;
     }
-  
+
     if(PrintStructures->dlg.lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
         res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam,
@@ -1226,5 +2037,5 @@
     switch (uMsg) {
     case WM_COMMAND:
-        return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures);
+        return PRINTDLG_WMCommandA(hDlg, wParam, lParam, PrintStructures);
 
     case WM_DESTROY:
@@ -1236,5 +2047,49 @@
 	    DestroyWindow(PrintStructures->hwndUpDown);
         return FALSE;
-    }    
+    }
+    return res;
+}
+
+BOOL WINAPI PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam,
+			  LPARAM lParam)
+{
+    PRINT_PTRW* PrintStructures;
+    LRESULT res=FALSE;
+
+    if (uMsg!=WM_INITDIALOG) {
+        PrintStructures = (PRINT_PTRW*) GetWindowLongA(hDlg, DWL_USER);
+	if (!PrintStructures)
+	    return FALSE;
+    } else {
+        PrintStructures = (PRINT_PTRW*) lParam;
+	SetWindowLongA(hDlg, DWL_USER, lParam);
+	res = PRINTDLG_WMInitDialogW(hDlg, wParam, PrintStructures);
+
+	if(PrintStructures->dlg.lpPrintDlg->Flags & PD_ENABLEPRINTHOOK)
+	    res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook(
+		hDlg, uMsg, wParam, (LPARAM)PrintStructures->dlg.lpPrintDlg
+	    );
+	return res;
+    }
+
+    if(PrintStructures->dlg.lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) {
+        res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam,
+							 lParam);
+	if(res) return res;
+    }
+
+    switch (uMsg) {
+    case WM_COMMAND:
+        return PRINTDLG_WMCommandW(hDlg, wParam, lParam, 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;
 }
@@ -1250,10 +2105,11 @@
 static HGLOBAL16 PRINTDLG_Get16TemplateFrom32(char *PrintResourceName)
 {
-        HANDLE hResInfo, hDlgTmpl32;
+	HRSRC hResInfo;
+	HGLOBAL hDlgTmpl32;
         LPCVOID template32;
         DWORD size;
         HGLOBAL16 hGlobal16;
         LPVOID template;
- 
+
         if (!(hResInfo = FindResourceA(COMMDLG_hInstance32,
                PrintResourceName, RT_DIALOGA)))
@@ -1295,12 +2151,13 @@
  *
  */
-static HGLOBAL PRINTDLG_GetDlgTemplate(PRINTDLGA *lppd)
-{
-    HGLOBAL hDlgTmpl, hResInfo;
+static HGLOBAL PRINTDLG_GetDlgTemplateA(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) {	
+	} else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
 	    hResInfo = FindResourceA(lppd->hInstance,
 				     lppd->lpSetupTemplateName, RT_DIALOGA);
@@ -1328,19 +2185,53 @@
 }
 
-
-#ifndef __WIN32OS2__
-/************************************************************
- *
- *      PRINTDLG_GetDlgTemplate
- *
- */
-static HGLOBAL16 PRINTDLG_GetDlgTemplate16(PRINTDLG16 *lppd)
-{
-    HGLOBAL16 hDlgTmpl, hResInfo;
+static HGLOBAL PRINTDLG_GetDlgTemplateW(PRINTDLGW *lppd)
+{
+    HRSRC hResInfo;
+    HGLOBAL hDlgTmpl;
+    const WCHAR xpsetup[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0};
+    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) {	
+	} else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
+	    hResInfo = FindResourceW(lppd->hInstance,
+				     lppd->lpSetupTemplateName, RT_DIALOGW);
+	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
+	} else {
+	    hResInfo = FindResourceW(COMDLG32_hInstance, xpsetup, RT_DIALOGW);
+	    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,
+				     RT_DIALOGW);
+	    hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
+	} else {
+	    hResInfo = FindResourceW(COMDLG32_hInstance, xprint, RT_DIALOGW);
+	    hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo);
+	}
+    }
+    return hDlgTmpl;
+}
+
+
+#ifndef __WIN32OS2__
+/************************************************************
+ *
+ *      PRINTDLG_GetDlgTemplate
+ *
+ */
+static HGLOBAL16 PRINTDLG_GetDlgTemplate16(PRINTDLG16 *lppd)
+{
+    HGLOBAL16 hDlgTmpl, hResInfo;
+
+    if (lppd->Flags & PD_PRINTSETUP) {
+	if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) {
+	    hDlgTmpl = lppd->hSetupTemplate;
+	} else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) {
 	    hResInfo = FindResource16(lppd->hInstance,
 				     MapSL(lppd->lpSetupTemplateName), RT_DIALOGA);
@@ -1370,5 +2261,5 @@
  *
  */
-static BOOL PRINTDLG_CreateDC(LPPRINTDLGA lppd)
+static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd)
 {
     DEVNAMES *pdn = GlobalLock(lppd->hDevNames);
@@ -1391,4 +2282,25 @@
 }
 
+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;
+}
+
 #ifndef __WIN32OS2__
 static BOOL PRINTDLG_CreateDC16(LPPRINTDLG16 lppd)
@@ -1431,7 +2343,8 @@
  *  * The Paper Orientation Icons are not implemented yet.
  *  * The Properties Button(s) should call DocumentPropertiesA().
- *  * Settings are not yet taken from a provided DevMode or 
+ *  * Settings are not yet taken from a provided DevMode or
  *    default printer settings.
  */
+
 BOOL WINAPI PrintDlgA(
 		      LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */
@@ -1441,8 +2354,4 @@
     LPVOID   ptr;
     HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE );
-
-#ifdef __WIN32OS2__
-    dprintf(("PrintDlgA %x", lppd));
-#endif
 
     if(TRACE_ON(commdlg)) {
@@ -1464,5 +2373,5 @@
         WARN("structure size failure !!!\n");
 	COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE);
-	return FALSE; 
+	return FALSE;
     }
 
@@ -1475,10 +2384,10 @@
 	if(lppd->hDevMode || lppd->hDevNames) {
 	    WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
-	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
 	    return FALSE;
 	}
         if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
 	    WARN("Can't find default printer\n");
-	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
 	    return FALSE;
 	}
@@ -1492,5 +2401,5 @@
 	if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) {
 	    ERR("GetPrinterDriverA failed, le %ld, fix your config for printer %s!\n",GetLastError(),pbuf->pPrinterName);
-	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
 	    return FALSE;
 	}
@@ -1514,8 +2423,8 @@
 	PRINT_PTRA *PrintStructures;
 
-    /* load Dialog resources, 
-     * depending on Flags indicates Print32 or Print32_setup dialog 
+    /* load Dialog resources,
+     * depending on Flags indicates Print32 or Print32_setup dialog
      */
-	hDlgTmpl = PRINTDLG_GetDlgTemplate(lppd);
+	hDlgTmpl = PRINTDLG_GetDlgTemplateA(lppd);
 	if (!hDlgTmpl) {
 	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
@@ -1585,29 +2494,17 @@
     }
     if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC))
-        bRet = PRINTDLG_CreateDC(lppd);
-
-    TRACE("exit! (%d)\n", bRet);        
-    return bRet;    
-}
-
-#ifndef __WIN32OS2__
+        bRet = PRINTDLG_CreateDCA(lppd);
+
+    TRACE("exit! (%d)\n", bRet);
+    return bRet;
+}
+
 /***********************************************************************
- *           PrintDlg   (COMMDLG.20)
- * 
- *  Displays the the PRINT dialog box, which enables the user to specify
- *  specific properties of the print job.
- *
- * RETURNS
- *  nonzero if the user pressed the OK button
- *  zero    if the user cancelled the window or an error occurred
- *
- * BUGS
- *  * calls up to the 32-bit versions of the Dialogs, which look different
- *  * Customizing is *not* implemented.
+ *           PrintDlgW   (COMDLG32.@)
  */
-
-BOOL16 WINAPI PrintDlg16(
-	      LPPRINTDLG16 lppd /* [in/out] ptr to PRINTDLG struct */
-) {
+BOOL WINAPI PrintDlgW(
+		      LPPRINTDLGW lppd /* [in/out] ptr to PRINTDLG32 struct */
+		      )
+{
     BOOL      bRet = FALSE;
     LPVOID   ptr;
@@ -1629,4 +2526,172 @@
     }
 
+    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, sizeof(WCHAR)*needed);
+	GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed);
+
+	GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed);
+	dbuf = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed);
+	if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) {
+	    ERR("GetPrinterDriverA failed, le %ld, fix your config for printer %s!\n",GetLastError(),debugstr_w(pbuf->pPrinterName));
+	    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->dlg.lpPrintDlg = lppd;
+
+	/* and create & process the dialog .
+	 * -1 is failure, 0 is broken hwnd, everything else is ok.
+	 */
+	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;
+}
+
+#ifndef __WIN32OS2__
+/***********************************************************************
+ *           PrintDlg   (COMMDLG.20)
+ *
+ *  Displays the the PRINT dialog box, which enables the user to specify
+ *  specific properties of the print job.
+ *
+ * RETURNS
+ *  nonzero if the user pressed the OK button
+ *  zero    if the user cancelled the window or an error occurred
+ *
+ * BUGS
+ *  * calls up to the 32-bit versions of the Dialogs, which look different
+ *  * Customizing is *not* implemented.
+ */
+
+BOOL16 WINAPI PrintDlg16(
+	      LPPRINTDLG16 lppd /* [in/out] ptr to PRINTDLG struct */
+) {
+    BOOL      bRet = FALSE;
+    LPVOID   ptr;
+    HINSTANCE hInst = GetWindowLongA( HWND_32(lppd->hwndOwner), GWL_HINSTANCE );
+
+    if(TRACE_ON(commdlg)) {
+        char flagstr[1000] = "";
+	struct pd_flags *pflag = pd_flags;
+	for( ; pflag->name; pflag++) {
+	    if(lppd->Flags & pflag->flag)
+	        strcat(flagstr, pflag->name);
+	}
+	TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
+	      "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n"
+	      "flags %08lx (%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(PRINTDLG16)) {
         ERR("structure size (%ld/%d)\n",lppd->lStructSize,sizeof(PRINTDLG16));
@@ -1643,10 +2708,10 @@
 	if(lppd->hDevMode || lppd->hDevNames) {
 	    WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n");
-	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
 	    return FALSE;
 	}
         if(!PRINTDLG_OpenDefaultPrinter(&hprn)) {
 	    WARN("Can't find default printer\n");
-	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN);
 	    return FALSE;
 	}
@@ -1660,5 +2725,5 @@
 	    ERR("GetPrinterDriverA failed for %s, le %ld, fix your config!\n",
 		    pbuf->pPrinterName,GetLastError());
-	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 
+	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE);
 	    return FALSE;
 	}
@@ -1681,6 +2746,6 @@
 	PRINT_PTRA *PrintStructures;
 
-    /* load Dialog resources, 
-     * depending on Flags indicates Print32 or Print32_setup dialog 
+    /* load Dialog resources,
+     * depending on Flags indicates Print32 or Print32_setup dialog
      */
 	hDlgTmpl = PRINTDLG_GetDlgTemplate16(lppd);
@@ -1695,5 +2760,7 @@
 #define CVAL(x)	PrintStructures->dlg.lpPrintDlg->x = lppd->x;
 #define MVAL(x)	PrintStructures->dlg.lpPrintDlg->x = MapSL(lppd->x);
-	CVAL(Flags);CVAL(hwndOwner);CVAL(hDC);
+	CVAL(Flags);
+	PrintStructures->dlg.lpPrintDlg->hwndOwner = HWND_32(lppd->hwndOwner);
+	CVAL(hDC);
 	CVAL(nFromPage);CVAL(nToPage);CVAL(nMinPage);CVAL(nMaxPage);
 	CVAL(nCopies);CVAL(hInstance);CVAL(lCustData);
@@ -1765,21 +2832,8 @@
         bRet = PRINTDLG_CreateDC16(lppd);
 
-    TRACE("exit! (%d)\n", bRet);        
-    return bRet;    
+    TRACE("exit! (%d)\n", bRet);
+    return bRet;
 }
 #endif
-
-
-/***********************************************************************
- *           PrintDlgW   (COMDLG32.@)
- */
-BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg )
-{
-#ifdef __WIN32OS2__
-    dprintf(("PrintDlgW %x NOT IMPLEMENTED", printdlg));
-#endif
-    FIXME("A really empty stub\n" );
-    return FALSE;
-}
 
 /***********************************************************************
@@ -1799,15 +2853,20 @@
 typedef struct {
     LPPAGESETUPDLGA	dlga;
-
     PRINTDLGA		pdlg;
-} PageSetupData;
-
-static HGLOBAL PRINTDLG_GetPGSTemplate(PAGESETUPDLGA *lppd)
-{
-    HGLOBAL hDlgTmpl, hResInfo;
+} PageSetupDataA;
+
+typedef struct {
+    LPPAGESETUPDLGW	dlga;
+    PRINTDLGW		pdlg;
+} PageSetupDataW;
+
+static HGLOBAL PRINTDLG_GetPGSTemplateA(PAGESETUPDLGA *lppd)
+{
+    HRSRC hResInfo;
+    HGLOBAL hDlgTmpl;
 
     if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) {
 	hDlgTmpl = lppd->hPageSetupTemplate;
-    } else if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATE) {	
+    } else if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATE) {
 	hResInfo = FindResourceA(lppd->hInstance,
 				 lppd->lpPageSetupTemplateName, RT_DIALOGA);
@@ -1815,4 +2874,22 @@
     } else {
 	hResInfo = FindResourceA(COMDLG32_hInstance,(LPCSTR)PAGESETUPDLGORD,RT_DIALOGA);
+	hDlgTmpl = LoadResource(COMDLG32_hInstance,hResInfo);
+    }
+    return hDlgTmpl;
+}
+
+static HGLOBAL PRINTDLG_GetPGSTemplateW(PAGESETUPDLGW *lppd)
+{
+    HRSRC hResInfo;
+    HGLOBAL hDlgTmpl;
+
+    if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) {
+	hDlgTmpl = lppd->hPageSetupTemplate;
+    } else if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATE) {
+	hResInfo = FindResourceW(lppd->hInstance,
+				 lppd->lpPageSetupTemplateName, RT_DIALOGW);
+	hDlgTmpl = LoadResource(lppd->hInstance, hResInfo);
+    } else {
+	hResInfo = FindResourceW(COMDLG32_hInstance,(LPCWSTR)PAGESETUPDLGORD,RT_DIALOGW);
 	hDlgTmpl = LoadResource(COMDLG32_hInstance,hResInfo);
     }
@@ -1828,5 +2905,4 @@
      */
     dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
-    FIXME("returning %ld/100 mm \n",size);
     return 10*size;
 }
@@ -1847,5 +2923,5 @@
 
 static void
-_c_size2str(PageSetupData *pda,DWORD size,LPSTR strout) {
+_c_size2strA(PageSetupDataA *pda,DWORD size,LPSTR strout) {
     strcpy(strout,"<undef>");
     if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) {
@@ -1861,7 +2937,22 @@
     return;
 }
+static void
+_c_size2strW(PageSetupDataW *pda,DWORD size,LPSTR strout) {
+    strcpy(strout,"<undef>");
+    if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) {
+	sprintf(strout,"%.2fmm",(size*1.0)/100.0);
+	return;
+    }
+    if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) {
+	sprintf(strout,"%.2fin",(size*1.0)/1000.0);
+	return;
+    }
+    pda->dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
+    sprintf(strout,"%.2fmm",(size*1.0)/100.0);
+    return;
+}
 
 static DWORD
-_c_str2size(PageSetupData *pda,LPCSTR strin) {
+_c_str2size(PAGESETUPDLGA *dlga,LPCSTR strin) {
     float	val;
     char	rest[200];
@@ -1872,5 +2963,5 @@
 
     if (!strcmp(rest,"in") || !strcmp(rest,"inch")) {
-	if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES)
+	if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES)
 	    return 1000*val;
 	else
@@ -1881,5 +2972,5 @@
 
     if (!strcmp(rest,"mm")) {
-	if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
+	if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
 	    return 100*val;
 	else
@@ -1888,9 +2979,9 @@
     if (rest[0]=='\0') {
 	/* use application supplied default */
-	if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) {
+	if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) {
 	    /* 100*mm */
 	    return 100.0*val;
 	}
-	if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) {
+	if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) {
 	    /* 1000*inch */
 	    return 1000.0*val;
@@ -1907,5 +2998,5 @@
  */
 static BOOL
-PRINTDLG_PS_UpdateDlgStruct(HWND hDlg, PageSetupData *pda) {
+PRINTDLG_PS_UpdateDlgStructA(HWND hDlg, PageSetupDataA *pda) {
     DEVNAMES	*dn;
     DEVMODEA	*dm;
@@ -1913,19 +3004,19 @@
     char	papername[64];
     char	buf[200];
-    
+
     dn = GlobalLock(pda->pdlg.hDevNames);
     dm = GlobalLock(pda->pdlg.hDevMode);
     devname	= ((char*)dn)+dn->wDeviceOffset;
     portname	= ((char*)dn)+dn->wOutputOffset;
-    PRINTDLG_SetUpPaperComboBox(hDlg,cmb2,devname,portname,dm);
-    PRINTDLG_SetUpPaperComboBox(hDlg,cmb3,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm);
 
     if (GetDlgItemTextA(hDlg,cmb2,papername,sizeof(papername))>0) {
-    	PRINTDLG_PaperSize(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize));
+    	PRINTDLG_PaperSizeA(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize));
 	pda->dlga->ptPaperSize.x = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.x);
 	pda->dlga->ptPaperSize.y = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.y);
     } else
 	FIXME("could not get dialog text for papersize cmbbox?\n");
-#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size(pda,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); }
+#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size(pda->dlga,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); }
     GETVAL(edt4,pda->dlga->rtMargin.left);
     GETVAL(edt5,pda->dlga->rtMargin.top);
@@ -1946,19 +3037,60 @@
 }
 
+static BOOL
+PRINTDLG_PS_UpdateDlgStructW(HWND hDlg, PageSetupDataW *pda) {
+    DEVNAMES	*dn;
+    DEVMODEW	*dm;
+    LPWSTR	devname,portname;
+    WCHAR	papername[64];
+
+    char	buf[200];
+
+    dn = GlobalLock(pda->pdlg.hDevNames);
+    dm = GlobalLock(pda->pdlg.hDevMode);
+    devname	= ((WCHAR*)dn)+dn->wDeviceOffset;
+    portname	= ((WCHAR*)dn)+dn->wOutputOffset;
+    PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb2,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb3,devname,portname,dm);
+
+    if (GetDlgItemTextW(hDlg,cmb2,papername,sizeof(papername))>0) {
+    	PRINTDLG_PaperSizeW(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize));
+	pda->dlga->ptPaperSize.x = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga,pda->dlga->ptPaperSize.x);
+	pda->dlga->ptPaperSize.y = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga,pda->dlga->ptPaperSize.y);
+    } else
+	FIXME("could not get dialog text for papersize cmbbox?\n");
+#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size((LPPAGESETUPDLGA)pda->dlga,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); }
+    GETVAL(edt4,pda->dlga->rtMargin.left);
+    GETVAL(edt5,pda->dlga->rtMargin.top);
+    GETVAL(edt6,pda->dlga->rtMargin.right);
+    GETVAL(edt7,pda->dlga->rtMargin.bottom);
+#undef GETVAL
+
+    /* If we are in landscape, swap x and y of page size */
+    if (IsDlgButtonChecked(hDlg, rad2)) {
+	DWORD tmp;
+	tmp = pda->dlga->ptPaperSize.x;
+	pda->dlga->ptPaperSize.x = pda->dlga->ptPaperSize.y;
+	pda->dlga->ptPaperSize.y = tmp;
+    }
+    GlobalUnlock(pda->pdlg.hDevNames);
+    GlobalUnlock(pda->pdlg.hDevMode);
+    return TRUE;
+}
+
 /*
  * This is called after returning from PrintDlg().
  */
 static BOOL
-PRINTDLG_PS_ChangePrinter(HWND hDlg, PageSetupData *pda) {
+PRINTDLG_PS_ChangePrinterA(HWND hDlg, PageSetupDataA *pda) {
     DEVNAMES	*dn;
     DEVMODEA	*dm;
     LPSTR	devname,portname;
-    
+
     dn = GlobalLock(pda->pdlg.hDevNames);
     dm = GlobalLock(pda->pdlg.hDevMode);
     devname	= ((char*)dn)+dn->wDeviceOffset;
     portname	= ((char*)dn)+dn->wOutputOffset;
-    PRINTDLG_SetUpPaperComboBox(hDlg,cmb2,devname,portname,dm);
-    PRINTDLG_SetUpPaperComboBox(hDlg,cmb3,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm);
     GlobalUnlock(pda->pdlg.hDevNames);
     GlobalUnlock(pda->pdlg.hDevMode);
@@ -1967,10 +3099,27 @@
 
 static BOOL
-PRINTDLG_PS_WMCommand(
-    HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupData *pda
+PRINTDLG_PS_ChangePrinterW(HWND hDlg, PageSetupDataW *pda) {
+    DEVNAMES	*dn;
+    DEVMODEW	*dm;
+    LPWSTR	devname,portname;
+
+    dn = GlobalLock(pda->pdlg.hDevNames);
+    dm = GlobalLock(pda->pdlg.hDevMode);
+    devname	= ((WCHAR*)dn)+dn->wDeviceOffset;
+    portname	= ((WCHAR*)dn)+dn->wOutputOffset;
+    PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb2,devname,portname,dm);
+    PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb3,devname,portname,dm);
+    GlobalUnlock(pda->pdlg.hDevNames);
+    GlobalUnlock(pda->pdlg.hDevMode);
+    return TRUE;
+}
+
+static BOOL
+PRINTDLG_PS_WMCommandA(
+    HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataA *pda
 ) {
     switch (LOWORD(wParam))  {
     case IDOK:
-        if (!PRINTDLG_PS_UpdateDlgStruct(hDlg, pda))
+        if (!PRINTDLG_PS_UpdateDlgStructA(hDlg, pda))
 	    return(FALSE);
 	EndDialog(hDlg, TRUE);
@@ -1985,5 +3134,5 @@
 	pda->pdlg.hwndOwner	= hDlg;
 	if (PrintDlgA(&(pda->pdlg)))
-	    PRINTDLG_PS_ChangePrinter(hDlg,pda);
+	    PRINTDLG_PS_ChangePrinterA(hDlg,pda);
 	return TRUE;
     }
@@ -1995,14 +3144,43 @@
 }
 
+static BOOL
+PRINTDLG_PS_WMCommandW(
+    HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataW *pda
+) {
+    switch (LOWORD(wParam))  {
+    case IDOK:
+        if (!PRINTDLG_PS_UpdateDlgStructW(hDlg, pda))
+	    return(FALSE);
+	EndDialog(hDlg, TRUE);
+	return TRUE ;
+
+    case IDCANCEL:
+        EndDialog(hDlg, FALSE);
+	return FALSE ;
+
+    case psh3: {
+	pda->pdlg.Flags		= 0;
+	pda->pdlg.hwndOwner	= hDlg;
+	if (PrintDlgW(&(pda->pdlg)))
+	    PRINTDLG_PS_ChangePrinterW(hDlg,pda);
+	return TRUE;
+    }
+    }
+    FIXME("loword (lparam) %d, wparam 0x%x, lparam %08lx, STUB mostly.\n",
+	    LOWORD(lParam),wParam,lParam
+    );
+    return FALSE;
+}
+
 
 static BOOL WINAPI
 PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    PageSetupData	*pda;
+    PageSetupDataA	*pda;
     BOOL		res = FALSE;
 
     if (uMsg==WM_INITDIALOG) {
 	res = TRUE;
-        pda = (PageSetupData*)lParam;
+        pda = (PageSetupDataA*)lParam;
 	SetPropA(hDlg,"__WINE_PAGESETUPDLGDATA",lParam);
 	if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) {
@@ -2017,10 +3195,10 @@
 	}
 	if (pda->dlga->Flags & PSD_DISABLEPRINTER)
-            EnableWindow(GetDlgItem(hDlg, psh3), FALSE);    
+            EnableWindow(GetDlgItem(hDlg, psh3), FALSE);
 	if (pda->dlga->Flags & PSD_DISABLEMARGINS) {
-            EnableWindow(GetDlgItem(hDlg, edt4), FALSE);    
-            EnableWindow(GetDlgItem(hDlg, edt5), FALSE);    
-            EnableWindow(GetDlgItem(hDlg, edt6), FALSE);    
-            EnableWindow(GetDlgItem(hDlg, edt7), FALSE);    
+            EnableWindow(GetDlgItem(hDlg, edt4), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt5), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt6), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt7), FALSE);
 	}
 	/* width larger as height -> landscape */
@@ -2036,11 +3214,11 @@
 	if (pda->dlga->Flags & PSD_MARGINS) {
 	    char str[100];
-	    _c_size2str(pda,pda->dlga->rtMargin.left,str);
+	    _c_size2strA(pda,pda->dlga->rtMargin.left,str);
 	    SetDlgItemTextA(hDlg,edt4,str);
-	    _c_size2str(pda,pda->dlga->rtMargin.top,str);
+	    _c_size2strA(pda,pda->dlga->rtMargin.top,str);
 	    SetDlgItemTextA(hDlg,edt5,str);
-	    _c_size2str(pda,pda->dlga->rtMargin.right,str);
+	    _c_size2strA(pda,pda->dlga->rtMargin.right,str);
 	    SetDlgItemTextA(hDlg,edt6,str);
-	    _c_size2str(pda,pda->dlga->rtMargin.bottom,str);
+	    _c_size2strA(pda,pda->dlga->rtMargin.bottom,str);
 	    SetDlgItemTextA(hDlg,edt7,str);
 	} else {
@@ -2048,5 +3226,5 @@
 	    DWORD size = _c_inch2size(pda->dlga,1000);
 	    char	str[20];
-	    _c_size2str(pda,size,str);
+	    _c_size2strA(pda,size,str);
 	    SetDlgItemTextA(hDlg,edt4,str);
 	    SetDlgItemTextA(hDlg,edt5,str);
@@ -2054,5 +3232,5 @@
 	    SetDlgItemTextA(hDlg,edt7,str);
 	}
-	PRINTDLG_PS_ChangePrinter(hDlg,pda);
+	PRINTDLG_PS_ChangePrinterA(hDlg,pda);
 	if (pda->dlga->Flags & PSD_DISABLEPAPER) {
 	    EnableWindow(GetDlgItem(hDlg,cmb2),FALSE);
@@ -2061,5 +3239,5 @@
 	return TRUE;
     } else {
-	pda = (PageSetupData*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA");
+	pda = (PageSetupDataA*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA");
 	if (!pda) {
 	    WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
@@ -2073,5 +3251,87 @@
     switch (uMsg) {
     case WM_COMMAND:
-        return PRINTDLG_PS_WMCommand(hDlg, wParam, lParam, pda);
+        return PRINTDLG_PS_WMCommandA(hDlg, wParam, lParam, pda);
+    }
+    return FALSE;
+}
+
+static BOOL WINAPI
+PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    PageSetupDataW	*pda;
+    BOOL		res = FALSE;
+
+    if (uMsg==WM_INITDIALOG) {
+	res = TRUE;
+        pda = (PageSetupDataW*)lParam;
+	SetPropA(hDlg,"__WINE_PAGESETUPDLGDATA",lParam);
+	if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) {
+	    res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,lParam);
+	    if (!res) {
+		FIXME("Setup page hook failed?\n");
+		res = TRUE;
+	    }
+	}
+	if (pda->dlga->Flags & PSD_ENABLEPAGEPAINTHOOK) {
+	    FIXME("PagePaintHook not yet implemented!\n");
+	}
+	if (pda->dlga->Flags & PSD_DISABLEPRINTER)
+            EnableWindow(GetDlgItem(hDlg, psh3), FALSE);
+	if (pda->dlga->Flags & PSD_DISABLEMARGINS) {
+            EnableWindow(GetDlgItem(hDlg, edt4), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt5), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt6), FALSE);
+            EnableWindow(GetDlgItem(hDlg, edt7), FALSE);
+	}
+	/* width larger as height -> landscape */
+	if (pda->dlga->ptPaperSize.x > pda->dlga->ptPaperSize.y)
+            CheckRadioButton(hDlg, rad1, rad2, rad2);
+	else /* this is default if papersize is not set */
+            CheckRadioButton(hDlg, rad1, rad2, rad1);
+	if (pda->dlga->Flags & PSD_DISABLEORIENTATION) {
+	    EnableWindow(GetDlgItem(hDlg,rad1),FALSE);
+	    EnableWindow(GetDlgItem(hDlg,rad2),FALSE);
+	}
+	/* We fill them out enabled or not */
+	if (pda->dlga->Flags & PSD_MARGINS) {
+	    char str[100];
+	    _c_size2strW(pda,pda->dlga->rtMargin.left,str);
+	    SetDlgItemTextA(hDlg,edt4,str);
+	    _c_size2strW(pda,pda->dlga->rtMargin.top,str);
+	    SetDlgItemTextA(hDlg,edt5,str);
+	    _c_size2strW(pda,pda->dlga->rtMargin.right,str);
+	    SetDlgItemTextA(hDlg,edt6,str);
+	    _c_size2strW(pda,pda->dlga->rtMargin.bottom,str);
+	    SetDlgItemTextA(hDlg,edt7,str);
+	} else {
+	    /* default is 1 inch */
+	    DWORD size = _c_inch2size((LPPAGESETUPDLGA)pda->dlga,1000);
+	    char	str[20];
+	    _c_size2strW(pda,size,str);
+	    SetDlgItemTextA(hDlg,edt4,str);
+	    SetDlgItemTextA(hDlg,edt5,str);
+	    SetDlgItemTextA(hDlg,edt6,str);
+	    SetDlgItemTextA(hDlg,edt7,str);
+	}
+	PRINTDLG_PS_ChangePrinterW(hDlg,pda);
+	if (pda->dlga->Flags & PSD_DISABLEPAPER) {
+	    EnableWindow(GetDlgItem(hDlg,cmb2),FALSE);
+	    EnableWindow(GetDlgItem(hDlg,cmb3),FALSE);
+	}
+	return TRUE;
+    } else {
+	pda = (PageSetupDataW*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA");
+	if (!pda) {
+	    WARN("__WINE_PAGESETUPDLGDATA prop not set?\n");
+	    return FALSE;
+	}
+	if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) {
+	    res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,lParam);
+	    if (res) return res;
+	}
+    }
+    switch (uMsg) {
+    case WM_COMMAND:
+        return PRINTDLG_PS_WMCommandW(hDlg, wParam, lParam, pda);
     }
     return FALSE;
@@ -2085,10 +3345,6 @@
     LPVOID		ptr;
     BOOL		bRet;
-    PageSetupData	*pda;
+    PageSetupDataA	*pda;
     PRINTDLGA		pdlg;
-
-#ifdef __WIN32OS2__
-    dprintf(("PageSetupDlgA %x", setupdlg));
-#endif
 
     if(TRACE_ON(commdlg)) {
@@ -2104,5 +3360,5 @@
 	      "hinst %08x, flags %08lx (%s)\n",
 	      setupdlg, setupdlg->hwndOwner, setupdlg->hDevMode,
-	      setupdlg->hDevNames, 
+	      setupdlg->hDevNames,
 	      setupdlg->hInstance, setupdlg->Flags, flagstr);
     }
@@ -2120,10 +3376,10 @@
 	setupdlg->hDevNames	= pdlg.hDevNames;
 	/* FIXME: Just return "A4" for now. */
-    	PRINTDLG_PaperSize(&pdlg,"A4",&setupdlg->ptPaperSize);
+    	PRINTDLG_PaperSizeA(&pdlg,"A4",&setupdlg->ptPaperSize);
 	setupdlg->ptPaperSize.x=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.x);
 	setupdlg->ptPaperSize.y=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.y);
 	return TRUE;
     }
-    hDlgTmpl = PRINTDLG_GetPGSTemplate(setupdlg);
+    hDlgTmpl = PRINTDLG_GetPGSTemplateA(setupdlg);
     if (!hDlgTmpl) {
 	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
@@ -2152,9 +3408,66 @@
  */
 BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) {
-#ifdef __WIN32OS2__
-    dprintf(("PageSetupDlgA %x NOT IMPLEMENTED", setupdlg));
-#endif
-	FIXME("(%p), stub!\n",setupdlg);
+    HGLOBAL		hDlgTmpl;
+    LPVOID		ptr;
+    BOOL		bRet;
+    PageSetupDataW	*pdw;
+    PRINTDLGW		pdlg;
+
+    if(TRACE_ON(commdlg)) {
+        char flagstr[1000] = "";
+	struct pd_flags *pflag = psd_flags;
+	for( ; pflag->name; pflag++) {
+	    if(setupdlg->Flags & pflag->flag) {
+	        strcat(flagstr, pflag->name);
+	        strcat(flagstr, "|");
+	    }
+	}
+	TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n"
+	      "hinst %08x, flags %08lx (%s)\n",
+	      setupdlg, setupdlg->hwndOwner, setupdlg->hDevMode,
+	      setupdlg->hDevNames,
+	      setupdlg->hInstance, setupdlg->Flags, flagstr);
+    }
+
+    /* First get default printer data, we need it right after that. */
+    memset(&pdlg,0,sizeof(pdlg));
+    pdlg.lStructSize	= sizeof(pdlg);
+    pdlg.Flags		= PD_RETURNDEFAULT;
+    bRet = PrintDlgW(&pdlg);
+    if (!bRet) return FALSE;
+
+    /* short cut exit, just return default values */
+    if (setupdlg->Flags & PSD_RETURNDEFAULT) {
+        const WCHAR a4[] = {'A','4',0};
+	setupdlg->hDevMode	= pdlg.hDevMode;
+	setupdlg->hDevNames	= pdlg.hDevNames;
+	/* FIXME: Just return "A4" for now. */
+    	PRINTDLG_PaperSizeW(&pdlg,a4,&setupdlg->ptPaperSize);
+	setupdlg->ptPaperSize.x=_c_10mm2size((LPPAGESETUPDLGA)setupdlg,setupdlg->ptPaperSize.x);
+	setupdlg->ptPaperSize.y=_c_10mm2size((LPPAGESETUPDLGA)setupdlg,setupdlg->ptPaperSize.y);
+	return TRUE;
+    }
+    hDlgTmpl = PRINTDLG_GetPGSTemplateW(setupdlg);
+    if (!hDlgTmpl) {
+	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
 	return FALSE;
+    }
+    ptr = LockResource( hDlgTmpl );
+    if (!ptr) {
+	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
+	return FALSE;
+    }
+    pdw = HeapAlloc(GetProcessHeap(),0,sizeof(*pdw));
+    pdw->dlga = setupdlg;
+    memcpy(&pdw->pdlg,&pdlg,sizeof(pdlg));
+
+    bRet = (0<DialogBoxIndirectParamW(
+		setupdlg->hInstance,
+		ptr,
+		setupdlg->hwndOwner,
+		PageDlgProcW,
+		(LPARAM)pdw)
+    );
+    return bRet;
 }
 
@@ -2168,17 +3481,18 @@
  *           PrintDlgProc   (COMMDLG.21)
  */
-LRESULT WINAPI PrintDlgProc16(HWND16 hDlg, UINT16 uMsg, WPARAM16 wParam,
+LRESULT WINAPI PrintDlgProc16(HWND16 hDlg16, UINT16 uMsg, WPARAM16 wParam,
                             LPARAM lParam)
 {
+    HWND hDlg = HWND_32(hDlg16);
     PRINT_PTRA* PrintStructures;
     LRESULT res=FALSE;
 
     if (uMsg!=WM_INITDIALOG) {
-        PrintStructures = (PRINT_PTRA*) GetWindowLongA(hDlg, DWL_USER);   
+        PrintStructures = (PRINT_PTRA*)GetPropA(hDlg,"__WINE_PRINTDLGDATA");
 	if (!PrintStructures)
 	    return FALSE;
     } else {
         PrintStructures = (PRINT_PTRA*) lParam;
-	SetWindowLongA(hDlg, DWL_USER, lParam); 
+	SetPropA(hDlg,"__WINE_PRINTDLGDATA",lParam);
 	res = PRINTDLG_WMInitDialog16(hDlg, wParam, PrintStructures);
 
@@ -2186,14 +3500,14 @@
 	    res = CallWindowProc16(
 		(WNDPROC16)PrintStructures->dlg.lpPrintDlg16->lpfnPrintHook,
-		hDlg, uMsg, wParam, (LPARAM)PrintStructures->dlg.lpPrintDlg16
+		hDlg16, uMsg, wParam, (LPARAM)PrintStructures->dlg.lpPrintDlg16
 	    );
 	}
 	return res;
     }
-  
+
     if(PrintStructures->dlg.lpPrintDlg16->Flags & PD_ENABLEPRINTHOOK) {
         res = CallWindowProc16(
 		(WNDPROC16)PrintStructures->dlg.lpPrintDlg16->lpfnPrintHook,
-		hDlg,uMsg, wParam, lParam
+		hDlg16,uMsg, wParam, lParam
 	);
 	if(LOWORD(res)) return res;
@@ -2205,5 +3519,5 @@
 	  * with 32Ato16 mapper in winproc.c
 	  */
-        return PRINTDLG_WMCommand(
+        return PRINTDLG_WMCommandA(
 		hDlg,
 		MAKEWPARAM(wParam,HIWORD(lParam)),
@@ -2218,5 +3532,5 @@
 
         return FALSE;
-    }    
+    }
     return res;
 }
@@ -2226,7 +3540,8 @@
  *           PrintSetupDlgProc   (COMMDLG.22)
  */
-LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd, UINT16 wMsg, WPARAM16 wParam,
+LRESULT WINAPI PrintSetupDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam,
 				   LPARAM lParam)
 {
+  HWND hWnd = HWND_32(hWnd16);
   switch (wMsg)
     {
