From b8cab4989a6c75f55bf72d62ad3b2c037c6b965a Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Thu, 11 Apr 2002 17:32:49 +0000 Subject: [PATCH] Implemented PrintDlgW and PageSetupDlgW. --- dlls/commdlg/printdlg.c | 1653 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 1495 insertions(+), 158 deletions(-) diff --git a/dlls/commdlg/printdlg.c b/dlls/commdlg/printdlg.c index 9a57a868019..e5b79684eb2 100644 --- a/dlls/commdlg/printdlg.c +++ b/dlls/commdlg/printdlg.c @@ -62,6 +62,22 @@ typedef struct HWND hwndUpDown; } PRINT_PTRA; +typedef struct +{ + LPDEVMODEW lpDevMode; + struct { + LPPRINTDLGW lpPrintDlg; + } dlg; + LPPRINTER_INFO_2W lpPrinterInfo; + LPDRIVER_INFO_3W lpDriverInfo; + UINT HelpMessageID; + HICON hCollateIcon; /* PrintDlg only */ + HICON hNoCollateIcon; /* PrintDlg only */ + HICON hPortraitIcon; /* PrintSetupDlg only */ + HICON hLandscapeIcon; /* PrintSetupDlg only */ + HWND hwndUpDown; +} PRINT_PTRW; + /* Debugging info */ static struct pd_flags { DWORD flag; @@ -126,7 +142,7 @@ static struct pd_flags psd_flags[] = { * * Returns TRUE on success else FALSE */ -static BOOL PRINTDLG_GetDefaultPrinterName(LPSTR buf, DWORD len) +static BOOL PRINTDLG_GetDefaultPrinterNameA(LPSTR buf, DWORD len) { char *ptr; @@ -142,6 +158,27 @@ static BOOL PRINTDLG_GetDefaultPrinterName(LPSTR buf, DWORD len) return TRUE; } +static BOOL PRINTDLG_GetDefaultPrinterNameW(LPWSTR buf, DWORD len) +{ + LPSTR ptr, bufA = (LPSTR)HeapAlloc(GetProcessHeap(),0,len+1); + + + if(!GetProfileStringA("windows", "device", "", bufA, len)) { + TRACE("No profile entry for default printer found.\n"); + HeapFree(GetProcessHeap(),0,bufA); + return FALSE; + } + if((ptr = strchr(bufA, ',')) == NULL) { + FIXME("bad format for default printer (%s)!\n",bufA); + HeapFree(GetProcessHeap(),0,bufA); + return FALSE; + } + *ptr = '\0'; + MultiByteToWideChar( CP_ACP, 0, bufA, -1, buf, len ); + HeapFree(GetProcessHeap(),0,bufA); + return TRUE; +} + /*********************************************************************** * PRINTDLG_OpenDefaultPrinter * @@ -154,7 +191,7 @@ static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) { char buf[260]; BOOL res; - if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf))) + if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf))) return FALSE; res = OpenPrinterA(buf, hprn, NULL); if (!res) @@ -175,7 +212,7 @@ static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) * * Returns number of printers added to list. */ -static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name) +static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) { DWORD needed, num; INT i; @@ -197,7 +234,7 @@ static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name) char buf[260]; FIXME("Can't find '%s' in printer list so trying to find default\n", name); - if(!PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf))) + if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf))) return num; i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); if(i == CB_ERR) @@ -207,6 +244,39 @@ static INT PRINTDLG_SetUpPrinterListCombo(HWND hDlg, UINT id, LPCSTR name) 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) { + + /* ansi is ok */ + char buf[260]; + FIXME("Can't find '%s' in printer list so trying to find default\n", + debugstr_w(name)); + if(!PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf))) + return num; + i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); + if(i == CB_ERR) + FIXME("Can't find default printer in printer list\n"); + } + SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0); + return num; +} + /*********************************************************************** * PRINTDLG_CreateDevNames [internal] * @@ -251,12 +321,57 @@ static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, char* DeviceDriverName, strcpy(pTempPtr, OutputPort); lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; - PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)); + PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)); lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; GlobalUnlock(*hmem); return TRUE; } +static BOOL PRINTDLG_CreateDevNamesW(HGLOBAL *hmem, LPCWSTR DeviceDriverName, + LPCWSTR DeviceName, LPCWSTR OutputPort) +{ + long size; + LPWSTR pDevNamesSpace; + LPWSTR pTempPtr; + LPDEVNAMES lpDevNames; + WCHAR bufW[260]; + char buf[260]; + + size = sizeof(WCHAR)*lstrlenW(DeviceDriverName) + 2 + + sizeof(WCHAR)*lstrlenW(DeviceName) + 2 + + sizeof(WCHAR)*lstrlenW(OutputPort) + 2 + + sizeof(DEVNAMES); + + if(*hmem) + *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); + else + *hmem = GlobalAlloc(GMEM_MOVEABLE, size); + if (*hmem == 0) + return FALSE; + + pDevNamesSpace = GlobalLock(*hmem); + lpDevNames = (LPDEVNAMES) pDevNamesSpace; + + pTempPtr = (LPWSTR)((LPDEVNAMES)pDevNamesSpace + 1); + lstrcpyW(pTempPtr, DeviceDriverName); + lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; + + pTempPtr += lstrlenW(DeviceDriverName) + 1; + lstrcpyW(pTempPtr, DeviceName); + lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; + + pTempPtr += lstrlenW(DeviceName) + 1; + lstrcpyW(pTempPtr, OutputPort); + lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; + + PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)); + MultiByteToWideChar(CP_ACP, 0, buf, -1, bufW, -1); + lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0; + GlobalUnlock(*hmem); + return TRUE; +} + + static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName, char* DeviceName, char* OutputPort) { @@ -293,7 +408,7 @@ static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName, strcpy(pTempPtr, OutputPort); lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; - PRINTDLG_GetDefaultPrinterName(buf, sizeof(buf)); + PRINTDLG_GetDefaultPrinterNameA(buf, sizeof(buf)); lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; GlobalUnlock16(*hmem); return TRUE; @@ -310,7 +425,7 @@ static BOOL PRINTDLG_CreateDevNames16(HGLOBAL16 *hmem, char* DeviceDriverName, * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values) * TRUE if succesful. */ -static BOOL PRINTDLG_UpdatePrintDlg(HWND hDlg, +static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg, PRINT_PTRA* PrintStructures) { LPPRINTDLGA lppd = PrintStructures->dlg.lpPrintDlg; @@ -384,7 +499,82 @@ static BOOL PRINTDLG_UpdatePrintDlg(HWND hDlg, return TRUE; } -static BOOL PRINTDLG_PaperSize( +static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg, + PRINT_PTRW* PrintStructures) +{ + LPPRINTDLGW lppd = PrintStructures->dlg.lpPrintDlg; + PDEVMODEW lpdm = PrintStructures->lpDevMode; + LPPRINTER_INFO_2W pi = PrintStructures->lpPrinterInfo; + + + if(!lpdm) { + FIXME("No lpdm ptr?\n"); + return FALSE; + } + + + if(!(lppd->Flags & PD_PRINTSETUP)) { + /* check whether nFromPage and nToPage are within range defined by + * nMinPage and nMaxPage + */ + if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ + WORD nToPage; + WORD nFromPage; + nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); + nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); + if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage || + nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) { + char resourcestr[256]; + char resultstr[256]; + LoadStringA(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, + resourcestr, 255); + sprintf(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage); + LoadStringA(COMDLG32_hInstance, PD32_PRINT_TITLE, + resourcestr, 255); + MessageBoxA(hDlg, resultstr, resourcestr, + MB_OK | MB_ICONWARNING); + return FALSE; + } + lppd->nFromPage = nFromPage; + lppd->nToPage = nToPage; + } + + if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ + static WCHAR file[] = {'F','I','L','E',':',0}; + lppd->Flags |= PD_PRINTTOFILE; + pi->pPortName = file; + } + + if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ + FIXME("Collate lppd not yet implemented as output\n"); + } + + /* set PD_Collate and nCopies */ + if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { + /* The application doesn't support multiple copies or collate... + */ + lppd->Flags &= ~PD_COLLATE; + lppd->nCopies = 1; + /* if the printer driver supports it... store info there + * otherwise no collate & multiple copies ! + */ + if (lpdm->dmFields & DM_COLLATE) + lpdm->dmCollate = + (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); + if (lpdm->dmFields & DM_COPIES) + lpdm->dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); + } else { + if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) + lppd->Flags |= PD_COLLATE; + else + lppd->Flags &= ~PD_COLLATE; + lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); + } + } + return TRUE; +} + +static BOOL PRINTDLG_PaperSizeA( PRINTDLGA *pdlga,const char *PaperSize,LPPOINT size ) { DEVNAMES *dn; @@ -433,7 +623,64 @@ static BOOL PRINTDLG_PaperSize( /* this is _10ths_ of a millimeter */ size->x=points[i].x; size->y=points[i].y; - FIXME("papersize is %ld x %ld\n",size->x,size->y); + retval = TRUE; +out: + GlobalUnlock(pdlga->hDevNames); + GlobalUnlock(pdlga->hDevMode); + if (Names) HeapFree(GetProcessHeap(),0,Names); + if (points) 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 = (WCHAR*)HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*NrOfEntries*64); + if (NrOfEntries != (ret=DeviceCapabilitiesW(devname,portname,DC_PAPERNAMES,Names,dm))) { + FIXME("Number of returned vals %d is not %d\n",NrOfEntries,ret); + goto out; + } + for (i=0;ix=points[i].x; + size->y=points[i].y; retval = TRUE; out: GlobalUnlock(pdlga->hDevNames); @@ -451,7 +698,7 @@ out: * 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_SetUpPaperComboBox(HWND hDlg, +static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg, int nIDComboBox, char* PrinterName, char* PortName, @@ -526,7 +773,7 @@ static BOOL PRINTDLG_SetUpPaperComboBox(HWND hDlg, NrOfEntries = 0; } - Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*NamesSize); + Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(char)*NamesSize); Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD)); NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Names, Names, dm); @@ -561,44 +808,192 @@ static BOOL PRINTDLG_SetUpPaperComboBox(HWND hDlg, return TRUE; } -/*********************************************************************** - * PRINTDLG_UpdatePrinterInfoTexts [internal] - */ -static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, LPPRINTER_INFO_2A pi) +static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg, + int nIDComboBox, + WCHAR* PrinterName, + WCHAR* PortName, + LPDEVMODEW dm) { - 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<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; } } - /* 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); - - SendDlgItemMessageA(hDlg, stc12, WM_SETTEXT, 0, (LPARAM)StatusMsg); - /* set all other printer info texts */ - SendDlgItemMessageA(hDlg, stc11, WM_SETTEXT, 0, (LPARAM)pi->pDriverName); - if (pi->pLocation != NULL && pi->pLocation[0] != '\0') - SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation); - else - SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName); - SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)(pi->pComment ? - pi->pComment : "")); - return; + if (nIDComboBox == cmb2) { + NamesSize = 64; + fwCapability_Names = DC_PAPERNAMES; + fwCapability_Words = DC_PAPERS; + } else { + nIDComboBox = cmb3; + NamesSize = 24; + fwCapability_Names = DC_BINNAMES; + fwCapability_Words = DC_BINS; + } + + /* for some printer drivers, DeviceCapabilities calls a VXD to obtain the + * paper settings. As Wine doesn't allow VXDs, this results in a crash. + */ + WARN(" if your printer driver uses VXDs, expect a crash now!\n"); + NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, + fwCapability_Names, NULL, dm); + if (NrOfEntries == 0) + WARN("no Name Entries found!\n"); + else if (NrOfEntries < 0) + return FALSE; + + if(DeviceCapabilitiesW(PrinterName, PortName, fwCapability_Words, NULL, dm) + != NrOfEntries) { + ERR("Number of caps is different\n"); + NrOfEntries = 0; + } + + Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WCHAR)*NamesSize); + Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD)); + NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, + fwCapability_Names, Names, dm); + NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, + fwCapability_Words, (LPWSTR)Words, dm); + + /* reset any current content in the combobox */ + SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); + + /* store new content */ + for (i = 0; i < NrOfEntries; i++) { + DWORD pos = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0, + (LPARAM)(&Names[i*NamesSize]) ); + SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos, + Words[i]); + } + + /* Look for old selection - can't do this is previous loop since + item order will change as more items are added */ + Sel = 0; + for (i = 0; i < NrOfEntries; i++) { + if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == + oldWord) { + Sel = i; + break; + } + } + SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); + + HeapFree(GetProcessHeap(),0,Words); + HeapFree(GetProcessHeap(),0,Names); + return TRUE; +} + + +/*********************************************************************** + * PRINTDLG_UpdatePrinterInfoTexts [internal] + */ +static void PRINTDLG_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<pDriverName); + if (pi->pLocation != NULL && pi->pLocation[0] != '\0') + SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation); + else + SendDlgItemMessageA(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName); + SendDlgItemMessageA(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)(pi->pComment ? + pi->pComment : "")); + return; +} + +static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, LPPRINTER_INFO_2W pi) +{ + WCHAR StatusMsg[256]; + WCHAR ResourceString[256]; + int i; + + /* Status Message */ + StatusMsg[0]='\0'; + + /* add all status messages */ + for (i = 0; i < 25; i++) { + if (pi->Status & (1<pDriverName); + if (pi->pLocation != NULL && pi->pLocation[0] != '\0') + SendDlgItemMessageW(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pLocation); + else + SendDlgItemMessageW(hDlg, stc14, WM_SETTEXT, 0,(LPARAM)pi->pPortName); + SendDlgItemMessageW(hDlg, stc13, WM_SETTEXT, 0, (LPARAM)(pi->pComment ? + pi->pComment : (LPCWSTR)"\0\0")); + return; } @@ -607,7 +1002,7 @@ static void PRINTDLG_UpdatePrinterInfoTexts(HWND hDlg, LPPRINTER_INFO_2A pi) * PRINTDLG_ChangePrinter * */ -static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name, +static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStructures) { LPPRINTDLGA lppd = PrintStructures->dlg.lpPrintDlg; @@ -637,7 +1032,7 @@ static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name, } ClosePrinter(hprn); - PRINTDLG_UpdatePrinterInfoTexts(hDlg, PrintStructures->lpPrinterInfo); + PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo); if(PrintStructures->lpDevMode) { HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); @@ -746,11 +1141,174 @@ static BOOL PRINTDLG_ChangePrinter(HWND hDlg, char *name, } else { /* PD_PRINTSETUP */ BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT); - PRINTDLG_SetUpPaperComboBox(hDlg, cmb2, + 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->dlg.lpPrintDlg; + LPDEVMODEW lpdm = NULL; + LONG dmSize; + DWORD needed; + HANDLE hprn; + + if(PrintStructures->lpPrinterInfo) + HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo); + if(PrintStructures->lpDriverInfo) + HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo); + if(!OpenPrinterW(name, &hprn, NULL)) { + ERR("Can't open printer %s\n", debugstr_w(name)); + return FALSE; + } + GetPrinterW(hprn, 2, NULL, 0, &needed); + PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed); + GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, + &needed); + GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); + PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed); + if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, + needed, &needed)) { + ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures->lpPrinterInfo->pPrinterName)); + return FALSE; + } + ClosePrinter(hprn); + + PRINTDLG_UpdatePrinterInfoTextsW(hDlg, PrintStructures->lpPrinterInfo); + + if(PrintStructures->lpDevMode) { + HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); + PrintStructures->lpDevMode = NULL; + } + + dmSize = DocumentPropertiesW(0, 0, name, NULL, NULL, 0); + if(dmSize == -1) { + ERR("DocumentProperties fails on %s\n", debugstr_w(name)); + return FALSE; + } + PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize); + dmSize = DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, NULL, + DM_OUT_BUFFER); + if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && + !lstrcmpW(lpdm->dmDeviceName, + PrintStructures->lpDevMode->dmDeviceName)) { + /* Supplied devicemode matches current printer so try to use it */ + DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, lpdm, + DM_OUT_BUFFER | DM_IN_BUFFER); + } + if(lpdm) + GlobalUnlock(lppd->hDevMode); + + lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ + + if(!(lppd->Flags & PD_PRINTSETUP)) { + /* Print range (All/Range/Selection) */ + SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE); + SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE); + CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */ + if (lppd->Flags & PD_NOSELECTION) + EnableWindow(GetDlgItem(hDlg, rad2), FALSE); + else + if (lppd->Flags & PD_SELECTION) + CheckRadioButton(hDlg, rad1, rad3, rad2); + if (lppd->Flags & PD_NOPAGENUMS) { + EnableWindow(GetDlgItem(hDlg, rad3), FALSE); + EnableWindow(GetDlgItem(hDlg, stc2),FALSE); + EnableWindow(GetDlgItem(hDlg, edt1), FALSE); + EnableWindow(GetDlgItem(hDlg, stc3),FALSE); + EnableWindow(GetDlgItem(hDlg, edt2), FALSE); + } else { + if (lppd->Flags & PD_PAGENUMS) + CheckRadioButton(hDlg, rad1, rad3, rad3); + } + /* "All xxx pages"... */ + { + /* ansi is ok */ + char resourcestr[64]; + char result[64]; + LoadStringA(COMDLG32_hInstance, PD32_PRINT_ALL_X_PAGES, + resourcestr, 49); + sprintf(result,resourcestr,lppd->nMaxPage - lppd->nMinPage + 1); + SendDlgItemMessageA(hDlg, rad1, WM_SETTEXT, 0, (LPARAM) result); + } + + /* Collate pages + * + * FIXME: The ico3 is not displayed for some reason. I don't know why. + */ + if (lppd->Flags & PD_COLLATE) { + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + (LPARAM)PrintStructures->hCollateIcon); + CheckDlgButton(hDlg, chx2, 1); + } else { + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + (LPARAM)PrintStructures->hNoCollateIcon); + CheckDlgButton(hDlg, chx2, 0); + } + + if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { + /* if printer doesn't support it: no Collate */ + if (!(lpdm->dmFields & DM_COLLATE)) { + EnableWindow(GetDlgItem(hDlg, chx2), FALSE); + EnableWindow(GetDlgItem(hDlg, ico3), FALSE); + } + } + + /* nCopies */ + { + INT copies; + if (lppd->hDevMode == 0) + copies = lppd->nCopies; + else + copies = lpdm->dmCopies; + if(copies == 0) copies = 1; + else if(copies < 0) copies = MAX_COPIES; + SetDlgItemInt(hDlg, edt3, copies, FALSE); + } + + if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { + /* if printer doesn't support it: no nCopies */ + if (!(lpdm->dmFields & DM_COPIES)) { + EnableWindow(GetDlgItem(hDlg, edt3), FALSE); + EnableWindow(GetDlgItem(hDlg, stc5), FALSE); + } + } + + /* print to file */ + CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0); + if (lppd->Flags & PD_DISABLEPRINTTOFILE) + EnableWindow(GetDlgItem(hDlg, chx1), FALSE); + if (lppd->Flags & PD_HIDEPRINTTOFILE) + ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE); + + } else { /* PD_PRINTSETUP */ + BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT); + + PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, PrintStructures->lpPrinterInfo->pPrinterName, PrintStructures->lpPrinterInfo->pPortName, lpdm); - PRINTDLG_SetUpPaperComboBox(hDlg, cmb3, + PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, PrintStructures->lpPrinterInfo->pPrinterName, PrintStructures->lpPrinterInfo->pPortName, lpdm); @@ -853,28 +1411,133 @@ static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, WPARAM wParam, name = (char*)pdn + pdn->wDeviceOffset; else if(pdm) name = pdm->dmDeviceName; - PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name); + PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); if(pdm) GlobalUnlock(lppd->hDevMode); if(pdn) GlobalUnlock(lppd->hDevNames); /* Now find selected printer and update rest of dlg */ name = HeapAlloc(GetProcessHeap(),0,256); if (GetDlgItemTextA(hDlg, comboID, name, 255)) - PRINTDLG_ChangePrinter(hDlg, name, PrintStructures); + PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); HeapFree(GetProcessHeap(),0,name); } else { /* else use default printer */ char name[200]; - BOOL ret = PRINTDLG_GetDefaultPrinterName(name, sizeof(name)); + BOOL ret = PRINTDLG_GetDefaultPrinterNameA(name, sizeof(name)); + + if (ret) + PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); + else + FIXME("No default printer found, expect problems!\n"); + } + return TRUE; +} + +static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, WPARAM wParam, + PRINT_PTRW* PrintStructures) +{ + LPPRINTDLGW lppd = PrintStructures->dlg.lpPrintDlg; + DEVNAMES *pdn; + DEVMODEW *pdm; + WCHAR *name = NULL; + UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; + + /* load Collate ICONs */ + /* We load these with LoadImage because they are not a standard + size and we don't want them rescaled */ + PrintStructures->hCollateIcon = + LoadImageA(COMDLG32_hInstance, "PD32_COLLATE", IMAGE_ICON, 0, 0, 0); + PrintStructures->hNoCollateIcon = + LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0); + + /* These can be done with LoadIcon */ + PrintStructures->hPortraitIcon = + LoadIconA(COMDLG32_hInstance, "PD32_PORTRAIT"); + PrintStructures->hLandscapeIcon = + LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE"); + + if(PrintStructures->hCollateIcon == 0 || + PrintStructures->hNoCollateIcon == 0 || + PrintStructures->hPortraitIcon == 0 || + PrintStructures->hLandscapeIcon == 0) { + ERR("no icon in resourcefile\n"); + COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); + EndDialog(hDlg, FALSE); + } + + /* + * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message + * must be registered and the Help button must be shown. + */ + if (lppd->Flags & PD_SHOWHELP) { + if((PrintStructures->HelpMessageID = + RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) { + COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); + return FALSE; + } + } else + PrintStructures->HelpMessageID = 0; + + if(!(lppd->Flags &PD_PRINTSETUP)) { + PrintStructures->hwndUpDown = + CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | + UDS_NOTHOUSANDS | UDS_ARROWKEYS | + UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, + hDlg, UPDOWN_ID, COMDLG32_hInstance, + GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); + } + + /* FIXME: I allow more freedom than either Win95 or WinNT, + * which do not agree to what errors should be thrown or not + * in case nToPage or nFromPage is out-of-range. + */ + if (lppd->nMaxPage < lppd->nMinPage) + lppd->nMaxPage = lppd->nMinPage; + if (lppd->nMinPage == lppd->nMaxPage) + lppd->Flags |= PD_NOPAGENUMS; + if (lppd->nToPage < lppd->nMinPage) + lppd->nToPage = lppd->nMinPage; + if (lppd->nToPage > lppd->nMaxPage) + lppd->nToPage = lppd->nMaxPage; + if (lppd->nFromPage < lppd->nMinPage) + lppd->nFromPage = lppd->nMinPage; + if (lppd->nFromPage > lppd->nMaxPage) + lppd->nFromPage = lppd->nMaxPage; + + /* if we have the combo box, fill it */ + if (GetDlgItem(hDlg,comboID)) { + /* Fill Combobox + */ + pdn = GlobalLock(lppd->hDevNames); + pdm = GlobalLock(lppd->hDevMode); + if(pdn) + name = (WCHAR*)pdn + pdn->wDeviceOffset; + else if(pdm) + name = pdm->dmDeviceName; + PRINTDLG_SetUpPrinterListComboW(hDlg, comboID, name); + if(pdm) GlobalUnlock(lppd->hDevMode); + if(pdn) GlobalUnlock(lppd->hDevNames); + + /* Now find selected printer and update rest of dlg */ + /* ansi is ok here */ + name = HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR)); + if (GetDlgItemTextW(hDlg, comboID, name, 255)) + PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); + HeapFree(GetProcessHeap(),0,name); + } else { + /* else use default printer */ + WCHAR name[200]; + BOOL ret = PRINTDLG_GetDefaultPrinterNameW(name, sizeof(name)); if (ret) - PRINTDLG_ChangePrinter(hDlg, name, PrintStructures); + PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); else FIXME("No default printer found, expect problems!\n"); } return TRUE; } + /*********************************************************************** * PRINTDLG_WMInitDialog [internal] */ @@ -968,21 +1631,21 @@ static LRESULT PRINTDLG_WMInitDialog16(HWND hDlg, WPARAM wParam, name = (char*)pdn + pdn->wDeviceOffset; else if(pdm) name = pdm->dmDeviceName; - PRINTDLG_SetUpPrinterListCombo(hDlg, comboID, name); + PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); if(pdm) GlobalUnlock16(lppd->hDevMode); if(pdn) GlobalUnlock16(lppd->hDevNames); /* Now find selected printer and update rest of dlg */ name = HeapAlloc(GetProcessHeap(),0,256); if (GetDlgItemTextA(hDlg, comboID, name, 255)) - PRINTDLG_ChangePrinter(hDlg, name, PrintStructures); + PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); } else { /* else just use default printer */ char name[200]; - BOOL ret = PRINTDLG_GetDefaultPrinterName(name, sizeof(name)); + BOOL ret = PRINTDLG_GetDefaultPrinterNameA(name, sizeof(name)); if (ret) - PRINTDLG_ChangePrinter(hDlg, name, PrintStructures); + PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); else FIXME("No default printer found, expect problems!\n"); } @@ -994,7 +1657,7 @@ static LRESULT PRINTDLG_WMInitDialog16(HWND hDlg, WPARAM wParam, /*********************************************************************** * PRINTDLG_WMCommand [internal] */ -static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, +static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, LPARAM lParam, PRINT_PTRA* PrintStructures) { LPPRINTDLGA lppd = PrintStructures->dlg.lpPrintDlg; @@ -1004,7 +1667,7 @@ static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, switch (LOWORD(wParam)) { case IDOK: TRACE(" OK button was hit\n"); - if (PRINTDLG_UpdatePrintDlg(hDlg, PrintStructures)!=TRUE) { + if (PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)!=TRUE) { FIXME("Update printdlg was not successful!\n"); return(FALSE); } @@ -1071,14 +1734,178 @@ static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, case psh2: /* Properties button */ { HANDLE hPrinter; - char PrinterName[256]; + 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 != 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->dlg.lpPrintDlg; + UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; + LPDEVMODEW lpdm = PrintStructures->lpDevMode; + + switch (LOWORD(wParam)) { + case IDOK: + TRACE(" OK button was hit\n"); + if (PRINTDLG_UpdatePrintDlgW(hDlg, PrintStructures)!=TRUE) { + FIXME("Update printdlg was not successful!\n"); + return(FALSE); + } + EndDialog(hDlg, TRUE); + return(TRUE); + + case IDCANCEL: + TRACE(" CANCEL button was hit\n"); + EndDialog(hDlg, FALSE); + return(FALSE); + + case pshHelp: + TRACE(" HELP button was hit\n"); + SendMessageW(lppd->hwndOwner, PrintStructures->HelpMessageID, + (WPARAM) hDlg, (LPARAM) lppd); + break; + + case chx2: /* collate pages checkbox */ + if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + (LPARAM)PrintStructures->hCollateIcon); + else + SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, (WPARAM) IMAGE_ICON, + (LPARAM)PrintStructures->hNoCollateIcon); + break; + case edt1: /* from page nr editbox */ + case edt2: /* to page nr editbox */ + if (HIWORD(wParam)==EN_CHANGE) { + WORD nToPage; + WORD nFromPage; + nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); + nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); + if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage) + CheckRadioButton(hDlg, rad1, rad3, rad3); + } + break; + + case edt3: + if(HIWORD(wParam) == EN_CHANGE) { + INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); + if(copies <= 1) + EnableWindow(GetDlgItem(hDlg, chx2), FALSE); + else + EnableWindow(GetDlgItem(hDlg, chx2), TRUE); + } + break; + + case psh1: /* Print Setup */ + { + ERR("psh1 is called from 16bit code only, we should not get here.\n"); + } + break; + case psh2: /* Properties button */ + { + HANDLE hPrinter; + WCHAR PrinterName[256]; - GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255); - if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { + GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255); + if (!OpenPrinterW(PrinterName, &hPrinter, NULL)) { FIXME(" Call to OpenPrinter did not succeed!\n"); break; } - DocumentPropertiesA(hDlg, hPrinter, PrinterName, + DocumentPropertiesW(hDlg, hPrinter, PrinterName, PrintStructures->lpDevMode, PrintStructures->lpDevMode, DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); @@ -1112,9 +1939,9 @@ static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, /* FALLTHROUGH */ case cmb4: /* Printer combobox */ if (HIWORD(wParam)==CBN_SELCHANGE) { - char PrinterName[256]; - GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255); - PRINTDLG_ChangePrinter(hDlg, PrinterName, PrintStructures); + WCHAR PrinterName[256]; + GetDlgItemTextW(hDlg, LOWORD(wParam), PrinterName, 255); + PRINTDLG_ChangePrinterW(hDlg, PrinterName, PrintStructures); } break; @@ -1132,7 +1959,7 @@ static LRESULT PRINTDLG_WMCommand(HWND hDlg, WPARAM wParam, { DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0); if(Sel != CB_ERR) - lpdm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3, + lpdm->dmDefaultSource = SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA, Sel, 0); } @@ -1202,7 +2029,51 @@ BOOL WINAPI PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, switch (uMsg) { case WM_COMMAND: - return PRINTDLG_WMCommand(hDlg, wParam, lParam, PrintStructures); + 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; +} + +BOOL WINAPI PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, + LPARAM lParam) +{ + PRINT_PTRW* PrintStructures; + LRESULT res=FALSE; + + if (uMsg!=WM_INITDIALOG) { + PrintStructures = (PRINT_PTRW*) GetWindowLongA(hDlg, DWL_USER); + if (!PrintStructures) + return FALSE; + } else { + PrintStructures = (PRINT_PTRW*) lParam; + SetWindowLongA(hDlg, DWL_USER, lParam); + res = PRINTDLG_WMInitDialogW(hDlg, wParam, PrintStructures); + + if(PrintStructures->dlg.lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) + res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook( + hDlg, uMsg, wParam, (LPARAM)PrintStructures->dlg.lpPrintDlg + ); + return res; + } + + if(PrintStructures->dlg.lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { + res = PrintStructures->dlg.lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, + lParam); + if(res) return res; + } + + switch (uMsg) { + case WM_COMMAND: + return PRINTDLG_WMCommandW(hDlg, wParam, lParam, PrintStructures); case WM_DESTROY: DestroyIcon(PrintStructures->hCollateIcon); @@ -1269,7 +2140,7 @@ static HGLOBAL16 PRINTDLG_Get16TemplateFrom32(char *PrintResourceName) * PRINTDLG_GetDlgTemplate * */ -static HGLOBAL PRINTDLG_GetDlgTemplate(PRINTDLGA *lppd) +static HGLOBAL PRINTDLG_GetDlgTemplateA(PRINTDLGA *lppd) { HGLOBAL hDlgTmpl, hResInfo; @@ -1302,6 +2173,40 @@ static HGLOBAL PRINTDLG_GetDlgTemplate(PRINTDLGA *lppd) return hDlgTmpl; } +static HGLOBAL PRINTDLG_GetDlgTemplateW(PRINTDLGW *lppd) +{ + HGLOBAL hDlgTmpl, hResInfo; + const WCHAR xpsetup[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0}; + const WCHAR xprint[] = { 'P','R','I','N','T','3','2',0}; + + if (lppd->Flags & PD_PRINTSETUP) { + if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { + hDlgTmpl = lppd->hSetupTemplate; + } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { + hResInfo = FindResourceW(lppd->hInstance, + lppd->lpSetupTemplateName, RT_DIALOGW); + hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); + } else { + hResInfo = FindResourceW(COMDLG32_hInstance, xpsetup, RT_DIALOGW); + hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); + } + } else { + if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { + hDlgTmpl = lppd->hPrintTemplate; + } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { + hResInfo = FindResourceW(lppd->hInstance, + lppd->lpPrintTemplateName, + RT_DIALOGW); + hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); + } else { + hResInfo = FindResourceW(COMDLG32_hInstance, xprint, RT_DIALOGW); + hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); + } + } + return hDlgTmpl; +} + + /************************************************************ * @@ -1342,7 +2247,7 @@ static HGLOBAL16 PRINTDLG_GetDlgTemplate16(PRINTDLG16 *lppd) * PRINTDLG_CreateDC * */ -static BOOL PRINTDLG_CreateDC(LPPRINTDLGA lppd) +static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd) { DEVNAMES *pdn = GlobalLock(lppd->hDevNames); DEVMODEA *pdm = GlobalLock(lppd->hDevMode); @@ -1363,6 +2268,27 @@ static BOOL PRINTDLG_CreateDC(LPPRINTDLGA lppd) 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; +} + static BOOL PRINTDLG_CreateDC16(LPPRINTDLG16 lppd) { DEVNAMES *pdn = GlobalLock16(lppd->hDevNames); @@ -1385,27 +2311,184 @@ static BOOL PRINTDLG_CreateDC16(LPPRINTDLG16 lppd) } /*********************************************************************** - * PrintDlgA (COMDLG32.@) - * - * Displays the the PRINT dialog box, which enables the user to specify - * specific properties of the print job. - * - * RETURNS - * nonzero if the user pressed the OK button - * zero if the user cancelled the window or an error occurred - * - * BUGS - * PrintDlg: - * * The Collate Icons do not display, even though they are in the code. - * * The Properties Button(s) should call DocumentPropertiesA(). - * PrintSetupDlg: - * * The Paper Orientation Icons are not implemented yet. - * * The Properties Button(s) should call DocumentPropertiesA(). - * * Settings are not yet taken from a provided DevMode or - * default printer settings. + * PrintDlgA (COMDLG32.@) + * + * Displays the the PRINT dialog box, which enables the user to specify + * specific properties of the print job. + * + * RETURNS + * nonzero if the user pressed the OK button + * zero if the user cancelled the window or an error occurred + * + * BUGS + * PrintDlg: + * * The Collate Icons do not display, even though they are in the code. + * * The Properties Button(s) should call DocumentPropertiesA(). + * PrintSetupDlg: + * * The Paper Orientation Icons are not implemented yet. + * * The Properties Button(s) should call DocumentPropertiesA(). + * * Settings are not yet taken from a provided DevMode or + * default printer settings. + */ + +BOOL WINAPI PrintDlgA( + LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */ + ) +{ + BOOL bRet = FALSE; + LPVOID ptr; + HINSTANCE hInst = GetWindowLongA( lppd->hwndOwner, GWL_HINSTANCE ); + + if(TRACE_ON(commdlg)) { + char flagstr[1000] = ""; + struct pd_flags *pflag = pd_flags; + for( ; pflag->name; pflag++) { + if(lppd->Flags & pflag->flag) + strcat(flagstr, pflag->name); + } + TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n" + "pp. %d-%d, min p %d, max p %d, copies %d, hinst %08x\n" + "flags %08lx (%s)\n", + lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, + lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, + lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); + } + + if(lppd->lStructSize != sizeof(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 %ld, 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->dlg.lpPrintDlg = lppd; + + /* and create & process the dialog . + * -1 is failure, 0 is broken hwnd, everything else is ok. + */ + bRet = (0hwndOwner, + 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 { + 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_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.@) */ -BOOL WINAPI PrintDlgA( - LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */ +BOOL WINAPI PrintDlgW( + LPPRINTDLGW lppd /* [in/out] ptr to PRINTDLG32 struct */ ) { BOOL bRet = FALSE; @@ -1427,15 +2510,15 @@ BOOL WINAPI PrintDlgA( lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); } - if(lppd->lStructSize != sizeof(PRINTDLGA)) { + if(lppd->lStructSize != sizeof(PRINTDLGW)) { WARN("structure size failure !!!\n"); COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); return FALSE; } if(lppd->Flags & PD_RETURNDEFAULT) { - PRINTER_INFO_2A *pbuf; - DRIVER_INFO_3A *dbuf; + PRINTER_INFO_2W *pbuf; + DRIVER_INFO_3W *dbuf; HANDLE hprn; DWORD needed; @@ -1450,20 +2533,20 @@ BOOL WINAPI PrintDlgA( return FALSE; } - GetPrinterA(hprn, 2, NULL, 0, &needed); - pbuf = HeapAlloc(GetProcessHeap(), 0, needed); - GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); + GetPrinterW(hprn, 2, NULL, 0, &needed); + pbuf = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*needed); + GetPrinterW(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 %ld, fix your config for printer %s!\n",GetLastError(),pbuf->pPrinterName); + GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); + dbuf = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*needed); + if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { + ERR("GetPrinterDriverA failed, le %ld, fix your config for printer %s!\n",GetLastError(),debugstr_w(pbuf->pPrinterName)); COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); return FALSE; } ClosePrinter(hprn); - PRINTDLG_CreateDevNames(&(lppd->hDevNames), + PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName); @@ -1478,12 +2561,12 @@ BOOL WINAPI PrintDlgA( bRet = TRUE; } else { HGLOBAL hDlgTmpl; - PRINT_PTRA *PrintStructures; + PRINT_PTRW *PrintStructures; /* load Dialog resources, * depending on Flags indicates Print32 or Print32_setup dialog */ - hDlgTmpl = PRINTDLG_GetDlgTemplate(lppd); + hDlgTmpl = PRINTDLG_GetDlgTemplateW(lppd); if (!hDlgTmpl) { COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); return FALSE; @@ -1495,20 +2578,20 @@ BOOL WINAPI PrintDlgA( } PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, - sizeof(PRINT_PTRA)); + sizeof(PRINT_PTRW)); PrintStructures->dlg.lpPrintDlg = lppd; /* and create & process the dialog . * -1 is failure, 0 is broken hwnd, everything else is ok. */ - bRet = (0hwndOwner, - PrintDlgProcA, + bRet = (0hwndOwner, + PrintDlgProcW, (LPARAM)PrintStructures)); if(bRet) { - DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn; - PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo; - DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo; + 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"); @@ -1538,7 +2621,7 @@ BOOL WINAPI PrintDlgA( GlobalUnlock(lppd->hDevNames); } } - PRINTDLG_CreateDevNames(&(lppd->hDevNames), + PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), di->pDriverPath, pi->pPrinterName, pi->pPortName @@ -1551,7 +2634,7 @@ BOOL WINAPI PrintDlgA( HeapFree(GetProcessHeap(), 0, PrintStructures); } if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) - bRet = PRINTDLG_CreateDC(lppd); + bRet = PRINTDLG_CreateDCW(lppd); TRACE("exit! (%d)\n", bRet); return bRet; @@ -1735,16 +2818,6 @@ BOOL16 WINAPI PrintDlg16( } - -/*********************************************************************** - * PrintDlgW (COMDLG32.@) - */ -BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg ) -{ - FIXME("A really empty stub\n" ); - return FALSE; -} - /*********************************************************************** * * PageSetupDlg @@ -1761,11 +2834,15 @@ BOOL WINAPI PrintDlgW( LPPRINTDLGW printdlg ) typedef struct { LPPAGESETUPDLGA dlga; - PRINTDLGA pdlg; -} PageSetupData; +} PageSetupDataA; + +typedef struct { + LPPAGESETUPDLGW dlga; + PRINTDLGW pdlg; +} PageSetupDataW; -static HGLOBAL PRINTDLG_GetPGSTemplate(PAGESETUPDLGA *lppd) +static HGLOBAL PRINTDLG_GetPGSTemplateA(PAGESETUPDLGA *lppd) { HGLOBAL hDlgTmpl, hResInfo; @@ -1782,6 +2859,23 @@ static HGLOBAL PRINTDLG_GetPGSTemplate(PAGESETUPDLGA *lppd) return hDlgTmpl; } +static HGLOBAL PRINTDLG_GetPGSTemplateW(PAGESETUPDLGW *lppd) +{ + HGLOBAL hDlgTmpl, hResInfo; + + if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) { + hDlgTmpl = lppd->hPageSetupTemplate; + } else if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATE) { + hResInfo = FindResourceW(lppd->hInstance, + lppd->lpPageSetupTemplateName, RT_DIALOGW); + hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); + } else { + hResInfo = FindResourceW(COMDLG32_hInstance,(LPCWSTR)PAGESETUPDLGORD,RT_DIALOGW); + hDlgTmpl = LoadResource(COMDLG32_hInstance,hResInfo); + } + return hDlgTmpl; +} + static DWORD _c_10mm2size(PAGESETUPDLGA *dlga,DWORD size) { if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) @@ -1790,7 +2884,6 @@ _c_10mm2size(PAGESETUPDLGA *dlga,DWORD size) { * to avoid confusing me */ dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; - FIXME("returning %ld/100 mm \n",size); return 10*size; } @@ -1809,7 +2902,22 @@ _c_inch2size(PAGESETUPDLGA *dlga,DWORD size) { } static void -_c_size2str(PageSetupData *pda,DWORD size,LPSTR strout) { +_c_size2strA(PageSetupDataA *pda,DWORD size,LPSTR strout) { + strcpy(strout,""); + if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { + sprintf(strout,"%.2fmm",(size*1.0)/100.0); + return; + } + if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { + sprintf(strout,"%.2fin",(size*1.0)/1000.0); + return; + } + pda->dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; + sprintf(strout,"%.2fmm",(size*1.0)/100.0); + return; +} +static void +_c_size2strW(PageSetupDataW *pda,DWORD size,LPSTR strout) { strcpy(strout,""); if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { sprintf(strout,"%.2fmm",(size*1.0)/100.0); @@ -1825,7 +2933,7 @@ _c_size2str(PageSetupData *pda,DWORD size,LPSTR strout) { } static DWORD -_c_str2size(PageSetupData *pda,LPCSTR strin) { +_c_str2size(PAGESETUPDLGA *dlga,LPCSTR strin) { float val; char rest[200]; @@ -1834,7 +2942,7 @@ _c_str2size(PageSetupData *pda,LPCSTR strin) { return 0; if (!strcmp(rest,"in") || !strcmp(rest,"inch")) { - if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) + if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) return 1000*val; else return val*25.4*100; @@ -1843,18 +2951,18 @@ _c_str2size(PageSetupData *pda,LPCSTR strin) { if (!strcmp(rest,"m")) { strcpy(rest,"mm"); val = val*1000.0; } if (!strcmp(rest,"mm")) { - if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) + if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) return 100*val; else return 1000.0*val/25.4; } if (rest[0]=='\0') { /* use application supplied default */ - if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { + if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { /* 100*mm */ return 100.0*val; } - if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { + if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { /* 1000*inch */ return 1000.0*val; } @@ -1869,7 +2977,7 @@ _c_str2size(PageSetupData *pda,LPCSTR strin) { * struct. */ static BOOL -PRINTDLG_PS_UpdateDlgStruct(HWND hDlg, PageSetupData *pda) { +PRINTDLG_PS_UpdateDlgStructA(HWND hDlg, PageSetupDataA *pda) { DEVNAMES *dn; DEVMODEA *dm; LPSTR devname,portname; @@ -1880,16 +2988,57 @@ PRINTDLG_PS_UpdateDlgStruct(HWND hDlg, PageSetupData *pda) { dm = GlobalLock(pda->pdlg.hDevMode); devname = ((char*)dn)+dn->wDeviceOffset; portname = ((char*)dn)+dn->wOutputOffset; - PRINTDLG_SetUpPaperComboBox(hDlg,cmb2,devname,portname,dm); - PRINTDLG_SetUpPaperComboBox(hDlg,cmb3,devname,portname,dm); + PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm); + PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm); if (GetDlgItemTextA(hDlg,cmb2,papername,sizeof(papername))>0) { - PRINTDLG_PaperSize(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize)); + PRINTDLG_PaperSizeA(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize)); pda->dlga->ptPaperSize.x = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.x); pda->dlga->ptPaperSize.y = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.y); } else FIXME("could not get dialog text for papersize cmbbox?\n"); -#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size(pda,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); } +#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size(pda->dlga,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); } + GETVAL(edt4,pda->dlga->rtMargin.left); + GETVAL(edt5,pda->dlga->rtMargin.top); + 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; +} + +static BOOL +PRINTDLG_PS_UpdateDlgStructW(HWND hDlg, PageSetupDataW *pda) { + DEVNAMES *dn; + DEVMODEW *dm; + LPWSTR devname,portname; + WCHAR papername[64]; + + char buf[200]; + + dn = GlobalLock(pda->pdlg.hDevNames); + dm = GlobalLock(pda->pdlg.hDevMode); + devname = ((WCHAR*)dn)+dn->wDeviceOffset; + portname = ((WCHAR*)dn)+dn->wOutputOffset; + PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb2,devname,portname,dm); + PRINTDLG_SetUpPaperComboBoxW(hDlg,cmb3,devname,portname,dm); + + if (GetDlgItemTextW(hDlg,cmb2,papername,sizeof(papername))>0) { + PRINTDLG_PaperSizeW(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize)); + pda->dlga->ptPaperSize.x = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga,pda->dlga->ptPaperSize.x); + pda->dlga->ptPaperSize.y = _c_10mm2size((LPPAGESETUPDLGA)pda->dlga,pda->dlga->ptPaperSize.y); + } else + FIXME("could not get dialog text for papersize cmbbox?\n"); +#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2size((LPPAGESETUPDLGA)pda->dlga,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); } GETVAL(edt4,pda->dlga->rtMargin.left); GETVAL(edt5,pda->dlga->rtMargin.top); GETVAL(edt6,pda->dlga->rtMargin.right); @@ -1912,7 +3061,7 @@ PRINTDLG_PS_UpdateDlgStruct(HWND hDlg, PageSetupData *pda) { * This is called after returning from PrintDlg(). */ static BOOL -PRINTDLG_PS_ChangePrinter(HWND hDlg, PageSetupData *pda) { +PRINTDLG_PS_ChangePrinterA(HWND hDlg, PageSetupDataA *pda) { DEVNAMES *dn; DEVMODEA *dm; LPSTR devname,portname; @@ -1921,20 +3070,37 @@ PRINTDLG_PS_ChangePrinter(HWND hDlg, PageSetupData *pda) { dm = GlobalLock(pda->pdlg.hDevMode); devname = ((char*)dn)+dn->wDeviceOffset; portname = ((char*)dn)+dn->wOutputOffset; - PRINTDLG_SetUpPaperComboBox(hDlg,cmb2,devname,portname,dm); - PRINTDLG_SetUpPaperComboBox(hDlg,cmb3,devname,portname,dm); + PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm); + PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm); + GlobalUnlock(pda->pdlg.hDevNames); + GlobalUnlock(pda->pdlg.hDevMode); + 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; } static BOOL -PRINTDLG_PS_WMCommand( - HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupData *pda +PRINTDLG_PS_WMCommandA( + HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataA *pda ) { switch (LOWORD(wParam)) { case IDOK: - if (!PRINTDLG_PS_UpdateDlgStruct(hDlg, pda)) + if (!PRINTDLG_PS_UpdateDlgStructA(hDlg, pda)) return(FALSE); EndDialog(hDlg, TRUE); return TRUE ; @@ -1947,7 +3113,36 @@ PRINTDLG_PS_WMCommand( pda->pdlg.Flags = 0; pda->pdlg.hwndOwner = hDlg; if (PrintDlgA(&(pda->pdlg))) - PRINTDLG_PS_ChangePrinter(hDlg,pda); + PRINTDLG_PS_ChangePrinterA(hDlg,pda); + return TRUE; + } + } + FIXME("loword (lparam) %d, wparam 0x%x, lparam %08lx, STUB mostly.\n", + LOWORD(lParam),wParam,lParam + ); + return FALSE; +} + +static BOOL +PRINTDLG_PS_WMCommandW( + HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataW *pda +) { + switch (LOWORD(wParam)) { + case IDOK: + if (!PRINTDLG_PS_UpdateDlgStructW(hDlg, pda)) + return(FALSE); + EndDialog(hDlg, TRUE); + return TRUE ; + + case IDCANCEL: + EndDialog(hDlg, FALSE); + return FALSE ; + + case psh3: { + pda->pdlg.Flags = 0; + pda->pdlg.hwndOwner = hDlg; + if (PrintDlgW(&(pda->pdlg))) + PRINTDLG_PS_ChangePrinterW(hDlg,pda); return TRUE; } } @@ -1961,12 +3156,12 @@ PRINTDLG_PS_WMCommand( static BOOL WINAPI PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { - PageSetupData *pda; + PageSetupDataA *pda; BOOL res = FALSE; if (uMsg==WM_INITDIALOG) { res = TRUE; - pda = (PageSetupData*)lParam; + pda = (PageSetupDataA*)lParam; SetPropA(hDlg,"__WINE_PAGESETUPDLGDATA",lParam); if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) { res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,lParam); @@ -1998,32 +3193,114 @@ PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) /* We fill them out enabled or not */ if (pda->dlga->Flags & PSD_MARGINS) { char str[100]; - _c_size2str(pda,pda->dlga->rtMargin.left,str); + _c_size2strA(pda,pda->dlga->rtMargin.left,str); SetDlgItemTextA(hDlg,edt4,str); - _c_size2str(pda,pda->dlga->rtMargin.top,str); + _c_size2strA(pda,pda->dlga->rtMargin.top,str); SetDlgItemTextA(hDlg,edt5,str); - _c_size2str(pda,pda->dlga->rtMargin.right,str); + _c_size2strA(pda,pda->dlga->rtMargin.right,str); SetDlgItemTextA(hDlg,edt6,str); - _c_size2str(pda,pda->dlga->rtMargin.bottom,str); + _c_size2strA(pda,pda->dlga->rtMargin.bottom,str); SetDlgItemTextA(hDlg,edt7,str); } else { /* default is 1 inch */ DWORD size = _c_inch2size(pda->dlga,1000); char str[20]; - _c_size2str(pda,size,str); + _c_size2strA(pda,size,str); + SetDlgItemTextA(hDlg,edt4,str); + SetDlgItemTextA(hDlg,edt5,str); + SetDlgItemTextA(hDlg,edt6,str); + SetDlgItemTextA(hDlg,edt7,str); + } + PRINTDLG_PS_ChangePrinterA(hDlg,pda); + if (pda->dlga->Flags & PSD_DISABLEPAPER) { + EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); + EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); + } + 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 BOOL WINAPI +PageDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + PageSetupDataW *pda; + BOOL res = FALSE; + + if (uMsg==WM_INITDIALOG) { + res = TRUE; + pda = (PageSetupDataW*)lParam; + SetPropA(hDlg,"__WINE_PAGESETUPDLGDATA",lParam); + if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) { + res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,lParam); + if (!res) { + FIXME("Setup page hook failed?\n"); + res = TRUE; + } + } + if (pda->dlga->Flags & PSD_ENABLEPAGEPAINTHOOK) { + FIXME("PagePaintHook not yet implemented!\n"); + } + if (pda->dlga->Flags & PSD_DISABLEPRINTER) + EnableWindow(GetDlgItem(hDlg, psh3), FALSE); + if (pda->dlga->Flags & PSD_DISABLEMARGINS) { + EnableWindow(GetDlgItem(hDlg, edt4), FALSE); + EnableWindow(GetDlgItem(hDlg, edt5), FALSE); + EnableWindow(GetDlgItem(hDlg, edt6), FALSE); + EnableWindow(GetDlgItem(hDlg, edt7), FALSE); + } + /* width larger as height -> landscape */ + if (pda->dlga->ptPaperSize.x > pda->dlga->ptPaperSize.y) + CheckRadioButton(hDlg, rad1, rad2, rad2); + else /* this is default if papersize is not set */ + CheckRadioButton(hDlg, rad1, rad2, rad1); + if (pda->dlga->Flags & PSD_DISABLEORIENTATION) { + EnableWindow(GetDlgItem(hDlg,rad1),FALSE); + EnableWindow(GetDlgItem(hDlg,rad2),FALSE); + } + /* We fill them out enabled or not */ + if (pda->dlga->Flags & PSD_MARGINS) { + char str[100]; + _c_size2strW(pda,pda->dlga->rtMargin.left,str); + SetDlgItemTextA(hDlg,edt4,str); + _c_size2strW(pda,pda->dlga->rtMargin.top,str); + SetDlgItemTextA(hDlg,edt5,str); + _c_size2strW(pda,pda->dlga->rtMargin.right,str); + SetDlgItemTextA(hDlg,edt6,str); + _c_size2strW(pda,pda->dlga->rtMargin.bottom,str); + SetDlgItemTextA(hDlg,edt7,str); + } else { + /* default is 1 inch */ + DWORD size = _c_inch2size((LPPAGESETUPDLGA)pda->dlga,1000); + char str[20]; + _c_size2strW(pda,size,str); SetDlgItemTextA(hDlg,edt4,str); SetDlgItemTextA(hDlg,edt5,str); SetDlgItemTextA(hDlg,edt6,str); SetDlgItemTextA(hDlg,edt7,str); } - PRINTDLG_PS_ChangePrinter(hDlg,pda); + 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 = (PageSetupData*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA"); + pda = (PageSetupDataW*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA"); if (!pda) { WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); return FALSE; @@ -2035,7 +3312,7 @@ PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) } switch (uMsg) { case WM_COMMAND: - return PRINTDLG_PS_WMCommand(hDlg, wParam, lParam, pda); + return PRINTDLG_PS_WMCommandW(hDlg, wParam, lParam, pda); } return FALSE; } @@ -2047,7 +3324,7 @@ BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) { HGLOBAL hDlgTmpl; LPVOID ptr; BOOL bRet; - PageSetupData *pda; + PageSetupDataA *pda; PRINTDLGA pdlg; if(TRACE_ON(commdlg)) { @@ -2078,12 +3355,12 @@ BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) { setupdlg->hDevMode = pdlg.hDevMode; setupdlg->hDevNames = pdlg.hDevNames; /* FIXME: Just return "A4" for now. */ - PRINTDLG_PaperSize(&pdlg,"A4",&setupdlg->ptPaperSize); + PRINTDLG_PaperSizeA(&pdlg,"A4",&setupdlg->ptPaperSize); setupdlg->ptPaperSize.x=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.x); setupdlg->ptPaperSize.y=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.y); return TRUE; } - hDlgTmpl = PRINTDLG_GetPGSTemplate(setupdlg); + hDlgTmpl = PRINTDLG_GetPGSTemplateA(setupdlg); if (!hDlgTmpl) { COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); return FALSE; @@ -2110,8 +3387,68 @@ BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) { * PageSetupDlgW (COMDLG32.@) */ BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) { - FIXME("(%p), stub!\n",setupdlg); + HGLOBAL hDlgTmpl; + LPVOID ptr; + BOOL bRet; + PageSetupDataW *pdw; + PRINTDLGW pdlg; + + if(TRACE_ON(commdlg)) { + char flagstr[1000] = ""; + struct pd_flags *pflag = psd_flags; + for( ; pflag->name; pflag++) { + if(setupdlg->Flags & pflag->flag) { + strcat(flagstr, pflag->name); + strcat(flagstr, "|"); + } + } + TRACE("(%p): hwndOwner = %08x, hDevMode = %08x, hDevNames = %08x\n" + "hinst %08x, flags %08lx (%s)\n", + setupdlg, setupdlg->hwndOwner, setupdlg->hDevMode, + setupdlg->hDevNames, + setupdlg->hInstance, setupdlg->Flags, flagstr); + } + + /* First get default printer data, we need it right after that. */ + memset(&pdlg,0,sizeof(pdlg)); + pdlg.lStructSize = sizeof(pdlg); + pdlg.Flags = PD_RETURNDEFAULT; + bRet = PrintDlgW(&pdlg); + if (!bRet) return FALSE; + + /* short cut exit, just return default values */ + if (setupdlg->Flags & PSD_RETURNDEFAULT) { + const WCHAR a4[] = {'A','4',0}; + setupdlg->hDevMode = pdlg.hDevMode; + setupdlg->hDevNames = pdlg.hDevNames; + /* FIXME: Just return "A4" for now. */ + PRINTDLG_PaperSizeW(&pdlg,a4,&setupdlg->ptPaperSize); + setupdlg->ptPaperSize.x=_c_10mm2size((LPPAGESETUPDLGA)setupdlg,setupdlg->ptPaperSize.x); + setupdlg->ptPaperSize.y=_c_10mm2size((LPPAGESETUPDLGA)setupdlg,setupdlg->ptPaperSize.y); + return TRUE; + } + hDlgTmpl = PRINTDLG_GetPGSTemplateW(setupdlg); + if (!hDlgTmpl) { + COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); + return FALSE; + } + ptr = LockResource( hDlgTmpl ); + if (!ptr) { + COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); return FALSE; + } + pdw = HeapAlloc(GetProcessHeap(),0,sizeof(*pdw)); + pdw->dlga = setupdlg; + memcpy(&pdw->pdlg,&pdlg,sizeof(pdlg)); + + bRet = (0hInstance, + ptr, + setupdlg->hwndOwner, + PageDlgProcW, + (LPARAM)pdw) + ); + return bRet; } /********************************************************************** @@ -2159,7 +3496,7 @@ LRESULT WINAPI PrintDlgProc16(HWND16 hDlg, UINT16 uMsg, WPARAM16 wParam, /* We need to map those for the 32bit window procedure, compare * with 32Ato16 mapper in winproc.c */ - return PRINTDLG_WMCommand( + return PRINTDLG_WMCommandA( hDlg, MAKEWPARAM(wParam,HIWORD(lParam)), LOWORD(lParam), -- 2.11.4.GIT