| /* |
| * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| #include <ctype.h> |
| #include <stdlib.h> |
| #include <stdarg.h> |
| #include <stdio.h> |
| #include <string.h> |
| |
| #define NONAMELESSUNION |
| #define NONAMELESSSTRUCT |
| #include "windef.h" |
| #include "winbase.h" |
| #include "wingdi.h" |
| #include "winuser.h" |
| #include "winspool.h" |
| #include "winerror.h" |
| |
| #include "wine/debug.h" |
| |
| #include "commdlg.h" |
| #include "dlgs.h" |
| #include "cderr.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(commdlg); |
| |
| #include "cdlg.h" |
| #include "printdlg.h" |
| |
| /* Yes these constants are the same, but we're just copying win98 */ |
| #define UPDOWN_ID 0x270f |
| #define MAX_COPIES 9999 |
| |
| /* Debugging info */ |
| static struct pd_flags psd_flags[] = { |
| {PSD_MINMARGINS,"PSD_MINMARGINS"}, |
| {PSD_MARGINS,"PSD_MARGINS"}, |
| {PSD_INTHOUSANDTHSOFINCHES,"PSD_INTHOUSANDTHSOFINCHES"}, |
| {PSD_INHUNDREDTHSOFMILLIMETERS,"PSD_INHUNDREDTHSOFMILLIMETERS"}, |
| {PSD_DISABLEMARGINS,"PSD_DISABLEMARGINS"}, |
| {PSD_DISABLEPRINTER,"PSD_DISABLEPRINTER"}, |
| {PSD_NOWARNING,"PSD_NOWARNING"}, |
| {PSD_DISABLEORIENTATION,"PSD_DISABLEORIENTATION"}, |
| {PSD_RETURNDEFAULT,"PSD_RETURNDEFAULT"}, |
| {PSD_DISABLEPAPER,"PSD_DISABLEPAPER"}, |
| {PSD_SHOWHELP,"PSD_SHOWHELP"}, |
| {PSD_ENABLEPAGESETUPHOOK,"PSD_ENABLEPAGESETUPHOOK"}, |
| {PSD_ENABLEPAGESETUPTEMPLATE,"PSD_ENABLEPAGESETUPTEMPLATE"}, |
| {PSD_ENABLEPAGESETUPTEMPLATEHANDLE,"PSD_ENABLEPAGESETUPTEMPLATEHANDLE"}, |
| {PSD_ENABLEPAGEPAINTHOOK,"PSD_ENABLEPAGEPAINTHOOK"}, |
| {PSD_DISABLEPAGEPAINTING,"PSD_DISABLEPAGEPAINTING"}, |
| {-1, NULL} |
| }; |
| |
| /* address of wndproc for subclassed Static control */ |
| static WNDPROC lpfnStaticWndProc; |
| /* the text of the fake document to render for the Page Setup dialog */ |
| static WCHAR wszFakeDocumentText[1024]; |
| |
| /*********************************************************************** |
| * PRINTDLG_OpenDefaultPrinter |
| * |
| * Returns a winspool printer handle to the default printer in *hprn |
| * Caller must call ClosePrinter on the handle |
| * |
| * Returns TRUE on success else FALSE |
| */ |
| BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) |
| { |
| WCHAR buf[260]; |
| DWORD dwBufLen = sizeof(buf) / sizeof(buf[0]); |
| BOOL res; |
| if(!GetDefaultPrinterW(buf, &dwBufLen)) |
| return FALSE; |
| res = OpenPrinterW(buf, hprn, NULL); |
| if (!res) |
| WARN("Could not open printer %s\n", debugstr_w(buf)); |
| return res; |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_SetUpPrinterListCombo |
| * |
| * Initializes printer list combox. |
| * hDlg: HWND of dialog |
| * id: Control id of combo |
| * name: Name of printer to select |
| * |
| * Initializes combo with list of available printers. Selects printer 'name' |
| * If name is NULL or does not exist select the default printer. |
| * |
| * Returns number of printers added to list. |
| */ |
| INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) |
| { |
| DWORD needed, num; |
| INT i; |
| LPPRINTER_INFO_2A pi; |
| EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); |
| pi = HeapAlloc(GetProcessHeap(), 0, needed); |
| EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, |
| &num); |
| |
| SendDlgItemMessageA(hDlg, id, CB_RESETCONTENT, 0, 0); |
| |
| for(i = 0; i < num; i++) { |
| SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0, |
| (LPARAM)pi[i].pPrinterName ); |
| } |
| HeapFree(GetProcessHeap(), 0, pi); |
| if(!name || |
| (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, |
| (LPARAM)name)) == CB_ERR) { |
| |
| char buf[260]; |
| DWORD dwBufLen = sizeof(buf); |
| FIXME("Can't find '%s' in printer list so trying to find default\n", |
| name); |
| if(!GetDefaultPrinterA(buf, &dwBufLen)) |
| return num; |
| i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); |
| if(i == CB_ERR) |
| FIXME("Can't find default printer in printer list\n"); |
| } |
| SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0); |
| return num; |
| } |
| |
| static INT PRINTDLG_SetUpPrinterListComboW(HWND hDlg, UINT id, LPCWSTR name) |
| { |
| DWORD needed, num; |
| INT i; |
| LPPRINTER_INFO_2W pi; |
| EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); |
| pi = HeapAlloc(GetProcessHeap(), 0, needed); |
| EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, |
| &num); |
| |
| for(i = 0; i < num; i++) { |
| SendDlgItemMessageW(hDlg, id, CB_ADDSTRING, 0, |
| (LPARAM)pi[i].pPrinterName ); |
| } |
| HeapFree(GetProcessHeap(), 0, pi); |
| if(!name || |
| (i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, |
| (LPARAM)name)) == CB_ERR) { |
| WCHAR buf[260]; |
| DWORD dwBufLen = sizeof(buf)/sizeof(buf[0]); |
| TRACE("Can't find '%s' in printer list so trying to find default\n", |
| debugstr_w(name)); |
| if(!GetDefaultPrinterW(buf, &dwBufLen)) |
| return num; |
| i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); |
| if(i == CB_ERR) |
| TRACE("Can't find default printer in printer list\n"); |
| } |
| SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0); |
| return num; |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_CreateDevNames [internal] |
| * |
| * |
| * creates a DevNames structure. |
| * |
| * (NB. when we handle unicode the offsets will be in wchars). |
| */ |
| static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, 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 = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); |
| else |
| *hmem = GlobalAlloc(GMEM_MOVEABLE, size); |
| if (*hmem == 0) |
| return FALSE; |
| |
| pDevNamesSpace = GlobalLock(*hmem); |
| lpDevNames = (LPDEVNAMES) pDevNamesSpace; |
| |
| pTempPtr = pDevNamesSpace + sizeof(DEVNAMES); |
| strcpy(pTempPtr, DeviceDriverName); |
| lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; |
| |
| pTempPtr += strlen(DeviceDriverName) + 1; |
| strcpy(pTempPtr, DeviceName); |
| lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; |
| |
| pTempPtr += strlen(DeviceName) + 1; |
| strcpy(pTempPtr, OutputPort); |
| lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; |
| |
| GetDefaultPrinterA(buf, &dwBufLen); |
| lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; |
| GlobalUnlock(*hmem); |
| return TRUE; |
| } |
| |
| static BOOL PRINTDLG_CreateDevNamesW(HGLOBAL *hmem, LPCWSTR DeviceDriverName, |
| LPCWSTR DeviceName, LPCWSTR OutputPort) |
| { |
| long size; |
| LPWSTR pDevNamesSpace; |
| LPWSTR pTempPtr; |
| LPDEVNAMES lpDevNames; |
| WCHAR bufW[260]; |
| DWORD dwBufLen = sizeof(bufW) / sizeof(WCHAR); |
| |
| size = sizeof(WCHAR)*lstrlenW(DeviceDriverName) + 2 |
| + sizeof(WCHAR)*lstrlenW(DeviceName) + 2 |
| + sizeof(WCHAR)*lstrlenW(OutputPort) + 2 |
| + sizeof(DEVNAMES); |
| |
| if(*hmem) |
| *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); |
| else |
| *hmem = GlobalAlloc(GMEM_MOVEABLE, size); |
| if (*hmem == 0) |
| return FALSE; |
| |
| pDevNamesSpace = GlobalLock(*hmem); |
| lpDevNames = (LPDEVNAMES) pDevNamesSpace; |
| |
| pTempPtr = (LPWSTR)((LPDEVNAMES)pDevNamesSpace + 1); |
| lstrcpyW(pTempPtr, DeviceDriverName); |
| lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; |
| |
| pTempPtr += lstrlenW(DeviceDriverName) + 1; |
| lstrcpyW(pTempPtr, DeviceName); |
| lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; |
| |
| pTempPtr += lstrlenW(DeviceName) + 1; |
| lstrcpyW(pTempPtr, OutputPort); |
| lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; |
| |
| GetDefaultPrinterW(bufW, &dwBufLen); |
| lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0; |
| GlobalUnlock(*hmem); |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_UpdatePrintDlg [internal] |
| * |
| * |
| * updates the PrintDlg structure for return values. |
| * |
| * RETURNS |
| * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values) |
| * TRUE if successful. |
| */ |
| static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg, |
| PRINT_PTRA* PrintStructures) |
| { |
| LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; |
| PDEVMODEA lpdm = PrintStructures->lpDevMode; |
| LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo; |
| |
| |
| if(!lpdm) { |
| FIXME("No lpdm ptr?\n"); |
| return FALSE; |
| } |
| |
| |
| if(!(lppd->Flags & PD_PRINTSETUP)) { |
| /* check whether nFromPage and nToPage are within range defined by |
| * nMinPage and nMaxPage |
| */ |
| if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ |
| WORD nToPage; |
| WORD nFromPage; |
| 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; |
| lppd->Flags |= PD_PAGENUMS; |
| } |
| else |
| lppd->Flags &= ~PD_PAGENUMS; |
| |
| if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ |
| static char file[] = "FILE:"; |
| lppd->Flags |= PD_PRINTTOFILE; |
| pi->pPortName = file; |
| } |
| |
| if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ |
| FIXME("Collate lppd not yet implemented as output\n"); |
| } |
| |
| /* set PD_Collate and nCopies */ |
| if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { |
| /* The application doesn't support multiple copies or collate... |
| */ |
| lppd->Flags &= ~PD_COLLATE; |
| lppd->nCopies = 1; |
| /* if the printer driver supports it... store info there |
| * otherwise no collate & multiple copies ! |
| */ |
| if (lpdm->dmFields & DM_COLLATE) |
| lpdm->dmCollate = |
| (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); |
| if (lpdm->dmFields & DM_COPIES) |
| lpdm->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_UpdatePrintDlgW(HWND hDlg, |
| PRINT_PTRW* PrintStructures) |
| { |
| LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; |
| PDEVMODEW lpdm = PrintStructures->lpDevMode; |
| LPPRINTER_INFO_2W pi = PrintStructures->lpPrinterInfo; |
| |
| |
| if(!lpdm) { |
| FIXME("No lpdm ptr?\n"); |
| return FALSE; |
| } |
| |
| |
| if(!(lppd->Flags & PD_PRINTSETUP)) { |
| /* check whether nFromPage and nToPage are within range defined by |
| * nMinPage and nMaxPage |
| */ |
| if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ |
| WORD nToPage; |
| WORD nFromPage; |
| 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) { |
| WCHAR resourcestr[256]; |
| WCHAR resultstr[256]; |
| LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, |
| resourcestr, 255); |
| wsprintfW(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage); |
| LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, |
| resourcestr, 255); |
| MessageBoxW(hDlg, resultstr, resourcestr, |
| MB_OK | MB_ICONWARNING); |
| return FALSE; |
| } |
| lppd->nFromPage = nFromPage; |
| lppd->nToPage = nToPage; |
| lppd->Flags |= PD_PAGENUMS; |
| } |
| else |
| lppd->Flags &= ~PD_PAGENUMS; |
| |
| if (IsDlgButtonChecked(hDlg, 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 WORD PaperSize,LPPOINT size |
| ) { |
| DEVNAMES *dn; |
| DEVMODEA *dm; |
| LPSTR devname,portname; |
| int i; |
| INT NrOfEntries,ret; |
| WORD *Words = NULL; |
| POINT *points = NULL; |
| BOOL retval = FALSE; |
| |
| dn = GlobalLock(pdlga->hDevNames); |
| dm = GlobalLock(pdlga->hDevMode); |
| devname = ((char*)dn)+dn->wDeviceOffset; |
| portname = ((char*)dn)+dn->wOutputOffset; |
| |
| |
| NrOfEntries = DeviceCapabilitiesA(devname,portname,DC_PAPERNAMES,NULL,dm); |
| if (!NrOfEntries) { |
| FIXME("No papernames found for %s/%s\n",devname,portname); |
| goto out; |
| } |
| if (NrOfEntries == -1) { |
| ERR("Hmm ? DeviceCapabilities() DC_PAPERNAMES failed, ret -1 !\n"); |
| goto out; |
| } |
| |
| Words = HeapAlloc(GetProcessHeap(),0,NrOfEntries*sizeof(WORD)); |
| if (NrOfEntries != (ret=DeviceCapabilitiesA(devname,portname,DC_PAPERS,(LPSTR)Words,dm))) { |
| FIXME("Number of returned vals %d is not %d\n",NrOfEntries,ret); |
| goto out; |
| } |
| for (i=0;i<NrOfEntries;i++) |
| if (Words[i] == PaperSize) |
| break; |
| HeapFree(GetProcessHeap(),0,Words); |
| if (i == NrOfEntries) { |
| FIXME("Papersize %d not found in list?\n",PaperSize); |
| goto out; |
| } |
| points = HeapAlloc(GetProcessHeap(),0,sizeof(points[0])*NrOfEntries); |
| if (NrOfEntries!=(ret=DeviceCapabilitiesA(devname,portname,DC_PAPERSIZE,(LPSTR)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); |
| HeapFree(GetProcessHeap(),0,Words); |
| HeapFree(GetProcessHeap(),0,points); |
| return retval; |
| } |
| |
| 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 = 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); |
| HeapFree(GetProcessHeap(),0,Names); |
| HeapFree(GetProcessHeap(),0,points); |
| return retval; |
| } |
| |
| |
| /************************************************************************ |
| * PRINTDLG_SetUpPaperComboBox |
| * |
| * Initialize either the papersize or inputslot combos of the Printer Setup |
| * dialog. We store the associated word (eg DMPAPER_A4) as the item data. |
| * We also try to re-select the old selection. |
| */ |
| static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg, |
| int nIDComboBox, |
| char* PrinterName, |
| char* PortName, |
| LPDEVMODEA dm) |
| { |
| int i; |
| int NrOfEntries; |
| char* Names; |
| WORD* Words; |
| DWORD Sel; |
| WORD oldWord = 0; |
| int NamesSize; |
| int fwCapability_Names; |
| int fwCapability_Words; |
| |
| TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName,PortName,nIDComboBox); |
| |
| /* query the dialog box for the current selected value */ |
| Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); |
| if(Sel != CB_ERR) { |
| /* we enter here only if a different printer is selected after |
| * the Print Setup dialog is opened. The current settings are |
| * stored into the newly selected printer. |
| */ |
| oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, |
| Sel, 0); |
| if (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 = DeviceCapabilitiesA(PrinterName, PortName, |
| fwCapability_Names, NULL, dm); |
| if (NrOfEntries == 0) |
| WARN("no Name Entries found!\n"); |
| else if (NrOfEntries < 0) |
| return FALSE; |
| |
| if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm) |
| != NrOfEntries) { |
| ERR("Number of caps is different\n"); |
| NrOfEntries = 0; |
| } |
| |
| Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(char)*NamesSize); |
| Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD)); |
| NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, |
| fwCapability_Names, Names, dm); |
| NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, |
| fwCapability_Words, (LPSTR)Words, dm); |
| |
| /* reset any current content in the combobox */ |
| SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); |
| |
| /* store new content */ |
| for (i = 0; i < NrOfEntries; i++) { |
| DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0, |
| (LPARAM)(&Names[i*NamesSize]) ); |
| SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos, |
| Words[i]); |
| } |
| |
| /* Look for old selection - 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; |
| } |
| |
| 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 = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); |
| if(Sel != CB_ERR) { |
| /* we enter here only if a different printer is selected after |
| * the Print Setup dialog is opened. The current settings are |
| * stored into the newly selected printer. |
| */ |
| oldWord = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, |
| Sel, 0); |
| if (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 */ |
| SendDlgItemMessageW(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); |
| |
| /* store new content */ |
| for (i = 0; i < NrOfEntries; i++) { |
| DWORD pos = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0, |
| (LPARAM)(&Names[i*NamesSize]) ); |
| SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos, |
| Words[i]); |
| } |
| |
| /* Look for old selection - 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(SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == |
| oldWord) { |
| Sel = i; |
| break; |
| } |
| } |
| SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); |
| |
| HeapFree(GetProcessHeap(),0,Words); |
| HeapFree(GetProcessHeap(),0,Names); |
| return TRUE; |
| } |
| |
| |
| /*********************************************************************** |
| * PRINTDLG_UpdatePrinterInfoTexts [internal] |
| */ |
| static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, LPPRINTER_INFO_2A pi) |
| { |
| char StatusMsg[256]; |
| char ResourceString[256]; |
| int i; |
| |
| /* Status Message */ |
| StatusMsg[0]='\0'; |
| |
| /* add all status messages */ |
| for (i = 0; i < 25; i++) { |
| if (pi->Status & (1<<i)) { |
| LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, |
| ResourceString, 255); |
| strcat(StatusMsg,ResourceString); |
| } |
| } |
| /* append "ready" */ |
| /* FIXME: status==ready must only be appended if really so. |
| but how to detect? */ |
| LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, |
| ResourceString, 255); |
| strcat(StatusMsg,ResourceString); |
| SetDlgItemTextA(hDlg, stc12, StatusMsg); |
| |
| /* set all other printer info texts */ |
| SetDlgItemTextA(hDlg, stc11, pi->pDriverName); |
| |
| if (pi->pLocation != NULL && pi->pLocation[0] != '\0') |
| SetDlgItemTextA(hDlg, stc14, pi->pLocation); |
| else |
| SetDlgItemTextA(hDlg, stc14, pi->pPortName); |
| SetDlgItemTextA(hDlg, stc13, pi->pComment ? pi->pComment : ""); |
| return; |
| } |
| |
| static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, LPPRINTER_INFO_2W pi) |
| { |
| WCHAR StatusMsg[256]; |
| WCHAR ResourceString[256]; |
| static const WCHAR emptyW[] = {0}; |
| int i; |
| |
| /* Status Message */ |
| StatusMsg[0]='\0'; |
| |
| /* add all status messages */ |
| for (i = 0; i < 25; i++) { |
| if (pi->Status & (1<<i)) { |
| LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, |
| ResourceString, 255); |
| lstrcatW(StatusMsg,ResourceString); |
| } |
| } |
| /* append "ready" */ |
| /* FIXME: status==ready must only be appended if really so. |
| but how to detect? */ |
| LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, |
| ResourceString, 255); |
| lstrcatW(StatusMsg,ResourceString); |
| SetDlgItemTextW(hDlg, stc12, StatusMsg); |
| |
| /* set all other printer info texts */ |
| SetDlgItemTextW(hDlg, stc11, pi->pDriverName); |
| if (pi->pLocation != NULL && pi->pLocation[0] != '\0') |
| SetDlgItemTextW(hDlg, stc14, pi->pLocation); |
| else |
| SetDlgItemTextW(hDlg, stc14, pi->pPortName); |
| SetDlgItemTextW(hDlg, stc13, pi->pComment ? pi->pComment : emptyW); |
| } |
| |
| |
| /******************************************************************* |
| * |
| * PRINTDLG_ChangePrinter |
| * |
| */ |
| BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, |
| PRINT_PTRA *PrintStructures) |
| { |
| LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; |
| LPDEVMODEA lpdm = NULL; |
| LONG dmSize; |
| DWORD needed; |
| HANDLE hprn; |
| |
| HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo); |
| HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo); |
| if(!OpenPrinterA(name, &hprn, NULL)) { |
| ERR("Can't open printer %s\n", name); |
| return FALSE; |
| } |
| GetPrinterA(hprn, 2, NULL, 0, &needed); |
| PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed); |
| GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, |
| &needed); |
| GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); |
| PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed); |
| if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, |
| needed, &needed)) { |
| ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures->lpPrinterInfo->pPrinterName); |
| return FALSE; |
| } |
| ClosePrinter(hprn); |
| |
| PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo); |
| |
| HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); |
| PrintStructures->lpDevMode = NULL; |
| |
| dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0); |
| if(dmSize == -1) { |
| ERR("DocumentProperties fails on %s\n", debugstr_a(name)); |
| return FALSE; |
| } |
| PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize); |
| dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL, |
| DM_OUT_BUFFER); |
| if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && |
| !lstrcmpA( (LPSTR) lpdm->dmDeviceName, |
| (LPSTR) PrintStructures->lpDevMode->dmDeviceName)) { |
| /* Supplied devicemode matches current printer so try to use it */ |
| DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm, |
| DM_OUT_BUFFER | DM_IN_BUFFER); |
| } |
| if(lpdm) |
| GlobalUnlock(lppd->hDevMode); |
| |
| lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ |
| |
| if(!(lppd->Flags & PD_PRINTSETUP)) { |
| /* Print range (All/Range/Selection) */ |
| 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); |
| } |
| |
| /* 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_SetUpPaperComboBoxA(hDlg, cmb2, |
| PrintStructures->lpPrinterInfo->pPrinterName, |
| PrintStructures->lpPrinterInfo->pPortName, |
| lpdm); |
| PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb3, |
| PrintStructures->lpPrinterInfo->pPrinterName, |
| PrintStructures->lpPrinterInfo->pPortName, |
| lpdm); |
| CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); |
| SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (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; |
| } |
| |
| static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name, |
| PRINT_PTRW *PrintStructures) |
| { |
| LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; |
| LPDEVMODEW lpdm = NULL; |
| LONG dmSize; |
| DWORD needed; |
| HANDLE hprn; |
| |
| HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo); |
| HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo); |
| if(!OpenPrinterW(name, &hprn, NULL)) { |
| ERR("Can't open printer %s\n", debugstr_w(name)); |
| return FALSE; |
| } |
| GetPrinterW(hprn, 2, NULL, 0, &needed); |
| PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,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); |
| |
| 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); |
| } |
| |
| /* Collate pages |
| * |
| * FIXME: The ico3 is not displayed for some reason. I don't know why. |
| */ |
| if (lppd->Flags & PD_COLLATE) { |
| SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)PrintStructures->hCollateIcon); |
| CheckDlgButton(hDlg, chx2, 1); |
| } else { |
| SendDlgItemMessageW(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); |
| SendDlgItemMessageW(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; |
| } |
| |
| /*********************************************************************** |
| * check_printer_setup [internal] |
| */ |
| static LRESULT check_printer_setup(HWND hDlg) |
| { |
| DWORD needed,num; |
| WCHAR resourcestr[256],resultstr[256]; |
| int res; |
| |
| EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); |
| if(needed == 0) |
| { |
| EnumPrintersW(PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &num); |
| } |
| if(needed > 0) |
| return TRUE; |
| else |
| { |
| LoadStringW(COMDLG32_hInstance, PD32_NO_DEVICES,resultstr, 255); |
| LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE,resourcestr, 255); |
| res = MessageBoxW(hDlg, resultstr, resourcestr,MB_OK | MB_ICONWARNING); |
| return FALSE; |
| } |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_WMInitDialog [internal] |
| */ |
| static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, |
| PRINT_PTRA* PrintStructures) |
| { |
| LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; |
| DEVNAMES *pdn; |
| DEVMODEA *pdm; |
| char *name = NULL; |
| UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; |
| |
| /* load Collate ICONs */ |
| /* We load these with LoadImage because they are not a standard |
| size and we don't want them rescaled */ |
| PrintStructures->hCollateIcon = |
| LoadImageA(COMDLG32_hInstance, "PD32_COLLATE", IMAGE_ICON, 0, 0, 0); |
| PrintStructures->hNoCollateIcon = |
| LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0); |
| |
| /* These can be done with LoadIcon */ |
| PrintStructures->hPortraitIcon = |
| LoadIconA(COMDLG32_hInstance, "PD32_PORTRAIT"); |
| PrintStructures->hLandscapeIcon = |
| LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE"); |
| |
| /* display the collate/no_collate icon */ |
| SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)PrintStructures->hNoCollateIcon); |
| |
| if(PrintStructures->hCollateIcon == 0 || |
| PrintStructures->hNoCollateIcon == 0 || |
| PrintStructures->hPortraitIcon == 0 || |
| PrintStructures->hLandscapeIcon == 0) { |
| ERR("no icon in resourcefile\n"); |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| EndDialog(hDlg, FALSE); |
| } |
| |
| /* |
| * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message |
| * must be registered and the Help button must be shown. |
| */ |
| if (lppd->Flags & PD_SHOWHELP) { |
| if((PrintStructures->HelpMessageID = |
| RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); |
| return FALSE; |
| } |
| } else |
| PrintStructures->HelpMessageID = 0; |
| |
| if(!(lppd->Flags &PD_PRINTSETUP)) { |
| PrintStructures->hwndUpDown = |
| CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | |
| UDS_NOTHOUSANDS | UDS_ARROWKEYS | |
| UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, |
| hDlg, UPDOWN_ID, COMDLG32_hInstance, |
| GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); |
| } |
| |
| /* FIXME: I allow more freedom than either Win95 or WinNT, |
| * which do not agree 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 = (char*)pdn + pdn->wDeviceOffset; |
| else if(pdm) |
| name = (char*)pdm->dmDeviceName; |
| PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); |
| if(pdm) GlobalUnlock(lppd->hDevMode); |
| if(pdn) GlobalUnlock(lppd->hDevNames); |
| |
| /* Now find selected printer and update rest of dlg */ |
| name = HeapAlloc(GetProcessHeap(),0,256); |
| if (GetDlgItemTextA(hDlg, comboID, name, 255)) |
| PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); |
| HeapFree(GetProcessHeap(),0,name); |
| } else { |
| /* else use default printer */ |
| char name[200]; |
| DWORD dwBufLen = sizeof(name); |
| BOOL ret = GetDefaultPrinterA(name, &dwBufLen); |
| |
| if (ret) |
| PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); |
| else |
| FIXME("No default printer found, expect problems!\n"); |
| } |
| return TRUE; |
| } |
| |
| static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam, |
| PRINT_PTRW* PrintStructures) |
| { |
| static const WCHAR PD32_COLLATE[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 }; |
| static const WCHAR PD32_NOCOLLATE[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 }; |
| static const WCHAR PD32_PORTRAIT[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 }; |
| static const WCHAR PD32_LANDSCAPE[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 }; |
| LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; |
| DEVNAMES *pdn; |
| DEVMODEW *pdm; |
| WCHAR *name = NULL; |
| UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; |
| |
| /* load Collate ICONs */ |
| /* We load these with LoadImage because they are not a standard |
| size and we don't want them rescaled */ |
| PrintStructures->hCollateIcon = |
| LoadImageW(COMDLG32_hInstance, PD32_COLLATE, IMAGE_ICON, 0, 0, 0); |
| PrintStructures->hNoCollateIcon = |
| LoadImageW(COMDLG32_hInstance, PD32_NOCOLLATE, IMAGE_ICON, 0, 0, 0); |
| |
| /* These can be done with LoadIcon */ |
| PrintStructures->hPortraitIcon = |
| LoadIconW(COMDLG32_hInstance, PD32_PORTRAIT); |
| PrintStructures->hLandscapeIcon = |
| LoadIconW(COMDLG32_hInstance, PD32_LANDSCAPE); |
| |
| /* display the collate/no_collate icon */ |
| SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)PrintStructures->hNoCollateIcon); |
| |
| if(PrintStructures->hCollateIcon == 0 || |
| PrintStructures->hNoCollateIcon == 0 || |
| PrintStructures->hPortraitIcon == 0 || |
| PrintStructures->hLandscapeIcon == 0) { |
| ERR("no icon in resourcefile\n"); |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| EndDialog(hDlg, FALSE); |
| } |
| |
| /* |
| * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message |
| * must be registered and the Help button must be shown. |
| */ |
| if (lppd->Flags & PD_SHOWHELP) { |
| if((PrintStructures->HelpMessageID = |
| RegisterWindowMessageW(HELPMSGSTRINGW)) == 0) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); |
| return FALSE; |
| } |
| } else |
| PrintStructures->HelpMessageID = 0; |
| |
| if(!(lppd->Flags &PD_PRINTSETUP)) { |
| PrintStructures->hwndUpDown = |
| CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | |
| UDS_NOTHOUSANDS | UDS_ARROWKEYS | |
| UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, |
| hDlg, UPDOWN_ID, COMDLG32_hInstance, |
| GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); |
| } |
| |
| /* FIXME: I allow more freedom than either Win95 or WinNT, |
| * which do not agree to what errors should be thrown or not |
| * in case nToPage or nFromPage is out-of-range. |
| */ |
| if (lppd->nMaxPage < lppd->nMinPage) |
| lppd->nMaxPage = lppd->nMinPage; |
| if (lppd->nMinPage == lppd->nMaxPage) |
| lppd->Flags |= PD_NOPAGENUMS; |
| if (lppd->nToPage < lppd->nMinPage) |
| lppd->nToPage = lppd->nMinPage; |
| if (lppd->nToPage > lppd->nMaxPage) |
| lppd->nToPage = lppd->nMaxPage; |
| if (lppd->nFromPage < lppd->nMinPage) |
| lppd->nFromPage = lppd->nMinPage; |
| if (lppd->nFromPage > lppd->nMaxPage) |
| lppd->nFromPage = lppd->nMaxPage; |
| |
| /* if we have the combo box, fill it */ |
| if (GetDlgItem(hDlg,comboID)) { |
| /* Fill Combobox |
| */ |
| pdn = GlobalLock(lppd->hDevNames); |
| pdm = GlobalLock(lppd->hDevMode); |
| if(pdn) |
| name = (WCHAR*)pdn + pdn->wDeviceOffset; |
| else if(pdm) |
| name = pdm->dmDeviceName; |
| PRINTDLG_SetUpPrinterListComboW(hDlg, comboID, name); |
| if(pdm) GlobalUnlock(lppd->hDevMode); |
| if(pdn) GlobalUnlock(lppd->hDevNames); |
| |
| /* Now find selected printer and update rest of dlg */ |
| /* ansi is ok here */ |
| name = HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR)); |
| if (GetDlgItemTextW(hDlg, comboID, name, 255)) |
| PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); |
| HeapFree(GetProcessHeap(),0,name); |
| } else { |
| /* else use default printer */ |
| WCHAR name[200]; |
| DWORD dwBufLen = sizeof(name) / sizeof(WCHAR); |
| BOOL ret = GetDefaultPrinterW(name, &dwBufLen); |
| |
| if (ret) |
| PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); |
| else |
| FIXME("No default printer found, expect problems!\n"); |
| } |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_WMCommand [internal] |
| */ |
| LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, |
| LPARAM lParam, PRINT_PTRA* PrintStructures) |
| { |
| LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; |
| UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; |
| LPDEVMODEA lpdm = PrintStructures->lpDevMode; |
| |
| switch (LOWORD(wParam)) { |
| case IDOK: |
| TRACE(" OK button was hit\n"); |
| if (!PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)) { |
| FIXME("Update printdlg was not successful!\n"); |
| return(FALSE); |
| } |
| EndDialog(hDlg, TRUE); |
| return(TRUE); |
| |
| case IDCANCEL: |
| TRACE(" CANCEL button was hit\n"); |
| EndDialog(hDlg, FALSE); |
| return(FALSE); |
| |
| case pshHelp: |
| TRACE(" HELP button was hit\n"); |
| SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, |
| (WPARAM) hDlg, (LPARAM) lppd); |
| break; |
| |
| case chx2: /* collate pages checkbox */ |
| if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) |
| SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (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; |
| |
| #if 0 |
| case psh1: /* Print Setup */ |
| { |
| PRINTDLG16 pdlg; |
| |
| if (!PrintStructures->dlg.lpPrintDlg16) { |
| FIXME("The 32bit print dialog does not have this button!?\n"); |
| break; |
| } |
| |
| memcpy(&pdlg,PrintStructures->dlg.lpPrintDlg16,sizeof(pdlg)); |
| pdlg.Flags |= PD_PRINTSETUP; |
| pdlg.hwndOwner = HWND_16(hDlg); |
| if (!PrintDlg16(&pdlg)) |
| break; |
| } |
| break; |
| #endif |
| case psh2: /* Properties button */ |
| { |
| HANDLE hPrinter; |
| char PrinterName[256]; |
| |
| GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255); |
| if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { |
| FIXME(" Call to OpenPrinter did not succeed!\n"); |
| break; |
| } |
| DocumentPropertiesA(hDlg, hPrinter, PrinterName, |
| PrintStructures->lpDevMode, |
| PrintStructures->lpDevMode, |
| DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); |
| ClosePrinter(hPrinter); |
| break; |
| } |
| |
| case rad1: /* Paperorientation */ |
| if (lppd->Flags & PD_PRINTSETUP) |
| { |
| lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; |
| SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, (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 != LOWORD(wParam)) { |
| FIXME("No handling for print quality combo box yet.\n"); |
| break; |
| } |
| /* FALLTHROUGH */ |
| case cmb4: /* Printer combobox */ |
| if (HIWORD(wParam)==CBN_SELCHANGE) { |
| char PrinterName[256]; |
| GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255); |
| PRINTDLG_ChangePrinterA(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 = SendDlgItemMessageA(hDlg, cmb3, |
| CB_GETITEMDATA, Sel, |
| 0); |
| } |
| break; |
| } |
| if(lppd->Flags & PD_PRINTSETUP) { |
| switch (LOWORD(wParam)) { |
| case rad1: /* orientation */ |
| case rad2: |
| if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { |
| if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { |
| lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; |
| SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, |
| (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; |
| } |
| |
| static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, |
| LPARAM lParam, PRINT_PTRW* PrintStructures) |
| { |
| LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; |
| UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; |
| LPDEVMODEW lpdm = PrintStructures->lpDevMode; |
| |
| switch (LOWORD(wParam)) { |
| case IDOK: |
| TRACE(" OK button was hit\n"); |
| if (!PRINTDLG_UpdatePrintDlgW(hDlg, PrintStructures)) { |
| FIXME("Update printdlg was not successful!\n"); |
| return(FALSE); |
| } |
| EndDialog(hDlg, TRUE); |
| return(TRUE); |
| |
| case IDCANCEL: |
| TRACE(" CANCEL button was hit\n"); |
| EndDialog(hDlg, FALSE); |
| return(FALSE); |
| |
| case pshHelp: |
| TRACE(" HELP button was hit\n"); |
| SendMessageW(lppd->hwndOwner, PrintStructures->HelpMessageID, |
| (WPARAM) hDlg, (LPARAM) lppd); |
| break; |
| |
| case chx2: /* collate pages checkbox */ |
| if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) |
| SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)PrintStructures->hCollateIcon); |
| else |
| SendDlgItemMessageW(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]; |
| |
| if (!GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255)) break; |
| if (!OpenPrinterW(PrinterName, &hPrinter, NULL)) { |
| FIXME(" Call to OpenPrinter did not succeed!\n"); |
| break; |
| } |
| DocumentPropertiesW(hDlg, hPrinter, PrinterName, |
| PrintStructures->lpDevMode, |
| PrintStructures->lpDevMode, |
| DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); |
| ClosePrinter(hPrinter); |
| break; |
| } |
| |
| case rad1: /* Paperorientation */ |
| if (lppd->Flags & PD_PRINTSETUP) |
| { |
| lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; |
| SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)(PrintStructures->hPortraitIcon)); |
| } |
| break; |
| |
| case rad2: /* Paperorientation */ |
| if (lppd->Flags & PD_PRINTSETUP) |
| { |
| lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; |
| SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, (WPARAM) IMAGE_ICON, |
| (LPARAM)(PrintStructures->hLandscapeIcon)); |
| } |
| break; |
| |
| case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT */ |
| if (PrinterComboID != LOWORD(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 = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0); |
| if(Sel != CB_ERR) |
| lpdm->u1.s1.dmPaperSize = SendDlgItemMessageW(hDlg, cmb2, |
| CB_GETITEMDATA, |
| Sel, 0); |
| } |
| break; |
| |
| case cmb3: /* Bin */ |
| { |
| DWORD Sel = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0); |
| if(Sel != CB_ERR) |
| lpdm->dmDefaultSource = SendDlgItemMessageW(hDlg, cmb3, |
| CB_GETITEMDATA, Sel, |
| 0); |
| } |
| break; |
| } |
| if(lppd->Flags & PD_PRINTSETUP) { |
| switch (LOWORD(wParam)) { |
| case rad1: /* orientation */ |
| case rad2: |
| if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { |
| if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { |
| lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; |
| SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, |
| (WPARAM)IMAGE_ICON, |
| (LPARAM)PrintStructures->hPortraitIcon); |
| SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, |
| (WPARAM)IMAGE_ICON, |
| (LPARAM)PrintStructures->hPortraitIcon); |
| } |
| } else { |
| if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) { |
| lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; |
| SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, |
| (WPARAM)IMAGE_ICON, |
| (LPARAM)PrintStructures->hLandscapeIcon); |
| SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, |
| (WPARAM)IMAGE_ICON, |
| (LPARAM)PrintStructures->hLandscapeIcon); |
| } |
| } |
| break; |
| } |
| } |
| return FALSE; |
| } |
| |
| /*********************************************************************** |
| * PrintDlgProcA [internal] |
| */ |
| static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, |
| LPARAM lParam) |
| { |
| PRINT_PTRA* PrintStructures; |
| INT_PTR res = FALSE; |
| |
| if (uMsg!=WM_INITDIALOG) { |
| PrintStructures = (PRINT_PTRA*)GetPropA(hDlg,"__WINE_PRINTDLGDATA"); |
| if (!PrintStructures) |
| return FALSE; |
| } else { |
| PrintStructures = (PRINT_PTRA*) lParam; |
| SetPropA(hDlg,"__WINE_PRINTDLGDATA",PrintStructures); |
| if(!check_printer_setup(hDlg)) |
| { |
| EndDialog(hDlg,FALSE); |
| return FALSE; |
| } |
| res = PRINTDLG_WMInitDialog(hDlg, wParam, PrintStructures); |
| |
| if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) |
| res = PrintStructures->lpPrintDlg->lpfnPrintHook( |
| hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg |
| ); |
| return res; |
| } |
| |
| if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { |
| res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, |
| lParam); |
| if(res) return res; |
| } |
| |
| switch (uMsg) { |
| case WM_COMMAND: |
| return PRINTDLG_WMCommandA(hDlg, wParam, 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; |
| } |
| |
| static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, |
| LPARAM lParam) |
| { |
| static const WCHAR propW[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0}; |
| PRINT_PTRW* PrintStructures; |
| INT_PTR res = FALSE; |
| |
| if (uMsg!=WM_INITDIALOG) { |
| PrintStructures = (PRINT_PTRW*) GetPropW(hDlg, propW); |
| if (!PrintStructures) |
| return FALSE; |
| } else { |
| PrintStructures = (PRINT_PTRW*) lParam; |
| SetPropW(hDlg, propW, PrintStructures); |
| if(!check_printer_setup(hDlg)) |
| { |
| EndDialog(hDlg,FALSE); |
| return FALSE; |
| } |
| res = PRINTDLG_WMInitDialogW(hDlg, wParam, PrintStructures); |
| |
| if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) |
| res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg); |
| return res; |
| } |
| |
| if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { |
| res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, lParam); |
| if(res) return res; |
| } |
| |
| switch (uMsg) { |
| case WM_COMMAND: |
| return PRINTDLG_WMCommandW(hDlg, wParam, 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; |
| } |
| |
| /************************************************************ |
| * |
| * PRINTDLG_GetDlgTemplate |
| * |
| */ |
| 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) { |
| hResInfo = FindResourceA(lppd->hInstance, |
| lppd->lpSetupTemplateName, (LPSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", |
| (LPSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); |
| } |
| } else { |
| if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { |
| hDlgTmpl = lppd->hPrintTemplate; |
| } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { |
| hResInfo = FindResourceA(lppd->hInstance, |
| lppd->lpPrintTemplateName, |
| (LPSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", |
| (LPSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); |
| } |
| } |
| return hDlgTmpl; |
| } |
| |
| static HGLOBAL PRINTDLG_GetDlgTemplateW(PRINTDLGW *lppd) |
| { |
| HRSRC hResInfo; |
| HGLOBAL hDlgTmpl; |
| static const WCHAR xpsetup[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0}; |
| static const WCHAR xprint[] = { 'P','R','I','N','T','3','2',0}; |
| |
| if (lppd->Flags & PD_PRINTSETUP) { |
| if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { |
| hDlgTmpl = lppd->hSetupTemplate; |
| } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { |
| hResInfo = FindResourceW(lppd->hInstance, |
| lppd->lpSetupTemplateName, (LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceW(COMDLG32_hInstance, xpsetup, (LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); |
| } |
| } else { |
| if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { |
| hDlgTmpl = lppd->hPrintTemplate; |
| } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { |
| hResInfo = FindResourceW(lppd->hInstance, |
| lppd->lpPrintTemplateName, |
| (LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceW(COMDLG32_hInstance, xprint, (LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); |
| } |
| } |
| return hDlgTmpl; |
| } |
| |
| /*********************************************************************** |
| * |
| * PRINTDLG_CreateDC |
| * |
| */ |
| static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd) |
| { |
| DEVNAMES *pdn = GlobalLock(lppd->hDevNames); |
| DEVMODEA *pdm = GlobalLock(lppd->hDevMode); |
| |
| if(lppd->Flags & PD_RETURNDC) { |
| lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset, |
| (char*)pdn + pdn->wDeviceOffset, |
| (char*)pdn + pdn->wOutputOffset, |
| pdm ); |
| } else if(lppd->Flags & PD_RETURNIC) { |
| lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset, |
| (char*)pdn + pdn->wDeviceOffset, |
| (char*)pdn + pdn->wOutputOffset, |
| pdm ); |
| } |
| GlobalUnlock(lppd->hDevNames); |
| GlobalUnlock(lppd->hDevMode); |
| return lppd->hDC ? TRUE : FALSE; |
| } |
| |
| static BOOL PRINTDLG_CreateDCW(LPPRINTDLGW lppd) |
| { |
| DEVNAMES *pdn = GlobalLock(lppd->hDevNames); |
| DEVMODEW *pdm = GlobalLock(lppd->hDevMode); |
| |
| if(lppd->Flags & PD_RETURNDC) { |
| lppd->hDC = CreateDCW((WCHAR*)pdn + pdn->wDriverOffset, |
| (WCHAR*)pdn + pdn->wDeviceOffset, |
| (WCHAR*)pdn + pdn->wOutputOffset, |
| pdm ); |
| } else if(lppd->Flags & PD_RETURNIC) { |
| lppd->hDC = CreateICW((WCHAR*)pdn + pdn->wDriverOffset, |
| (WCHAR*)pdn + pdn->wDeviceOffset, |
| (WCHAR*)pdn + pdn->wOutputOffset, |
| pdm ); |
| } |
| GlobalUnlock(lppd->hDevNames); |
| GlobalUnlock(lppd->hDevMode); |
| return lppd->hDC ? TRUE : FALSE; |
| } |
| |
| /*********************************************************************** |
| * PrintDlgA (COMDLG32.@) |
| * |
| * Displays the the PRINT dialog box, which enables the user to specify |
| * specific properties of the print job. |
| * |
| * PARAMS |
| * lppd [IO] ptr to PRINTDLG32 struct |
| * |
| * RETURNS |
| * nonzero if the user pressed the OK button |
| * zero if the user cancelled the window or an error occurred |
| * |
| * BUGS |
| * PrintDlg: |
| * * The Collate Icons do not display, even though they are in the code. |
| * * The Properties Button(s) should call DocumentPropertiesA(). |
| */ |
| |
| BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd) |
| { |
| BOOL bRet = FALSE; |
| LPVOID ptr; |
| HINSTANCE hInst = (HINSTANCE)GetWindowLongPtrA( lppd->hwndOwner, GWLP_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 = %p, hDevMode = %p, hDevNames = %p\n" |
| "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" |
| "flags %08x (%s)\n", |
| lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, |
| lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, |
| lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); |
| } |
| |
| if(lppd->lStructSize != sizeof(PRINTDLGA)) { |
| WARN("structure size failure !!!\n"); |
| COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); |
| return FALSE; |
| } |
| |
| if(lppd->Flags & PD_RETURNDEFAULT) { |
| PRINTER_INFO_2A *pbuf; |
| DRIVER_INFO_3A *dbuf; |
| HANDLE hprn; |
| DWORD needed; |
| |
| if(lppd->hDevMode || lppd->hDevNames) { |
| WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); |
| COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); |
| return FALSE; |
| } |
| if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { |
| WARN("Can't find default printer\n"); |
| COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); |
| return FALSE; |
| } |
| |
| GetPrinterA(hprn, 2, NULL, 0, &needed); |
| pbuf = HeapAlloc(GetProcessHeap(), 0, needed); |
| GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); |
| |
| GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); |
| dbuf = HeapAlloc(GetProcessHeap(),0,needed); |
| if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { |
| ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n",GetLastError(),pbuf->pPrinterName); |
| COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); |
| return FALSE; |
| } |
| ClosePrinter(hprn); |
| |
| PRINTDLG_CreateDevNames(&(lppd->hDevNames), |
| dbuf->pDriverPath, |
| pbuf->pPrinterName, |
| pbuf->pPortName); |
| lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + |
| pbuf->pDevMode->dmDriverExtra); |
| ptr = GlobalLock(lppd->hDevMode); |
| memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + |
| pbuf->pDevMode->dmDriverExtra); |
| GlobalUnlock(lppd->hDevMode); |
| HeapFree(GetProcessHeap(), 0, pbuf); |
| HeapFree(GetProcessHeap(), 0, dbuf); |
| bRet = TRUE; |
| } else { |
| HGLOBAL hDlgTmpl; |
| PRINT_PTRA *PrintStructures; |
| |
| /* load Dialog resources, |
| * depending on Flags indicates Print32 or Print32_setup dialog |
| */ |
| hDlgTmpl = PRINTDLG_GetDlgTemplateA(lppd); |
| if (!hDlgTmpl) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| return FALSE; |
| } |
| ptr = LockResource( hDlgTmpl ); |
| if (!ptr) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| return FALSE; |
| } |
| |
| PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, |
| sizeof(PRINT_PTRA)); |
| PrintStructures->lpPrintDlg = lppd; |
| |
| /* and create & process the dialog . |
| * -1 is failure, 0 is broken hwnd, everything else is ok. |
| */ |
| bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner, |
| PrintDlgProcA, |
| (LPARAM)PrintStructures)); |
| |
| if(bRet) { |
| DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn; |
| PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo; |
| DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo; |
| |
| if (lppd->hDevMode == 0) { |
| TRACE(" No hDevMode yet... Need to create my own\n"); |
| lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, |
| lpdm->dmSize + lpdm->dmDriverExtra); |
| } else { |
| lppd->hDevMode = GlobalReAlloc(lppd->hDevMode, |
| lpdm->dmSize + lpdm->dmDriverExtra, |
| GMEM_MOVEABLE); |
| } |
| lpdmReturn = GlobalLock(lppd->hDevMode); |
| memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); |
| |
| PRINTDLG_CreateDevNames(&(lppd->hDevNames), |
| di->pDriverPath, |
| pi->pPrinterName, |
| pi->pPortName |
| ); |
| GlobalUnlock(lppd->hDevMode); |
| } |
| HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); |
| HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo); |
| HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo); |
| HeapFree(GetProcessHeap(), 0, PrintStructures); |
| } |
| if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) |
| bRet = PRINTDLG_CreateDCA(lppd); |
| |
| TRACE("exit! (%d)\n", bRet); |
| return bRet; |
| } |
| |
| /*********************************************************************** |
| * PrintDlgW (COMDLG32.@) |
| * |
| * See PrintDlgA. |
| */ |
| BOOL WINAPI PrintDlgW( |
| LPPRINTDLGW lppd /* [in/out] ptr to PRINTDLG32 struct */ |
| ) |
| { |
| BOOL bRet = FALSE; |
| LPVOID ptr; |
| HINSTANCE hInst = (HINSTANCE)GetWindowLongPtrW( lppd->hwndOwner, GWLP_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 = %p, hDevMode = %p, hDevNames = %p\n" |
| "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" |
| "flags %08x (%s)\n", |
| lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, |
| lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, |
| lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); |
| } |
| |
| if(lppd->lStructSize != sizeof(PRINTDLGW)) { |
| WARN("structure size failure !!!\n"); |
| COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); |
| return FALSE; |
| } |
| |
| if(lppd->Flags & PD_RETURNDEFAULT) { |
| PRINTER_INFO_2W *pbuf; |
| DRIVER_INFO_3W *dbuf; |
| HANDLE hprn; |
| DWORD needed; |
| |
| if(lppd->hDevMode || lppd->hDevNames) { |
| WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); |
| COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); |
| return FALSE; |
| } |
| if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { |
| WARN("Can't find default printer\n"); |
| COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); |
| return FALSE; |
| } |
| |
| GetPrinterW(hprn, 2, NULL, 0, &needed); |
| pbuf = HeapAlloc(GetProcessHeap(), 0, 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 %d, 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->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; |
| } |
| |
| /*********************************************************************** |
| * |
| * PageSetupDlg |
| * rad1 - portrait |
| * rad2 - landscape |
| * cmb1 - printer select (not in standart dialog template) |
| * cmb2 - paper size |
| * cmb3 - source (tray?) |
| * edt4 - border left |
| * edt5 - border top |
| * edt6 - border right |
| * edt7 - border bottom |
| * psh3 - "Printer..." |
| */ |
| |
| typedef struct { |
| LPPAGESETUPDLGA dlga; /* Handler to user defined struct */ |
| PRINTDLGA pdlg; |
| HWND hDlg; /* Page Setup dialog handler */ |
| PAGESETUPDLGA curdlg; /* Struct means cerrent dialog state */ |
| RECT rtDrawRect; /* Drawing rect for page */ |
| } 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) { |
| hResInfo = FindResourceA(lppd->hInstance, |
| lppd->lpPageSetupTemplateName, (LPSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceA(COMDLG32_hInstance,(LPCSTR)PAGESETUPDLGORD,(LPSTR)RT_DIALOG); |
| 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, (LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); |
| } else { |
| hResInfo = FindResourceW(COMDLG32_hInstance,(LPCWSTR)PAGESETUPDLGORD,(LPWSTR)RT_DIALOG); |
| hDlgTmpl = LoadResource(COMDLG32_hInstance,hResInfo); |
| } |
| return hDlgTmpl; |
| } |
| |
| static DWORD |
| _c_10mm2size(PAGESETUPDLGA *dlga,DWORD size) { |
| if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) |
| return 10*size*100/254; |
| /* If we don't have a flag, we can choose one. Use millimeters |
| * to avoid confusing me |
| */ |
| dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; |
| return 10*size; |
| } |
| |
| |
| static DWORD |
| _c_inch2size(PAGESETUPDLGA *dlga,DWORD size) { |
| if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) |
| return size; |
| if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) |
| return (size*254)/100; |
| /* if we don't have a flag, we can choose one. Use millimeters |
| * to avoid confusing me |
| */ |
| dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; |
| return (size*254)/100; |
| } |
| |
| static void |
| _c_size2strA(PageSetupDataA *pda,DWORD size,LPSTR strout) { |
| strcpy(strout,"<undef>"); |
| if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { |
| sprintf(strout,"%d",(size)/100); |
| return; |
| } |
| if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { |
| sprintf(strout,"%din",(size)/1000); |
| return; |
| } |
| pda->dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; |
| sprintf(strout,"%d",(size)/100); |
| return; |
| } |
| static void |
| _c_size2strW(PageSetupDataW *pda,DWORD size,LPWSTR strout) { |
| static const WCHAR UNDEF[] = { '<', 'u', 'n', 'd', 'e', 'f', '>', 0 }; |
| static const WCHAR mm_fmt[] = { '%', '.', '2', 'f', 'm', 'm', 0 }; |
| static const WCHAR in_fmt[] = { '%', '.', '2', 'f', 'i', 'n', 0 }; |
| lstrcpyW(strout, UNDEF); |
| if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { |
| wsprintfW(strout,mm_fmt,(size*1.0)/100.0); |
| return; |
| } |
| if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { |
| wsprintfW(strout,in_fmt,(size*1.0)/1000.0); |
| return; |
| } |
| pda->dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; |
| wsprintfW(strout,mm_fmt,(size*1.0)/100.0); |
| return; |
| } |
| |
| static DWORD |
| _c_str2sizeA(PAGESETUPDLGA *dlga,LPCSTR strin) { |
| float val; |
| char rest[200]; |
| |
| rest[0]='\0'; |
| if (!sscanf(strin,"%f%s",&val,rest)) |
| return 0; |
| |
| if (!strcmp(rest,"in") || !strcmp(rest,"inch")) { |
| if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) |
| return 1000*val; |
| else |
| return val*25.4*100; |
| } |
| if (!strcmp(rest,"cm")) { rest[0]='m'; val = val*10.0; } |
| if (!strcmp(rest,"m")) { strcpy(rest,"mm"); val = val*1000.0; } |
| |
| if (!strcmp(rest,"mm")) { |
| if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) |
| return 100*val; |
| else |
| return 1000.0*val/25.4; |
| } |
| if (rest[0]=='\0') { |
| /* use application supplied default */ |
| if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { |
| /* 100*mm */ |
| return 100.0*val; |
| } |
| if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { |
| /* 1000*inch */ |
| return 1000.0*val; |
| } |
| } |
| ERR("Did not find a conversion for type '%s'!\n",rest); |
| return 0; |
| } |
| |
| |
| static DWORD |
| _c_str2sizeW(PAGESETUPDLGW *dlga, LPCWSTR strin) { |
| char buf[200]; |
| |
| /* this W -> A transition is OK */ |
| /* we need a unicode version of sscanf to avoid it */ |
| WideCharToMultiByte(CP_ACP, 0, strin, -1, buf, sizeof(buf), NULL, NULL); |
| return _c_str2sizeA((PAGESETUPDLGA *)dlga, buf); |
| } |
| |
| |
| /**************************************************************************** |
| * PRINTDLG_PS_UpdateDlgStructA |
| * |
| * Updates pda->dlga structure |
| * Function calls when user presses OK button |
| * |
| * PARAMS |
| * hDlg [in] main window dialog HANDLE |
| * pda [in/out] ptr to PageSetupDataA structere |
| * |
| * RETURNS |
| * TRUE |
| */ |
| static BOOL |
| PRINTDLG_PS_UpdateDlgStructA(HWND hDlg, PageSetupDataA *pda) { |
| DEVNAMES *dn; |
| DEVMODEA *dm; |
| DWORD paperword; |
| |
| memcpy(pda->dlga, &pda->curdlg, sizeof(pda->curdlg)); |
| pda->dlga->hDevMode = pda->pdlg.hDevMode; |
| pda->dlga->hDevNames = pda->pdlg.hDevNames; |
| |
| dn = GlobalLock(pda->pdlg.hDevNames); |
| dm = GlobalLock(pda->pdlg.hDevMode); |
| |
| /* Save paper orientation into device context */ |
| if(pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y) |
| dm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; |
| else |
| dm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; |
| |
| /* Save paper size into the device context */ |
| paperword = SendDlgItemMessageA(hDlg,cmb2,CB_GETITEMDATA, |
| SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); |
| if (paperword != CB_ERR) |
| dm->u1.s1.dmPaperSize = paperword; |
| else |
| FIXME("could not get dialog text for papersize cmbbox?\n"); |
| |
| /* Save paper source into the device context */ |
| paperword = SendDlgItemMessageA(hDlg,cmb1,CB_GETITEMDATA, |
| SendDlgItemMessageA(hDlg, cmb1, CB_GETCURSEL, 0, 0), 0); |
| if (paperword != CB_ERR) |
| dm->dmDefaultSource = paperword; |
| else |
| FIXME("could not get dialog text for papersize cmbbox?\n"); |
| |
| GlobalUnlock(pda->pdlg.hDevNames); |
| GlobalUnlock(pda->pdlg.hDevMode); |
| |
| return TRUE; |
| } |
| |
| static BOOL |
| PRINTDLG_PS_UpdateDlgStructW(HWND hDlg, PageSetupDataW *pda) { |
| DEVNAMES *dn; |
| DEVMODEW *dm; |
| LPWSTR devname,portname; |
| WCHAR papername[64]; |
| WCHAR buf[200]; |
| |
| dn = GlobalLock(pda->pdlg.hDevNames); |
| dm = GlobalLock(pda->pdlg.hDevMode); |
| devname = ((WCHAR*)dn)+dn->wDeviceOffset; |
| portname = ((WCHAR*)dn)+dn->wOutputOffset; |
| |
| /* Save paper size into device context */ |
| PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb2,devname,portname,dm); |
| /* Save paper source into device context */ |
| 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 (GetDlgItemTextW(hDlg,id,buf,sizeof(buf)/sizeof(buf[0]))>0) { val = _c_str2sizeW(pda->dlga,buf); } else { FIXME("could not get dlgitemtextw 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; |
| } |
| |
| /********************************************************************************************** |
| * PRINTDLG_PS_ChangeActivePrinerA |
| * |
| * Redefines hDevMode and hDevNames HANDLES and initialises it. |
| * |
| * PARAMS |
| * name [in] Name of a printer for activation |
| * pda [in/out] ptr to PageSetupDataA structure |
| * |
| * RETURN |
| * TRUE if success |
| * FALSE if fail |
| */ |
| static BOOL |
| PRINTDLG_PS_ChangeActivePrinterA(LPSTR name, PageSetupDataA *pda){ |
| HANDLE hprn; |
| DWORD needed; |
| LPPRINTER_INFO_2A lpPrinterInfo; |
| LPDRIVER_INFO_3A lpDriverInfo; |
| DEVMODEA *pDevMode, *dm; |
| |
| if(!OpenPrinterA(name, &hprn, NULL)){ |
| ERR("Can't open printer %s\n", name); |
| return FALSE; |
| } |
| GetPrinterA(hprn, 2, NULL, 0, &needed); |
| lpPrinterInfo = HeapAlloc(GetProcessHeap(), 0, needed); |
| GetPrinterA(hprn, 2, (LPBYTE)lpPrinterInfo, needed, &needed); |
| GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); |
| lpDriverInfo = HeapAlloc(GetProcessHeap(), 0, needed); |
| if(!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)lpDriverInfo, needed, &needed)) { |
| ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo->pPrinterName); |
| return FALSE; |
| } |
| ClosePrinter(hprn); |
| |
| needed = DocumentPropertiesA(0, 0, name, NULL, NULL, 0); |
| if(needed == -1) { |
| ERR("DocumentProperties fails on %s\n", debugstr_a(name)); |
| return FALSE; |
| } |
| pDevMode = HeapAlloc(GetProcessHeap(), 0, needed); |
| DocumentPropertiesA(0, 0, name, pDevMode, NULL, DM_OUT_BUFFER); |
| |
| pda->pdlg.hDevMode = GlobalReAlloc(pda->pdlg.hDevMode, |
| pDevMode->dmSize + pDevMode->dmDriverExtra, |
| GMEM_MOVEABLE); |
| dm = GlobalLock(pda->pdlg.hDevMode); |
| memcpy(dm, pDevMode, pDevMode->dmSize + pDevMode->dmDriverExtra); |
| |
| PRINTDLG_CreateDevNames(&(pda->pdlg.hDevNames), |
| lpDriverInfo->pDriverPath, |
| lpPrinterInfo->pPrinterName, |
| lpPrinterInfo->pPortName); |
| |
| GlobalUnlock(pda->pdlg.hDevMode); |
| HeapFree(GetProcessHeap(), 0, pDevMode); |
| HeapFree(GetProcessHeap(), 0, lpPrinterInfo); |
| HeapFree(GetProcessHeap(), 0, lpDriverInfo); |
| return TRUE; |
| } |
| |
| /**************************************************************************************** |
| * PRINTDLG_PS_ChangePrinterA |
| * |
| * Fills Printers, Paper and Source combo |
| * |
| * RETURNS |
| * TRUE |
| */ |
| static BOOL |
| 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_SetUpPrinterListComboA(hDlg, cmb1, devname); |
| PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm); |
| PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm); |
| GlobalUnlock(pda->pdlg.hDevNames); |
| GlobalUnlock(pda->pdlg.hDevMode); |
| return TRUE; |
| } |
| |
| static BOOL |
| 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; |
| } |
| |
| /****************************************************************************************** |
| * PRINTDLG_PS_ChangePaperPrev |
| * |
| * Changes paper preview size / position |
| * |
| * PARAMS: |
| * pda [i] Pointer for current PageSetupDataA structure |
| * |
| * RETURNS: |
| * always - TRUE |
| */ |
| static BOOL |
| PRINTDLG_PS_ChangePaperPrev(PageSetupDataA *pda) |
| { |
| LONG width, height, x, y; |
| RECT rtTmp; |
| |
| if(pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y) { |
| width = pda->rtDrawRect.right - pda->rtDrawRect.left; |
| height = pda->curdlg.ptPaperSize.y * width / pda->curdlg.ptPaperSize.x; |
| } else { |
| height = pda->rtDrawRect.bottom - pda->rtDrawRect.top; |
| width = pda->curdlg.ptPaperSize.x * height / pda->curdlg.ptPaperSize.y; |
| } |
| x = (pda->rtDrawRect.right + pda->rtDrawRect.left - width) / 2; |
| y = (pda->rtDrawRect.bottom + pda->rtDrawRect.top - height) / 2; |
| TRACE("rtDrawRect(%d, %d, %d, %d) x=%d, y=%d, w=%d, h=%d\n", |
| pda->rtDrawRect.left, pda->rtDrawRect.top, pda->rtDrawRect.right, pda->rtDrawRect.bottom, |
| x, y, width, height); |
| |
| #define SHADOW 4 |
| MoveWindow(GetDlgItem(pda->hDlg, rct2), x+width, y+SHADOW, SHADOW, height, FALSE); |
| MoveWindow(GetDlgItem(pda->hDlg, rct3), x+SHADOW, y+height, width, SHADOW, FALSE); |
| MoveWindow(GetDlgItem(pda->hDlg, rct1), x, y, width, height, FALSE); |
| memcpy(&rtTmp, &pda->rtDrawRect, sizeof(RECT)); |
| rtTmp.right += SHADOW; |
| rtTmp.bottom += SHADOW; |
| #undef SHADOW |
| |
| InvalidateRect(pda->hDlg, &rtTmp, TRUE); |
| return TRUE; |
| } |
| |
| #define GETVAL(idc,val) \ |
| if(msg == EN_CHANGE){ \ |
| if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\ |
| val = _c_str2sizeA(pda->dlga,buf); \ |
| else\ |
| FIXME("could not get dlgitemtexta for %x\n",id); \ |
| } |
| |
| /******************************************************************************** |
| * PRINTDLG_PS_WMCommandA |
| * process WM_COMMAND message for PageSetupDlgA |
| * |
| * PARAMS |
| * hDlg [in] Main dialog HANDLE |
| * wParam [in] WM_COMMAND wParam |
| * lParam [in] WM_COMMAND lParam |
| * pda [in/out] ptr to PageSetupDataA |
| */ |
| |
| static BOOL |
| PRINTDLG_PS_WMCommandA( |
| HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataA *pda |
| ) { |
| WORD msg = HIWORD(wParam); |
| WORD id = LOWORD(wParam); |
| char buf[200]; |
| |
| TRACE("loword (lparam) %d, wparam 0x%x, lparam %08lx\n", |
| LOWORD(lParam),wParam,lParam); |
| switch (id) { |
| case IDOK: |
| if (!PRINTDLG_PS_UpdateDlgStructA(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 (PrintDlgA(&(pda->pdlg))) |
| PRINTDLG_PS_ChangePrinterA(hDlg,pda); |
| } |
| return TRUE; |
| case rad1: |
| if (pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y){ |
| DWORD tmp = pda->curdlg.ptPaperSize.x; |
| pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; |
| pda->curdlg.ptPaperSize.y = tmp; |
| } |
| PRINTDLG_PS_ChangePaperPrev(pda); |
| break; |
| case rad2: |
| if (pda->curdlg.ptPaperSize.y > pda->curdlg.ptPaperSize.x){ |
| DWORD tmp = pda->curdlg.ptPaperSize.x; |
| pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; |
| pda->curdlg.ptPaperSize.y = tmp; |
| } |
| PRINTDLG_PS_ChangePaperPrev(pda); |
| break; |
| case cmb1: /* Printer combo */ |
| if(msg == CBN_SELCHANGE){ |
| char crPrinterName[256]; |
| GetDlgItemTextA(hDlg, id, crPrinterName, 255); |
| PRINTDLG_PS_ChangeActivePrinterA(crPrinterName, pda); |
| PRINTDLG_PS_ChangePrinterA(hDlg, pda); |
| } |
| break; |
| case cmb2: /* Paper combo */ |
| if(msg == CBN_SELCHANGE){ |
| DWORD paperword = SendDlgItemMessageA(hDlg,cmb2,CB_GETITEMDATA, |
| SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); |
| if (paperword != CB_ERR) { |
| PRINTDLG_PaperSizeA(&(pda->pdlg), paperword,&(pda->curdlg.ptPaperSize)); |
| pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga,pda->curdlg.ptPaperSize.x); |
| pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga,pda->curdlg.ptPaperSize.y); |
| |
| if (IsDlgButtonChecked(hDlg, rad2)) { |
| DWORD tmp = pda->curdlg.ptPaperSize.x; |
| pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; |
| pda->curdlg.ptPaperSize.y = tmp; |
| } |
| PRINTDLG_PS_ChangePaperPrev(pda); |
| } else |
| FIXME("could not get dialog text for papersize cmbbox?\n"); |
| } |
| break; |
| case cmb3: |
| if(msg == CBN_SELCHANGE){ |
| DEVMODEA *dm = GlobalLock(pda->pdlg.hDevMode); |
| dm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3,CB_GETITEMDATA, |
| SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0), 0); |
| GlobalUnlock(pda->pdlg.hDevMode); |
| } |
| break; |
| case psh2: /* Printer Properties button */ |
| { |
| HANDLE hPrinter; |
| char PrinterName[256]; |
| DEVMODEA *dm; |
| LRESULT count; |
| int i; |
| |
| GetDlgItemTextA(hDlg, cmb1, PrinterName, 255); |
| if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { |
| FIXME("Call to OpenPrinter did not succeed!\n"); |
| break; |
| } |
| dm = GlobalLock(pda->pdlg.hDevMode); |
| DocumentPropertiesA(hDlg, hPrinter, PrinterName, dm, dm, |
| DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); |
| ClosePrinter(hPrinter); |
| /* Changing paper */ |
| PRINTDLG_PaperSizeA(&(pda->pdlg), dm->u1.s1.dmPaperSize, &(pda->curdlg.ptPaperSize)); |
| pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.x); |
| pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.y); |
| if (dm->u1.s1.dmOrientation == DMORIENT_LANDSCAPE){ |
| DWORD tmp = pda->curdlg.ptPaperSize.x; |
| pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; |
| pda->curdlg.ptPaperSize.y = tmp; |
| CheckRadioButton(hDlg, rad1, rad2, rad2); |
| } |
| else |
| CheckRadioButton(hDlg, rad1, rad2, rad1); |
| /* Changing paper preview */ |
| PRINTDLG_PS_ChangePaperPrev(pda); |
| /* Selecting paper in combo */ |
| count = SendDlgItemMessageA(hDlg, cmb2, CB_GETCOUNT, 0, 0); |
| if(count != CB_ERR){ |
| for(i=0; i<count; ++i){ |
| if(SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0) == dm->u1.s1.dmPaperSize) { |
| SendDlgItemMessageA(hDlg, cmb2, CB_SETCURSEL, i, 0); |
| break; |
| } |
| } |
| } |
| |
| GlobalUnlock(pda->pdlg.hDevMode); |
| break; |
| } |
| case edt4: |
| GETVAL(id, pda->curdlg.rtMargin.left); |
| break; |
| case edt5: |
| GETVAL(id, pda->curdlg.rtMargin.right); |
| break; |
| case edt6: |
| GETVAL(id, pda->curdlg.rtMargin.top); |
| break; |
| case edt7: |
| GETVAL(id, pda->curdlg.rtMargin.bottom); |
| break; |
| } |
| InvalidateRect(GetDlgItem(hDlg, rct1), NULL, TRUE); |
| return FALSE; |
| } |
| #undef GETVAL |
| |
| static BOOL |
| PRINTDLG_PS_WMCommandW( |
| HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataW *pda |
| ) { |
| TRACE("loword (lparam) %d, wparam 0x%x, lparam %08lx\n", |
| LOWORD(lParam),wParam,lParam); |
| 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; |
| } |
| } |
| return FALSE; |
| } |
| |
| |
| /*********************************************************************** |
| * DefaultPagePaintHook |
| * Default hook paint procedure that receives WM_PSD_* messages from the dialog box |
| * whenever the sample page is redrawn. |
| */ |
| |
| static UINT_PTR |
| PRINTDLG_DefaultPagePaintHook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, PageSetupDataA *pda) |
| { |
| LPRECT lprc = (LPRECT) lParam; |
| HDC hdc = (HDC) wParam; |
| HPEN hpen, holdpen; |
| LOGFONTW lf; |
| HFONT hfont, holdfont; |
| INT oldbkmode; |
| TRACE("uMsg: WM_USER+%d\n",uMsg-WM_USER); |
| /* Call user paint hook if enable */ |
| if (pda->dlga->Flags & PSD_ENABLEPAGEPAINTHOOK) |
| if (pda->dlga->lpfnPagePaintHook(hwndDlg, uMsg, wParam, lParam)) |
| return TRUE; |
| |
| switch (uMsg) { |
| /* LPPAGESETUPDLG in lParam */ |
| case WM_PSD_PAGESETUPDLG: |
| /* Inform about the sample page rectangle */ |
| case WM_PSD_FULLPAGERECT: |
| /* Inform about the margin rectangle */ |
| case WM_PSD_MINMARGINRECT: |
| return FALSE; |
| |
| /* Draw dashed rectangle showing margins */ |
| case WM_PSD_MARGINRECT: |
| hpen = CreatePen(PS_DASH, 1, GetSysColor(COLOR_3DSHADOW)); |
| holdpen = SelectObject(hdc, hpen); |
| Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); |
| DeleteObject(SelectObject(hdc, holdpen)); |
| return TRUE; |
| /* Draw the fake document */ |
| case WM_PSD_GREEKTEXTRECT: |
| /* select a nice scalable font, because we want the text really small */ |
| SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); |
| lf.lfHeight = 6; /* value chosen based on visual effect */ |
| hfont = CreateFontIndirectW(&lf); |
| holdfont = SelectObject(hdc, hfont); |
| |
| /* if text not loaded, then do so now */ |
| if (wszFakeDocumentText[0] == '\0') |
| LoadStringW(COMDLG32_hInstance, |
| IDS_FAKEDOCTEXT, |
| wszFakeDocumentText, |
| sizeof(wszFakeDocumentText)/sizeof(wszFakeDocumentText[0])); |
| |
| oldbkmode = SetBkMode(hdc, TRANSPARENT); |
| DrawTextW(hdc, wszFakeDocumentText, -1, lprc, DT_TOP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK); |
| SetBkMode(hdc, oldbkmode); |
| |
| DeleteObject(SelectObject(hdc, holdfont)); |
| return TRUE; |
| |
| /* Envelope stamp */ |
| case WM_PSD_ENVSTAMPRECT: |
| /* Return address */ |
| case WM_PSD_YAFULLPAGERECT: |
| FIXME("envelope/stamp is not implemented\n"); |
| return FALSE; |
| default: |
| FIXME("Unknown message %x\n",uMsg); |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| /*********************************************************************** |
| * PagePaintProc |
| * The main paint procedure for the PageSetupDlg function. |
| * The Page Setup dialog box includes an image of a sample page that shows how |
| * the user's selections affect the appearance of the printed output. |
| * The image consists of a rectangle that represents the selected paper |
| * or envelope type, with a dotted-line rectangle representing |
| * the current margins, and partial (Greek text) characters |
| * to show how text looks on the printed page. |
| * |
| * The following messages in the order sends to user hook procedure: |
| * WM_PSD_PAGESETUPDLG Draw the contents of the sample page |
| * WM_PSD_FULLPAGERECT Inform about the bounding rectangle |
| * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?) |
| * WM_PSD_MARGINRECT Draw the margin rectangle |
| * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle |
| * If any of first three messages returns TRUE, painting done. |
| * |
| * PARAMS: |
| * hWnd [in] Handle to the Page Setup dialog box |
| * uMsg [in] Received message |
| * |
| * TODO: |
| * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only) |
| * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes) |
| * |
| * RETURNS: |
| * FALSE if all done correctly |
| * |
| */ |
| |
| |
| static LRESULT CALLBACK |
| PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| { |
| PAINTSTRUCT ps; |
| RECT rcClient, rcMargin; |
| HPEN hpen, holdpen; |
| HDC hdc; |
| HBRUSH hbrush, holdbrush; |
| PageSetupDataA *pda; |
| int papersize=0, orientation=0; /* FIXME: set this values for user paint hook */ |
| double scalx, scaly; |
| #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda) |
| |
| if (uMsg != WM_PAINT) |
| return CallWindowProcA(lpfnStaticWndProc, hWnd, uMsg, wParam, lParam); |
| |
| /* Processing WM_PAINT message */ |
| pda = (PageSetupDataA*)GetPropA(hWnd, "__WINE_PAGESETUPDLGDATA"); |
| if (!pda) { |
| WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); |
| return FALSE; |
| } |
| if (PRINTDLG_DefaultPagePaintHook(hWnd, WM_PSD_PAGESETUPDLG, MAKELONG(papersize, orientation), (LPARAM)pda->dlga, pda)) |
| return FALSE; |
| |
| hdc = BeginPaint(hWnd, &ps); |
| GetClientRect(hWnd, &rcClient); |
| |
| scalx = rcClient.right / (double)pda->curdlg.ptPaperSize.x; |
| scaly = rcClient.bottom / (double)pda->curdlg.ptPaperSize.y; |
| rcMargin = rcClient; |
| |
| rcMargin.left += (LONG)pda->curdlg.rtMargin.left * scalx; |
| rcMargin.top += (LONG)pda->curdlg.rtMargin.top * scalx; |
| rcMargin.right -= (LONG)pda->curdlg.rtMargin.right * scaly; |
| rcMargin.bottom -= (LONG)pda->curdlg.rtMargin.bottom * scaly; |
| |
| /* if the space is too small then we make sure to not draw anything */ |
| rcMargin.left = min(rcMargin.left, rcMargin.right); |
| rcMargin.top = min(rcMargin.top, rcMargin.bottom); |
| |
| if (!CALLPAINTHOOK(WM_PSD_FULLPAGERECT, &rcClient) && |
| !CALLPAINTHOOK(WM_PSD_MINMARGINRECT, &rcMargin) ) |
| { |
| /* fill background */ |
| hbrush = GetSysColorBrush(COLOR_3DHIGHLIGHT); |
| FillRect(hdc, &rcClient, hbrush); |
| holdbrush = SelectObject(hdc, hbrush); |
| |
| hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); |
| holdpen = SelectObject(hdc, hpen); |
| |
| /* paint left edge */ |
| MoveToEx(hdc, rcClient.left, rcClient.top, NULL); |
| LineTo(hdc, rcClient.left, rcClient.bottom-1); |
| |
| /* paint top edge */ |
| MoveToEx(hdc, rcClient.left, rcClient.top, NULL); |
| LineTo(hdc, rcClient.right, rcClient.top); |
| |
| hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)); |
| DeleteObject(SelectObject(hdc, hpen)); |
| |
| /* paint right edge */ |
| MoveToEx(hdc, rcClient.right-1, rcClient.top, NULL); |
| LineTo(hdc, rcClient.right-1, rcClient.bottom); |
| |
| /* paint bottom edge */ |
| MoveToEx(hdc, rcClient.left, rcClient.bottom-1, NULL); |
| LineTo(hdc, rcClient.right, rcClient.bottom-1); |
| |
| DeleteObject(SelectObject(hdc, holdpen)); |
| DeleteObject(SelectObject(hdc, holdbrush)); |
| |
| CALLPAINTHOOK(WM_PSD_MARGINRECT, &rcMargin); |
| |
| /* give text a bit of a space from the frame */ |
| rcMargin.left += 2; |
| rcMargin.top += 2; |
| rcMargin.right -= 2; |
| rcMargin.bottom -= 2; |
| |
| /* if the space is too small then we make sure to not draw anything */ |
| rcMargin.left = min(rcMargin.left, rcMargin.right); |
| rcMargin.top = min(rcMargin.top, rcMargin.bottom); |
| |
| CALLPAINTHOOK(WM_PSD_GREEKTEXTRECT, &rcMargin); |
| } |
| |
| EndPaint(hWnd, &ps); |
| return FALSE; |
| #undef CALLPAINTHOOK |
| } |
| |
| /*********************************************************************** |
| * PRINTDLG_PageDlgProcA |
| * Message handler for PageSetupDlgA |
| */ |
| static INT_PTR CALLBACK |
| PRINTDLG_PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| { |
| DEVMODEA *dm; |
| PageSetupDataA *pda; |
| INT_PTR res = FALSE; |
| HWND hDrawWnd; |
| |
| if (uMsg == WM_INITDIALOG) { /*Init dialog*/ |
| pda = (PageSetupDataA*)lParam; |
| pda->hDlg = hDlg; /* saving handle to main window to PageSetupDataA structure */ |
| memcpy(&pda->curdlg, pda->dlga, sizeof(pda->curdlg)); |
| |
| hDrawWnd = GetDlgItem(hDlg, rct1); |
| TRACE("set property to %p\n", pda); |
| SetPropA(hDlg, "__WINE_PAGESETUPDLGDATA", pda); |
| SetPropA(hDrawWnd, "__WINE_PAGESETUPDLGDATA", pda); |
| GetWindowRect(hDrawWnd, &pda->rtDrawRect); /* Calculating rect in client coordinates where paper draws */ |
| ScreenToClient(hDlg, (LPPOINT)&pda->rtDrawRect); |
| ScreenToClient(hDlg, (LPPOINT)(&pda->rtDrawRect.right)); |
| lpfnStaticWndProc = (WNDPROC)SetWindowLongPtrW( |
| hDrawWnd, |
| GWLP_WNDPROC, |
| (ULONG_PTR)PRINTDLG_PagePaintProc); |
| |
| /* FIXME: Paint hook. Must it be at begin of initializtion or at end? */ |
| res = TRUE; |
| if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) { |
| if (!pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,(LPARAM)pda->dlga)) |
| FIXME("Setup page hook failed?\n"); |
| } |
| |
| /* if printer button disabled */ |
| if (pda->dlga->Flags & PSD_DISABLEPRINTER) |
| EnableWindow(GetDlgItem(hDlg, psh3), FALSE); |
| /* if margin edit boxes disabled */ |
| 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); |
| } |
| /* Set orientation radiobutton properly */ |
| dm = GlobalLock(pda->dlga->hDevMode); |
| if (dm->u1.s1.dmOrientation == DMORIENT_LANDSCAPE) |
| CheckRadioButton(hDlg, rad1, rad2, rad2); |
| else /* this is default if papersize is not set */ |
| CheckRadioButton(hDlg, rad1, rad2, rad1); |
| GlobalUnlock(pda->dlga->hDevMode); |
| |
| /* if orientation disabled */ |
| 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_size2strA(pda,pda->dlga->rtMargin.left,str); |
| SetDlgItemTextA(hDlg,edt4,str); |
| _c_size2strA(pda,pda->dlga->rtMargin.top,str); |
| SetDlgItemTextA(hDlg,edt5,str); |
| _c_size2strA(pda,pda->dlga->rtMargin.right,str); |
| SetDlgItemTextA(hDlg,edt6,str); |
| _c_size2strA(pda,pda->dlga->rtMargin.bottom,str); |
| SetDlgItemTextA(hDlg,edt7,str); |
| } else { |
| /* default is 1 inch */ |
| DWORD size = _c_inch2size(pda->dlga,1000); |
| char str[20]; |
| _c_size2strA(pda,size,str); |
| SetDlgItemTextA(hDlg,edt4,str); |
| SetDlgItemTextA(hDlg,edt5,str); |
| SetDlgItemTextA(hDlg,edt6,str); |
| SetDlgItemTextA(hDlg,edt7,str); |
| pda->curdlg.rtMargin.left = size; |
| pda->curdlg.rtMargin.top = size; |
| pda->curdlg.rtMargin.right = size; |
| pda->curdlg.rtMargin.bottom = size; |
| } |
| /* if paper disabled */ |
| if (pda->dlga->Flags & PSD_DISABLEPAPER) { |
| EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); |
| EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); |
| } |
| /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */ |
| PRINTDLG_PS_ChangePrinterA(hDlg, pda); |
| dm = GlobalLock(pda->pdlg.hDevMode); |
| if(dm){ |
| dm->dmDefaultSource = 15; /*FIXME: Automatic select. Does it always 15 at start? */ |
| PRINTDLG_PaperSizeA(&(pda->pdlg), dm->u1.s1.dmPaperSize, &pda->curdlg.ptPaperSize); |
| GlobalUnlock(pda->pdlg.hDevMode); |
| pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.x); |
| pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.y); |
| if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) { /* Landscape orientation */ |
| DWORD tmp = pda->curdlg.ptPaperSize.y; |
| pda->curdlg.ptPaperSize.y = pda->curdlg.ptPaperSize.x; |
| pda->curdlg.ptPaperSize.x = tmp; |
| } |
| } else |
| WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%p\n", pda->pdlg.hDevMode); |
| /* Drawing paper prev */ |
| PRINTDLG_PS_ChangePaperPrev(pda); |
| return TRUE; |
| } else { |
| pda = (PageSetupDataA*)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_WMCommandA(hDlg, wParam, lParam, pda); |
| } |
| return FALSE; |
| } |
| |
| static INT_PTR CALLBACK |
| PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) |
| { |
| static const WCHAR __WINE_PAGESETUPDLGDATA[] = |
| { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E', |
| 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 }; |
| PageSetupDataW *pda; |
| BOOL res = FALSE; |
| |
| if (uMsg==WM_INITDIALOG) { |
| res = TRUE; |
| pda = (PageSetupDataW*)lParam; |
| SetPropW(hDlg, __WINE_PAGESETUPDLGDATA, pda); |
| if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) { |
| res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,(LPARAM)pda->dlga); |
| 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) { |
| WCHAR str[100]; |
| _c_size2strW(pda,pda->dlga->rtMargin.left,str); |
| SetDlgItemTextW(hDlg,edt4,str); |
| _c_size2strW(pda,pda->dlga->rtMargin.top,str); |
| SetDlgItemTextW(hDlg,edt5,str); |
| _c_size2strW(pda,pda->dlga->rtMargin.right,str); |
| SetDlgItemTextW(hDlg,edt6,str); |
| _c_size2strW(pda,pda->dlga->rtMargin.bottom,str); |
| SetDlgItemTextW(hDlg,edt7,str); |
| } else { |
| /* default is 1 inch */ |
| DWORD size = _c_inch2size((LPPAGESETUPDLGA)pda->dlga,1000); |
| WCHAR str[20]; |
| _c_size2strW(pda,size,str); |
| SetDlgItemTextW(hDlg,edt4,str); |
| SetDlgItemTextW(hDlg,edt5,str); |
| SetDlgItemTextW(hDlg,edt6,str); |
| SetDlgItemTextW(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*)GetPropW(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; |
| } |
| |
| /*********************************************************************** |
| * PageSetupDlgA (COMDLG32.@) |
| * |
| * Displays the the PAGE SETUP dialog box, which enables the user to specify |
| * specific properties of a printed page such as |
| * size, source, orientation and the width of the page margins. |
| * |
| * PARAMS |
| * setupdlg [IO] PAGESETUPDLGA struct |
| * |
| * RETURNS |
| * TRUE if the user pressed the OK button |
| * FALSE if the user cancelled the window or an error occurred |
| * |
| * NOTES |
| * The values of hDevMode and hDevNames are filled on output and can be |
| * changed in PAGESETUPDLG when they are passed in PageSetupDlg. |
| * |
| */ |
| |
| BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) { |
| HGLOBAL hDlgTmpl; |
| LPVOID ptr; |
| BOOL bRet; |
| PageSetupDataA *pda; |
| PRINTDLGA pdlg; |
| |
| /* TRACE */ |
| 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 = %p, hDevMode = %p, hDevNames = %p\n" |
| "hinst %p, flags %08x (%s)\n", |
| setupdlg, setupdlg->hwndOwner, setupdlg->hDevMode, |
| setupdlg->hDevNames, |
| setupdlg->hInstance, setupdlg->Flags, flagstr); |
| } |
| /* Checking setupdlg structure */ |
| if (setupdlg == NULL) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); |
| return FALSE; |
| } |
| if(setupdlg->lStructSize != sizeof(PAGESETUPDLGA)) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); |
| return FALSE; |
| } |
| if ((setupdlg->Flags & PSD_ENABLEPAGEPAINTHOOK) && |
| (setupdlg->lpfnPagePaintHook == NULL)) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); |
| return FALSE; |
| } |
| |
| /* Initialize default printer struct. If no printer device info is specified |
| retrieve the default printer data. */ |
| memset(&pdlg,0,sizeof(pdlg)); |
| pdlg.lStructSize = sizeof(pdlg); |
| if (setupdlg->hDevMode && setupdlg->hDevNames) { |
| pdlg.hDevMode = setupdlg->hDevMode; |
| pdlg.hDevNames = setupdlg->hDevNames; |
| } else { |
| pdlg.Flags = PD_RETURNDEFAULT; |
| bRet = PrintDlgA(&pdlg); |
| if (!bRet){ |
| if (!(setupdlg->Flags & PSD_NOWARNING)) { |
| char errstr[256]; |
| LoadStringA(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255); |
| MessageBoxA(setupdlg->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR); |
| } |
| return FALSE; |
| } |
| } |
| |
| /* short cut exit, just return default values */ |
| if (setupdlg->Flags & PSD_RETURNDEFAULT) { |
| DEVMODEA *dm; |
| |
| dm = GlobalLock(pdlg.hDevMode); |
| PRINTDLG_PaperSizeA(&pdlg, dm->u1.s1.dmPaperSize, &setupdlg->ptPaperSize); |
| GlobalUnlock(pdlg.hDevMode); |
| setupdlg->ptPaperSize.x=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.x); |
| setupdlg->ptPaperSize.y=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.y); |
| return TRUE; |
| } |
| |
| /* get dialog template */ |
| hDlgTmpl = PRINTDLG_GetPGSTemplateA(setupdlg); |
| if (!hDlgTmpl) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| return FALSE; |
| } |
| ptr = LockResource( hDlgTmpl ); |
| if (!ptr) { |
| COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); |
| return FALSE; |
| } |
| |
| pda = HeapAlloc(GetProcessHeap(),0,sizeof(*pda)); |
| pda->dlga = setupdlg; |
| memcpy(&pda->pdlg,&pdlg,sizeof(pdlg)); |
| |
| bRet = (0<DialogBoxIndirectParamA( |
| setupdlg->hInstance, |
| ptr, |
| setupdlg->hwndOwner, |
| PRINTDLG_PageDlgProcA, |
| (LPARAM)pda) |
| ); |
| |
| HeapFree(GetProcessHeap(),0,pda); |
| return bRet; |
| } |
| /*********************************************************************** |
| * PageSetupDlgW (COMDLG32.@) |
| * |
| * See PageSetupDlgA. |
| */ |
| BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) { |
| HGLOBAL hDlgTmpl; |
| LPVOID ptr; |
| BOOL bRet; |
| PageSetupDataW *pdw; |
| PRINTDLGW pdlg; |
| |
| FIXME("Unicode implementation is not done yet\n"); |
| 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 = %p, hDevMode = %p, hDevNames = %p\n" |
| "hinst %p, flags %08x (%s)\n", |
| setupdlg, setupdlg->hwndOwner, setupdlg->hDevMode, |
| setupdlg->hDevNames, |
| setupdlg->hInstance, setupdlg->Flags, flagstr); |
| } |
| |
| /* Initialize default printer struct. If no printer device info is specified |
| retrieve the default printer data. */ |
| memset(&pdlg,0,sizeof(pdlg)); |
| pdlg.lStructSize = sizeof(pdlg); |
| if (setupdlg->hDevMode && setupdlg->hDevNames) { |
| pdlg.hDevMode = setupdlg->hDevMode; |
| pdlg.hDevNames = setupdlg->hDevNames; |
| } else { |
| pdlg.Flags = PD_RETURNDEFAULT; |
| bRet = PrintDlgW(&pdlg); |
| if (!bRet){ |
| if (!(setupdlg->Flags & PSD_NOWARNING)) { |
| WCHAR errstr[256]; |
| LoadStringW(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255); |
| MessageBoxW(setupdlg->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR); |
| } |
| return FALSE; |
| } |
| } |
| |
| /* short cut exit, just return default values */ |
| if (setupdlg->Flags & PSD_RETURNDEFAULT) { |
| static 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; |
| } |
| |
| /*********************************************************************** |
| * PrintDlgExA (COMDLG32.@) |
| * |
| * See PrintDlgExW. |
| * |
| * FIXME |
| * Stub |
| */ |
| HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lpPrintDlgExA) |
| { |
| FIXME("stub\n"); |
| return E_NOTIMPL; |
| } |
| |
| /*********************************************************************** |
| * PrintDlgExW (COMDLG32.@) |
| * |
| * Display the the PRINT dialog box, which enables the user to specify |
| * specific properties of the print job. The property sheet can also have |
| * additional application-specific and driver-specific property pages. |
| * |
| * PARAMS |
| * lppd [IO] ptr to PRINTDLGEX struct |
| * |
| * RETURNS |
| * Success: S_OK |
| * Failure: One of the following COM error codes: |
| * E_OUTOFMEMORY Insufficient memory. |
| * E_INVALIDARG One or more arguments are invalid. |
| * E_POINTER Invalid pointer. |
| * E_HANDLE Invalid handle. |
| * E_FAIL Unspecified error. |
| * |
| * FIXME |
| * Stub |
| */ |
| HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lpPrintDlgExW) |
| { |
| FIXME("stub\n"); |
| return E_NOTIMPL; |
| } |