Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenprintdlg.c
Go to the documentation of this file.
00001 /* 00002 * COMMDLG - Print Dialog 00003 * 00004 * Copyright 1994 Martin Ayotte 00005 * Copyright 1996 Albrecht Kleine 00006 * Copyright 1999 Klaas van Gend 00007 * Copyright 2000 Huw D M Davies 00008 * Copyright 2010 Vitaly Perov 00009 * 00010 * This library is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 2.1 of the License, or (at your option) any later version. 00014 * 00015 * This library is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 00023 */ 00024 #include <ctype.h> 00025 #include <stdlib.h> 00026 #include <stdarg.h> 00027 #include <stdio.h> 00028 #include <string.h> 00029 #include <assert.h> 00030 00031 #define NONAMELESSUNION 00032 #define NONAMELESSSTRUCT 00033 #include "windef.h" 00034 #include "winbase.h" 00035 #include "wingdi.h" 00036 #include "winuser.h" 00037 #include "winspool.h" 00038 #include "winerror.h" 00039 00040 #include "wine/unicode.h" 00041 #include "wine/debug.h" 00042 00043 #include "commdlg.h" 00044 #include "dlgs.h" 00045 #include "cderr.h" 00046 #include "cdlg.h" 00047 00048 WINE_DEFAULT_DEBUG_CHANNEL(commdlg); 00049 00050 /* Yes these constants are the same, but we're just copying win98 */ 00051 #define UPDOWN_ID 0x270f 00052 #define MAX_COPIES 9999 00053 00054 /* This PRINTDLGA internal structure stores 00055 * pointers to several throughout useful structures. 00056 */ 00057 00058 typedef struct 00059 { 00060 LPDEVMODEA lpDevMode; 00061 LPPRINTDLGA lpPrintDlg; 00062 LPPRINTER_INFO_2A lpPrinterInfo; 00063 LPDRIVER_INFO_3A lpDriverInfo; 00064 UINT HelpMessageID; 00065 HICON hCollateIcon; /* PrintDlg only */ 00066 HICON hNoCollateIcon; /* PrintDlg only */ 00067 HICON hPortraitIcon; /* PrintSetupDlg only */ 00068 HICON hLandscapeIcon; /* PrintSetupDlg only */ 00069 HWND hwndUpDown; 00070 } PRINT_PTRA; 00071 00072 typedef struct 00073 { 00074 LPDEVMODEW lpDevMode; 00075 LPPRINTDLGW lpPrintDlg; 00076 LPPRINTER_INFO_2W lpPrinterInfo; 00077 LPDRIVER_INFO_3W lpDriverInfo; 00078 UINT HelpMessageID; 00079 HICON hCollateIcon; /* PrintDlg only */ 00080 HICON hNoCollateIcon; /* PrintDlg only */ 00081 HICON hPortraitIcon; /* PrintSetupDlg only */ 00082 HICON hLandscapeIcon; /* PrintSetupDlg only */ 00083 HWND hwndUpDown; 00084 } PRINT_PTRW; 00085 00086 /* Debugging info */ 00087 struct pd_flags 00088 { 00089 DWORD flag; 00090 LPCSTR name; 00091 }; 00092 00093 static const struct pd_flags psd_flags[] = { 00094 {PSD_MINMARGINS,"PSD_MINMARGINS"}, 00095 {PSD_MARGINS,"PSD_MARGINS"}, 00096 {PSD_INTHOUSANDTHSOFINCHES,"PSD_INTHOUSANDTHSOFINCHES"}, 00097 {PSD_INHUNDREDTHSOFMILLIMETERS,"PSD_INHUNDREDTHSOFMILLIMETERS"}, 00098 {PSD_DISABLEMARGINS,"PSD_DISABLEMARGINS"}, 00099 {PSD_DISABLEPRINTER,"PSD_DISABLEPRINTER"}, 00100 {PSD_NOWARNING,"PSD_NOWARNING"}, 00101 {PSD_DISABLEORIENTATION,"PSD_DISABLEORIENTATION"}, 00102 {PSD_RETURNDEFAULT,"PSD_RETURNDEFAULT"}, 00103 {PSD_DISABLEPAPER,"PSD_DISABLEPAPER"}, 00104 {PSD_SHOWHELP,"PSD_SHOWHELP"}, 00105 {PSD_ENABLEPAGESETUPHOOK,"PSD_ENABLEPAGESETUPHOOK"}, 00106 {PSD_ENABLEPAGESETUPTEMPLATE,"PSD_ENABLEPAGESETUPTEMPLATE"}, 00107 {PSD_ENABLEPAGESETUPTEMPLATEHANDLE,"PSD_ENABLEPAGESETUPTEMPLATEHANDLE"}, 00108 {PSD_ENABLEPAGEPAINTHOOK,"PSD_ENABLEPAGEPAINTHOOK"}, 00109 {PSD_DISABLEPAGEPAINTING,"PSD_DISABLEPAGEPAINTING"}, 00110 {-1, NULL} 00111 }; 00112 00113 static const struct pd_flags pd_flags[] = { 00114 {PD_SELECTION, "PD_SELECTION "}, 00115 {PD_PAGENUMS, "PD_PAGENUMS "}, 00116 {PD_NOSELECTION, "PD_NOSELECTION "}, 00117 {PD_NOPAGENUMS, "PD_NOPAGENUMS "}, 00118 {PD_COLLATE, "PD_COLLATE "}, 00119 {PD_PRINTTOFILE, "PD_PRINTTOFILE "}, 00120 {PD_PRINTSETUP, "PD_PRINTSETUP "}, 00121 {PD_NOWARNING, "PD_NOWARNING "}, 00122 {PD_RETURNDC, "PD_RETURNDC "}, 00123 {PD_RETURNIC, "PD_RETURNIC "}, 00124 {PD_RETURNDEFAULT, "PD_RETURNDEFAULT "}, 00125 {PD_SHOWHELP, "PD_SHOWHELP "}, 00126 {PD_ENABLEPRINTHOOK, "PD_ENABLEPRINTHOOK "}, 00127 {PD_ENABLESETUPHOOK, "PD_ENABLESETUPHOOK "}, 00128 {PD_ENABLEPRINTTEMPLATE, "PD_ENABLEPRINTTEMPLATE "}, 00129 {PD_ENABLESETUPTEMPLATE, "PD_ENABLESETUPTEMPLATE "}, 00130 {PD_ENABLEPRINTTEMPLATEHANDLE, "PD_ENABLEPRINTTEMPLATEHANDLE "}, 00131 {PD_ENABLESETUPTEMPLATEHANDLE, "PD_ENABLESETUPTEMPLATEHANDLE "}, 00132 {PD_USEDEVMODECOPIES, "PD_USEDEVMODECOPIES[ANDCOLLATE] "}, 00133 {PD_DISABLEPRINTTOFILE, "PD_DISABLEPRINTTOFILE "}, 00134 {PD_HIDEPRINTTOFILE, "PD_HIDEPRINTTOFILE "}, 00135 {PD_NONETWORKBUTTON, "PD_NONETWORKBUTTON "}, 00136 {-1, NULL} 00137 }; 00138 /* address of wndproc for subclassed Static control */ 00139 static WNDPROC lpfnStaticWndProc; 00140 static WNDPROC edit_wndproc; 00141 /* the text of the fake document to render for the Page Setup dialog */ 00142 static WCHAR wszFakeDocumentText[1024]; 00143 static const WCHAR pd32_collateW[] = { 'P', 'D', '3', '2', '_', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 }; 00144 static const WCHAR pd32_nocollateW[] = { 'P', 'D', '3', '2', '_', 'N', 'O', 'C', 'O', 'L', 'L', 'A', 'T', 'E', 0 }; 00145 static const WCHAR pd32_portraitW[] = { 'P', 'D', '3', '2', '_', 'P', 'O', 'R', 'T', 'R', 'A', 'I', 'T', 0 }; 00146 static const WCHAR pd32_landscapeW[] = { 'P', 'D', '3', '2', '_', 'L', 'A', 'N', 'D', 'S', 'C', 'A', 'P', 'E', 0 }; 00147 static const WCHAR printdlg_prop[] = {'_','_','W','I','N','E','_','P','R','I','N','T','D','L','G','D','A','T','A',0}; 00148 static const WCHAR pagesetupdlg_prop[] = { '_', '_', 'W', 'I', 'N', 'E', '_', 'P', 'A', 'G', 'E', 00149 'S', 'E', 'T', 'U', 'P', 'D', 'L', 'G', 'D', 'A', 'T', 'A', 0 }; 00150 00151 00152 static LPWSTR strdupW(LPCWSTR p) 00153 { 00154 LPWSTR ret; 00155 DWORD len; 00156 00157 if(!p) return NULL; 00158 len = (strlenW(p) + 1) * sizeof(WCHAR); 00159 ret = HeapAlloc(GetProcessHeap(), 0, len); 00160 memcpy(ret, p, len); 00161 return ret; 00162 } 00163 00164 /*********************************************************** 00165 * convert_to_devmodeA 00166 * 00167 * Creates an ansi copy of supplied devmode 00168 */ 00169 static DEVMODEA *convert_to_devmodeA(const DEVMODEW *dmW) 00170 { 00171 DEVMODEA *dmA; 00172 DWORD size; 00173 00174 if (!dmW) return NULL; 00175 size = dmW->dmSize - CCHDEVICENAME - 00176 ((dmW->dmSize > FIELD_OFFSET(DEVMODEW, dmFormName)) ? CCHFORMNAME : 0); 00177 00178 dmA = HeapAlloc(GetProcessHeap(), 0, size + dmW->dmDriverExtra); 00179 if (!dmA) return NULL; 00180 00181 WideCharToMultiByte(CP_ACP, 0, dmW->dmDeviceName, -1, 00182 (LPSTR)dmA->dmDeviceName, CCHDEVICENAME, NULL, NULL); 00183 00184 if (FIELD_OFFSET(DEVMODEW, dmFormName) >= dmW->dmSize) 00185 { 00186 memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, 00187 dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmSpecVersion)); 00188 } 00189 else 00190 { 00191 memcpy(&dmA->dmSpecVersion, &dmW->dmSpecVersion, 00192 FIELD_OFFSET(DEVMODEW, dmFormName) - FIELD_OFFSET(DEVMODEW, dmSpecVersion)); 00193 WideCharToMultiByte(CP_ACP, 0, dmW->dmFormName, -1, 00194 (LPSTR)dmA->dmFormName, CCHFORMNAME, NULL, NULL); 00195 00196 memcpy(&dmA->dmLogPixels, &dmW->dmLogPixels, dmW->dmSize - FIELD_OFFSET(DEVMODEW, dmLogPixels)); 00197 } 00198 00199 dmA->dmSize = size; 00200 memcpy((char *)dmA + dmA->dmSize, (const char *)dmW + dmW->dmSize, dmW->dmDriverExtra); 00201 return dmA; 00202 } 00203 00204 /*********************************************************************** 00205 * PRINTDLG_OpenDefaultPrinter 00206 * 00207 * Returns a winspool printer handle to the default printer in *hprn 00208 * Caller must call ClosePrinter on the handle 00209 * 00210 * Returns TRUE on success else FALSE 00211 */ 00212 static BOOL PRINTDLG_OpenDefaultPrinter(HANDLE *hprn) 00213 { 00214 WCHAR buf[260]; 00215 DWORD dwBufLen = sizeof(buf) / sizeof(buf[0]); 00216 BOOL res; 00217 if(!GetDefaultPrinterW(buf, &dwBufLen)) 00218 return FALSE; 00219 res = OpenPrinterW(buf, hprn, NULL); 00220 if (!res) 00221 WARN("Could not open printer %s\n", debugstr_w(buf)); 00222 return res; 00223 } 00224 00225 /*********************************************************************** 00226 * PRINTDLG_SetUpPrinterListCombo 00227 * 00228 * Initializes printer list combox. 00229 * hDlg: HWND of dialog 00230 * id: Control id of combo 00231 * name: Name of printer to select 00232 * 00233 * Initializes combo with list of available printers. Selects printer 'name' 00234 * If name is NULL or does not exist select the default printer. 00235 * 00236 * Returns number of printers added to list. 00237 */ 00238 static INT PRINTDLG_SetUpPrinterListComboA(HWND hDlg, UINT id, LPCSTR name) 00239 { 00240 DWORD needed, num; 00241 INT i; 00242 LPPRINTER_INFO_2A pi; 00243 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); 00244 pi = HeapAlloc(GetProcessHeap(), 0, needed); 00245 EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, 00246 &num); 00247 00248 SendDlgItemMessageA(hDlg, id, CB_RESETCONTENT, 0, 0); 00249 00250 for(i = 0; i < num; i++) { 00251 SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0, 00252 (LPARAM)pi[i].pPrinterName ); 00253 } 00254 HeapFree(GetProcessHeap(), 0, pi); 00255 if(!name || 00256 (i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, 00257 (LPARAM)name)) == CB_ERR) { 00258 00259 char buf[260]; 00260 DWORD dwBufLen = sizeof(buf); 00261 if (name != NULL) 00262 WARN("Can't find %s in printer list so trying to find default\n", 00263 debugstr_a(name)); 00264 if(!GetDefaultPrinterA(buf, &dwBufLen)) 00265 return num; 00266 i = SendDlgItemMessageA(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); 00267 if(i == CB_ERR) 00268 FIXME("Can't find default printer in printer list\n"); 00269 } 00270 SendDlgItemMessageA(hDlg, id, CB_SETCURSEL, i, 0); 00271 return num; 00272 } 00273 00274 static INT PRINTDLG_SetUpPrinterListComboW(HWND hDlg, UINT id, LPCWSTR name) 00275 { 00276 DWORD needed, num; 00277 INT i; 00278 LPPRINTER_INFO_2W pi; 00279 EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); 00280 pi = HeapAlloc(GetProcessHeap(), 0, needed); 00281 EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, 00282 &num); 00283 00284 for(i = 0; i < num; i++) { 00285 SendDlgItemMessageW(hDlg, id, CB_ADDSTRING, 0, 00286 (LPARAM)pi[i].pPrinterName ); 00287 } 00288 HeapFree(GetProcessHeap(), 0, pi); 00289 if(!name || 00290 (i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, 00291 (LPARAM)name)) == CB_ERR) { 00292 WCHAR buf[260]; 00293 DWORD dwBufLen = sizeof(buf)/sizeof(buf[0]); 00294 if (name != NULL) 00295 WARN("Can't find %s in printer list so trying to find default\n", 00296 debugstr_w(name)); 00297 if(!GetDefaultPrinterW(buf, &dwBufLen)) 00298 return num; 00299 i = SendDlgItemMessageW(hDlg, id, CB_FINDSTRINGEXACT, -1, (LPARAM)buf); 00300 if(i == CB_ERR) 00301 TRACE("Can't find default printer in printer list\n"); 00302 } 00303 SendDlgItemMessageW(hDlg, id, CB_SETCURSEL, i, 0); 00304 return num; 00305 } 00306 00307 /*********************************************************************** 00308 * PRINTDLG_CreateDevNames [internal] 00309 * 00310 * 00311 * creates a DevNames structure. 00312 * 00313 * (NB. when we handle unicode the offsets will be in wchars). 00314 */ 00315 static BOOL PRINTDLG_CreateDevNames(HGLOBAL *hmem, const char* DeviceDriverName, 00316 const char* DeviceName, const char* OutputPort) 00317 { 00318 long size; 00319 char* pDevNamesSpace; 00320 char* pTempPtr; 00321 LPDEVNAMES lpDevNames; 00322 char buf[260]; 00323 DWORD dwBufLen = sizeof(buf); 00324 00325 size = strlen(DeviceDriverName) + 1 00326 + strlen(DeviceName) + 1 00327 + strlen(OutputPort) + 1 00328 + sizeof(DEVNAMES); 00329 00330 if(*hmem) 00331 *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); 00332 else 00333 *hmem = GlobalAlloc(GMEM_MOVEABLE, size); 00334 if (*hmem == 0) 00335 return FALSE; 00336 00337 pDevNamesSpace = GlobalLock(*hmem); 00338 lpDevNames = (LPDEVNAMES) pDevNamesSpace; 00339 00340 pTempPtr = pDevNamesSpace + sizeof(DEVNAMES); 00341 strcpy(pTempPtr, DeviceDriverName); 00342 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; 00343 00344 pTempPtr += strlen(DeviceDriverName) + 1; 00345 strcpy(pTempPtr, DeviceName); 00346 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; 00347 00348 pTempPtr += strlen(DeviceName) + 1; 00349 strcpy(pTempPtr, OutputPort); 00350 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; 00351 00352 GetDefaultPrinterA(buf, &dwBufLen); 00353 lpDevNames->wDefault = (strcmp(buf, DeviceName) == 0) ? 1 : 0; 00354 GlobalUnlock(*hmem); 00355 return TRUE; 00356 } 00357 00358 static BOOL PRINTDLG_CreateDevNamesW(HGLOBAL *hmem, LPCWSTR DeviceDriverName, 00359 LPCWSTR DeviceName, LPCWSTR OutputPort) 00360 { 00361 long size; 00362 LPWSTR pDevNamesSpace; 00363 LPWSTR pTempPtr; 00364 LPDEVNAMES lpDevNames; 00365 WCHAR bufW[260]; 00366 DWORD dwBufLen = sizeof(bufW) / sizeof(WCHAR); 00367 00368 size = sizeof(WCHAR)*lstrlenW(DeviceDriverName) + 2 00369 + sizeof(WCHAR)*lstrlenW(DeviceName) + 2 00370 + sizeof(WCHAR)*lstrlenW(OutputPort) + 2 00371 + sizeof(DEVNAMES); 00372 00373 if(*hmem) 00374 *hmem = GlobalReAlloc(*hmem, size, GMEM_MOVEABLE); 00375 else 00376 *hmem = GlobalAlloc(GMEM_MOVEABLE, size); 00377 if (*hmem == 0) 00378 return FALSE; 00379 00380 pDevNamesSpace = GlobalLock(*hmem); 00381 lpDevNames = (LPDEVNAMES) pDevNamesSpace; 00382 00383 pTempPtr = (LPWSTR)((LPDEVNAMES)pDevNamesSpace + 1); 00384 lstrcpyW(pTempPtr, DeviceDriverName); 00385 lpDevNames->wDriverOffset = pTempPtr - pDevNamesSpace; 00386 00387 pTempPtr += lstrlenW(DeviceDriverName) + 1; 00388 lstrcpyW(pTempPtr, DeviceName); 00389 lpDevNames->wDeviceOffset = pTempPtr - pDevNamesSpace; 00390 00391 pTempPtr += lstrlenW(DeviceName) + 1; 00392 lstrcpyW(pTempPtr, OutputPort); 00393 lpDevNames->wOutputOffset = pTempPtr - pDevNamesSpace; 00394 00395 GetDefaultPrinterW(bufW, &dwBufLen); 00396 lpDevNames->wDefault = (lstrcmpW(bufW, DeviceName) == 0) ? 1 : 0; 00397 GlobalUnlock(*hmem); 00398 return TRUE; 00399 } 00400 00401 /*********************************************************************** 00402 * PRINTDLG_UpdatePrintDlg [internal] 00403 * 00404 * 00405 * updates the PrintDlg structure for return values. 00406 * 00407 * RETURNS 00408 * FALSE if user is not allowed to close (i.e. wrong nTo or nFrom values) 00409 * TRUE if successful. 00410 */ 00411 static BOOL PRINTDLG_UpdatePrintDlgA(HWND hDlg, 00412 PRINT_PTRA* PrintStructures) 00413 { 00414 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; 00415 PDEVMODEA lpdm = PrintStructures->lpDevMode; 00416 LPPRINTER_INFO_2A pi = PrintStructures->lpPrinterInfo; 00417 00418 00419 if(!lpdm) { 00420 FIXME("No lpdm ptr?\n"); 00421 return FALSE; 00422 } 00423 00424 00425 if(!(lppd->Flags & PD_PRINTSETUP)) { 00426 /* check whether nFromPage and nToPage are within range defined by 00427 * nMinPage and nMaxPage 00428 */ 00429 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ 00430 WORD nToPage; 00431 WORD nFromPage; 00432 BOOL translated; 00433 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); 00434 nToPage = GetDlgItemInt(hDlg, edt2, &translated, FALSE); 00435 00436 /* if no ToPage value is entered, use the FromPage value */ 00437 if(!translated) nToPage = nFromPage; 00438 00439 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage || 00440 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) { 00441 WCHAR resourcestr[256]; 00442 WCHAR resultstr[256]; 00443 LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, resourcestr, 255); 00444 wsprintfW(resultstr,resourcestr, lppd->nMinPage, lppd->nMaxPage); 00445 LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, resourcestr, 255); 00446 MessageBoxW(hDlg, resultstr, resourcestr, MB_OK | MB_ICONWARNING); 00447 return FALSE; 00448 } 00449 lppd->nFromPage = nFromPage; 00450 lppd->nToPage = nToPage; 00451 lppd->Flags |= PD_PAGENUMS; 00452 } 00453 else 00454 lppd->Flags &= ~PD_PAGENUMS; 00455 00456 if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */ 00457 lppd->Flags |= PD_SELECTION; 00458 else 00459 lppd->Flags &= ~PD_SELECTION; 00460 00461 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ 00462 static char file[] = "FILE:"; 00463 lppd->Flags |= PD_PRINTTOFILE; 00464 pi->pPortName = file; 00465 } 00466 00467 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ 00468 FIXME("Collate lppd not yet implemented as output\n"); 00469 } 00470 00471 /* set PD_Collate and nCopies */ 00472 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 00473 /* The application doesn't support multiple copies or collate... 00474 */ 00475 lppd->Flags &= ~PD_COLLATE; 00476 lppd->nCopies = 1; 00477 /* if the printer driver supports it... store info there 00478 * otherwise no collate & multiple copies ! 00479 */ 00480 if (lpdm->dmFields & DM_COLLATE) 00481 lpdm->dmCollate = 00482 (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); 00483 if (lpdm->dmFields & DM_COPIES) 00484 lpdm->u1.s1.dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 00485 } else { 00486 /* Application is responsible for multiple copies */ 00487 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) 00488 lppd->Flags |= PD_COLLATE; 00489 else 00490 lppd->Flags &= ~PD_COLLATE; 00491 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 00492 /* multiple copies already included in the document. Driver must print only one copy */ 00493 lpdm->u1.s1.dmCopies = 1; 00494 } 00495 00496 /* Print quality, PrintDlg16 */ 00497 if(GetDlgItem(hDlg, cmb1)) 00498 { 00499 HWND hQuality = GetDlgItem(hDlg, cmb1); 00500 int Sel = SendMessageA(hQuality, CB_GETCURSEL, 0, 0); 00501 00502 if(Sel != CB_ERR) 00503 { 00504 LONG dpi = SendMessageA(hQuality, CB_GETITEMDATA, Sel, 0); 00505 lpdm->dmFields |= DM_PRINTQUALITY | DM_YRESOLUTION; 00506 lpdm->u1.s1.dmPrintQuality = LOWORD(dpi); 00507 lpdm->dmYResolution = HIWORD(dpi); 00508 } 00509 } 00510 } 00511 return TRUE; 00512 } 00513 00514 static BOOL PRINTDLG_UpdatePrintDlgW(HWND hDlg, 00515 PRINT_PTRW* PrintStructures) 00516 { 00517 LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; 00518 PDEVMODEW lpdm = PrintStructures->lpDevMode; 00519 LPPRINTER_INFO_2W pi = PrintStructures->lpPrinterInfo; 00520 00521 00522 if(!lpdm) { 00523 FIXME("No lpdm ptr?\n"); 00524 return FALSE; 00525 } 00526 00527 00528 if(!(lppd->Flags & PD_PRINTSETUP)) { 00529 /* check whether nFromPage and nToPage are within range defined by 00530 * nMinPage and nMaxPage 00531 */ 00532 if (IsDlgButtonChecked(hDlg, rad3) == BST_CHECKED) { /* Pages */ 00533 WORD nToPage; 00534 WORD nFromPage; 00535 BOOL translated; 00536 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); 00537 nToPage = GetDlgItemInt(hDlg, edt2, &translated, FALSE); 00538 00539 /* if no ToPage value is entered, use the FromPage value */ 00540 if(!translated) nToPage = nFromPage; 00541 00542 if (nFromPage < lppd->nMinPage || nFromPage > lppd->nMaxPage || 00543 nToPage < lppd->nMinPage || nToPage > lppd->nMaxPage) { 00544 WCHAR resourcestr[256]; 00545 WCHAR resultstr[256]; 00546 DWORD_PTR args[2]; 00547 LoadStringW(COMDLG32_hInstance, PD32_INVALID_PAGE_RANGE, 00548 resourcestr, 255); 00549 args[0] = lppd->nMinPage; 00550 args[1] = lppd->nMaxPage; 00551 FormatMessageW(FORMAT_MESSAGE_FROM_STRING|FORMAT_MESSAGE_ARGUMENT_ARRAY, 00552 resourcestr, 0, 0, resultstr, 00553 sizeof(resultstr)/sizeof(*resultstr), 00554 (__ms_va_list*)args); 00555 LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE, 00556 resourcestr, 255); 00557 MessageBoxW(hDlg, resultstr, resourcestr, 00558 MB_OK | MB_ICONWARNING); 00559 return FALSE; 00560 } 00561 lppd->nFromPage = nFromPage; 00562 lppd->nToPage = nToPage; 00563 lppd->Flags |= PD_PAGENUMS; 00564 } 00565 else 00566 lppd->Flags &= ~PD_PAGENUMS; 00567 00568 if (IsDlgButtonChecked(hDlg, rad2) == BST_CHECKED) /* Selection */ 00569 lppd->Flags |= PD_SELECTION; 00570 else 00571 lppd->Flags &= ~PD_SELECTION; 00572 00573 if (IsDlgButtonChecked(hDlg, chx1) == BST_CHECKED) {/* Print to file */ 00574 static WCHAR file[] = {'F','I','L','E',':',0}; 00575 lppd->Flags |= PD_PRINTTOFILE; 00576 pi->pPortName = file; 00577 } 00578 00579 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) { /* Collate */ 00580 FIXME("Collate lppd not yet implemented as output\n"); 00581 } 00582 00583 /* set PD_Collate and nCopies */ 00584 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 00585 /* The application doesn't support multiple copies or collate... 00586 */ 00587 lppd->Flags &= ~PD_COLLATE; 00588 lppd->nCopies = 1; 00589 /* if the printer driver supports it... store info there 00590 * otherwise no collate & multiple copies ! 00591 */ 00592 if (lpdm->dmFields & DM_COLLATE) 00593 lpdm->dmCollate = 00594 (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED); 00595 if (lpdm->dmFields & DM_COPIES) 00596 lpdm->u1.s1.dmCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 00597 } else { 00598 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) 00599 lppd->Flags |= PD_COLLATE; 00600 else 00601 lppd->Flags &= ~PD_COLLATE; 00602 lppd->nCopies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 00603 } 00604 } 00605 return TRUE; 00606 } 00607 00608 /************************************************************************ 00609 * PRINTDLG_SetUpPaperComboBox 00610 * 00611 * Initialize either the papersize or inputslot combos of the Printer Setup 00612 * dialog. We store the associated word (eg DMPAPER_A4) as the item data. 00613 * We also try to re-select the old selection. 00614 */ 00615 static BOOL PRINTDLG_SetUpPaperComboBoxA(HWND hDlg, 00616 int nIDComboBox, 00617 char* PrinterName, 00618 char* PortName, 00619 LPDEVMODEA dm) 00620 { 00621 int i; 00622 int NrOfEntries; 00623 char* Names; 00624 WORD* Words; 00625 DWORD Sel, old_Sel; 00626 WORD oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */ 00627 int NamesSize; 00628 int fwCapability_Names; 00629 int fwCapability_Words; 00630 00631 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",PrinterName,PortName,nIDComboBox); 00632 00633 /* query the dialog box for the current selected value */ 00634 Sel = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); 00635 if(Sel != CB_ERR) { 00636 /* we enter here only if a different printer is selected after 00637 * the Print Setup dialog is opened. The current settings are 00638 * stored into the newly selected printer. 00639 */ 00640 oldWord = SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, 00641 Sel, 0); 00642 if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */ 00643 oldWord = 0; /* There's no point in trying to keep custom 00644 paper / bin sizes across printers */ 00645 } 00646 00647 if (dm) 00648 newWord = (nIDComboBox == cmb2) ? dm->u1.s1.dmPaperSize : dm->u1.s1.dmDefaultSource; 00649 00650 if (nIDComboBox == cmb2) { 00651 NamesSize = 64; 00652 fwCapability_Names = DC_PAPERNAMES; 00653 fwCapability_Words = DC_PAPERS; 00654 } else { 00655 nIDComboBox = cmb3; 00656 NamesSize = 24; 00657 fwCapability_Names = DC_BINNAMES; 00658 fwCapability_Words = DC_BINS; 00659 } 00660 00661 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, 00662 fwCapability_Names, NULL, dm); 00663 if (NrOfEntries == 0) 00664 WARN("no Name Entries found!\n"); 00665 else if (NrOfEntries < 0) 00666 return FALSE; 00667 00668 if(DeviceCapabilitiesA(PrinterName, PortName, fwCapability_Words, NULL, dm) 00669 != NrOfEntries) { 00670 ERR("Number of caps is different\n"); 00671 NrOfEntries = 0; 00672 } 00673 00674 Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(char)*NamesSize); 00675 Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD)); 00676 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, 00677 fwCapability_Names, Names, dm); 00678 NrOfEntries = DeviceCapabilitiesA(PrinterName, PortName, 00679 fwCapability_Words, (LPSTR)Words, dm); 00680 00681 /* reset any current content in the combobox */ 00682 SendDlgItemMessageA(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); 00683 00684 /* store new content */ 00685 for (i = 0; i < NrOfEntries; i++) { 00686 DWORD pos = SendDlgItemMessageA(hDlg, nIDComboBox, CB_ADDSTRING, 0, 00687 (LPARAM)(&Names[i*NamesSize]) ); 00688 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETITEMDATA, pos, 00689 Words[i]); 00690 } 00691 00692 /* Look for old selection or the new default. 00693 Can't do this is previous loop since item order will change as more items are added */ 00694 Sel = 0; 00695 old_Sel = NrOfEntries; 00696 for (i = 0; i < NrOfEntries; i++) { 00697 if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == 00698 oldWord) { 00699 old_Sel = i; 00700 break; 00701 } 00702 if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord) 00703 Sel = i; 00704 } 00705 00706 if(old_Sel < NrOfEntries) 00707 { 00708 if (dm) 00709 { 00710 if(nIDComboBox == cmb2) 00711 dm->u1.s1.dmPaperSize = oldWord; 00712 else 00713 dm->u1.s1.dmDefaultSource = oldWord; 00714 } 00715 Sel = old_Sel; 00716 } 00717 00718 SendDlgItemMessageA(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); 00719 00720 HeapFree(GetProcessHeap(),0,Words); 00721 HeapFree(GetProcessHeap(),0,Names); 00722 return TRUE; 00723 } 00724 00725 static BOOL PRINTDLG_SetUpPaperComboBoxW(HWND hDlg, 00726 int nIDComboBox, 00727 const WCHAR* PrinterName, 00728 const WCHAR* PortName, 00729 LPDEVMODEW dm) 00730 { 00731 int i; 00732 int NrOfEntries; 00733 WCHAR* Names; 00734 WORD* Words; 00735 DWORD Sel, old_Sel; 00736 WORD oldWord = 0, newWord = 0; /* DMPAPER_ and DMBIN_ start at 1 */ 00737 int NamesSize; 00738 int fwCapability_Names; 00739 int fwCapability_Words; 00740 00741 TRACE(" Printer: %s, Port: %s, ComboID: %d\n",debugstr_w(PrinterName),debugstr_w(PortName),nIDComboBox); 00742 00743 /* query the dialog box for the current selected value */ 00744 Sel = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETCURSEL, 0, 0); 00745 if(Sel != CB_ERR) { 00746 /* we enter here only if a different printer is selected after 00747 * the Print Setup dialog is opened. The current settings are 00748 * stored into the newly selected printer. 00749 */ 00750 oldWord = SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, 00751 Sel, 0); 00752 00753 if(oldWord >= DMPAPER_USER) /* DMPAPER_USER == DMBIN_USER */ 00754 oldWord = 0; /* There's no point in trying to keep custom 00755 paper / bin sizes across printers */ 00756 } 00757 00758 if (dm) 00759 newWord = (nIDComboBox == cmb2) ? dm->u1.s1.dmPaperSize : dm->u1.s1.dmDefaultSource; 00760 00761 if (nIDComboBox == cmb2) { 00762 NamesSize = 64; 00763 fwCapability_Names = DC_PAPERNAMES; 00764 fwCapability_Words = DC_PAPERS; 00765 } else { 00766 nIDComboBox = cmb3; 00767 NamesSize = 24; 00768 fwCapability_Names = DC_BINNAMES; 00769 fwCapability_Words = DC_BINS; 00770 } 00771 00772 NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, 00773 fwCapability_Names, NULL, dm); 00774 if (NrOfEntries == 0) 00775 WARN("no Name Entries found!\n"); 00776 else if (NrOfEntries < 0) 00777 return FALSE; 00778 00779 if(DeviceCapabilitiesW(PrinterName, PortName, fwCapability_Words, NULL, dm) 00780 != NrOfEntries) { 00781 ERR("Number of caps is different\n"); 00782 NrOfEntries = 0; 00783 } 00784 00785 Names = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WCHAR)*NamesSize); 00786 Words = HeapAlloc(GetProcessHeap(),0, NrOfEntries*sizeof(WORD)); 00787 NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, 00788 fwCapability_Names, Names, dm); 00789 NrOfEntries = DeviceCapabilitiesW(PrinterName, PortName, 00790 fwCapability_Words, Words, dm); 00791 00792 /* reset any current content in the combobox */ 00793 SendDlgItemMessageW(hDlg, nIDComboBox, CB_RESETCONTENT, 0, 0); 00794 00795 /* store new content */ 00796 for (i = 0; i < NrOfEntries; i++) { 00797 DWORD pos = SendDlgItemMessageW(hDlg, nIDComboBox, CB_ADDSTRING, 0, 00798 (LPARAM)(&Names[i*NamesSize]) ); 00799 SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETITEMDATA, pos, 00800 Words[i]); 00801 } 00802 00803 /* Look for old selection or the new default. 00804 Can't do this is previous loop since item order will change as more items are added */ 00805 Sel = 0; 00806 old_Sel = NrOfEntries; 00807 for (i = 0; i < NrOfEntries; i++) { 00808 if(SendDlgItemMessageW(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == 00809 oldWord) { 00810 old_Sel = i; 00811 break; 00812 } 00813 if(SendDlgItemMessageA(hDlg, nIDComboBox, CB_GETITEMDATA, i, 0) == newWord) 00814 Sel = i; 00815 } 00816 00817 if(old_Sel < NrOfEntries) 00818 { 00819 if (dm) 00820 { 00821 if(nIDComboBox == cmb2) 00822 dm->u1.s1.dmPaperSize = oldWord; 00823 else 00824 dm->u1.s1.dmDefaultSource = oldWord; 00825 } 00826 Sel = old_Sel; 00827 } 00828 00829 SendDlgItemMessageW(hDlg, nIDComboBox, CB_SETCURSEL, Sel, 0); 00830 00831 HeapFree(GetProcessHeap(),0,Words); 00832 HeapFree(GetProcessHeap(),0,Names); 00833 return TRUE; 00834 } 00835 00836 00837 /*********************************************************************** 00838 * PRINTDLG_UpdatePrinterInfoTexts [internal] 00839 */ 00840 static void PRINTDLG_UpdatePrinterInfoTextsA(HWND hDlg, const PRINTER_INFO_2A *pi) 00841 { 00842 char StatusMsg[256]; 00843 char ResourceString[256]; 00844 int i; 00845 00846 /* Status Message */ 00847 StatusMsg[0]='\0'; 00848 00849 /* add all status messages */ 00850 for (i = 0; i < 25; i++) { 00851 if (pi->Status & (1<<i)) { 00852 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, 00853 ResourceString, 255); 00854 strcat(StatusMsg,ResourceString); 00855 } 00856 } 00857 /* append "ready" */ 00858 /* FIXME: status==ready must only be appended if really so. 00859 but how to detect? */ 00860 LoadStringA(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, 00861 ResourceString, 255); 00862 strcat(StatusMsg,ResourceString); 00863 SetDlgItemTextA(hDlg, stc12, StatusMsg); 00864 00865 /* set all other printer info texts */ 00866 SetDlgItemTextA(hDlg, stc11, pi->pDriverName); 00867 00868 if (pi->pLocation != NULL && pi->pLocation[0] != '\0') 00869 SetDlgItemTextA(hDlg, stc14, pi->pLocation); 00870 else 00871 SetDlgItemTextA(hDlg, stc14, pi->pPortName); 00872 SetDlgItemTextA(hDlg, stc13, pi->pComment ? pi->pComment : ""); 00873 return; 00874 } 00875 00876 static void PRINTDLG_UpdatePrinterInfoTextsW(HWND hDlg, const PRINTER_INFO_2W *pi) 00877 { 00878 WCHAR StatusMsg[256]; 00879 WCHAR ResourceString[256]; 00880 static const WCHAR emptyW[] = {0}; 00881 int i; 00882 00883 /* Status Message */ 00884 StatusMsg[0]='\0'; 00885 00886 /* add all status messages */ 00887 for (i = 0; i < 25; i++) { 00888 if (pi->Status & (1<<i)) { 00889 LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_PAUSED+i, 00890 ResourceString, 255); 00891 lstrcatW(StatusMsg,ResourceString); 00892 } 00893 } 00894 /* append "ready" */ 00895 /* FIXME: status==ready must only be appended if really so. 00896 but how to detect? */ 00897 LoadStringW(COMDLG32_hInstance, PD32_PRINTER_STATUS_READY, 00898 ResourceString, 255); 00899 lstrcatW(StatusMsg,ResourceString); 00900 SetDlgItemTextW(hDlg, stc12, StatusMsg); 00901 00902 /* set all other printer info texts */ 00903 SetDlgItemTextW(hDlg, stc11, pi->pDriverName); 00904 if (pi->pLocation != NULL && pi->pLocation[0] != '\0') 00905 SetDlgItemTextW(hDlg, stc14, pi->pLocation); 00906 else 00907 SetDlgItemTextW(hDlg, stc14, pi->pPortName); 00908 SetDlgItemTextW(hDlg, stc13, pi->pComment ? pi->pComment : emptyW); 00909 } 00910 00911 00912 /******************************************************************* 00913 * 00914 * PRINTDLG_ChangePrinter 00915 * 00916 */ 00917 static BOOL PRINTDLG_ChangePrinterA(HWND hDlg, char *name, PRINT_PTRA *PrintStructures) 00918 { 00919 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; 00920 LPDEVMODEA lpdm = NULL; 00921 LONG dmSize; 00922 DWORD needed; 00923 HANDLE hprn; 00924 00925 HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo); 00926 HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo); 00927 if(!OpenPrinterA(name, &hprn, NULL)) { 00928 ERR("Can't open printer %s\n", name); 00929 return FALSE; 00930 } 00931 GetPrinterA(hprn, 2, NULL, 0, &needed); 00932 PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed); 00933 GetPrinterA(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, 00934 &needed); 00935 GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); 00936 PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed); 00937 if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, 00938 needed, &needed)) { 00939 ERR("GetPrinterDriverA failed for %s, fix your config!\n",PrintStructures->lpPrinterInfo->pPrinterName); 00940 return FALSE; 00941 } 00942 ClosePrinter(hprn); 00943 00944 PRINTDLG_UpdatePrinterInfoTextsA(hDlg, PrintStructures->lpPrinterInfo); 00945 00946 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); 00947 PrintStructures->lpDevMode = NULL; 00948 00949 dmSize = DocumentPropertiesA(0, 0, name, NULL, NULL, 0); 00950 if(dmSize == -1) { 00951 ERR("DocumentProperties fails on %s\n", debugstr_a(name)); 00952 return FALSE; 00953 } 00954 PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize); 00955 dmSize = DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, NULL, 00956 DM_OUT_BUFFER); 00957 if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && 00958 !lstrcmpA( (LPSTR) lpdm->dmDeviceName, 00959 (LPSTR) PrintStructures->lpDevMode->dmDeviceName)) { 00960 /* Supplied devicemode matches current printer so try to use it */ 00961 DocumentPropertiesA(0, 0, name, PrintStructures->lpDevMode, lpdm, 00962 DM_OUT_BUFFER | DM_IN_BUFFER); 00963 } 00964 if(lpdm) 00965 GlobalUnlock(lppd->hDevMode); 00966 00967 lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ 00968 00969 if(!(lppd->Flags & PD_PRINTSETUP)) { 00970 /* Print range (All/Range/Selection) */ 00971 if(lppd->nFromPage != 0xffff) 00972 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE); 00973 if(lppd->nToPage != 0xffff) 00974 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE); 00975 00976 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */ 00977 if (lppd->Flags & PD_NOSELECTION) 00978 EnableWindow(GetDlgItem(hDlg, rad2), FALSE); 00979 else 00980 if (lppd->Flags & PD_SELECTION) 00981 CheckRadioButton(hDlg, rad1, rad3, rad2); 00982 if (lppd->Flags & PD_NOPAGENUMS) { 00983 EnableWindow(GetDlgItem(hDlg, rad3), FALSE); 00984 EnableWindow(GetDlgItem(hDlg, stc2),FALSE); 00985 EnableWindow(GetDlgItem(hDlg, edt1), FALSE); 00986 EnableWindow(GetDlgItem(hDlg, stc3),FALSE); 00987 EnableWindow(GetDlgItem(hDlg, edt2), FALSE); 00988 } else { 00989 if (lppd->Flags & PD_PAGENUMS) 00990 CheckRadioButton(hDlg, rad1, rad3, rad3); 00991 } 00992 00993 /* Collate pages 00994 * 00995 * FIXME: The ico3 is not displayed for some reason. I don't know why. 00996 */ 00997 if (lppd->Flags & PD_COLLATE) { 00998 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 00999 (LPARAM)PrintStructures->hCollateIcon); 01000 CheckDlgButton(hDlg, chx2, 1); 01001 } else { 01002 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01003 (LPARAM)PrintStructures->hNoCollateIcon); 01004 CheckDlgButton(hDlg, chx2, 0); 01005 } 01006 01007 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 01008 /* if printer doesn't support it: no Collate */ 01009 if (!(lpdm->dmFields & DM_COLLATE)) { 01010 EnableWindow(GetDlgItem(hDlg, chx2), FALSE); 01011 EnableWindow(GetDlgItem(hDlg, ico3), FALSE); 01012 } 01013 } 01014 01015 /* nCopies */ 01016 { 01017 INT copies; 01018 if (lppd->hDevMode == 0) 01019 copies = lppd->nCopies; 01020 else 01021 copies = lpdm->u1.s1.dmCopies; 01022 if(copies == 0) copies = 1; 01023 else if(copies < 0) copies = MAX_COPIES; 01024 SetDlgItemInt(hDlg, edt3, copies, FALSE); 01025 } 01026 01027 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 01028 /* if printer doesn't support it: no nCopies */ 01029 if (!(lpdm->dmFields & DM_COPIES)) { 01030 EnableWindow(GetDlgItem(hDlg, edt3), FALSE); 01031 EnableWindow(GetDlgItem(hDlg, stc5), FALSE); 01032 } 01033 } 01034 01035 /* print to file */ 01036 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0); 01037 if (lppd->Flags & PD_DISABLEPRINTTOFILE) 01038 EnableWindow(GetDlgItem(hDlg, chx1), FALSE); 01039 if (lppd->Flags & PD_HIDEPRINTTOFILE) 01040 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE); 01041 01042 /* Fill print quality combo, PrintDlg16 */ 01043 if(GetDlgItem(hDlg, cmb1)) 01044 { 01045 DWORD numResolutions = DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName, 01046 PrintStructures->lpPrinterInfo->pPortName, 01047 DC_ENUMRESOLUTIONS, NULL, lpdm); 01048 01049 if(numResolutions != -1) 01050 { 01051 HWND hQuality = GetDlgItem(hDlg, cmb1); 01052 LONG* Resolutions; 01053 char buf[255]; 01054 DWORD i; 01055 int dpiX, dpiY; 01056 HDC hPrinterDC = CreateDCA(PrintStructures->lpPrinterInfo->pDriverName, 01057 PrintStructures->lpPrinterInfo->pPrinterName, 01058 0, lpdm); 01059 01060 Resolutions = HeapAlloc(GetProcessHeap(), 0, numResolutions*sizeof(LONG)*2); 01061 DeviceCapabilitiesA(PrintStructures->lpPrinterInfo->pPrinterName, 01062 PrintStructures->lpPrinterInfo->pPortName, 01063 DC_ENUMRESOLUTIONS, (LPSTR)Resolutions, lpdm); 01064 01065 dpiX = GetDeviceCaps(hPrinterDC, LOGPIXELSX); 01066 dpiY = GetDeviceCaps(hPrinterDC, LOGPIXELSY); 01067 DeleteDC(hPrinterDC); 01068 01069 SendMessageA(hQuality, CB_RESETCONTENT, 0, 0); 01070 for(i = 0; i < (numResolutions * 2); i += 2) 01071 { 01072 BOOL IsDefault = FALSE; 01073 LRESULT Index; 01074 01075 if(Resolutions[i] == Resolutions[i+1]) 01076 { 01077 if(dpiX == Resolutions[i]) 01078 IsDefault = TRUE; 01079 sprintf(buf, "%d dpi", Resolutions[i]); 01080 } else 01081 { 01082 if(dpiX == Resolutions[i] && dpiY == Resolutions[i+1]) 01083 IsDefault = TRUE; 01084 sprintf(buf, "%d dpi x %d dpi", Resolutions[i], Resolutions[i+1]); 01085 } 01086 01087 Index = SendMessageA(hQuality, CB_ADDSTRING, 0, (LPARAM)buf); 01088 01089 if(IsDefault) 01090 SendMessageA(hQuality, CB_SETCURSEL, Index, 0); 01091 01092 SendMessageA(hQuality, CB_SETITEMDATA, Index, MAKELONG(dpiX,dpiY)); 01093 } 01094 HeapFree(GetProcessHeap(), 0, Resolutions); 01095 } 01096 } 01097 } else { /* PD_PRINTSETUP */ 01098 BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT); 01099 01100 PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb2, 01101 PrintStructures->lpPrinterInfo->pPrinterName, 01102 PrintStructures->lpPrinterInfo->pPortName, 01103 lpdm); 01104 PRINTDLG_SetUpPaperComboBoxA(hDlg, cmb3, 01105 PrintStructures->lpPrinterInfo->pPrinterName, 01106 PrintStructures->lpPrinterInfo->pPortName, 01107 lpdm); 01108 CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); 01109 SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01110 (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : 01111 PrintStructures->hLandscapeIcon)); 01112 01113 } 01114 01115 /* help button */ 01116 if ((lppd->Flags & PD_SHOWHELP)==0) { 01117 /* hide if PD_SHOWHELP not specified */ 01118 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE); 01119 } 01120 return TRUE; 01121 } 01122 01123 static BOOL PRINTDLG_ChangePrinterW(HWND hDlg, WCHAR *name, 01124 PRINT_PTRW *PrintStructures) 01125 { 01126 LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; 01127 LPDEVMODEW lpdm = NULL; 01128 LONG dmSize; 01129 DWORD needed; 01130 HANDLE hprn; 01131 01132 HeapFree(GetProcessHeap(),0, PrintStructures->lpPrinterInfo); 01133 HeapFree(GetProcessHeap(),0, PrintStructures->lpDriverInfo); 01134 if(!OpenPrinterW(name, &hprn, NULL)) { 01135 ERR("Can't open printer %s\n", debugstr_w(name)); 01136 return FALSE; 01137 } 01138 GetPrinterW(hprn, 2, NULL, 0, &needed); 01139 PrintStructures->lpPrinterInfo = HeapAlloc(GetProcessHeap(),0,needed); 01140 GetPrinterW(hprn, 2, (LPBYTE)PrintStructures->lpPrinterInfo, needed, 01141 &needed); 01142 GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); 01143 PrintStructures->lpDriverInfo = HeapAlloc(GetProcessHeap(),0,needed); 01144 if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)PrintStructures->lpDriverInfo, 01145 needed, &needed)) { 01146 ERR("GetPrinterDriverA failed for %s, fix your config!\n",debugstr_w(PrintStructures->lpPrinterInfo->pPrinterName)); 01147 return FALSE; 01148 } 01149 ClosePrinter(hprn); 01150 01151 PRINTDLG_UpdatePrinterInfoTextsW(hDlg, PrintStructures->lpPrinterInfo); 01152 01153 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); 01154 PrintStructures->lpDevMode = NULL; 01155 01156 dmSize = DocumentPropertiesW(0, 0, name, NULL, NULL, 0); 01157 if(dmSize == -1) { 01158 ERR("DocumentProperties fails on %s\n", debugstr_w(name)); 01159 return FALSE; 01160 } 01161 PrintStructures->lpDevMode = HeapAlloc(GetProcessHeap(), 0, dmSize); 01162 dmSize = DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, NULL, 01163 DM_OUT_BUFFER); 01164 if(lppd->hDevMode && (lpdm = GlobalLock(lppd->hDevMode)) && 01165 !lstrcmpW(lpdm->dmDeviceName, 01166 PrintStructures->lpDevMode->dmDeviceName)) { 01167 /* Supplied devicemode matches current printer so try to use it */ 01168 DocumentPropertiesW(0, 0, name, PrintStructures->lpDevMode, lpdm, 01169 DM_OUT_BUFFER | DM_IN_BUFFER); 01170 } 01171 if(lpdm) 01172 GlobalUnlock(lppd->hDevMode); 01173 01174 lpdm = PrintStructures->lpDevMode; /* use this as a shortcut */ 01175 01176 if(!(lppd->Flags & PD_PRINTSETUP)) { 01177 /* Print range (All/Range/Selection) */ 01178 if(lppd->nFromPage != 0xffff) 01179 SetDlgItemInt(hDlg, edt1, lppd->nFromPage, FALSE); 01180 if(lppd->nToPage != 0xffff) 01181 SetDlgItemInt(hDlg, edt2, lppd->nToPage, FALSE); 01182 01183 CheckRadioButton(hDlg, rad1, rad3, rad1); /* default */ 01184 if (lppd->Flags & PD_NOSELECTION) 01185 EnableWindow(GetDlgItem(hDlg, rad2), FALSE); 01186 else 01187 if (lppd->Flags & PD_SELECTION) 01188 CheckRadioButton(hDlg, rad1, rad3, rad2); 01189 if (lppd->Flags & PD_NOPAGENUMS) { 01190 EnableWindow(GetDlgItem(hDlg, rad3), FALSE); 01191 EnableWindow(GetDlgItem(hDlg, stc2),FALSE); 01192 EnableWindow(GetDlgItem(hDlg, edt1), FALSE); 01193 EnableWindow(GetDlgItem(hDlg, stc3),FALSE); 01194 EnableWindow(GetDlgItem(hDlg, edt2), FALSE); 01195 } else { 01196 if (lppd->Flags & PD_PAGENUMS) 01197 CheckRadioButton(hDlg, rad1, rad3, rad3); 01198 } 01199 01200 /* Collate pages 01201 * 01202 * FIXME: The ico3 is not displayed for some reason. I don't know why. 01203 */ 01204 if (lppd->Flags & PD_COLLATE) { 01205 SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01206 (LPARAM)PrintStructures->hCollateIcon); 01207 CheckDlgButton(hDlg, chx2, 1); 01208 } else { 01209 SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01210 (LPARAM)PrintStructures->hNoCollateIcon); 01211 CheckDlgButton(hDlg, chx2, 0); 01212 } 01213 01214 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 01215 /* if printer doesn't support it: no Collate */ 01216 if (!(lpdm->dmFields & DM_COLLATE)) { 01217 EnableWindow(GetDlgItem(hDlg, chx2), FALSE); 01218 EnableWindow(GetDlgItem(hDlg, ico3), FALSE); 01219 } 01220 } 01221 01222 /* nCopies */ 01223 { 01224 INT copies; 01225 if (lppd->hDevMode == 0) 01226 copies = lppd->nCopies; 01227 else 01228 copies = lpdm->u1.s1.dmCopies; 01229 if(copies == 0) copies = 1; 01230 else if(copies < 0) copies = MAX_COPIES; 01231 SetDlgItemInt(hDlg, edt3, copies, FALSE); 01232 } 01233 01234 if (lppd->Flags & PD_USEDEVMODECOPIESANDCOLLATE) { 01235 /* if printer doesn't support it: no nCopies */ 01236 if (!(lpdm->dmFields & DM_COPIES)) { 01237 EnableWindow(GetDlgItem(hDlg, edt3), FALSE); 01238 EnableWindow(GetDlgItem(hDlg, stc5), FALSE); 01239 } 01240 } 01241 01242 /* print to file */ 01243 CheckDlgButton(hDlg, chx1, (lppd->Flags & PD_PRINTTOFILE) ? 1 : 0); 01244 if (lppd->Flags & PD_DISABLEPRINTTOFILE) 01245 EnableWindow(GetDlgItem(hDlg, chx1), FALSE); 01246 if (lppd->Flags & PD_HIDEPRINTTOFILE) 01247 ShowWindow(GetDlgItem(hDlg, chx1), SW_HIDE); 01248 01249 } else { /* PD_PRINTSETUP */ 01250 BOOL bPortrait = (lpdm->u1.s1.dmOrientation == DMORIENT_PORTRAIT); 01251 01252 PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, 01253 PrintStructures->lpPrinterInfo->pPrinterName, 01254 PrintStructures->lpPrinterInfo->pPortName, 01255 lpdm); 01256 PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, 01257 PrintStructures->lpPrinterInfo->pPrinterName, 01258 PrintStructures->lpPrinterInfo->pPortName, 01259 lpdm); 01260 CheckRadioButton(hDlg, rad1, rad2, bPortrait ? rad1: rad2); 01261 SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01262 (LPARAM)(bPortrait ? PrintStructures->hPortraitIcon : 01263 PrintStructures->hLandscapeIcon)); 01264 01265 } 01266 01267 /* help button */ 01268 if ((lppd->Flags & PD_SHOWHELP)==0) { 01269 /* hide if PD_SHOWHELP not specified */ 01270 ShowWindow(GetDlgItem(hDlg, pshHelp), SW_HIDE); 01271 } 01272 return TRUE; 01273 } 01274 01275 /*********************************************************************** 01276 * check_printer_setup [internal] 01277 */ 01278 static LRESULT check_printer_setup(HWND hDlg) 01279 { 01280 DWORD needed,num; 01281 WCHAR resourcestr[256],resultstr[256]; 01282 01283 EnumPrintersW(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &needed, &num); 01284 if(needed == 0) 01285 { 01286 EnumPrintersW(PRINTER_ENUM_CONNECTIONS, NULL, 2, NULL, 0, &needed, &num); 01287 } 01288 if(needed > 0) 01289 return TRUE; 01290 else 01291 { 01292 LoadStringW(COMDLG32_hInstance, PD32_NO_DEVICES,resultstr, 255); 01293 LoadStringW(COMDLG32_hInstance, PD32_PRINT_TITLE,resourcestr, 255); 01294 MessageBoxW(hDlg, resultstr, resourcestr,MB_OK | MB_ICONWARNING); 01295 return FALSE; 01296 } 01297 } 01298 01299 /*********************************************************************** 01300 * PRINTDLG_WMInitDialog [internal] 01301 */ 01302 static LRESULT PRINTDLG_WMInitDialog(HWND hDlg, 01303 PRINT_PTRA* PrintStructures) 01304 { 01305 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; 01306 DEVNAMES *pdn; 01307 DEVMODEA *pdm; 01308 char *name = NULL; 01309 UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; 01310 01311 /* load Collate ICONs */ 01312 /* We load these with LoadImage because they are not a standard 01313 size and we don't want them rescaled */ 01314 PrintStructures->hCollateIcon = 01315 LoadImageA(COMDLG32_hInstance, "PD32_COLLATE", IMAGE_ICON, 0, 0, 0); 01316 PrintStructures->hNoCollateIcon = 01317 LoadImageA(COMDLG32_hInstance, "PD32_NOCOLLATE", IMAGE_ICON, 0, 0, 0); 01318 01319 /* These can be done with LoadIcon */ 01320 PrintStructures->hPortraitIcon = 01321 LoadIconA(COMDLG32_hInstance, "PD32_PORTRAIT"); 01322 PrintStructures->hLandscapeIcon = 01323 LoadIconA(COMDLG32_hInstance, "PD32_LANDSCAPE"); 01324 01325 /* display the collate/no_collate icon */ 01326 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01327 (LPARAM)PrintStructures->hNoCollateIcon); 01328 01329 if(PrintStructures->hCollateIcon == 0 || 01330 PrintStructures->hNoCollateIcon == 0 || 01331 PrintStructures->hPortraitIcon == 0 || 01332 PrintStructures->hLandscapeIcon == 0) { 01333 ERR("no icon in resourcefile\n"); 01334 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 01335 EndDialog(hDlg, FALSE); 01336 } 01337 01338 /* 01339 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message 01340 * must be registered and the Help button must be shown. 01341 */ 01342 if (lppd->Flags & PD_SHOWHELP) { 01343 if((PrintStructures->HelpMessageID = 01344 RegisterWindowMessageA(HELPMSGSTRINGA)) == 0) { 01345 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); 01346 return FALSE; 01347 } 01348 } else 01349 PrintStructures->HelpMessageID = 0; 01350 01351 if(!(lppd->Flags &PD_PRINTSETUP)) { 01352 PrintStructures->hwndUpDown = 01353 CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | 01354 UDS_NOTHOUSANDS | UDS_ARROWKEYS | 01355 UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, 01356 hDlg, UPDOWN_ID, COMDLG32_hInstance, 01357 GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); 01358 } 01359 01360 /* FIXME: I allow more freedom than either Win95 or WinNT, 01361 * which do not agree to what errors should be thrown or not 01362 * in case nToPage or nFromPage is out-of-range. 01363 */ 01364 if (lppd->nMaxPage < lppd->nMinPage) 01365 lppd->nMaxPage = lppd->nMinPage; 01366 if (lppd->nMinPage == lppd->nMaxPage) 01367 lppd->Flags |= PD_NOPAGENUMS; 01368 if (lppd->nToPage < lppd->nMinPage) 01369 lppd->nToPage = lppd->nMinPage; 01370 if (lppd->nToPage > lppd->nMaxPage) 01371 lppd->nToPage = lppd->nMaxPage; 01372 if (lppd->nFromPage < lppd->nMinPage) 01373 lppd->nFromPage = lppd->nMinPage; 01374 if (lppd->nFromPage > lppd->nMaxPage) 01375 lppd->nFromPage = lppd->nMaxPage; 01376 01377 /* if we have the combo box, fill it */ 01378 if (GetDlgItem(hDlg,comboID)) { 01379 /* Fill Combobox 01380 */ 01381 pdn = GlobalLock(lppd->hDevNames); 01382 pdm = GlobalLock(lppd->hDevMode); 01383 if(pdn) 01384 name = (char*)pdn + pdn->wDeviceOffset; 01385 else if(pdm) 01386 name = (char*)pdm->dmDeviceName; 01387 PRINTDLG_SetUpPrinterListComboA(hDlg, comboID, name); 01388 if(pdm) GlobalUnlock(lppd->hDevMode); 01389 if(pdn) GlobalUnlock(lppd->hDevNames); 01390 01391 /* Now find selected printer and update rest of dlg */ 01392 name = HeapAlloc(GetProcessHeap(),0,256); 01393 if (GetDlgItemTextA(hDlg, comboID, name, 255)) 01394 PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); 01395 HeapFree(GetProcessHeap(),0,name); 01396 } else { 01397 /* else use default printer */ 01398 char name[200]; 01399 DWORD dwBufLen = sizeof(name); 01400 BOOL ret = GetDefaultPrinterA(name, &dwBufLen); 01401 01402 if (ret) 01403 PRINTDLG_ChangePrinterA(hDlg, name, PrintStructures); 01404 else 01405 FIXME("No default printer found, expect problems!\n"); 01406 } 01407 return TRUE; 01408 } 01409 01410 static LRESULT PRINTDLG_WMInitDialogW(HWND hDlg, 01411 PRINT_PTRW* PrintStructures) 01412 { 01413 LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; 01414 DEVNAMES *pdn; 01415 DEVMODEW *pdm; 01416 WCHAR *name = NULL; 01417 UINT comboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; 01418 01419 /* load Collate ICONs */ 01420 /* We load these with LoadImage because they are not a standard 01421 size and we don't want them rescaled */ 01422 PrintStructures->hCollateIcon = 01423 LoadImageW(COMDLG32_hInstance, pd32_collateW, IMAGE_ICON, 0, 0, 0); 01424 PrintStructures->hNoCollateIcon = 01425 LoadImageW(COMDLG32_hInstance, pd32_nocollateW, IMAGE_ICON, 0, 0, 0); 01426 01427 /* These can be done with LoadIcon */ 01428 PrintStructures->hPortraitIcon = 01429 LoadIconW(COMDLG32_hInstance, pd32_portraitW); 01430 PrintStructures->hLandscapeIcon = 01431 LoadIconW(COMDLG32_hInstance, pd32_landscapeW); 01432 01433 /* display the collate/no_collate icon */ 01434 SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01435 (LPARAM)PrintStructures->hNoCollateIcon); 01436 01437 if(PrintStructures->hCollateIcon == 0 || 01438 PrintStructures->hNoCollateIcon == 0 || 01439 PrintStructures->hPortraitIcon == 0 || 01440 PrintStructures->hLandscapeIcon == 0) { 01441 ERR("no icon in resourcefile\n"); 01442 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 01443 EndDialog(hDlg, FALSE); 01444 } 01445 01446 /* 01447 * if lppd->Flags PD_SHOWHELP is specified, a HELPMESGSTRING message 01448 * must be registered and the Help button must be shown. 01449 */ 01450 if (lppd->Flags & PD_SHOWHELP) { 01451 if((PrintStructures->HelpMessageID = 01452 RegisterWindowMessageW(HELPMSGSTRINGW)) == 0) { 01453 COMDLG32_SetCommDlgExtendedError(CDERR_REGISTERMSGFAIL); 01454 return FALSE; 01455 } 01456 } else 01457 PrintStructures->HelpMessageID = 0; 01458 01459 if(!(lppd->Flags &PD_PRINTSETUP)) { 01460 PrintStructures->hwndUpDown = 01461 CreateUpDownControl(WS_CHILD | WS_VISIBLE | WS_BORDER | 01462 UDS_NOTHOUSANDS | UDS_ARROWKEYS | 01463 UDS_ALIGNRIGHT | UDS_SETBUDDYINT, 0, 0, 0, 0, 01464 hDlg, UPDOWN_ID, COMDLG32_hInstance, 01465 GetDlgItem(hDlg, edt3), MAX_COPIES, 1, 1); 01466 } 01467 01468 /* FIXME: I allow more freedom than either Win95 or WinNT, 01469 * which do not agree to what errors should be thrown or not 01470 * in case nToPage or nFromPage is out-of-range. 01471 */ 01472 if (lppd->nMaxPage < lppd->nMinPage) 01473 lppd->nMaxPage = lppd->nMinPage; 01474 if (lppd->nMinPage == lppd->nMaxPage) 01475 lppd->Flags |= PD_NOPAGENUMS; 01476 if (lppd->nToPage < lppd->nMinPage) 01477 lppd->nToPage = lppd->nMinPage; 01478 if (lppd->nToPage > lppd->nMaxPage) 01479 lppd->nToPage = lppd->nMaxPage; 01480 if (lppd->nFromPage < lppd->nMinPage) 01481 lppd->nFromPage = lppd->nMinPage; 01482 if (lppd->nFromPage > lppd->nMaxPage) 01483 lppd->nFromPage = lppd->nMaxPage; 01484 01485 /* if we have the combo box, fill it */ 01486 if (GetDlgItem(hDlg,comboID)) { 01487 /* Fill Combobox 01488 */ 01489 pdn = GlobalLock(lppd->hDevNames); 01490 pdm = GlobalLock(lppd->hDevMode); 01491 if(pdn) 01492 name = (WCHAR*)pdn + pdn->wDeviceOffset; 01493 else if(pdm) 01494 name = pdm->dmDeviceName; 01495 PRINTDLG_SetUpPrinterListComboW(hDlg, comboID, name); 01496 if(pdm) GlobalUnlock(lppd->hDevMode); 01497 if(pdn) GlobalUnlock(lppd->hDevNames); 01498 01499 /* Now find selected printer and update rest of dlg */ 01500 /* ansi is ok here */ 01501 name = HeapAlloc(GetProcessHeap(),0,256*sizeof(WCHAR)); 01502 if (GetDlgItemTextW(hDlg, comboID, name, 255)) 01503 PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); 01504 HeapFree(GetProcessHeap(),0,name); 01505 } else { 01506 /* else use default printer */ 01507 WCHAR name[200]; 01508 DWORD dwBufLen = sizeof(name) / sizeof(WCHAR); 01509 BOOL ret = GetDefaultPrinterW(name, &dwBufLen); 01510 01511 if (ret) 01512 PRINTDLG_ChangePrinterW(hDlg, name, PrintStructures); 01513 else 01514 FIXME("No default printer found, expect problems!\n"); 01515 } 01516 return TRUE; 01517 } 01518 01519 /*********************************************************************** 01520 * PRINTDLG_WMCommand [internal] 01521 */ 01522 static LRESULT PRINTDLG_WMCommandA(HWND hDlg, WPARAM wParam, 01523 PRINT_PTRA* PrintStructures) 01524 { 01525 LPPRINTDLGA lppd = PrintStructures->lpPrintDlg; 01526 UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; 01527 LPDEVMODEA lpdm = PrintStructures->lpDevMode; 01528 01529 switch (LOWORD(wParam)) { 01530 case IDOK: 01531 TRACE(" OK button was hit\n"); 01532 if (!PRINTDLG_UpdatePrintDlgA(hDlg, PrintStructures)) { 01533 FIXME("Update printdlg was not successful!\n"); 01534 return(FALSE); 01535 } 01536 EndDialog(hDlg, TRUE); 01537 return(TRUE); 01538 01539 case IDCANCEL: 01540 TRACE(" CANCEL button was hit\n"); 01541 EndDialog(hDlg, FALSE); 01542 return(FALSE); 01543 01544 case pshHelp: 01545 TRACE(" HELP button was hit\n"); 01546 SendMessageA(lppd->hwndOwner, PrintStructures->HelpMessageID, 01547 (WPARAM) hDlg, (LPARAM) lppd); 01548 break; 01549 01550 case chx2: /* collate pages checkbox */ 01551 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) 01552 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01553 (LPARAM)PrintStructures->hCollateIcon); 01554 else 01555 SendDlgItemMessageA(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01556 (LPARAM)PrintStructures->hNoCollateIcon); 01557 break; 01558 case edt1: /* from page nr editbox */ 01559 case edt2: /* to page nr editbox */ 01560 if (HIWORD(wParam)==EN_CHANGE) { 01561 WORD nToPage; 01562 WORD nFromPage; 01563 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); 01564 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); 01565 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage) 01566 CheckRadioButton(hDlg, rad1, rad3, rad3); 01567 } 01568 break; 01569 01570 case edt3: 01571 if(HIWORD(wParam) == EN_CHANGE) { 01572 INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 01573 if(copies <= 1) 01574 EnableWindow(GetDlgItem(hDlg, chx2), FALSE); 01575 else 01576 EnableWindow(GetDlgItem(hDlg, chx2), TRUE); 01577 } 01578 break; 01579 01580 case psh2: /* Properties button */ 01581 { 01582 HANDLE hPrinter; 01583 char PrinterName[256]; 01584 01585 GetDlgItemTextA(hDlg, PrinterComboID, PrinterName, 255); 01586 if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { 01587 FIXME(" Call to OpenPrinter did not succeed!\n"); 01588 break; 01589 } 01590 DocumentPropertiesA(hDlg, hPrinter, PrinterName, 01591 PrintStructures->lpDevMode, 01592 PrintStructures->lpDevMode, 01593 DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); 01594 ClosePrinter(hPrinter); 01595 break; 01596 } 01597 01598 case rad1: /* Paperorientation */ 01599 if (lppd->Flags & PD_PRINTSETUP) 01600 { 01601 lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; 01602 SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01603 (LPARAM)(PrintStructures->hPortraitIcon)); 01604 } 01605 break; 01606 01607 case rad2: /* Paperorientation */ 01608 if (lppd->Flags & PD_PRINTSETUP) 01609 { 01610 lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; 01611 SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01612 (LPARAM)(PrintStructures->hLandscapeIcon)); 01613 } 01614 break; 01615 01616 case cmb1: /* Printer Combobox in PRINT SETUP, quality combobox in PRINT16 */ 01617 if (PrinterComboID != LOWORD(wParam)) { 01618 break; 01619 } 01620 /* FALLTHROUGH */ 01621 case cmb4: /* Printer combobox */ 01622 if (HIWORD(wParam)==CBN_SELCHANGE) { 01623 char PrinterName[256]; 01624 GetDlgItemTextA(hDlg, LOWORD(wParam), PrinterName, 255); 01625 PRINTDLG_ChangePrinterA(hDlg, PrinterName, PrintStructures); 01626 } 01627 break; 01628 01629 case cmb2: /* Papersize */ 01630 { 01631 DWORD Sel = SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0); 01632 if(Sel != CB_ERR) 01633 lpdm->u1.s1.dmPaperSize = SendDlgItemMessageA(hDlg, cmb2, 01634 CB_GETITEMDATA, 01635 Sel, 0); 01636 } 01637 break; 01638 01639 case cmb3: /* Bin */ 01640 { 01641 DWORD Sel = SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0); 01642 if(Sel != CB_ERR) 01643 lpdm->u1.s1.dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3, 01644 CB_GETITEMDATA, Sel, 01645 0); 01646 } 01647 break; 01648 } 01649 if(lppd->Flags & PD_PRINTSETUP) { 01650 switch (LOWORD(wParam)) { 01651 case rad1: /* orientation */ 01652 case rad2: 01653 if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { 01654 if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { 01655 lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; 01656 SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, 01657 (LPARAM)PrintStructures->hPortraitIcon); 01658 SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01659 (LPARAM)PrintStructures->hPortraitIcon); 01660 } 01661 } else { 01662 if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) { 01663 lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; 01664 SendDlgItemMessageA(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, 01665 (LPARAM)PrintStructures->hLandscapeIcon); 01666 SendDlgItemMessageA(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01667 (LPARAM)PrintStructures->hLandscapeIcon); 01668 } 01669 } 01670 break; 01671 } 01672 } 01673 return FALSE; 01674 } 01675 01676 static LRESULT PRINTDLG_WMCommandW(HWND hDlg, WPARAM wParam, 01677 PRINT_PTRW* PrintStructures) 01678 { 01679 LPPRINTDLGW lppd = PrintStructures->lpPrintDlg; 01680 UINT PrinterComboID = (lppd->Flags & PD_PRINTSETUP) ? cmb1 : cmb4; 01681 LPDEVMODEW lpdm = PrintStructures->lpDevMode; 01682 01683 switch (LOWORD(wParam)) { 01684 case IDOK: 01685 TRACE(" OK button was hit\n"); 01686 if (!PRINTDLG_UpdatePrintDlgW(hDlg, PrintStructures)) { 01687 FIXME("Update printdlg was not successful!\n"); 01688 return(FALSE); 01689 } 01690 EndDialog(hDlg, TRUE); 01691 return(TRUE); 01692 01693 case IDCANCEL: 01694 TRACE(" CANCEL button was hit\n"); 01695 EndDialog(hDlg, FALSE); 01696 return(FALSE); 01697 01698 case pshHelp: 01699 TRACE(" HELP button was hit\n"); 01700 SendMessageW(lppd->hwndOwner, PrintStructures->HelpMessageID, 01701 (WPARAM) hDlg, (LPARAM) lppd); 01702 break; 01703 01704 case chx2: /* collate pages checkbox */ 01705 if (IsDlgButtonChecked(hDlg, chx2) == BST_CHECKED) 01706 SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01707 (LPARAM)PrintStructures->hCollateIcon); 01708 else 01709 SendDlgItemMessageW(hDlg, ico3, STM_SETIMAGE, IMAGE_ICON, 01710 (LPARAM)PrintStructures->hNoCollateIcon); 01711 break; 01712 case edt1: /* from page nr editbox */ 01713 case edt2: /* to page nr editbox */ 01714 if (HIWORD(wParam)==EN_CHANGE) { 01715 WORD nToPage; 01716 WORD nFromPage; 01717 nFromPage = GetDlgItemInt(hDlg, edt1, NULL, FALSE); 01718 nToPage = GetDlgItemInt(hDlg, edt2, NULL, FALSE); 01719 if (nFromPage != lppd->nFromPage || nToPage != lppd->nToPage) 01720 CheckRadioButton(hDlg, rad1, rad3, rad3); 01721 } 01722 break; 01723 01724 case edt3: 01725 if(HIWORD(wParam) == EN_CHANGE) { 01726 INT copies = GetDlgItemInt(hDlg, edt3, NULL, FALSE); 01727 if(copies <= 1) 01728 EnableWindow(GetDlgItem(hDlg, chx2), FALSE); 01729 else 01730 EnableWindow(GetDlgItem(hDlg, chx2), TRUE); 01731 } 01732 break; 01733 01734 case psh2: /* Properties button */ 01735 { 01736 HANDLE hPrinter; 01737 WCHAR PrinterName[256]; 01738 01739 if (!GetDlgItemTextW(hDlg, PrinterComboID, PrinterName, 255)) break; 01740 if (!OpenPrinterW(PrinterName, &hPrinter, NULL)) { 01741 FIXME(" Call to OpenPrinter did not succeed!\n"); 01742 break; 01743 } 01744 DocumentPropertiesW(hDlg, hPrinter, PrinterName, 01745 PrintStructures->lpDevMode, 01746 PrintStructures->lpDevMode, 01747 DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); 01748 ClosePrinter(hPrinter); 01749 break; 01750 } 01751 01752 case rad1: /* Paperorientation */ 01753 if (lppd->Flags & PD_PRINTSETUP) 01754 { 01755 lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; 01756 SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01757 (LPARAM)(PrintStructures->hPortraitIcon)); 01758 } 01759 break; 01760 01761 case rad2: /* Paperorientation */ 01762 if (lppd->Flags & PD_PRINTSETUP) 01763 { 01764 lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; 01765 SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01766 (LPARAM)(PrintStructures->hLandscapeIcon)); 01767 } 01768 break; 01769 01770 case cmb1: /* Printer Combobox in PRINT SETUP */ 01771 /* FALLTHROUGH */ 01772 case cmb4: /* Printer combobox */ 01773 if (HIWORD(wParam)==CBN_SELCHANGE) { 01774 WCHAR PrinterName[256]; 01775 GetDlgItemTextW(hDlg, LOWORD(wParam), PrinterName, 255); 01776 PRINTDLG_ChangePrinterW(hDlg, PrinterName, PrintStructures); 01777 } 01778 break; 01779 01780 case cmb2: /* Papersize */ 01781 { 01782 DWORD Sel = SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0); 01783 if(Sel != CB_ERR) 01784 lpdm->u1.s1.dmPaperSize = SendDlgItemMessageW(hDlg, cmb2, 01785 CB_GETITEMDATA, 01786 Sel, 0); 01787 } 01788 break; 01789 01790 case cmb3: /* Bin */ 01791 { 01792 DWORD Sel = SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0); 01793 if(Sel != CB_ERR) 01794 lpdm->u1.s1.dmDefaultSource = SendDlgItemMessageW(hDlg, cmb3, 01795 CB_GETITEMDATA, Sel, 01796 0); 01797 } 01798 break; 01799 } 01800 if(lppd->Flags & PD_PRINTSETUP) { 01801 switch (LOWORD(wParam)) { 01802 case rad1: /* orientation */ 01803 case rad2: 01804 if (IsDlgButtonChecked(hDlg, rad1) == BST_CHECKED) { 01805 if(lpdm->u1.s1.dmOrientation != DMORIENT_PORTRAIT) { 01806 lpdm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; 01807 SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, 01808 (LPARAM)PrintStructures->hPortraitIcon); 01809 SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01810 (LPARAM)PrintStructures->hPortraitIcon); 01811 } 01812 } else { 01813 if(lpdm->u1.s1.dmOrientation != DMORIENT_LANDSCAPE) { 01814 lpdm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; 01815 SendDlgItemMessageW(hDlg, stc10, STM_SETIMAGE, IMAGE_ICON, 01816 (LPARAM)PrintStructures->hLandscapeIcon); 01817 SendDlgItemMessageW(hDlg, ico1, STM_SETIMAGE, IMAGE_ICON, 01818 (LPARAM)PrintStructures->hLandscapeIcon); 01819 } 01820 } 01821 break; 01822 } 01823 } 01824 return FALSE; 01825 } 01826 01827 /*********************************************************************** 01828 * PrintDlgProcA [internal] 01829 */ 01830 static INT_PTR CALLBACK PrintDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, 01831 LPARAM lParam) 01832 { 01833 PRINT_PTRA* PrintStructures; 01834 INT_PTR res = FALSE; 01835 01836 if (uMsg!=WM_INITDIALOG) { 01837 PrintStructures = GetPropW(hDlg, printdlg_prop); 01838 if (!PrintStructures) 01839 return FALSE; 01840 } else { 01841 PrintStructures = (PRINT_PTRA*) lParam; 01842 SetPropW(hDlg, printdlg_prop, PrintStructures); 01843 if(!check_printer_setup(hDlg)) 01844 { 01845 EndDialog(hDlg,FALSE); 01846 return FALSE; 01847 } 01848 res = PRINTDLG_WMInitDialog(hDlg, PrintStructures); 01849 01850 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) 01851 res = PrintStructures->lpPrintDlg->lpfnPrintHook( 01852 hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg 01853 ); 01854 return res; 01855 } 01856 01857 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { 01858 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, 01859 lParam); 01860 if(res) return res; 01861 } 01862 01863 switch (uMsg) { 01864 case WM_COMMAND: 01865 return PRINTDLG_WMCommandA(hDlg, wParam, PrintStructures); 01866 01867 case WM_DESTROY: 01868 DestroyIcon(PrintStructures->hCollateIcon); 01869 DestroyIcon(PrintStructures->hNoCollateIcon); 01870 DestroyIcon(PrintStructures->hPortraitIcon); 01871 DestroyIcon(PrintStructures->hLandscapeIcon); 01872 if(PrintStructures->hwndUpDown) 01873 DestroyWindow(PrintStructures->hwndUpDown); 01874 return FALSE; 01875 } 01876 return res; 01877 } 01878 01879 static INT_PTR CALLBACK PrintDlgProcW(HWND hDlg, UINT uMsg, WPARAM wParam, 01880 LPARAM lParam) 01881 { 01882 PRINT_PTRW* PrintStructures; 01883 INT_PTR res = FALSE; 01884 01885 if (uMsg!=WM_INITDIALOG) { 01886 PrintStructures = GetPropW(hDlg, printdlg_prop); 01887 if (!PrintStructures) 01888 return FALSE; 01889 } else { 01890 PrintStructures = (PRINT_PTRW*) lParam; 01891 SetPropW(hDlg, printdlg_prop, PrintStructures); 01892 if(!check_printer_setup(hDlg)) 01893 { 01894 EndDialog(hDlg,FALSE); 01895 return FALSE; 01896 } 01897 res = PRINTDLG_WMInitDialogW(hDlg, PrintStructures); 01898 01899 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) 01900 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg, uMsg, wParam, (LPARAM)PrintStructures->lpPrintDlg); 01901 return res; 01902 } 01903 01904 if(PrintStructures->lpPrintDlg->Flags & PD_ENABLEPRINTHOOK) { 01905 res = PrintStructures->lpPrintDlg->lpfnPrintHook(hDlg,uMsg,wParam, lParam); 01906 if(res) return res; 01907 } 01908 01909 switch (uMsg) { 01910 case WM_COMMAND: 01911 return PRINTDLG_WMCommandW(hDlg, wParam, PrintStructures); 01912 01913 case WM_DESTROY: 01914 DestroyIcon(PrintStructures->hCollateIcon); 01915 DestroyIcon(PrintStructures->hNoCollateIcon); 01916 DestroyIcon(PrintStructures->hPortraitIcon); 01917 DestroyIcon(PrintStructures->hLandscapeIcon); 01918 if(PrintStructures->hwndUpDown) 01919 DestroyWindow(PrintStructures->hwndUpDown); 01920 return FALSE; 01921 } 01922 return res; 01923 } 01924 01925 /************************************************************ 01926 * 01927 * PRINTDLG_GetDlgTemplate 01928 * 01929 */ 01930 static HGLOBAL PRINTDLG_GetDlgTemplateA(const PRINTDLGA *lppd) 01931 { 01932 HRSRC hResInfo; 01933 HGLOBAL hDlgTmpl; 01934 01935 if (lppd->Flags & PD_PRINTSETUP) { 01936 if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { 01937 hDlgTmpl = lppd->hSetupTemplate; 01938 } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { 01939 hResInfo = FindResourceA(lppd->hInstance, 01940 lppd->lpSetupTemplateName, (LPSTR)RT_DIALOG); 01941 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); 01942 } else { 01943 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32_SETUP", 01944 (LPSTR)RT_DIALOG); 01945 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); 01946 } 01947 } else { 01948 if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { 01949 hDlgTmpl = lppd->hPrintTemplate; 01950 } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { 01951 hResInfo = FindResourceA(lppd->hInstance, 01952 lppd->lpPrintTemplateName, 01953 (LPSTR)RT_DIALOG); 01954 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); 01955 } else { 01956 hResInfo = FindResourceA(COMDLG32_hInstance, "PRINT32", 01957 (LPSTR)RT_DIALOG); 01958 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); 01959 } 01960 } 01961 return hDlgTmpl; 01962 } 01963 01964 static HGLOBAL PRINTDLG_GetDlgTemplateW(const PRINTDLGW *lppd) 01965 { 01966 HRSRC hResInfo; 01967 HGLOBAL hDlgTmpl; 01968 static const WCHAR xpsetup[] = { 'P','R','I','N','T','3','2','_','S','E','T','U','P',0}; 01969 static const WCHAR xprint[] = { 'P','R','I','N','T','3','2',0}; 01970 01971 if (lppd->Flags & PD_PRINTSETUP) { 01972 if(lppd->Flags & PD_ENABLESETUPTEMPLATEHANDLE) { 01973 hDlgTmpl = lppd->hSetupTemplate; 01974 } else if(lppd->Flags & PD_ENABLESETUPTEMPLATE) { 01975 hResInfo = FindResourceW(lppd->hInstance, 01976 lppd->lpSetupTemplateName, (LPWSTR)RT_DIALOG); 01977 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); 01978 } else { 01979 hResInfo = FindResourceW(COMDLG32_hInstance, xpsetup, (LPWSTR)RT_DIALOG); 01980 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); 01981 } 01982 } else { 01983 if(lppd->Flags & PD_ENABLEPRINTTEMPLATEHANDLE) { 01984 hDlgTmpl = lppd->hPrintTemplate; 01985 } else if(lppd->Flags & PD_ENABLEPRINTTEMPLATE) { 01986 hResInfo = FindResourceW(lppd->hInstance, 01987 lppd->lpPrintTemplateName, 01988 (LPWSTR)RT_DIALOG); 01989 hDlgTmpl = LoadResource(lppd->hInstance, hResInfo); 01990 } else { 01991 hResInfo = FindResourceW(COMDLG32_hInstance, xprint, (LPWSTR)RT_DIALOG); 01992 hDlgTmpl = LoadResource(COMDLG32_hInstance, hResInfo); 01993 } 01994 } 01995 return hDlgTmpl; 01996 } 01997 01998 /*********************************************************************** 01999 * 02000 * PRINTDLG_CreateDC 02001 * 02002 */ 02003 static BOOL PRINTDLG_CreateDCA(LPPRINTDLGA lppd) 02004 { 02005 DEVNAMES *pdn = GlobalLock(lppd->hDevNames); 02006 DEVMODEA *pdm = GlobalLock(lppd->hDevMode); 02007 02008 if(lppd->Flags & PD_RETURNDC) { 02009 lppd->hDC = CreateDCA((char*)pdn + pdn->wDriverOffset, 02010 (char*)pdn + pdn->wDeviceOffset, 02011 (char*)pdn + pdn->wOutputOffset, 02012 pdm ); 02013 } else if(lppd->Flags & PD_RETURNIC) { 02014 lppd->hDC = CreateICA((char*)pdn + pdn->wDriverOffset, 02015 (char*)pdn + pdn->wDeviceOffset, 02016 (char*)pdn + pdn->wOutputOffset, 02017 pdm ); 02018 } 02019 GlobalUnlock(lppd->hDevNames); 02020 GlobalUnlock(lppd->hDevMode); 02021 return lppd->hDC ? TRUE : FALSE; 02022 } 02023 02024 static BOOL PRINTDLG_CreateDCW(LPPRINTDLGW lppd) 02025 { 02026 DEVNAMES *pdn = GlobalLock(lppd->hDevNames); 02027 DEVMODEW *pdm = GlobalLock(lppd->hDevMode); 02028 02029 if(lppd->Flags & PD_RETURNDC) { 02030 lppd->hDC = CreateDCW((WCHAR*)pdn + pdn->wDriverOffset, 02031 (WCHAR*)pdn + pdn->wDeviceOffset, 02032 (WCHAR*)pdn + pdn->wOutputOffset, 02033 pdm ); 02034 } else if(lppd->Flags & PD_RETURNIC) { 02035 lppd->hDC = CreateICW((WCHAR*)pdn + pdn->wDriverOffset, 02036 (WCHAR*)pdn + pdn->wDeviceOffset, 02037 (WCHAR*)pdn + pdn->wOutputOffset, 02038 pdm ); 02039 } 02040 GlobalUnlock(lppd->hDevNames); 02041 GlobalUnlock(lppd->hDevMode); 02042 return lppd->hDC ? TRUE : FALSE; 02043 } 02044 02045 /*********************************************************************** 02046 * PrintDlgA (COMDLG32.@) 02047 * 02048 * Displays the PRINT dialog box, which enables the user to specify 02049 * specific properties of the print job. 02050 * 02051 * PARAMS 02052 * lppd [IO] ptr to PRINTDLG32 struct 02053 * 02054 * RETURNS 02055 * nonzero if the user pressed the OK button 02056 * zero if the user cancelled the window or an error occurred 02057 * 02058 * BUGS 02059 * PrintDlg: 02060 * * The Collate Icons do not display, even though they are in the code. 02061 * * The Properties Button(s) should call DocumentPropertiesA(). 02062 */ 02063 02064 BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd) 02065 { 02066 BOOL bRet = FALSE; 02067 LPVOID ptr; 02068 HINSTANCE hInst; 02069 02070 if (!lppd) 02071 { 02072 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); 02073 return FALSE; 02074 } 02075 02076 if(TRACE_ON(commdlg)) { 02077 char flagstr[1000] = ""; 02078 const struct pd_flags *pflag = pd_flags; 02079 for( ; pflag->name; pflag++) { 02080 if(lppd->Flags & pflag->flag) 02081 strcat(flagstr, pflag->name); 02082 } 02083 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" 02084 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" 02085 "flags %08x (%s)\n", 02086 lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, 02087 lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, 02088 lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); 02089 } 02090 02091 if(lppd->lStructSize != sizeof(PRINTDLGA)) { 02092 WARN("structure size failure !!!\n"); 02093 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); 02094 return FALSE; 02095 } 02096 02097 if(lppd->Flags & PD_RETURNDEFAULT) { 02098 PRINTER_INFO_2A *pbuf; 02099 DRIVER_INFO_3A *dbuf; 02100 HANDLE hprn; 02101 DWORD needed; 02102 02103 if(lppd->hDevMode || lppd->hDevNames) { 02104 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); 02105 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 02106 return FALSE; 02107 } 02108 if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { 02109 WARN("Can't find default printer\n"); 02110 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 02111 return FALSE; 02112 } 02113 02114 GetPrinterA(hprn, 2, NULL, 0, &needed); 02115 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 02116 GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); 02117 02118 GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); 02119 dbuf = HeapAlloc(GetProcessHeap(),0,needed); 02120 if (!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { 02121 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n", 02122 GetLastError(),pbuf->pPrinterName); 02123 HeapFree(GetProcessHeap(), 0, dbuf); 02124 HeapFree(GetProcessHeap(), 0, pbuf); 02125 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 02126 return FALSE; 02127 } 02128 ClosePrinter(hprn); 02129 02130 PRINTDLG_CreateDevNames(&(lppd->hDevNames), 02131 dbuf->pDriverPath, 02132 pbuf->pPrinterName, 02133 pbuf->pPortName); 02134 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + 02135 pbuf->pDevMode->dmDriverExtra); 02136 ptr = GlobalLock(lppd->hDevMode); 02137 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + 02138 pbuf->pDevMode->dmDriverExtra); 02139 GlobalUnlock(lppd->hDevMode); 02140 HeapFree(GetProcessHeap(), 0, pbuf); 02141 HeapFree(GetProcessHeap(), 0, dbuf); 02142 bRet = TRUE; 02143 } else { 02144 HGLOBAL hDlgTmpl; 02145 PRINT_PTRA *PrintStructures; 02146 02147 /* load Dialog resources, 02148 * depending on Flags indicates Print32 or Print32_setup dialog 02149 */ 02150 hDlgTmpl = PRINTDLG_GetDlgTemplateA(lppd); 02151 if (!hDlgTmpl) { 02152 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 02153 return FALSE; 02154 } 02155 ptr = LockResource( hDlgTmpl ); 02156 if (!ptr) { 02157 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 02158 return FALSE; 02159 } 02160 02161 PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 02162 sizeof(PRINT_PTRA)); 02163 PrintStructures->lpPrintDlg = lppd; 02164 02165 /* and create & process the dialog . 02166 * -1 is failure, 0 is broken hwnd, everything else is ok. 02167 */ 02168 hInst = COMDLG32_hInstance; 02169 if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance; 02170 bRet = (0<DialogBoxIndirectParamA(hInst, ptr, lppd->hwndOwner, 02171 PrintDlgProcA, 02172 (LPARAM)PrintStructures)); 02173 02174 if(bRet) { 02175 DEVMODEA *lpdm = PrintStructures->lpDevMode, *lpdmReturn; 02176 PRINTER_INFO_2A *pi = PrintStructures->lpPrinterInfo; 02177 DRIVER_INFO_3A *di = PrintStructures->lpDriverInfo; 02178 02179 if (lppd->hDevMode == 0) { 02180 TRACE(" No hDevMode yet... Need to create my own\n"); 02181 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, 02182 lpdm->dmSize + lpdm->dmDriverExtra); 02183 } else { 02184 lppd->hDevMode = GlobalReAlloc(lppd->hDevMode, 02185 lpdm->dmSize + lpdm->dmDriverExtra, 02186 GMEM_MOVEABLE); 02187 } 02188 lpdmReturn = GlobalLock(lppd->hDevMode); 02189 memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); 02190 02191 PRINTDLG_CreateDevNames(&(lppd->hDevNames), 02192 di->pDriverPath, 02193 pi->pPrinterName, 02194 pi->pPortName 02195 ); 02196 GlobalUnlock(lppd->hDevMode); 02197 } 02198 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); 02199 HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo); 02200 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo); 02201 HeapFree(GetProcessHeap(), 0, PrintStructures); 02202 } 02203 if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) 02204 bRet = PRINTDLG_CreateDCA(lppd); 02205 02206 TRACE("exit! (%d)\n", bRet); 02207 return bRet; 02208 } 02209 02210 /*********************************************************************** 02211 * PrintDlgW (COMDLG32.@) 02212 * 02213 * See PrintDlgA. 02214 */ 02215 BOOL WINAPI PrintDlgW(LPPRINTDLGW lppd) 02216 { 02217 BOOL bRet = FALSE; 02218 LPVOID ptr; 02219 HINSTANCE hInst; 02220 02221 if (!lppd) 02222 { 02223 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); 02224 return FALSE; 02225 } 02226 02227 if(TRACE_ON(commdlg)) { 02228 char flagstr[1000] = ""; 02229 const struct pd_flags *pflag = pd_flags; 02230 for( ; pflag->name; pflag++) { 02231 if(lppd->Flags & pflag->flag) 02232 strcat(flagstr, pflag->name); 02233 } 02234 TRACE("(%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" 02235 "pp. %d-%d, min p %d, max p %d, copies %d, hinst %p\n" 02236 "flags %08x (%s)\n", 02237 lppd, lppd->hwndOwner, lppd->hDevMode, lppd->hDevNames, 02238 lppd->nFromPage, lppd->nToPage, lppd->nMinPage, lppd->nMaxPage, 02239 lppd->nCopies, lppd->hInstance, lppd->Flags, flagstr); 02240 } 02241 02242 if(lppd->lStructSize != sizeof(PRINTDLGW)) { 02243 WARN("structure size failure !!!\n"); 02244 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); 02245 return FALSE; 02246 } 02247 02248 if(lppd->Flags & PD_RETURNDEFAULT) { 02249 PRINTER_INFO_2W *pbuf; 02250 DRIVER_INFO_3W *dbuf; 02251 HANDLE hprn; 02252 DWORD needed; 02253 02254 if(lppd->hDevMode || lppd->hDevNames) { 02255 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); 02256 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 02257 return FALSE; 02258 } 02259 if(!PRINTDLG_OpenDefaultPrinter(&hprn)) { 02260 WARN("Can't find default printer\n"); 02261 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 02262 return FALSE; 02263 } 02264 02265 GetPrinterW(hprn, 2, NULL, 0, &needed); 02266 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 02267 GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed); 02268 02269 GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); 02270 dbuf = HeapAlloc(GetProcessHeap(),0,needed); 02271 if (!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed)) { 02272 ERR("GetPrinterDriverA failed, le %d, fix your config for printer %s!\n", 02273 GetLastError(),debugstr_w(pbuf->pPrinterName)); 02274 HeapFree(GetProcessHeap(), 0, dbuf); 02275 HeapFree(GetProcessHeap(), 0, pbuf); 02276 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 02277 return FALSE; 02278 } 02279 ClosePrinter(hprn); 02280 02281 PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), 02282 dbuf->pDriverPath, 02283 pbuf->pPrinterName, 02284 pbuf->pPortName); 02285 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + 02286 pbuf->pDevMode->dmDriverExtra); 02287 ptr = GlobalLock(lppd->hDevMode); 02288 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + 02289 pbuf->pDevMode->dmDriverExtra); 02290 GlobalUnlock(lppd->hDevMode); 02291 HeapFree(GetProcessHeap(), 0, pbuf); 02292 HeapFree(GetProcessHeap(), 0, dbuf); 02293 bRet = TRUE; 02294 } else { 02295 HGLOBAL hDlgTmpl; 02296 PRINT_PTRW *PrintStructures; 02297 02298 /* load Dialog resources, 02299 * depending on Flags indicates Print32 or Print32_setup dialog 02300 */ 02301 hDlgTmpl = PRINTDLG_GetDlgTemplateW(lppd); 02302 if (!hDlgTmpl) { 02303 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 02304 return FALSE; 02305 } 02306 ptr = LockResource( hDlgTmpl ); 02307 if (!ptr) { 02308 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); 02309 return FALSE; 02310 } 02311 02312 PrintStructures = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 02313 sizeof(PRINT_PTRW)); 02314 PrintStructures->lpPrintDlg = lppd; 02315 02316 /* and create & process the dialog . 02317 * -1 is failure, 0 is broken hwnd, everything else is ok. 02318 */ 02319 hInst = COMDLG32_hInstance; 02320 if (lppd->Flags & (PD_ENABLESETUPTEMPLATE | PD_ENABLEPRINTTEMPLATE)) hInst = lppd->hInstance; 02321 bRet = (0<DialogBoxIndirectParamW(hInst, ptr, lppd->hwndOwner, 02322 PrintDlgProcW, 02323 (LPARAM)PrintStructures)); 02324 02325 if(bRet) { 02326 DEVMODEW *lpdm = PrintStructures->lpDevMode, *lpdmReturn; 02327 PRINTER_INFO_2W *pi = PrintStructures->lpPrinterInfo; 02328 DRIVER_INFO_3W *di = PrintStructures->lpDriverInfo; 02329 02330 if (lppd->hDevMode == 0) { 02331 TRACE(" No hDevMode yet... Need to create my own\n"); 02332 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, 02333 lpdm->dmSize + lpdm->dmDriverExtra); 02334 } else { 02335 WORD locks; 02336 if((locks = (GlobalFlags(lppd->hDevMode) & GMEM_LOCKCOUNT))) { 02337 WARN("hDevMode has %d locks on it. Unlocking it now\n", locks); 02338 while(locks--) { 02339 GlobalUnlock(lppd->hDevMode); 02340 TRACE("Now got %d locks\n", locks); 02341 } 02342 } 02343 lppd->hDevMode = GlobalReAlloc(lppd->hDevMode, 02344 lpdm->dmSize + lpdm->dmDriverExtra, 02345 GMEM_MOVEABLE); 02346 } 02347 lpdmReturn = GlobalLock(lppd->hDevMode); 02348 memcpy(lpdmReturn, lpdm, lpdm->dmSize + lpdm->dmDriverExtra); 02349 02350 if (lppd->hDevNames != 0) { 02351 WORD locks; 02352 if((locks = (GlobalFlags(lppd->hDevNames) & GMEM_LOCKCOUNT))) { 02353 WARN("hDevNames has %d locks on it. Unlocking it now\n", locks); 02354 while(locks--) 02355 GlobalUnlock(lppd->hDevNames); 02356 } 02357 } 02358 PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), 02359 di->pDriverPath, 02360 pi->pPrinterName, 02361 pi->pPortName 02362 ); 02363 GlobalUnlock(lppd->hDevMode); 02364 } 02365 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDevMode); 02366 HeapFree(GetProcessHeap(), 0, PrintStructures->lpPrinterInfo); 02367 HeapFree(GetProcessHeap(), 0, PrintStructures->lpDriverInfo); 02368 HeapFree(GetProcessHeap(), 0, PrintStructures); 02369 } 02370 if(bRet && (lppd->Flags & PD_RETURNDC || lppd->Flags & PD_RETURNIC)) 02371 bRet = PRINTDLG_CreateDCW(lppd); 02372 02373 TRACE("exit! (%d)\n", bRet); 02374 return bRet; 02375 } 02376 02377 /*********************************************************************** 02378 * 02379 * PageSetupDlg 02380 * rad1 - portrait 02381 * rad2 - landscape 02382 * cmb1 - printer select (not in standard dialog template) 02383 * cmb2 - paper size 02384 * cmb3 - source (tray?) 02385 * edt4 - border left 02386 * edt5 - border top 02387 * edt6 - border right 02388 * edt7 - border bottom 02389 * psh3 - "Printer..." 02390 */ 02391 02392 typedef struct 02393 { 02394 BOOL unicode; 02395 union 02396 { 02397 LPPAGESETUPDLGA dlga; 02398 LPPAGESETUPDLGW dlgw; 02399 } u; 02400 HWND hDlg; /* Page Setup dialog handle */ 02401 RECT rtDrawRect; /* Drawing rect for page */ 02402 } pagesetup_data; 02403 02404 static inline DWORD pagesetup_get_flags(const pagesetup_data *data) 02405 { 02406 return data->u.dlgw->Flags; 02407 } 02408 02409 static inline BOOL is_metric(const pagesetup_data *data) 02410 { 02411 return pagesetup_get_flags(data) & PSD_INHUNDREDTHSOFMILLIMETERS; 02412 } 02413 02414 static inline LONG tenths_mm_to_size(const pagesetup_data *data, LONG size) 02415 { 02416 if (is_metric(data)) 02417 return 10 * size; 02418 else 02419 return 10 * size * 100 / 254; 02420 } 02421 02422 static inline LONG thousandths_inch_to_size(const pagesetup_data *data, LONG size) 02423 { 02424 if (is_metric(data)) 02425 return size * 254 / 100; 02426 else 02427 return size; 02428 } 02429 02430 static WCHAR get_decimal_sep(void) 02431 { 02432 static WCHAR sep; 02433 02434 if(!sep) 02435 { 02436 WCHAR buf[] = {'.', 0}; 02437 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_SDECIMAL, buf, sizeof(buf) / sizeof(buf[0])); 02438 sep = buf[0]; 02439 } 02440 return sep; 02441 } 02442 02443 static void size2str(const pagesetup_data *data, DWORD size, LPWSTR strout) 02444 { 02445 WCHAR integer_fmt[] = {'%','d',0}; 02446 WCHAR hundredths_fmt[] = {'%','d','%','c','%','0','2','d',0}; 02447 WCHAR thousandths_fmt[] = {'%','d','%','c','%','0','3','d',0}; 02448 02449 /* FIXME use LOCALE_SDECIMAL when the edit parsing code can cope */ 02450 02451 if (is_metric(data)) 02452 { 02453 if(size % 100) 02454 wsprintfW(strout, hundredths_fmt, size / 100, get_decimal_sep(), size % 100); 02455 else 02456 wsprintfW(strout, integer_fmt, size / 100); 02457 } 02458 else 02459 { 02460 if(size % 1000) 02461 wsprintfW(strout, thousandths_fmt, size / 1000, get_decimal_sep(), size % 1000); 02462 else 02463 wsprintfW(strout, integer_fmt, size / 1000); 02464 02465 } 02466 } 02467 02468 static inline BOOL is_default_metric(void) 02469 { 02470 DWORD system; 02471 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE | LOCALE_RETURN_NUMBER, 02472 (LPWSTR)&system, sizeof(system)); 02473 return system == 0; 02474 } 02475 02476 /********************************************** 02477 * rotate_rect 02478 * Cyclically permute the four members of rc 02479 * If sense is TRUE l -> t -> r -> b 02480 * otherwise l <- t <- r <- b 02481 */ 02482 static inline void rotate_rect(RECT *rc, BOOL sense) 02483 { 02484 INT tmp; 02485 if(sense) 02486 { 02487 tmp = rc->bottom; 02488 rc->bottom = rc->right; 02489 rc->right = rc->top; 02490 rc->top = rc->left; 02491 rc->left = tmp; 02492 } 02493 else 02494 { 02495 tmp = rc->left; 02496 rc->left = rc->top; 02497 rc->top = rc->right; 02498 rc->right = rc->bottom; 02499 rc->bottom = tmp; 02500 } 02501 } 02502 02503 static void pagesetup_set_orientation(pagesetup_data *data, WORD orient) 02504 { 02505 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02506 02507 assert(orient == DMORIENT_PORTRAIT || orient == DMORIENT_LANDSCAPE); 02508 02509 if(data->unicode) 02510 dm->u1.s1.dmOrientation = orient; 02511 else 02512 { 02513 DEVMODEA *dmA = (DEVMODEA *)dm; 02514 dmA->u1.s1.dmOrientation = orient; 02515 } 02516 GlobalUnlock(data->u.dlgw->hDevMode); 02517 } 02518 02519 static WORD pagesetup_get_orientation(const pagesetup_data *data) 02520 { 02521 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02522 WORD orient; 02523 02524 if(data->unicode) 02525 orient = dm->u1.s1.dmOrientation; 02526 else 02527 { 02528 DEVMODEA *dmA = (DEVMODEA *)dm; 02529 orient = dmA->u1.s1.dmOrientation; 02530 } 02531 GlobalUnlock(data->u.dlgw->hDevMode); 02532 return orient; 02533 } 02534 02535 static void pagesetup_set_papersize(pagesetup_data *data, WORD paper) 02536 { 02537 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02538 02539 if(data->unicode) 02540 dm->u1.s1.dmPaperSize = paper; 02541 else 02542 { 02543 DEVMODEA *dmA = (DEVMODEA *)dm; 02544 dmA->u1.s1.dmPaperSize = paper; 02545 } 02546 GlobalUnlock(data->u.dlgw->hDevMode); 02547 } 02548 02549 static WORD pagesetup_get_papersize(const pagesetup_data *data) 02550 { 02551 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02552 WORD paper; 02553 02554 if(data->unicode) 02555 paper = dm->u1.s1.dmPaperSize; 02556 else 02557 { 02558 DEVMODEA *dmA = (DEVMODEA *)dm; 02559 paper = dmA->u1.s1.dmPaperSize; 02560 } 02561 GlobalUnlock(data->u.dlgw->hDevMode); 02562 return paper; 02563 } 02564 02565 static void pagesetup_set_defaultsource(pagesetup_data *data, WORD source) 02566 { 02567 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02568 02569 if(data->unicode) 02570 dm->u1.s1.dmDefaultSource = source; 02571 else 02572 { 02573 DEVMODEA *dmA = (DEVMODEA *)dm; 02574 dmA->u1.s1.dmDefaultSource = source; 02575 } 02576 GlobalUnlock(data->u.dlgw->hDevMode); 02577 } 02578 02579 typedef enum 02580 { 02581 devnames_driver_name, 02582 devnames_device_name, 02583 devnames_output_name 02584 } devnames_name; 02585 02586 02587 static inline WORD get_devname_offset(const DEVNAMES *dn, devnames_name which) 02588 { 02589 switch(which) 02590 { 02591 case devnames_driver_name: return dn->wDriverOffset; 02592 case devnames_device_name: return dn->wDeviceOffset; 02593 case devnames_output_name: return dn->wOutputOffset; 02594 } 02595 ERR("Shouldn't be here\n"); 02596 return 0; 02597 } 02598 02599 static WCHAR *pagesetup_get_a_devname(const pagesetup_data *data, devnames_name which) 02600 { 02601 DEVNAMES *dn; 02602 WCHAR *name; 02603 02604 dn = GlobalLock(data->u.dlgw->hDevNames); 02605 if(data->unicode) 02606 name = strdupW((WCHAR *)dn + get_devname_offset(dn, which)); 02607 else 02608 { 02609 int len = MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, NULL, 0); 02610 name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 02611 MultiByteToWideChar(CP_ACP, 0, (char*)dn + get_devname_offset(dn, which), -1, name, len); 02612 } 02613 GlobalUnlock(data->u.dlgw->hDevNames); 02614 return name; 02615 } 02616 02617 static WCHAR *pagesetup_get_drvname(const pagesetup_data *data) 02618 { 02619 return pagesetup_get_a_devname(data, devnames_driver_name); 02620 } 02621 02622 static WCHAR *pagesetup_get_devname(const pagesetup_data *data) 02623 { 02624 return pagesetup_get_a_devname(data, devnames_device_name); 02625 } 02626 02627 static WCHAR *pagesetup_get_portname(const pagesetup_data *data) 02628 { 02629 return pagesetup_get_a_devname(data, devnames_output_name); 02630 } 02631 02632 static void pagesetup_release_a_devname(const pagesetup_data *data, WCHAR *name) 02633 { 02634 HeapFree(GetProcessHeap(), 0, name); 02635 } 02636 02637 static void pagesetup_set_devnames(pagesetup_data *data, LPCWSTR drv, LPCWSTR devname, LPCWSTR port) 02638 { 02639 DEVNAMES *dn; 02640 WCHAR def[256]; 02641 DWORD len = sizeof(DEVNAMES), drv_len, dev_len, port_len; 02642 02643 if(data->unicode) 02644 { 02645 drv_len = (strlenW(drv) + 1) * sizeof(WCHAR); 02646 dev_len = (strlenW(devname) + 1) * sizeof(WCHAR); 02647 port_len = (strlenW(port) + 1) * sizeof(WCHAR); 02648 } 02649 else 02650 { 02651 drv_len = WideCharToMultiByte(CP_ACP, 0, drv, -1, NULL, 0, NULL, NULL); 02652 dev_len = WideCharToMultiByte(CP_ACP, 0, devname, -1, NULL, 0, NULL, NULL); 02653 port_len = WideCharToMultiByte(CP_ACP, 0, port, -1, NULL, 0, NULL, NULL); 02654 } 02655 len += drv_len + dev_len + port_len; 02656 02657 if(data->u.dlgw->hDevNames) 02658 data->u.dlgw->hDevNames = GlobalReAlloc(data->u.dlgw->hDevNames, len, GMEM_MOVEABLE); 02659 else 02660 data->u.dlgw->hDevNames = GlobalAlloc(GMEM_MOVEABLE, len); 02661 02662 dn = GlobalLock(data->u.dlgw->hDevNames); 02663 02664 if(data->unicode) 02665 { 02666 WCHAR *ptr = (WCHAR *)(dn + 1); 02667 len = sizeof(DEVNAMES) / sizeof(WCHAR); 02668 dn->wDriverOffset = len; 02669 strcpyW(ptr, drv); 02670 ptr += drv_len / sizeof(WCHAR); 02671 len += drv_len / sizeof(WCHAR); 02672 dn->wDeviceOffset = len; 02673 strcpyW(ptr, devname); 02674 ptr += dev_len / sizeof(WCHAR); 02675 len += dev_len / sizeof(WCHAR); 02676 dn->wOutputOffset = len; 02677 strcpyW(ptr, port); 02678 } 02679 else 02680 { 02681 char *ptr = (char *)(dn + 1); 02682 len = sizeof(DEVNAMES); 02683 dn->wDriverOffset = len; 02684 WideCharToMultiByte(CP_ACP, 0, drv, -1, ptr, drv_len, NULL, NULL); 02685 ptr += drv_len; 02686 len += drv_len; 02687 dn->wDeviceOffset = len; 02688 WideCharToMultiByte(CP_ACP, 0, devname, -1, ptr, dev_len, NULL, NULL); 02689 ptr += dev_len; 02690 len += dev_len; 02691 dn->wOutputOffset = len; 02692 WideCharToMultiByte(CP_ACP, 0, port, -1, ptr, port_len, NULL, NULL); 02693 } 02694 02695 dn->wDefault = 0; 02696 len = sizeof(def) / sizeof(def[0]); 02697 GetDefaultPrinterW(def, &len); 02698 if(!lstrcmpW(def, devname)) 02699 dn->wDefault = 1; 02700 02701 GlobalUnlock(data->u.dlgw->hDevNames); 02702 } 02703 02704 static DEVMODEW *pagesetup_get_devmode(const pagesetup_data *data) 02705 { 02706 DEVMODEW *dm = GlobalLock(data->u.dlgw->hDevMode); 02707 DEVMODEW *ret; 02708 02709 if(data->unicode) 02710 { 02711 /* We make a copy even in the unicode case because the ptr 02712 may get passed back to us in pagesetup_set_devmode. */ 02713 ret = HeapAlloc(GetProcessHeap(), 0, dm->dmSize + dm->dmDriverExtra); 02714 memcpy(ret, dm, dm->dmSize + dm->dmDriverExtra); 02715 } 02716 else 02717 ret = GdiConvertToDevmodeW((DEVMODEA *)dm); 02718 02719 GlobalUnlock(data->u.dlgw->hDevMode); 02720 return ret; 02721 } 02722 02723 static void pagesetup_release_devmode(const pagesetup_data *data, DEVMODEW *dm) 02724 { 02725 HeapFree(GetProcessHeap(), 0, dm); 02726 } 02727 02728 static void pagesetup_set_devmode(pagesetup_data *data, DEVMODEW *dm) 02729 { 02730 DEVMODEA *dmA = NULL; 02731 void *src, *dst; 02732 DWORD size; 02733 02734 if(data->unicode) 02735 { 02736 size = dm->dmSize + dm->dmDriverExtra; 02737 src = dm; 02738 } 02739 else 02740 { 02741 dmA = convert_to_devmodeA(dm); 02742 size = dmA->dmSize + dmA->dmDriverExtra; 02743 src = dmA; 02744 } 02745 02746 if(data->u.dlgw->hDevMode) 02747 data->u.dlgw->hDevMode = GlobalReAlloc(data->u.dlgw->hDevMode, size, 02748 GMEM_MOVEABLE); 02749 else 02750 data->u.dlgw->hDevMode = GlobalAlloc(GMEM_MOVEABLE, size); 02751 02752 dst = GlobalLock(data->u.dlgw->hDevMode); 02753 memcpy(dst, src, size); 02754 GlobalUnlock(data->u.dlgw->hDevMode); 02755 HeapFree(GetProcessHeap(), 0, dmA); 02756 } 02757 02758 static inline POINT *pagesetup_get_papersize_pt(const pagesetup_data *data) 02759 { 02760 return &data->u.dlgw->ptPaperSize; 02761 } 02762 02763 static inline RECT *pagesetup_get_margin_rect(const pagesetup_data *data) 02764 { 02765 return &data->u.dlgw->rtMargin; 02766 } 02767 02768 typedef enum 02769 { 02770 page_setup_hook, 02771 page_paint_hook 02772 } hook_type; 02773 02774 static inline LPPAGESETUPHOOK pagesetup_get_hook(const pagesetup_data *data, hook_type which) 02775 { 02776 switch(which) 02777 { 02778 case page_setup_hook: return data->u.dlgw->lpfnPageSetupHook; 02779 case page_paint_hook: return data->u.dlgw->lpfnPagePaintHook; 02780 } 02781 return NULL; 02782 } 02783 02784 /* This should only be used in calls to hook procs so we return the ptr 02785 already cast to LPARAM */ 02786 static inline LPARAM pagesetup_get_dlg_struct(const pagesetup_data *data) 02787 { 02788 return (LPARAM)data->u.dlgw; 02789 } 02790 02791 static inline void swap_point(POINT *pt) 02792 { 02793 LONG tmp = pt->x; 02794 pt->x = pt->y; 02795 pt->y = tmp; 02796 } 02797 02798 static BOOL pagesetup_update_papersize(pagesetup_data *data) 02799 { 02800 DEVMODEW *dm; 02801 LPWSTR devname, portname; 02802 int i, num; 02803 WORD *words = NULL, paperword; 02804 POINT *points = NULL; 02805 BOOL retval = FALSE; 02806 02807 dm = pagesetup_get_devmode(data); 02808 devname = pagesetup_get_devname(data); 02809 portname = pagesetup_get_portname(data); 02810 02811 num = DeviceCapabilitiesW(devname, portname, DC_PAPERS, NULL, dm); 02812 if (num <= 0) 02813 { 02814 FIXME("No papernames found for %s/%s\n", debugstr_w(devname), debugstr_w(portname)); 02815 goto end; 02816 } 02817 02818 words = HeapAlloc(GetProcessHeap(), 0, num * sizeof(WORD)); 02819 points = HeapAlloc(GetProcessHeap(), 0, num * sizeof(POINT)); 02820 02821 if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERS, (LPWSTR)words, dm)) 02822 { 02823 FIXME("Number of returned words is not %d\n", num); 02824 goto end; 02825 } 02826 02827 if (num != DeviceCapabilitiesW(devname, portname, DC_PAPERSIZE, (LPWSTR)points, dm)) 02828 { 02829 FIXME("Number of returned sizes is not %d\n", num); 02830 goto end; 02831 } 02832 02833 paperword = pagesetup_get_papersize(data); 02834 02835 for (i = 0; i < num; i++) 02836 if (words[i] == paperword) 02837 break; 02838 02839 if (i == num) 02840 { 02841 FIXME("Papersize %d not found in list?\n", paperword); 02842 goto end; 02843 } 02844 02845 /* this is _10ths_ of a millimeter */ 02846 pagesetup_get_papersize_pt(data)->x = tenths_mm_to_size(data, points[i].x); 02847 pagesetup_get_papersize_pt(data)->y = tenths_mm_to_size(data, points[i].y); 02848 02849 if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) 02850 swap_point(pagesetup_get_papersize_pt(data)); 02851 02852 retval = TRUE; 02853 02854 end: 02855 HeapFree(GetProcessHeap(), 0, words); 02856 HeapFree(GetProcessHeap(), 0, points); 02857 pagesetup_release_a_devname(data, portname); 02858 pagesetup_release_a_devname(data, devname); 02859 pagesetup_release_devmode(data, dm); 02860 02861 return retval; 02862 } 02863 02864 /********************************************************************************************** 02865 * pagesetup_change_printer 02866 * 02867 * Redefines hDevMode and hDevNames HANDLES and initialises it. 02868 * 02869 */ 02870 static BOOL pagesetup_change_printer(LPWSTR name, pagesetup_data *data) 02871 { 02872 HANDLE hprn; 02873 DWORD needed; 02874 PRINTER_INFO_2W *prn_info = NULL; 02875 DRIVER_INFO_3W *drv_info = NULL; 02876 DEVMODEW *dm = NULL; 02877 BOOL retval = FALSE; 02878 02879 if(!OpenPrinterW(name, &hprn, NULL)) 02880 { 02881 ERR("Can't open printer %s\n", debugstr_w(name)); 02882 goto end; 02883 } 02884 02885 GetPrinterW(hprn, 2, NULL, 0, &needed); 02886 prn_info = HeapAlloc(GetProcessHeap(), 0, needed); 02887 GetPrinterW(hprn, 2, (LPBYTE)prn_info, needed, &needed); 02888 GetPrinterDriverW(hprn, NULL, 3, NULL, 0, &needed); 02889 drv_info = HeapAlloc(GetProcessHeap(), 0, needed); 02890 if(!GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)drv_info, needed, &needed)) 02891 { 02892 ERR("GetPrinterDriverA failed for %s, fix your config!\n", debugstr_w(prn_info->pPrinterName)); 02893 goto end; 02894 } 02895 ClosePrinter(hprn); 02896 02897 needed = DocumentPropertiesW(0, 0, name, NULL, NULL, 0); 02898 if(needed == -1) 02899 { 02900 ERR("DocumentProperties fails on %s\n", debugstr_w(name)); 02901 goto end; 02902 } 02903 02904 dm = HeapAlloc(GetProcessHeap(), 0, needed); 02905 DocumentPropertiesW(0, 0, name, dm, NULL, DM_OUT_BUFFER); 02906 02907 pagesetup_set_devmode(data, dm); 02908 pagesetup_set_devnames(data, drv_info->pDriverPath, prn_info->pPrinterName, 02909 prn_info->pPortName); 02910 02911 retval = TRUE; 02912 end: 02913 HeapFree(GetProcessHeap(), 0, dm); 02914 HeapFree(GetProcessHeap(), 0, prn_info); 02915 HeapFree(GetProcessHeap(), 0, drv_info); 02916 return retval; 02917 } 02918 02919 /**************************************************************************************** 02920 * pagesetup_init_combos 02921 * 02922 * Fills Printers, Paper and Source combos 02923 * 02924 */ 02925 static void pagesetup_init_combos(HWND hDlg, pagesetup_data *data) 02926 { 02927 DEVMODEW *dm; 02928 LPWSTR devname, portname; 02929 02930 dm = pagesetup_get_devmode(data); 02931 devname = pagesetup_get_devname(data); 02932 portname = pagesetup_get_portname(data); 02933 02934 PRINTDLG_SetUpPrinterListComboW(hDlg, cmb1, devname); 02935 PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb2, devname, portname, dm); 02936 PRINTDLG_SetUpPaperComboBoxW(hDlg, cmb3, devname, portname, dm); 02937 02938 pagesetup_release_a_devname(data, portname); 02939 pagesetup_release_a_devname(data, devname); 02940 pagesetup_release_devmode(data, dm); 02941 } 02942 02943 02944 /**************************************************************************************** 02945 * pagesetup_change_printer_dialog 02946 * 02947 * Pops up another dialog that lets the user pick another printer. 02948 * 02949 * For now we display the PrintDlg, this should display a striped down version of it. 02950 */ 02951 static void pagesetup_change_printer_dialog(HWND hDlg, pagesetup_data *data) 02952 { 02953 PRINTDLGW prnt; 02954 LPWSTR drvname, devname, portname; 02955 DEVMODEW *tmp_dm, *dm; 02956 02957 memset(&prnt, 0, sizeof(prnt)); 02958 prnt.lStructSize = sizeof(prnt); 02959 prnt.Flags = 0; 02960 prnt.hwndOwner = hDlg; 02961 02962 drvname = pagesetup_get_drvname(data); 02963 devname = pagesetup_get_devname(data); 02964 portname = pagesetup_get_portname(data); 02965 prnt.hDevNames = 0; 02966 PRINTDLG_CreateDevNamesW(&prnt.hDevNames, drvname, devname, portname); 02967 pagesetup_release_a_devname(data, portname); 02968 pagesetup_release_a_devname(data, devname); 02969 pagesetup_release_a_devname(data, drvname); 02970 02971 tmp_dm = pagesetup_get_devmode(data); 02972 prnt.hDevMode = GlobalAlloc(GMEM_MOVEABLE, tmp_dm->dmSize + tmp_dm->dmDriverExtra); 02973 dm = GlobalLock(prnt.hDevMode); 02974 memcpy(dm, tmp_dm, tmp_dm->dmSize + tmp_dm->dmDriverExtra); 02975 GlobalUnlock(prnt.hDevMode); 02976 pagesetup_release_devmode(data, tmp_dm); 02977 02978 if (PrintDlgW(&prnt)) 02979 { 02980 DEVMODEW *dm = GlobalLock(prnt.hDevMode); 02981 DEVNAMES *dn = GlobalLock(prnt.hDevNames); 02982 02983 pagesetup_set_devnames(data, (WCHAR*)dn + dn->wDriverOffset, 02984 (WCHAR*)dn + dn->wDeviceOffset, (WCHAR *)dn + dn->wOutputOffset); 02985 pagesetup_set_devmode(data, dm); 02986 GlobalUnlock(prnt.hDevNames); 02987 GlobalUnlock(prnt.hDevMode); 02988 pagesetup_init_combos(hDlg, data); 02989 } 02990 02991 GlobalFree(prnt.hDevMode); 02992 GlobalFree(prnt.hDevNames); 02993 02994 } 02995 02996 /****************************************************************************************** 02997 * pagesetup_change_preview 02998 * 02999 * Changes paper preview size / position 03000 * 03001 */ 03002 static void pagesetup_change_preview(const pagesetup_data *data) 03003 { 03004 LONG width, height, x, y; 03005 RECT tmp; 03006 const int shadow = 4; 03007 03008 if(pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) 03009 { 03010 width = data->rtDrawRect.right - data->rtDrawRect.left; 03011 height = pagesetup_get_papersize_pt(data)->y * width / pagesetup_get_papersize_pt(data)->x; 03012 } 03013 else 03014 { 03015 height = data->rtDrawRect.bottom - data->rtDrawRect.top; 03016 width = pagesetup_get_papersize_pt(data)->x * height / pagesetup_get_papersize_pt(data)->y; 03017 } 03018 x = (data->rtDrawRect.right + data->rtDrawRect.left - width) / 2; 03019 y = (data->rtDrawRect.bottom + data->rtDrawRect.top - height) / 2; 03020 TRACE("draw rect %s x=%d, y=%d, w=%d, h=%d\n", 03021 wine_dbgstr_rect(&data->rtDrawRect), x, y, width, height); 03022 03023 MoveWindow(GetDlgItem(data->hDlg, rct2), x + width, y + shadow, shadow, height, FALSE); 03024 MoveWindow(GetDlgItem(data->hDlg, rct3), x + shadow, y + height, width, shadow, FALSE); 03025 MoveWindow(GetDlgItem(data->hDlg, rct1), x, y, width, height, FALSE); 03026 03027 tmp = data->rtDrawRect; 03028 tmp.right += shadow; 03029 tmp.bottom += shadow; 03030 InvalidateRect(data->hDlg, &tmp, TRUE); 03031 } 03032 03033 static inline LONG *element_from_margin_id(RECT *rc, WORD id) 03034 { 03035 switch(id) 03036 { 03037 case edt4: return &rc->left; 03038 case edt5: return &rc->top; 03039 case edt6: return &rc->right; 03040 case edt7: return &rc->bottom; 03041 } 03042 return NULL; 03043 } 03044 03045 static void update_margin_edits(HWND hDlg, const pagesetup_data *data, WORD id) 03046 { 03047 WCHAR str[100]; 03048 WORD idx; 03049 03050 for(idx = edt4; idx <= edt7; idx++) 03051 { 03052 if(id == 0 || id == idx) 03053 { 03054 size2str(data, *element_from_margin_id(pagesetup_get_margin_rect(data), idx), str); 03055 SetDlgItemTextW(hDlg, idx, str); 03056 } 03057 } 03058 } 03059 03060 static void margin_edit_notification(HWND hDlg, const pagesetup_data *data, WORD msg, WORD id) 03061 { 03062 switch (msg) 03063 { 03064 case EN_CHANGE: 03065 { 03066 WCHAR buf[10]; 03067 LONG val = 0; 03068 LONG *value = element_from_margin_id(pagesetup_get_margin_rect(data), id); 03069 03070 if (GetDlgItemTextW(hDlg, id, buf, sizeof(buf) / sizeof(buf[0])) != 0) 03071 { 03072 WCHAR *end; 03073 WCHAR decimal = get_decimal_sep(); 03074 03075 val = strtolW(buf, &end, 10); 03076 if(end != buf || *end == decimal) 03077 { 03078 int mult = is_metric(data) ? 100 : 1000; 03079 val *= mult; 03080 if(*end == decimal) 03081 { 03082 while(mult > 1) 03083 { 03084 end++; 03085 mult /= 10; 03086 if(isdigitW(*end)) 03087 val += (*end - '0') * mult; 03088 else 03089 break; 03090 } 03091 } 03092 } 03093 } 03094 *value = val; 03095 return; 03096 } 03097 03098 case EN_KILLFOCUS: 03099 update_margin_edits(hDlg, data, id); 03100 return; 03101 } 03102 } 03103 03104 static void set_margin_groupbox_title(HWND hDlg, const pagesetup_data *data) 03105 { 03106 WCHAR title[256]; 03107 03108 if(LoadStringW(COMDLG32_hInstance, is_metric(data) ? PD32_MARGINS_IN_MILLIMETERS : PD32_MARGINS_IN_INCHES, 03109 title, sizeof(title)/sizeof(title[0]))) 03110 SetDlgItemTextW(hDlg, grp4, title); 03111 } 03112 03113 static void pagesetup_update_orientation_buttons(HWND hDlg, const pagesetup_data *data) 03114 { 03115 if (pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) 03116 CheckRadioButton(hDlg, rad1, rad2, rad2); 03117 else 03118 CheckRadioButton(hDlg, rad1, rad2, rad1); 03119 } 03120 03121 /**************************************************************************************** 03122 * pagesetup_printer_properties 03123 * 03124 * Handle invocation of the 'Properties' button (not present in the default template). 03125 */ 03126 static void pagesetup_printer_properties(HWND hDlg, pagesetup_data *data) 03127 { 03128 HANDLE hprn; 03129 LPWSTR devname; 03130 DEVMODEW *dm; 03131 LRESULT count; 03132 int i; 03133 03134 devname = pagesetup_get_devname(data); 03135 03136 if (!OpenPrinterW(devname, &hprn, NULL)) 03137 { 03138 FIXME("Call to OpenPrinter did not succeed!\n"); 03139 pagesetup_release_a_devname(data, devname); 03140 return; 03141 } 03142 03143 dm = pagesetup_get_devmode(data); 03144 DocumentPropertiesW(hDlg, hprn, devname, dm, dm, DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); 03145 pagesetup_set_devmode(data, dm); 03146 pagesetup_release_devmode(data, dm); 03147 pagesetup_release_a_devname(data, devname); 03148 ClosePrinter(hprn); 03149 03150 /* Changing paper */ 03151 pagesetup_update_papersize(data); 03152 pagesetup_update_orientation_buttons(hDlg, data); 03153 03154 /* Changing paper preview */ 03155 pagesetup_change_preview(data); 03156 03157 /* Selecting paper in combo */ 03158 count = SendDlgItemMessageW(hDlg, cmb2, CB_GETCOUNT, 0, 0); 03159 if(count != CB_ERR) 03160 { 03161 WORD paperword = pagesetup_get_papersize(data); 03162 for(i = 0; i < count; i++) 03163 { 03164 if(SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, i, 0) == paperword) { 03165 SendDlgItemMessageW(hDlg, cmb2, CB_SETCURSEL, i, 0); 03166 break; 03167 } 03168 } 03169 } 03170 } 03171 03172 /******************************************************************************** 03173 * pagesetup_wm_command 03174 * process WM_COMMAND message for PageSetupDlg 03175 * 03176 * PARAMS 03177 * hDlg [in] Main dialog HANDLE 03178 * wParam [in] WM_COMMAND wParam 03179 * lParam [in] WM_COMMAND lParam 03180 * pda [in/out] ptr to PageSetupDataA 03181 */ 03182 03183 static BOOL pagesetup_wm_command(HWND hDlg, WPARAM wParam, LPARAM lParam, pagesetup_data *data) 03184 { 03185 WORD msg = HIWORD(wParam); 03186 WORD id = LOWORD(wParam); 03187 03188 TRACE("loword (lparam) %d, wparam 0x%lx, lparam %08lx\n", 03189 LOWORD(lParam),wParam,lParam); 03190 switch (id) { 03191 case IDOK: 03192 EndDialog(hDlg, TRUE); 03193 return TRUE ; 03194 03195 case IDCANCEL: 03196 EndDialog(hDlg, FALSE); 03197 return FALSE ; 03198 03199 case psh3: /* Printer... */ 03200 pagesetup_change_printer_dialog(hDlg, data); 03201 return TRUE; 03202 03203 case rad1: /* Portrait */ 03204 case rad2: /* Landscape */ 03205 if((id == rad1 && pagesetup_get_orientation(data) == DMORIENT_LANDSCAPE) || 03206 (id == rad2 && pagesetup_get_orientation(data) == DMORIENT_PORTRAIT)) 03207 { 03208 pagesetup_set_orientation(data, (id == rad1) ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE); 03209 pagesetup_update_papersize(data); 03210 rotate_rect(pagesetup_get_margin_rect(data), (id == rad2)); 03211 update_margin_edits(hDlg, data, 0); 03212 pagesetup_change_preview(data); 03213 } 03214 break; 03215 case cmb1: /* Printer combo */ 03216 if(msg == CBN_SELCHANGE) 03217 { 03218 WCHAR name[256]; 03219 GetDlgItemTextW(hDlg, id, name, sizeof(name) / sizeof(name[0])); 03220 pagesetup_change_printer(name, data); 03221 pagesetup_init_combos(hDlg, data); 03222 } 03223 break; 03224 case cmb2: /* Paper combo */ 03225 if(msg == CBN_SELCHANGE) 03226 { 03227 DWORD paperword = SendDlgItemMessageW(hDlg, cmb2, CB_GETITEMDATA, 03228 SendDlgItemMessageW(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); 03229 if (paperword != CB_ERR) 03230 { 03231 pagesetup_set_papersize(data, paperword); 03232 pagesetup_update_papersize(data); 03233 pagesetup_change_preview(data); 03234 } else 03235 FIXME("could not get dialog text for papersize cmbbox?\n"); 03236 } 03237 break; 03238 case cmb3: /* Paper Source */ 03239 if(msg == CBN_SELCHANGE) 03240 { 03241 WORD source = SendDlgItemMessageW(hDlg, cmb3, CB_GETITEMDATA, 03242 SendDlgItemMessageW(hDlg, cmb3, CB_GETCURSEL, 0, 0), 0); 03243 pagesetup_set_defaultsource(data, source); 03244 } 03245 break; 03246 case psh2: /* Printer Properties button */ 03247 pagesetup_printer_properties(hDlg, data); 03248 break; 03249 case edt4: 03250 case edt5: 03251 case edt6: 03252 case edt7: 03253 margin_edit_notification(hDlg, data, msg, id); 03254 break; 03255 } 03256 InvalidateRect(GetDlgItem(hDlg, rct1), NULL, TRUE); 03257 return FALSE; 03258 } 03259 03260 /*********************************************************************** 03261 * default_page_paint_hook 03262 * Default hook paint procedure that receives WM_PSD_* messages from the dialog box 03263 * whenever the sample page is redrawn. 03264 */ 03265 static UINT_PTR default_page_paint_hook(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam, 03266 const pagesetup_data *data) 03267 { 03268 LPRECT lprc = (LPRECT) lParam; 03269 HDC hdc = (HDC) wParam; 03270 HPEN hpen, holdpen; 03271 LOGFONTW lf; 03272 HFONT hfont, holdfont; 03273 INT oldbkmode; 03274 TRACE("uMsg: WM_USER+%d\n",uMsg-WM_USER); 03275 /* Call user paint hook if enable */ 03276 if (pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK) 03277 if (pagesetup_get_hook(data, page_paint_hook)(hwndDlg, uMsg, wParam, lParam)) 03278 return TRUE; 03279 03280 switch (uMsg) { 03281 /* LPPAGESETUPDLG in lParam */ 03282 case WM_PSD_PAGESETUPDLG: 03283 /* Inform about the sample page rectangle */ 03284 case WM_PSD_FULLPAGERECT: 03285 /* Inform about the margin rectangle */ 03286 case WM_PSD_MINMARGINRECT: 03287 return FALSE; 03288 03289 /* Draw dashed rectangle showing margins */ 03290 case WM_PSD_MARGINRECT: 03291 hpen = CreatePen(PS_DASH, 1, GetSysColor(COLOR_3DSHADOW)); 03292 holdpen = SelectObject(hdc, hpen); 03293 Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); 03294 DeleteObject(SelectObject(hdc, holdpen)); 03295 return TRUE; 03296 /* Draw the fake document */ 03297 case WM_PSD_GREEKTEXTRECT: 03298 /* select a nice scalable font, because we want the text really small */ 03299 SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); 03300 lf.lfHeight = 6; /* value chosen based on visual effect */ 03301 hfont = CreateFontIndirectW(&lf); 03302 holdfont = SelectObject(hdc, hfont); 03303 03304 /* if text not loaded, then do so now */ 03305 if (wszFakeDocumentText[0] == '\0') 03306 LoadStringW(COMDLG32_hInstance, 03307 IDS_FAKEDOCTEXT, 03308 wszFakeDocumentText, 03309 sizeof(wszFakeDocumentText)/sizeof(wszFakeDocumentText[0])); 03310 03311 oldbkmode = SetBkMode(hdc, TRANSPARENT); 03312 DrawTextW(hdc, wszFakeDocumentText, -1, lprc, DT_TOP|DT_LEFT|DT_NOPREFIX|DT_WORDBREAK); 03313 SetBkMode(hdc, oldbkmode); 03314 03315 DeleteObject(SelectObject(hdc, holdfont)); 03316 return TRUE; 03317 03318 /* Envelope stamp */ 03319 case WM_PSD_ENVSTAMPRECT: 03320 /* Return address */ 03321 case WM_PSD_YAFULLPAGERECT: 03322 FIXME("envelope/stamp is not implemented\n"); 03323 return FALSE; 03324 default: 03325 FIXME("Unknown message %x\n",uMsg); 03326 return FALSE; 03327 } 03328 return TRUE; 03329 } 03330 03331 /*********************************************************************** 03332 * PagePaintProc 03333 * The main paint procedure for the PageSetupDlg function. 03334 * The Page Setup dialog box includes an image of a sample page that shows how 03335 * the user's selections affect the appearance of the printed output. 03336 * The image consists of a rectangle that represents the selected paper 03337 * or envelope type, with a dotted-line rectangle representing 03338 * the current margins, and partial (Greek text) characters 03339 * to show how text looks on the printed page. 03340 * 03341 * The following messages in the order sends to user hook procedure: 03342 * WM_PSD_PAGESETUPDLG Draw the contents of the sample page 03343 * WM_PSD_FULLPAGERECT Inform about the bounding rectangle 03344 * WM_PSD_MINMARGINRECT Inform about the margin rectangle (min margin?) 03345 * WM_PSD_MARGINRECT Draw the margin rectangle 03346 * WM_PSD_GREEKTEXTRECT Draw the Greek text inside the margin rectangle 03347 * If any of first three messages returns TRUE, painting done. 03348 * 03349 * PARAMS: 03350 * hWnd [in] Handle to the Page Setup dialog box 03351 * uMsg [in] Received message 03352 * 03353 * TODO: 03354 * WM_PSD_ENVSTAMPRECT Draw in the envelope-stamp rectangle (for envelopes only) 03355 * WM_PSD_YAFULLPAGERECT Draw the return address portion (for envelopes and other paper sizes) 03356 * 03357 * RETURNS: 03358 * FALSE if all done correctly 03359 * 03360 */ 03361 03362 03363 static LRESULT CALLBACK 03364 PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 03365 { 03366 PAINTSTRUCT ps; 03367 RECT rcClient, rcMargin; 03368 HPEN hpen, holdpen; 03369 HDC hdc; 03370 HBRUSH hbrush, holdbrush; 03371 pagesetup_data *data; 03372 int papersize=0, orientation=0; /* FIXME: set these values for the user paint hook */ 03373 double scalx, scaly; 03374 03375 if (uMsg != WM_PAINT) 03376 return CallWindowProcA(lpfnStaticWndProc, hWnd, uMsg, wParam, lParam); 03377 03378 /* Processing WM_PAINT message */ 03379 data = GetPropW(hWnd, pagesetupdlg_prop); 03380 if (!data) { 03381 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); 03382 return FALSE; 03383 } 03384 if (default_page_paint_hook(hWnd, WM_PSD_PAGESETUPDLG, MAKELONG(papersize, orientation), 03385 pagesetup_get_dlg_struct(data), data)) 03386 return FALSE; 03387 03388 hdc = BeginPaint(hWnd, &ps); 03389 GetClientRect(hWnd, &rcClient); 03390 03391 scalx = rcClient.right / (double)pagesetup_get_papersize_pt(data)->x; 03392 scaly = rcClient.bottom / (double)pagesetup_get_papersize_pt(data)->y; 03393 rcMargin = rcClient; 03394 03395 rcMargin.left += pagesetup_get_margin_rect(data)->left * scalx; 03396 rcMargin.top += pagesetup_get_margin_rect(data)->top * scaly; 03397 rcMargin.right -= pagesetup_get_margin_rect(data)->right * scalx; 03398 rcMargin.bottom -= pagesetup_get_margin_rect(data)->bottom * scaly; 03399 03400 /* if the space is too small then we make sure to not draw anything */ 03401 rcMargin.left = min(rcMargin.left, rcMargin.right); 03402 rcMargin.top = min(rcMargin.top, rcMargin.bottom); 03403 03404 if (!default_page_paint_hook(hWnd, WM_PSD_FULLPAGERECT, (WPARAM)hdc, (LPARAM)&rcClient, data) && 03405 !default_page_paint_hook(hWnd, WM_PSD_MINMARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data) ) 03406 { 03407 /* fill background */ 03408 hbrush = GetSysColorBrush(COLOR_3DHIGHLIGHT); 03409 FillRect(hdc, &rcClient, hbrush); 03410 holdbrush = SelectObject(hdc, hbrush); 03411 03412 hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); 03413 holdpen = SelectObject(hdc, hpen); 03414 03415 /* paint left edge */ 03416 MoveToEx(hdc, rcClient.left, rcClient.top, NULL); 03417 LineTo(hdc, rcClient.left, rcClient.bottom-1); 03418 03419 /* paint top edge */ 03420 MoveToEx(hdc, rcClient.left, rcClient.top, NULL); 03421 LineTo(hdc, rcClient.right, rcClient.top); 03422 03423 hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DDKSHADOW)); 03424 DeleteObject(SelectObject(hdc, hpen)); 03425 03426 /* paint right edge */ 03427 MoveToEx(hdc, rcClient.right-1, rcClient.top, NULL); 03428 LineTo(hdc, rcClient.right-1, rcClient.bottom); 03429 03430 /* paint bottom edge */ 03431 MoveToEx(hdc, rcClient.left, rcClient.bottom-1, NULL); 03432 LineTo(hdc, rcClient.right, rcClient.bottom-1); 03433 03434 DeleteObject(SelectObject(hdc, holdpen)); 03435 DeleteObject(SelectObject(hdc, holdbrush)); 03436 03437 default_page_paint_hook(hWnd, WM_PSD_MARGINRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data); 03438 03439 /* give text a bit of a space from the frame */ 03440 rcMargin.left += 2; 03441 rcMargin.top += 2; 03442 rcMargin.right -= 2; 03443 rcMargin.bottom -= 2; 03444 03445 /* if the space is too small then we make sure to not draw anything */ 03446 rcMargin.left = min(rcMargin.left, rcMargin.right); 03447 rcMargin.top = min(rcMargin.top, rcMargin.bottom); 03448 03449 default_page_paint_hook(hWnd, WM_PSD_GREEKTEXTRECT, (WPARAM)hdc, (LPARAM)&rcMargin, data); 03450 } 03451 03452 EndPaint(hWnd, &ps); 03453 return FALSE; 03454 } 03455 03456 /******************************************************* 03457 * The margin edit controls are subclassed to filter 03458 * anything other than numbers and the decimal separator. 03459 */ 03460 static LRESULT CALLBACK pagesetup_margin_editproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) 03461 { 03462 if (msg == WM_CHAR) 03463 { 03464 WCHAR decimal = get_decimal_sep(); 03465 WCHAR wc = (WCHAR)wparam; 03466 if(!isdigitW(wc) && wc != decimal && wc != VK_BACK) return 0; 03467 } 03468 return CallWindowProcW(edit_wndproc, hwnd, msg, wparam, lparam); 03469 } 03470 03471 static void subclass_margin_edits(HWND hDlg) 03472 { 03473 int id; 03474 WNDPROC old_proc; 03475 03476 for(id = edt4; id <= edt7; id++) 03477 { 03478 old_proc = (WNDPROC)SetWindowLongPtrW(GetDlgItem(hDlg, id), 03479 GWLP_WNDPROC, 03480 (ULONG_PTR)pagesetup_margin_editproc); 03481 InterlockedCompareExchangePointer((void**)&edit_wndproc, old_proc, NULL); 03482 } 03483 } 03484 03485 /*********************************************************************** 03486 * pagesetup_dlg_proc 03487 * 03488 * Message handler for PageSetupDlg 03489 */ 03490 static INT_PTR CALLBACK pagesetup_dlg_proc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 03491 { 03492 pagesetup_data *data; 03493 INT_PTR res = FALSE; 03494 HWND hDrawWnd; 03495 03496 if (uMsg == WM_INITDIALOG) { /*Init dialog*/ 03497 data = (pagesetup_data *)lParam; 03498 data->hDlg = hDlg; 03499 03500 hDrawWnd = GetDlgItem(hDlg, rct1); 03501 TRACE("set property to %p\n", data); 03502 SetPropW(hDlg, pagesetupdlg_prop, data); 03503 SetPropW(hDrawWnd, pagesetupdlg_prop, data); 03504 GetWindowRect(hDrawWnd, &data->rtDrawRect); /* Calculating rect in client coordinates where paper draws */ 03505 MapWindowPoints( 0, hDlg, (LPPOINT)&data->rtDrawRect, 2 ); 03506 lpfnStaticWndProc = (WNDPROC)SetWindowLongPtrW( 03507 hDrawWnd, 03508 GWLP_WNDPROC, 03509 (ULONG_PTR)PRINTDLG_PagePaintProc); 03510 03511 /* FIXME: Paint hook. Must it be at begin of initialization or at end? */ 03512 res = TRUE; 03513 if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK) 03514 { 03515 if (!pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam, 03516 pagesetup_get_dlg_struct(data))) 03517 FIXME("Setup page hook failed?\n"); 03518 } 03519 03520 /* if printer button disabled */ 03521 if (pagesetup_get_flags(data) & PSD_DISABLEPRINTER) 03522 EnableWindow(GetDlgItem(hDlg, psh3), FALSE); 03523 /* if margin edit boxes disabled */ 03524 if (pagesetup_get_flags(data) & PSD_DISABLEMARGINS) 03525 { 03526 EnableWindow(GetDlgItem(hDlg, edt4), FALSE); 03527 EnableWindow(GetDlgItem(hDlg, edt5), FALSE); 03528 EnableWindow(GetDlgItem(hDlg, edt6), FALSE); 03529 EnableWindow(GetDlgItem(hDlg, edt7), FALSE); 03530 } 03531 03532 /* Set orientation radiobuttons properly */ 03533 pagesetup_update_orientation_buttons(hDlg, data); 03534 03535 /* if orientation disabled */ 03536 if (pagesetup_get_flags(data) & PSD_DISABLEORIENTATION) 03537 { 03538 EnableWindow(GetDlgItem(hDlg,rad1),FALSE); 03539 EnableWindow(GetDlgItem(hDlg,rad2),FALSE); 03540 } 03541 03542 /* We fill them out enabled or not */ 03543 if (!(pagesetup_get_flags(data) & PSD_MARGINS)) 03544 { 03545 /* default is 1 inch */ 03546 LONG size = thousandths_inch_to_size(data, 1000); 03547 SetRect(pagesetup_get_margin_rect(data), size, size, size, size); 03548 } 03549 update_margin_edits(hDlg, data, 0); 03550 subclass_margin_edits(hDlg); 03551 set_margin_groupbox_title(hDlg, data); 03552 03553 /* if paper disabled */ 03554 if (pagesetup_get_flags(data) & PSD_DISABLEPAPER) 03555 { 03556 EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); 03557 EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); 03558 } 03559 03560 /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */ 03561 pagesetup_init_combos(hDlg, data); 03562 pagesetup_update_papersize(data); 03563 pagesetup_set_defaultsource(data, DMBIN_FORMSOURCE); /* FIXME: This is the auto select bin. Is this correct? */ 03564 03565 /* Drawing paper prev */ 03566 pagesetup_change_preview(data); 03567 return TRUE; 03568 } else { 03569 data = GetPropW(hDlg, pagesetupdlg_prop); 03570 if (!data) 03571 { 03572 WARN("__WINE_PAGESETUPDLGDATA prop not set?\n"); 03573 return FALSE; 03574 } 03575 if (pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPHOOK) 03576 { 03577 res = pagesetup_get_hook(data, page_setup_hook)(hDlg, uMsg, wParam, lParam); 03578 if (res) return res; 03579 } 03580 } 03581 switch (uMsg) { 03582 case WM_COMMAND: 03583 return pagesetup_wm_command(hDlg, wParam, lParam, data); 03584 } 03585 return FALSE; 03586 } 03587 03588 static WCHAR *get_default_printer(void) 03589 { 03590 WCHAR *name = NULL; 03591 DWORD len = 0; 03592 03593 GetDefaultPrinterW(NULL, &len); 03594 if(len) 03595 { 03596 name = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); 03597 GetDefaultPrinterW(name, &len); 03598 } 03599 return name; 03600 } 03601 03602 static void pagesetup_dump_dlg_struct(const pagesetup_data *data) 03603 { 03604 if(TRACE_ON(commdlg)) 03605 { 03606 char flagstr[1000] = ""; 03607 const struct pd_flags *pflag = psd_flags; 03608 for( ; pflag->name; pflag++) 03609 { 03610 if(pagesetup_get_flags(data) & pflag->flag) 03611 { 03612 strcat(flagstr, pflag->name); 03613 strcat(flagstr, "|"); 03614 } 03615 } 03616 TRACE("%s: (%p): hwndOwner = %p, hDevMode = %p, hDevNames = %p\n" 03617 "hinst %p, flags %08x (%s)\n", 03618 data->unicode ? "unicode" : "ansi", 03619 data->u.dlgw, data->u.dlgw->hwndOwner, data->u.dlgw->hDevMode, 03620 data->u.dlgw->hDevNames, data->u.dlgw->hInstance, 03621 pagesetup_get_flags(data), flagstr); 03622 } 03623 } 03624 03625 static void *pagesetup_get_template(pagesetup_data *data) 03626 { 03627 HRSRC res; 03628 HGLOBAL tmpl_handle; 03629 03630 if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) 03631 { 03632 tmpl_handle = data->u.dlgw->hPageSetupTemplate; 03633 } 03634 else if(pagesetup_get_flags(data) & PSD_ENABLEPAGESETUPTEMPLATE) 03635 { 03636 if(data->unicode) 03637 res = FindResourceW(data->u.dlgw->hInstance, 03638 data->u.dlgw->lpPageSetupTemplateName, MAKEINTRESOURCEW(RT_DIALOG)); 03639 else 03640 res = FindResourceA(data->u.dlga->hInstance, 03641 data->u.dlga->lpPageSetupTemplateName, MAKEINTRESOURCEA(RT_DIALOG)); 03642 tmpl_handle = LoadResource(data->u.dlgw->hInstance, res); 03643 } 03644 else 03645 { 03646 res = FindResourceW(COMDLG32_hInstance, MAKEINTRESOURCEW(PAGESETUPDLGORD), 03647 MAKEINTRESOURCEW(RT_DIALOG)); 03648 tmpl_handle = LoadResource(COMDLG32_hInstance, res); 03649 } 03650 return LockResource(tmpl_handle); 03651 } 03652 03653 static BOOL pagesetup_common(pagesetup_data *data) 03654 { 03655 BOOL ret; 03656 void *tmpl; 03657 03658 if(!pagesetup_get_dlg_struct(data)) 03659 { 03660 COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); 03661 return FALSE; 03662 } 03663 03664 pagesetup_dump_dlg_struct(data); 03665 03666 if(data->u.dlgw->lStructSize != sizeof(PAGESETUPDLGW)) 03667 { 03668 COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); 03669 return FALSE; 03670 } 03671 03672 if ((pagesetup_get_flags(data) & PSD_ENABLEPAGEPAINTHOOK) && 03673 (pagesetup_get_hook(data, page_paint_hook) == NULL)) 03674 { 03675 COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); 03676 return FALSE; 03677 } 03678 03679 if(!(pagesetup_get_flags(data) & (PSD_INTHOUSANDTHSOFINCHES | PSD_INHUNDREDTHSOFMILLIMETERS))) 03680 data->u.dlgw->Flags |= is_default_metric() ? 03681 PSD_INHUNDREDTHSOFMILLIMETERS : PSD_INTHOUSANDTHSOFINCHES; 03682 03683 if (!data->u.dlgw->hDevMode || !data->u.dlgw->hDevNames) 03684 { 03685 WCHAR *def = get_default_printer(); 03686 if(!def) 03687 { 03688 if (!(pagesetup_get_flags(data) & PSD_NOWARNING)) 03689 { 03690 WCHAR errstr[256]; 03691 LoadStringW(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255); 03692 MessageBoxW(data->u.dlgw->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR); 03693 } 03694 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 03695 return FALSE; 03696 } 03697 pagesetup_change_printer(def, data); 03698 HeapFree(GetProcessHeap(), 0, def); 03699 } 03700 03701 if (pagesetup_get_flags(data) & PSD_RETURNDEFAULT) 03702 { 03703 pagesetup_update_papersize(data); 03704 return TRUE; 03705 } 03706 03707 tmpl = pagesetup_get_template(data); 03708 03709 ret = DialogBoxIndirectParamW(data->u.dlgw->hInstance, tmpl, 03710 data->u.dlgw->hwndOwner, 03711 pagesetup_dlg_proc, (LPARAM)data) > 0; 03712 return ret; 03713 } 03714 03715 /*********************************************************************** 03716 * PageSetupDlgA (COMDLG32.@) 03717 * 03718 * Displays the PAGE SETUP dialog box, which enables the user to specify 03719 * specific properties of a printed page such as 03720 * size, source, orientation and the width of the page margins. 03721 * 03722 * PARAMS 03723 * setupdlg [IO] PAGESETUPDLGA struct 03724 * 03725 * RETURNS 03726 * TRUE if the user pressed the OK button 03727 * FALSE if the user cancelled the window or an error occurred 03728 * 03729 * NOTES 03730 * The values of hDevMode and hDevNames are filled on output and can be 03731 * changed in PAGESETUPDLG when they are passed in PageSetupDlg. 03732 * 03733 */ 03734 BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) 03735 { 03736 pagesetup_data data; 03737 03738 data.unicode = FALSE; 03739 data.u.dlga = setupdlg; 03740 03741 return pagesetup_common(&data); 03742 } 03743 03744 /*********************************************************************** 03745 * PageSetupDlgW (COMDLG32.@) 03746 * 03747 * See PageSetupDlgA. 03748 */ 03749 BOOL WINAPI PageSetupDlgW(LPPAGESETUPDLGW setupdlg) 03750 { 03751 pagesetup_data data; 03752 03753 data.unicode = TRUE; 03754 data.u.dlgw = setupdlg; 03755 03756 return pagesetup_common(&data); 03757 } 03758 03759 /*********************************************************************** 03760 * PrintDlgExA (COMDLG32.@) 03761 * 03762 * See PrintDlgExW. 03763 * 03764 * BUGS 03765 * Only a Stub 03766 * 03767 */ 03768 HRESULT WINAPI PrintDlgExA(LPPRINTDLGEXA lppd) 03769 { 03770 DWORD ret = E_FAIL; 03771 LPVOID ptr; 03772 03773 FIXME("(%p) not fully implemented\n", lppd); 03774 if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXA))) 03775 return E_INVALIDARG; 03776 03777 if (!IsWindow(lppd->hwndOwner)) 03778 return E_HANDLE; 03779 03780 if (lppd->Flags & PD_RETURNDEFAULT) 03781 { 03782 PRINTER_INFO_2A *pbuf; 03783 DRIVER_INFO_2A *dbuf; 03784 HANDLE hprn; 03785 DWORD needed = 1024; 03786 BOOL bRet; 03787 03788 if (lppd->hDevMode || lppd->hDevNames) 03789 { 03790 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); 03791 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 03792 return E_INVALIDARG; 03793 } 03794 if (!PRINTDLG_OpenDefaultPrinter(&hprn)) 03795 { 03796 WARN("Can't find default printer\n"); 03797 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 03798 return E_FAIL; 03799 } 03800 03801 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03802 bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); 03803 if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) 03804 { 03805 HeapFree(GetProcessHeap(), 0, pbuf); 03806 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03807 bRet = GetPrinterA(hprn, 2, (LPBYTE)pbuf, needed, &needed); 03808 } 03809 if (!bRet) 03810 { 03811 HeapFree(GetProcessHeap(), 0, pbuf); 03812 ClosePrinter(hprn); 03813 return E_FAIL; 03814 } 03815 03816 needed = 1024; 03817 dbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03818 bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); 03819 if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) 03820 { 03821 HeapFree(GetProcessHeap(), 0, dbuf); 03822 dbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03823 bRet = GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); 03824 } 03825 if (!bRet) 03826 { 03827 ERR("GetPrinterDriverА failed, last error %d, fix your config for printer %s!\n", 03828 GetLastError(), pbuf->pPrinterName); 03829 HeapFree(GetProcessHeap(), 0, dbuf); 03830 HeapFree(GetProcessHeap(), 0, pbuf); 03831 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 03832 ClosePrinter(hprn); 03833 return E_FAIL; 03834 } 03835 ClosePrinter(hprn); 03836 03837 PRINTDLG_CreateDevNames(&(lppd->hDevNames), 03838 dbuf->pDriverPath, 03839 pbuf->pPrinterName, 03840 pbuf->pPortName); 03841 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + 03842 pbuf->pDevMode->dmDriverExtra); 03843 if (lppd->hDevMode) 03844 { 03845 ptr = GlobalLock(lppd->hDevMode); 03846 if (ptr) 03847 { 03848 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + 03849 pbuf->pDevMode->dmDriverExtra); 03850 GlobalUnlock(lppd->hDevMode); 03851 ret = S_OK; 03852 } 03853 } 03854 HeapFree(GetProcessHeap(), 0, pbuf); 03855 HeapFree(GetProcessHeap(), 0, dbuf); 03856 03857 return ret; 03858 } 03859 03860 return E_NOTIMPL; 03861 } 03862 03863 /*********************************************************************** 03864 * PrintDlgExW (COMDLG32.@) 03865 * 03866 * Display the property sheet style PRINT dialog box 03867 * 03868 * PARAMS 03869 * lppd [IO] ptr to PRINTDLGEX struct 03870 * 03871 * RETURNS 03872 * Success: S_OK 03873 * Failure: One of the following COM error codes: 03874 * E_OUTOFMEMORY Insufficient memory. 03875 * E_INVALIDARG One or more arguments are invalid. 03876 * E_POINTER Invalid pointer. 03877 * E_HANDLE Invalid handle. 03878 * E_FAIL Unspecified error. 03879 * 03880 * NOTES 03881 * This Dialog enables the user to specify specific properties of the print job. 03882 * The property sheet can also have additional application-specific and 03883 * driver-specific property pages. 03884 * 03885 * BUGS 03886 * Not fully implemented 03887 * 03888 */ 03889 HRESULT WINAPI PrintDlgExW(LPPRINTDLGEXW lppd) 03890 { 03891 DWORD ret = E_FAIL; 03892 LPVOID ptr; 03893 03894 FIXME("(%p) not fully implemented\n", lppd); 03895 03896 if ((lppd == NULL) || (lppd->lStructSize != sizeof(PRINTDLGEXW))) { 03897 return E_INVALIDARG; 03898 } 03899 03900 if (!IsWindow(lppd->hwndOwner)) { 03901 return E_HANDLE; 03902 } 03903 03904 if (lppd->Flags & PD_RETURNDEFAULT) { 03905 PRINTER_INFO_2W *pbuf; 03906 DRIVER_INFO_2W *dbuf; 03907 HANDLE hprn; 03908 DWORD needed = 1024; 03909 BOOL bRet; 03910 03911 if (lppd->hDevMode || lppd->hDevNames) { 03912 WARN("hDevMode or hDevNames non-zero for PD_RETURNDEFAULT\n"); 03913 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 03914 return E_INVALIDARG; 03915 } 03916 if (!PRINTDLG_OpenDefaultPrinter(&hprn)) { 03917 WARN("Can't find default printer\n"); 03918 COMDLG32_SetCommDlgExtendedError(PDERR_NODEFAULTPRN); 03919 return E_FAIL; 03920 } 03921 03922 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03923 bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed); 03924 if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 03925 HeapFree(GetProcessHeap(), 0, pbuf); 03926 pbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03927 bRet = GetPrinterW(hprn, 2, (LPBYTE)pbuf, needed, &needed); 03928 } 03929 if (!bRet) { 03930 HeapFree(GetProcessHeap(), 0, pbuf); 03931 ClosePrinter(hprn); 03932 return E_FAIL; 03933 } 03934 03935 needed = 1024; 03936 dbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03937 bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); 03938 if (!bRet && (GetLastError() == ERROR_INSUFFICIENT_BUFFER)) { 03939 HeapFree(GetProcessHeap(), 0, dbuf); 03940 dbuf = HeapAlloc(GetProcessHeap(), 0, needed); 03941 bRet = GetPrinterDriverW(hprn, NULL, 3, (LPBYTE)dbuf, needed, &needed); 03942 } 03943 if (!bRet) { 03944 ERR("GetPrinterDriverW failed, last error %d, fix your config for printer %s!\n", 03945 GetLastError(), debugstr_w(pbuf->pPrinterName)); 03946 HeapFree(GetProcessHeap(), 0, dbuf); 03947 HeapFree(GetProcessHeap(), 0, pbuf); 03948 COMDLG32_SetCommDlgExtendedError(PDERR_RETDEFFAILURE); 03949 ClosePrinter(hprn); 03950 return E_FAIL; 03951 } 03952 ClosePrinter(hprn); 03953 03954 PRINTDLG_CreateDevNamesW(&(lppd->hDevNames), 03955 dbuf->pDriverPath, 03956 pbuf->pPrinterName, 03957 pbuf->pPortName); 03958 lppd->hDevMode = GlobalAlloc(GMEM_MOVEABLE, pbuf->pDevMode->dmSize + 03959 pbuf->pDevMode->dmDriverExtra); 03960 if (lppd->hDevMode) { 03961 ptr = GlobalLock(lppd->hDevMode); 03962 if (ptr) { 03963 memcpy(ptr, pbuf->pDevMode, pbuf->pDevMode->dmSize + 03964 pbuf->pDevMode->dmDriverExtra); 03965 GlobalUnlock(lppd->hDevMode); 03966 ret = S_OK; 03967 } 03968 } 03969 HeapFree(GetProcessHeap(), 0, pbuf); 03970 HeapFree(GetProcessHeap(), 0, dbuf); 03971 03972 return ret; 03973 } 03974 03975 return E_NOTIMPL; 03976 } Generated on Mon May 28 2012 04:22:47 for ReactOS by
1.7.6.1
|