| /* | 
 |  * COMMDLG - Print Dialog | 
 |  * | 
 |  * Copyright 1994 Martin Ayotte | 
 |  * Copyright 1996 Albrecht Kleine | 
 |  * 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> | 
 | #include <stdlib.h> | 
 | #include <stdarg.h> | 
 | #include <stdio.h> | 
 | #include <string.h> | 
 |  | 
 | #define NONAMELESSUNION | 
 | #define NONAMELESSSTRUCT | 
 | #include "windef.h" | 
 | #include "winbase.h" | 
 | #include "wingdi.h" | 
 | #include "wine/wingdi16.h" | 
 | #include "winuser.h" | 
 | #include "wine/winuser16.h" | 
 | #include "commdlg.h" | 
 | #include "dlgs.h" | 
 | #include "wine/debug.h" | 
 | #include "cderr.h" | 
 | #include "winspool.h" | 
 | #include "winerror.h" | 
 |  | 
 | WINE_DEFAULT_DEBUG_CHANNEL(commdlg); | 
 |  | 
 | #include "cdlg.h" | 
 | #include "cdlg16.h" | 
 | #include "printdlg.h" | 
 |  | 
 | typedef struct | 
 | { | 
 |     PRINT_PTRA   print32; | 
 |     LPPRINTDLG16 lpPrintDlg16; | 
 | } PRINT_PTRA16; | 
 |  | 
 | /* Internal Functions */ | 
 |  | 
 | static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName, | 
 | 				      char* DeviceName, char* OutputPort) | 
 | { | 
 |     long size; | 
 |     char*   pDevNamesSpace; | 
 |     char*   pTempPtr; | 
 |     LPDEVNAMES lpDevNames; | 
 |     char buf[260]; | 
 |     DWORD dwBufLen = sizeof(buf); | 
 |  | 
 |     size = strlen(DeviceDriverName) + 1 | 
 |             + strlen(DeviceName) + 1 | 
 |             + strlen(OutputPort) + 1 | 
 |             + sizeof(DEVNAMES); | 
 |  | 
 |     if(*hmem) | 
 |         *hmem = GlobalReAlloc16(*hmem, size, GMEM_MOVEABLE); | 
 |     else | 
 |         *hmem = GlobalAlloc16(GMEM_MOVEABLE, size); | 
 |     if (*hmem == 0) | 
 |         return FALSE; | 
 |  | 
 |     pDevNamesSpace = GlobalLock16(*hmem); | 
 |     lpDevNames = (LPDEVNAMES) pDevNamesSpace; | 
 |  | 
 |     pTempPtr = pDevNamesSpace + sizeof(DEVNAMES); | 
 |     strcpy(pTempPtr, DeviceDriverName); | 
 |     lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; | 
 |  | 
 |     pTempPtr += strlen(DeviceDriverName) + 1; | 
 |     strcpy(pTempPtr, DeviceName); | 
 |     lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; | 
 |  | 
 |     pTempPtr += strlen(DeviceName) + 1; | 
 |     strcpy(pTempPtr, OutputPort); | 
 |     lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; | 
 |  | 
 |     GetDefaultPrinterA(buf, &dwBufLen); | 
 |     lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; | 
 |     GlobalUnlock16(*hmem); | 
 |     return TRUE; | 
 | } | 
 |  | 
 |  | 
 | /*********************************************************************** | 
 |  *           PRINTDLG_WMInitDialog                      [internal] | 
 |  */ | 
 | static LRESULT PRINTDLG_WMInitDialog16(HWND hDlg, WPARAM wParam, PRINT_PTRA16* ptr16) | 
 | { | 
 |     PRINT_PTRA *PrintStructures = &ptr16->print32; | 
 |     LPPRINTDLG16 lppd = ptr16->lpPrintDlg16; | 
 |     DEVNAMES *pdn; | 
 |     DEVMODEA *pdm; | 
 |     char *name = NULL; | 
 |     UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; | 
 |  | 
 |     /* load Collate ICONs */ | 
 |     PrintStructures->hCollateIcon = | 
 |       LoadIconA(COMDLG32_hInstance, "PD32_COLLATE"); | 
 |     PrintStructures->hNoCollateIcon = | 
 |       LoadIconA(COMDLG32_hInstance, "PD32_NOCOLLATE"); | 
 |     if(PrintStructures->hCollateIcon == 0 || | 
 |        PrintStructures->hNoCollateIcon == 0) { | 
 |         ERR("no icon in resourcefile\n"); | 
 | 	COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); | 
 | 	EndDialog(hDlg, FALSE); | 
 |     } | 
 |  | 
 |     /* load Paper Orientation ICON */ | 
 |     /* FIXME: not implemented yet */ | 
 |  | 
 |     /* | 
 |      * 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)) { | 
 | 	/* We have a print quality combo box. What shall we do? */ | 
 | 	if (GetDlgItem(hDlg,cmb1)) { | 
 | 	    char buf [20]; | 
 |  | 
 | 	    FIXME("Print quality only displaying currently.\n"); | 
 |  | 
 | 	    pdm = GlobalLock16(lppd->hDevMode); | 
 | 	    if(pdm) { | 
 | 		switch (pdm->dmPrintQuality) { | 
 | 		case DMRES_HIGH		: strcpy(buf,"High");break; | 
 | 		case DMRES_MEDIUM	: strcpy(buf,"Medium");break; | 
 | 		case DMRES_LOW		: strcpy(buf,"Low");break; | 
 | 		case DMRES_DRAFT	: strcpy(buf,"Draft");break; | 
 | 		case 0			: strcpy(buf,"Default");break; | 
 | 		default			: sprintf(buf,"%ddpi",pdm->dmPrintQuality);break; | 
 | 		} | 
 | 	        GlobalUnlock16(lppd->hDevMode); | 
 | 	    } else | 
 | 		strcpy(buf,"Default"); | 
 | 	    SendDlgItemMessageA(hDlg,cmb1,CB_ADDSTRING,0,(LPARAM)buf); | 
 | 	    SendDlgItemMessageA(hDlg,cmb1,CB_SETCURSEL,0,0); | 
 | 	    EnableWindow(GetDlgItem(hDlg,cmb1),FALSE); | 
 | 	} | 
 |     } | 
 |  | 
 |     /* 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 the printer combo box is in the dialog, fill it */ | 
 |     if (GetDlgItem(hDlg,comboID)) { | 
 | 	/* Fill Combobox | 
 | 	 */ | 
 | 	pdn = GlobalLock16(lppd->hDevNames); | 
 | 	pdm = GlobalLock16(lppd->hDevMode); | 
 | 	if(pdn) | 
 | 	    name = (char*)pdn + pdn->wDeviceOffset; | 
 | 	else if(pdm) | 
 | 	    name = pdm->dmDeviceName; | 
 | 	PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); | 
 | 	if(pdm) GlobalUnlock16(lppd->hDevMode); | 
 | 	if(pdn) GlobalUnlock16(lppd->hDevNames); | 
 |  | 
 | 	/* Now find selected printer and update rest of dlg */ | 
 | 	name = HeapAlloc(GetProcessHeap(),0,256); | 
 | 	if (GetDlgItemTextA(hDlg, comboID, name, 255)) | 
 | 	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); | 
 |     } else { | 
 | 	/* else just use default printer */ | 
 | 	char name[200]; | 
 |         DWORD dwBufLen = sizeof(name); | 
 | 	BOOL ret = GetDefaultPrinterA(name, &dwBufLen); | 
 |  | 
 | 	if (ret) | 
 | 	    PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); | 
 | 	else | 
 | 	    FIXME("No default printer found, expect problems!\n"); | 
 |     } | 
 |     HeapFree(GetProcessHeap(),0,name); | 
 |  | 
 |     return TRUE; | 
 | } | 
 |  | 
 | /************************************************************ | 
 |  * | 
 |  *      PRINTDLG_Get16TemplateFrom32             [Internal] | 
 |  *      Generates a 16 bits template from the Wine 32 bits resource | 
 |  * | 
 |  */ | 
 | static HGLOBAL16 PRINTDLG_Get16TemplateFrom32(LPCSTR PrintResourceName) | 
 | { | 
 | 	HRSRC hResInfo; | 
 | 	HGLOBAL hDlgTmpl32; | 
 |         LPCVOID template32; | 
 |         DWORD size; | 
 |         HGLOBAL16 hGlobal16; | 
 |         LPVOID template; | 
 |  | 
 |         if (!(hResInfo = FindResourceA(COMDLG32_hInstance, | 
 |                PrintResourceName, (LPSTR)RT_DIALOG))) | 
 |         { | 
 |             COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE); | 
 |             return 0; | 
 |         } | 
 |         if (!(hDlgTmpl32 = LoadResource(COMDLG32_hInstance, hResInfo )) || | 
 |             !(template32 = LockResource( hDlgTmpl32 ))) | 
 |         { | 
 |             COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); | 
 |             return 0; | 
 |         } | 
 |         size = SizeofResource(COMDLG32_hInstance, hResInfo); | 
 |         hGlobal16 = GlobalAlloc16(0, size); | 
 |         if (!hGlobal16) | 
 |         { | 
 |             COMDLG32_SetCommDlgExtendedError(CDERR_MEMALLOCFAILURE); | 
 |             ERR("alloc failure for %ld bytes\n", size); | 
 |             return 0; | 
 |         } | 
 |         template = GlobalLock16(hGlobal16); | 
 |         if (!template) | 
 |         { | 
 |             COMDLG32_SetCommDlgExtendedError(CDERR_MEMLOCKFAILURE); | 
 |             ERR("global lock failure for %x handle\n", hGlobal16); | 
 |             GlobalFree16(hGlobal16); | 
 |             return 0; | 
 |         } | 
 |         ConvertDialog32To16((LPVOID)template32, size, (LPVOID)template); | 
 |         GlobalUnlock16(hGlobal16); | 
 |         return hGlobal16; | 
 | } | 
 |  | 
 | static BOOL PRINTDLG_CreateDC16(LPPRINTDLG16 lppd) | 
 | { | 
 |     DEVNAMES *pdn = GlobalLock16(lppd->hDevNames); | 
 |     DEVMODEA *pdm = GlobalLock16(lppd->hDevMode); | 
 |  | 
 |     if(lppd->Flags & PD_RETURNDC) { | 
 |         lppd->hDC = HDC_16(CreateDCA((char*)pdn + pdn->wDriverOffset, | 
 | 			      (char*)pdn + pdn->wDeviceOffset, | 
 | 			      (char*)pdn + pdn->wOutputOffset, | 
 | 			      pdm )); | 
 |     } else if(lppd->Flags & PD_RETURNIC) { | 
 |         lppd->hDC = HDC_16(CreateICA((char*)pdn + pdn->wDriverOffset, | 
 | 			      (char*)pdn + pdn->wDeviceOffset, | 
 | 			      (char*)pdn + pdn->wOutputOffset, | 
 | 			      pdm )); | 
 |     } | 
 |     GlobalUnlock16(lppd->hDevNames); | 
 |     GlobalUnlock16(lppd->hDevMode); | 
 |     return lppd->hDC ? TRUE : FALSE; | 
 | } | 
 |  | 
 | /************************************************************ | 
 |  * | 
 |  *      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), (LPSTR)RT_DIALOG); | 
 | 	    hDlgTmpl = LoadResource16(lppd->hInstance, hResInfo); | 
 | 	} else { | 
 | 	    hDlgTmpl = PRINTDLG_Get16TemplateFrom32("PRINT32_SETUP"); | 
 | 	} | 
 |     } else { | 
 | 	if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { | 
 | 	    hDlgTmpl = lppd->hPrintTemplate; | 
 | 	} else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { | 
 | 	    hResInfo = FindResource16(lppd->hInstance, | 
 | 				     MapSL(lppd->lpPrintTemplateName), | 
 | 				     (LPSTR)RT_DIALOG); | 
 | 	    hDlgTmpl = LoadResource16(lppd->hInstance, hResInfo); | 
 | 	} else { | 
 | 	    hDlgTmpl = PRINTDLG_Get16TemplateFrom32("PRINT32"); | 
 | 	} | 
 |     } | 
 |     return hDlgTmpl; | 
 | } | 
 |  | 
 | /********************************************************************** | 
 |  * | 
 |  *      16 bit commdlg | 
 |  */ | 
 |  | 
 | /*********************************************************************** | 
 |  *           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; | 
 |     HINSTANCE16 hInst = GetWindowWord( 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)); | 
 | 	COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); | 
 | 	return FALSE; | 
 |     } | 
 |  | 
 |     if(lppd->Flags & PD_RETURNDEFAULT) { | 
 |         PRINTER_INFO_2A *pbuf; | 
 | 	DRIVER_INFO_3A	*dbuf; | 
 | 	HANDLE hprn; | 
 | 	DWORD needed; | 
 |  | 
 | 	if(lppd->hDevMode || lppd->hDevNames) { | 
 | 	    WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); | 
 | 	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); | 
 | 	    return FALSE; | 
 | 	} | 
 |         if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { | 
 | 	    WARN("Can't find default printer\n"); | 
 | 	    COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); | 
 | 	    return FALSE; | 
 | 	} | 
 |  | 
 | 	GetPrinterA(hprn, 2, NULL, 0, &needed); | 
 | 	pbuf = HeapAlloc(GetProcessHeap(), 0, needed); | 
 | 	GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); | 
 | 	GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); | 
 | 	dbuf = HeapAlloc(GetProcessHeap(),0,needed); | 
 | 	if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { | 
 | 	    ERR("GetPrinterDriverA failed for %s, le %ld, fix your config!\n", | 
 | 		    pbuf->pPrinterName,GetLastError()); | 
 |             HeapFree(GetProcessHeap(), 0, dbuf); | 
 | 	    COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); | 
 | 	    return FALSE; | 
 | 	} | 
 | 	ClosePrinter(hprn); | 
 | 	PRINTDLG_CreateDevNames16(&(lppd->hDevNames), | 
 | 				dbuf->pDriverPath, | 
 | 				pbuf->pPrinterName, | 
 | 				pbuf->pPortName); | 
 | 	lppd->hDevMode = GlobalAlloc16(GMEM_MOVEABLE,pbuf->pDevMode->dmSize+ | 
 | 				     pbuf->pDevMode->dmDriverExtra); | 
 | 	ptr = GlobalLock16(lppd->hDevMode); | 
 | 	memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + | 
 | 	       pbuf->pDevMode->dmDriverExtra); | 
 | 	GlobalUnlock16(lppd->hDevMode); | 
 | 	HeapFree(GetProcessHeap(), 0, pbuf); | 
 | 	HeapFree(GetProcessHeap(), 0, dbuf); | 
 | 	bRet = TRUE; | 
 |     } else { | 
 | 	HGLOBAL16 hDlgTmpl; | 
 | 	PRINT_PTRA *PrintStructures; | 
 | 	PRINT_PTRA16 *ptr16; | 
 |  | 
 |     /* load Dialog resources, | 
 |      * depending on Flags indicates Print32 or Print32_setup dialog | 
 |      */ | 
 | 	hDlgTmpl = PRINTDLG_GetDlgTemplate16(lppd); | 
 | 	if (!hDlgTmpl) { | 
 | 	    COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); | 
 | 	    return FALSE; | 
 | 	} | 
 |         ptr16 = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(PRINT_PTRA16)); | 
 |         ptr16->lpPrintDlg16 = lppd; | 
 |         PrintStructures = &ptr16->print32; | 
 |         PrintStructures->lpPrintDlg = (LPPRINTDLGA)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(PRINTDLGA)); | 
 | #define CVAL(x)	PrintStructures->lpPrintDlg->x = lppd->x; | 
 | #define MVAL(x)	PrintStructures->lpPrintDlg->x = MapSL(lppd->x); | 
 | 	CVAL(Flags); | 
 | 	PrintStructures->lpPrintDlg->hwndOwner = HWND_32(lppd->hwndOwner); | 
 | 	PrintStructures->lpPrintDlg->hDC = HDC_32(lppd->hDC); | 
 | 	CVAL(nFromPage);CVAL(nToPage);CVAL(nMinPage);CVAL(nMaxPage); | 
 | 	CVAL(nCopies); | 
 | 	PrintStructures->lpPrintDlg->hInstance = HINSTANCE_32(lppd->hInstance); | 
 | 	CVAL(lCustData); | 
 | 	MVAL(lpPrintTemplateName);MVAL(lpSetupTemplateName); | 
 | 	/* Don't copy rest, it is 16 bit specific */ | 
 | #undef MVAL | 
 | #undef CVAL | 
 |  | 
 | 	PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(),0,sizeof(DEVMODEA)); | 
 |  | 
 | 	/* and create & process the dialog . | 
 | 	 * -1 is failure, 0 is broken hwnd, everything else is ok. | 
 | 	 */ | 
 | 	bRet =	(0<DialogBoxIndirectParam16( | 
 | 		 hInst, hDlgTmpl, lppd->hwndOwner, | 
 | 		 (DLGPROC16)GetProcAddress16(GetModuleHandle16("COMMDLG"),(LPCSTR)21), | 
 | 		 (LPARAM)PrintStructures | 
 | 		) | 
 | 	); | 
 | 	if (!PrintStructures->lpPrinterInfo) bRet = FALSE; | 
 | 	if(bRet) { | 
 | 	    DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn; | 
 | 	    PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo; | 
 | 	    DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo; | 
 |  | 
 | 	    if (lppd->hDevMode == 0) { | 
 | 	        TRACE(" No hDevMode yet... Need to create my own\n"); | 
 | 		lppd->hDevMode = GlobalAlloc16(GMEM_MOVEABLE, | 
 | 					lpdm->dmSize + lpdm->dmDriverExtra); | 
 | 	    } else { | 
 | 	        WORD locks; | 
 | 		if((locks = (GlobalFlags16(lppd->hDevMode)&GMEM_LOCKCOUNT))) { | 
 | 		    WARN("hDevMode has %d locks on it. Unlocking it now\n", locks); | 
 | 		    while(locks--) { | 
 | 		        GlobalUnlock16(lppd->hDevMode); | 
 | 			TRACE("Now got %d locks\n", locks); | 
 | 		    } | 
 | 		} | 
 | 		lppd->hDevMode = GlobalReAlloc16(lppd->hDevMode, | 
 | 					       lpdm->dmSize + lpdm->dmDriverExtra, | 
 | 					       GMEM_MOVEABLE); | 
 | 	    } | 
 | 	    lpdmReturn = GlobalLock16(lppd->hDevMode); | 
 | 	    memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); | 
 |  | 
 | 	    if (lppd->hDevNames != 0) { | 
 | 	        WORD locks; | 
 | 		if((locks = (GlobalFlags16(lppd->hDevNames)&GMEM_LOCKCOUNT))) { | 
 | 		    WARN("hDevNames has %d locks on it. Unlocking it now\n", locks); | 
 | 		    while(locks--) | 
 | 		        GlobalUnlock16(lppd->hDevNames); | 
 | 		} | 
 | 	    } | 
 | 	    PRINTDLG_CreateDevNames16(&(lppd->hDevNames), | 
 | 		    di->pDriverPath, | 
 | 		    pi->pPrinterName, | 
 | 		    pi->pPortName | 
 | 	    ); | 
 | 	    GlobalUnlock16(lppd->hDevMode); | 
 | 	} | 
 | 	if (!(lppd->Flags & (PD_ENABLESETUPTEMPLATEHANDLE | PD_ENABLESETUPTEMPLATE))) | 
 |             GlobalFree16(hDlgTmpl); /* created from the 32 bits resource */ | 
 | 	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_CreateDC16(lppd); | 
 |  | 
 |     TRACE("exit! (%d)\n", bRet); | 
 |     return bRet; | 
 | } | 
 |  | 
 | /*********************************************************************** | 
 |  *           PrintDlgProc   (COMMDLG.21) | 
 |  */ | 
 | BOOL16 CALLBACK PrintDlgProc16(HWND16 hDlg16, UINT16 uMsg, WPARAM16 wParam, | 
 |                             LPARAM lParam) | 
 | { | 
 |     HWND hDlg = HWND_32(hDlg16); | 
 |     PRINT_PTRA16 *PrintStructures; | 
 |     BOOL16 res = FALSE; | 
 |  | 
 |     if (uMsg!=WM_INITDIALOG) { | 
 |         PrintStructures = (PRINT_PTRA16*)GetPropA(hDlg,"__WINE_PRINTDLGDATA"); | 
 | 	if (!PrintStructures) | 
 | 	    return FALSE; | 
 |     } else { | 
 |         PrintStructures = (PRINT_PTRA16*) lParam; | 
 | 	SetPropA(hDlg,"__WINE_PRINTDLGDATA",PrintStructures); | 
 | 	res = PRINTDLG_WMInitDialog16(hDlg, wParam, PrintStructures); | 
 |  | 
 | 	if(PrintStructures->lpPrintDlg16->Flags & PD_ENABLEPRINTHOOK) { | 
 | 	    res = CallWindowProc16( | 
 | 		(WNDPROC16)PrintStructures->lpPrintDlg16->lpfnPrintHook, | 
 | 		hDlg16, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg16 | 
 | 	    ); | 
 | 	} | 
 | 	return res; | 
 |     } | 
 |  | 
 |     if(PrintStructures->lpPrintDlg16->Flags & PD_ENABLEPRINTHOOK) { | 
 |         res = CallWindowProc16( | 
 | 		(WNDPROC16)PrintStructures->lpPrintDlg16->lpfnPrintHook, | 
 | 		hDlg16,uMsg, wParam, lParam | 
 | 	); | 
 | 	if(LOWORD(res)) return res; | 
 |     } | 
 |  | 
 |     switch (uMsg) { | 
 |     case WM_COMMAND: { | 
 | 	 /* We need to map those for the 32bit window procedure, compare | 
 | 	  * with 32Ato16 mapper in winproc.c | 
 | 	  */ | 
 |         return PRINTDLG_WMCommandA( | 
 | 		hDlg, | 
 | 		MAKEWPARAM(wParam,HIWORD(lParam)), | 
 | 		LOWORD(lParam), | 
 | 		&PrintStructures->print32 | 
 | 	); | 
 |     } | 
 |     case WM_DESTROY: | 
 | 	DestroyIcon(PrintStructures->print32.hCollateIcon); | 
 | 	DestroyIcon(PrintStructures->print32.hNoCollateIcon); | 
 |     /* FIXME: don't forget to delete the paper orientation icons here! */ | 
 |  | 
 |         return FALSE; | 
 |     } | 
 |     return res; | 
 | } | 
 |  | 
 | /*********************************************************************** | 
 |  *           PrintSetupDlgProc   (COMMDLG.22) | 
 |  */ | 
 | BOOL16 CALLBACK PrintSetupDlgProc16(HWND16 hWnd16, UINT16 wMsg, WPARAM16 wParam, | 
 | 				   LPARAM lParam) | 
 | { | 
 |   HWND hWnd = HWND_32(hWnd16); | 
 |   switch (wMsg) | 
 |     { | 
 |     case WM_INITDIALOG: | 
 |       TRACE("WM_INITDIALOG lParam=%08lX\n", lParam); | 
 |       ShowWindow(hWnd, SW_SHOWNORMAL); | 
 |       return (TRUE); | 
 |     case WM_COMMAND: | 
 |       switch (wParam) { | 
 |       case IDOK: | 
 | 	EndDialog(hWnd, TRUE); | 
 | 	return(TRUE); | 
 |       case IDCANCEL: | 
 | 	EndDialog(hWnd, FALSE); | 
 | 	return(TRUE); | 
 |       } | 
 |       return(FALSE); | 
 |     } | 
 |   return FALSE; | 
 | } |