Implement most functionality of PageSetupDlg function.
diff --git a/dlls/commdlg/cdlg_En.rc b/dlls/commdlg/cdlg_En.rc index fb2764d..732eff0 100644 --- a/dlls/commdlg/cdlg_En.rc +++ b/dlls/commdlg/cdlg_En.rc
@@ -313,13 +313,13 @@ AUTORADIOBUTTON "&Landscape", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON GROUPBOX "Borders", grp4, 80, 156, 152, 56, BS_GROUPBOX LTEXT "L&eft:", stc15, 88, 172, 21, 8 - EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + EDITTEXT edt4, 111, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER LTEXT "&Right:", stc16, 159, 172, 27, 8 - EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + EDITTEXT edt6, 187, 170, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER LTEXT "T&op:", stc17, 88, 192, 21, 8 - EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + EDITTEXT edt5, 111, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER LTEXT "&Bottom:", stc18, 159, 192, 23, 8 - EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER + EDITTEXT edt7, 187, 190, 39, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER DEFPUSHBUTTON "OK", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON PUSHBUTTON "Cancel", IDCANCEL, 126, 220, 50, 14 PUSHBUTTON "P&rinter...", psh3, 184, 220, 48, 14
diff --git a/dlls/commdlg/cdlg_Ru.rc b/dlls/commdlg/cdlg_Ru.rc index 81a2d15..44ec328 100644 --- a/dlls/commdlg/cdlg_Ru.rc +++ b/dlls/commdlg/cdlg_Ru.rc
@@ -294,6 +294,37 @@ CONTROL "Ë&àíäøàôò", rad2,"Button",BS_AUTORADIOBUTTON,224,126,52,12 END +PAGESETUPDLGORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 32, 32, 240, 240 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "Ïàðàìåòðû ñòðàíèöû" +FONT 8, "MS Shell Dlg" +BEGIN + CONTROL "", rct1, "Static", SS_WHITERECT, 80, 8, 80, 80 + CONTROL "", rct2, "Static", SS_GRAYRECT, 160, 12, 4, 80 + CONTROL "", rct3, "Static", SS_GRAYRECT, 84, 88, 80, 4 + GROUPBOX "Áóìàãà", grp2, 8, 96, 224, 56, BS_GROUPBOX + LTEXT "&Ðàçìåð:", stc2, 16, 112, 36, 8 + COMBOBOX cmb2, 64, 110, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL + LTEXT "Ïîäà&÷à:", stc3, 16, 132, 36, 8 + COMBOBOX cmb3, 64, 130, 160, 160, CBS_SIMPLE|CBS_DROPDOWN|CBS_SORT|WS_GROUP|WS_TABSTOP|WS_VSCROLL + GROUPBOX "Îðèåíòàöèÿ", grp1, 8, 156, 64, 56, BS_GROUPBOX + AUTORADIOBUTTON "Ê&íèæíàÿ", rad1, 16, 170, 52, 12, BS_AUTORADIOBUTTON + AUTORADIOBUTTON "Àëü&áîìíàÿ", rad2, 16, 190, 52, 12, BS_AUTORADIOBUTTON + GROUPBOX "Ïîëÿ", grp4, 80, 156, 152, 56, BS_GROUPBOX + LTEXT "&Ñëåâà:", stc15, 88, 172, 31, 8 + EDITTEXT edt4, 121, 170, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER + LTEXT "Ñ&âåðõó:", stc16, 159, 172, 27, 8 + EDITTEXT edt6, 187, 170, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER + LTEXT "Ñïð&àâà:", stc17, 88, 192, 31, 8 + EDITTEXT edt5, 121, 190, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER + LTEXT "Ñíè&çó:", stc18, 159, 192, 23, 8 + EDITTEXT edt7, 187, 190, 29, 12, WS_TABSTOP|WS_GROUP|WS_BORDER|ES_NUMBER + DEFPUSHBUTTON "ÎÊ", IDOK, 71, 220, 50, 14, BS_PUSHBUTTON + PUSHBUTTON "Îòìåíà", IDCANCEL, 126, 220, 50, 14 + PUSHBUTTON "&Ïðèíòåð...", psh3, 184, 220, 48, 14 +END + + NEWFILEOPENORD DIALOG LOADONCALL MOVEABLE DISCARDABLE 0, 0, 280, 164 STYLE DS_MODALFRAME | DS_CONTEXTHELP | WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN CAPTION "Îòêðûòü"
diff --git a/dlls/commdlg/printdlg.c b/dlls/commdlg/printdlg.c index dd56519..47eadb9 100644 --- a/dlls/commdlg/printdlg.c +++ b/dlls/commdlg/printdlg.c
@@ -120,6 +120,8 @@ EnumPrintersA(PRINTER_ENUM_LOCAL, NULL, 2, (LPBYTE)pi, needed, &needed, &num); + SendDlgItemMessageA(hDlg, id, CB_RESETCONTENT, 0, 0); + for(i = 0; i < num; i++) { SendDlgItemMessageA(hDlg, id, CB_ADDSTRING, 0, (LPARAM)pi[i].pPrinterName ); @@ -432,14 +434,14 @@ } static BOOL PRINTDLG_PaperSizeA( - PRINTDLGA *pdlga,const char *PaperSize,LPPOINT size + PRINTDLGA *pdlga,const WORD PaperSize,LPPOINT size ) { DEVNAMES *dn; DEVMODEA *dm; LPSTR devname,portname; int i; INT NrOfEntries,ret; - char *Names = NULL; + WORD *Words = NULL; POINT *points = NULL; BOOL retval = FALSE; @@ -459,17 +461,17 @@ goto out; } - Names = HeapAlloc(GetProcessHeap(),0,NrOfEntries*64); - if (NrOfEntries != (ret=DeviceCapabilitiesA(devname,portname,DC_PAPERNAMES,Names,dm))) { + Words = HeapAlloc(GetProcessHeap(),0,NrOfEntries*sizeof(WORD)); + if (NrOfEntries != (ret=DeviceCapabilitiesA(devname,portname,DC_PAPERS,(LPSTR)Words,dm))) { FIXME("Number of returned vals %d is not %d\n",NrOfEntries,ret); goto out; } for (i=0;i<NrOfEntries;i++) - if (!strcmp(PaperSize,Names+(64*i))) + if (Words[i] == PaperSize) break; - HeapFree(GetProcessHeap(),0,Names); - if (i==NrOfEntries) { - FIXME("Papersize %s not found in list?\n",PaperSize); + HeapFree(GetProcessHeap(),0,Words); + if (i == NrOfEntries) { + FIXME("Papersize %d not found in list?\n",PaperSize); goto out; } points = HeapAlloc(GetProcessHeap(),0,sizeof(points[0])*NrOfEntries); @@ -484,7 +486,7 @@ out: GlobalUnlock(pdlga->hDevNames); GlobalUnlock(pdlga->hDevMode); - HeapFree(GetProcessHeap(),0,Names); + HeapFree(GetProcessHeap(),0,Words); HeapFree(GetProcessHeap(),0,points); return retval; } @@ -1936,20 +1938,21 @@ * * Displays the the PRINT dialog box, which enables the user to specify * specific properties of the print job. - * + * + * PARAMS + * lppd [IO] ptr to PRINTDLG32 struct + * * RETURNS * nonzero if the user pressed the OK button * zero if the user cancelled the window or an error occurred - * + * * BUGS * PrintDlg: * * The Collate Icons do not display, even though they are in the code. * * The Properties Button(s) should call DocumentPropertiesA(). */ -BOOL WINAPI PrintDlgA( - LPPRINTDLGA lppd /* [in/out] ptr to PRINTDLG32 struct */ - ) +BOOL WINAPI PrintDlgA(LPPRINTDLGA lppd) { BOOL bRet = FALSE; LPVOID ptr; @@ -2272,8 +2275,11 @@ */ typedef struct { - LPPAGESETUPDLGA dlga; + LPPAGESETUPDLGA dlga; /* Handler to user defined struct */ PRINTDLGA pdlg; + HWND hDlg; /* Page Setup dialog handler */ + PAGESETUPDLGA curdlg; /* Struct means cerrent dialog state */ + RECT rtDrawRect; /* Drawing rect for page */ } PageSetupDataA; typedef struct { @@ -2281,11 +2287,12 @@ PRINTDLGW pdlg; } PageSetupDataW; + static HGLOBAL PRINTDLG_GetPGSTemplateA(PAGESETUPDLGA *lppd) { HRSRC hResInfo; HGLOBAL hDlgTmpl; - + if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATEHANDLE) { hDlgTmpl = lppd->hPageSetupTemplate; } else if(lppd->Flags & PSD_ENABLEPAGESETUPTEMPLATE) { @@ -2320,7 +2327,7 @@ static DWORD _c_10mm2size(PAGESETUPDLGA *dlga,DWORD size) { if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) - return 10*size*10/25.4; + return 10*size*100/254; /* If we don't have a flag, we can choose one. Use millimeters * to avoid confusing me */ @@ -2334,27 +2341,27 @@ if (dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) return size; if (dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) - return (size*254)/10; + return (size*254)/100; /* if we don't have a flag, we can choose one. Use millimeters * to avoid confusing me */ dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; - return (size*254)/10; + return (size*254)/100; } static void _c_size2strA(PageSetupDataA *pda,DWORD size,LPSTR strout) { strcpy(strout,"<undef>"); if (pda->dlga->Flags & PSD_INHUNDREDTHSOFMILLIMETERS) { - sprintf(strout,"%.2fmm",(size*1.0)/100.0); + sprintf(strout,"%ld",(size)/100); return; } if (pda->dlga->Flags & PSD_INTHOUSANDTHSOFINCHES) { - sprintf(strout,"%.2fin",(size*1.0)/1000.0); + sprintf(strout,"%ldin",(size)/1000); return; } pda->dlga->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS; - sprintf(strout,"%.2fmm",(size*1.0)/100.0); + sprintf(strout,"%ld",(size)/100); return; } static void @@ -2427,47 +2434,46 @@ } -/* - * This is called on finish and will update the output fields of the - * struct. +/**************************************************************************** + * PRINTDLG_PS_UpdateDlgStructA + * + * Updates pda->dlga structure + * Function calls when user presses OK button + * + * PARAMS + * hDlg [in] main window dialog HANDLE + * pda [in/out] ptr to PageSetupDataA structere + * + * RETURNS + * TRUE */ static BOOL PRINTDLG_PS_UpdateDlgStructA(HWND hDlg, PageSetupDataA *pda) { DEVNAMES *dn; DEVMODEA *dm; - LPSTR devname,portname; - char papername[64]; - char buf[200]; + DWORD paperword; + memcpy(pda->dlga, &pda->curdlg, sizeof(pda->curdlg)); + pda->dlga->hDevMode = pda->pdlg.hDevMode; + pda->dlga->hDevNames = pda->pdlg.hDevNames; + dn = GlobalLock(pda->pdlg.hDevNames); dm = GlobalLock(pda->pdlg.hDevMode); - devname = ((char*)dn)+dn->wDeviceOffset; - portname = ((char*)dn)+dn->wOutputOffset; - PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm); - PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm); - - if (GetDlgItemTextA(hDlg,cmb2,papername,sizeof(papername))>0) { - PRINTDLG_PaperSizeA(&(pda->pdlg),papername,&(pda->dlga->ptPaperSize)); - pda->dlga->ptPaperSize.x = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.x); - pda->dlga->ptPaperSize.y = _c_10mm2size(pda->dlga,pda->dlga->ptPaperSize.y); - } else + if(pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y) + dm->u1.s1.dmOrientation = DMORIENT_LANDSCAPE; + else + dm->u1.s1.dmOrientation = DMORIENT_PORTRAIT; + + paperword = SendDlgItemMessageA(hDlg,cmb2,CB_GETITEMDATA, + SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); + if (paperword != CB_ERR) + dm->u1.s1.dmPaperSize = paperword; + else FIXME("could not get dialog text for papersize cmbbox?\n"); -#define GETVAL(id,val) if (GetDlgItemTextA(hDlg,id,buf,sizeof(buf))>0) { val = _c_str2sizeA(pda->dlga,buf); } else { FIXME("could not get dlgitemtexta for %x\n",id); } - GETVAL(edt4,pda->dlga->rtMargin.left); - GETVAL(edt5,pda->dlga->rtMargin.top); - GETVAL(edt6,pda->dlga->rtMargin.right); - GETVAL(edt7,pda->dlga->rtMargin.bottom); -#undef GETVAL - - /* If we are in landscape, swap x and y of page size */ - if (IsDlgButtonChecked(hDlg, rad2)) { - DWORD tmp; - tmp = pda->dlga->ptPaperSize.x; - pda->dlga->ptPaperSize.x = pda->dlga->ptPaperSize.y; - pda->dlga->ptPaperSize.y = tmp; - } + GlobalUnlock(pda->pdlg.hDevNames); GlobalUnlock(pda->pdlg.hDevMode); + return TRUE; } @@ -2511,19 +2517,87 @@ return TRUE; } -/* - * This is called after returning from PrintDlg(). +/********************************************************************************************** + * PRINTDLG_PS_ChangeActivePrinerA + * + * Redefines hDevMode and hDevNames HANDLES and initialises it. + * + * PARAMS + * name [in] Name of a printer for activation + * pda [in/out] ptr to PageSetupDataA structure + * + * RETURN + * TRUE if success + * FALSE if fail + */ +static BOOL +PRINTDLG_PS_ChangeActivePrinterA(LPSTR name, PageSetupDataA *pda){ + HANDLE hprn; + DWORD needed; + LPPRINTER_INFO_2A lpPrinterInfo; + LPDRIVER_INFO_3A lpDriverInfo; + DEVMODEA *pDevMode, *dm; + + if(!OpenPrinterA(name, &hprn, NULL)){ + ERR("Can't open printer %s\n", name); + return FALSE; + } + GetPrinterA(hprn, 2, NULL, 0, &needed); + lpPrinterInfo = HeapAlloc(GetProcessHeap(), 0, needed); + GetPrinterA(hprn, 2, (LPBYTE)lpPrinterInfo, needed, &needed); + GetPrinterDriverA(hprn, NULL, 3, NULL, 0, &needed); + lpDriverInfo = HeapAlloc(GetProcessHeap(), 0, needed); + if(!GetPrinterDriverA(hprn, NULL, 3, (LPBYTE)lpDriverInfo, needed, &needed)) { + ERR("GetPrinterDriverA failed for %s, fix your config!\n", lpPrinterInfo->pPrinterName); + return FALSE; + } + ClosePrinter(hprn); + + needed = DocumentPropertiesA(0, 0, name, NULL, NULL, 0); + if(needed == -1) { + ERR("DocumentProperties fails on %s\n", debugstr_a(name)); + return FALSE; + } + pDevMode = HeapAlloc(GetProcessHeap(), 0, needed); + DocumentPropertiesA(0, 0, name, pDevMode, NULL, DM_OUT_BUFFER); + + pda->pdlg.hDevMode = GlobalReAlloc(pda->pdlg.hDevMode, + pDevMode->dmSize + pDevMode->dmDriverExtra, + GMEM_MOVEABLE); + dm = GlobalLock(pda->pdlg.hDevMode); + memcpy(dm, pDevMode, pDevMode->dmSize + pDevMode->dmDriverExtra); + + PRINTDLG_CreateDevNames(&(pda->pdlg.hDevNames), + lpDriverInfo->pDriverPath, + lpPrinterInfo->pPrinterName, + lpPrinterInfo->pPortName); + + GlobalUnlock(pda->pdlg.hDevMode); + HeapFree(GetProcessHeap(), 0, pDevMode); + HeapFree(GetProcessHeap(), 0, lpPrinterInfo); + HeapFree(GetProcessHeap(), 0, lpDriverInfo); + return TRUE; +} + +/**************************************************************************************** + * PRINTDLG_PS_ChangePrinterA + * + * Fills Printers, Paper and Source combo + * + * RETURNS + * TRUE */ static BOOL PRINTDLG_PS_ChangePrinterA(HWND hDlg, PageSetupDataA *pda) { DEVNAMES *dn; DEVMODEA *dm; LPSTR devname,portname; - + dn = GlobalLock(pda->pdlg.hDevNames); dm = GlobalLock(pda->pdlg.hDevMode); - devname = ((char*)dn)+dn->wDeviceOffset; + devname = ((char*)dn)+dn->wDeviceOffset; portname = ((char*)dn)+dn->wOutputOffset; + PRINTDLG_SetUpPrinterListComboA(hDlg, cmb1, devname); PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb2,devname,portname,dm); PRINTDLG_SetUpPaperComboBoxA(hDlg,cmb3,devname,portname,dm); GlobalUnlock(pda->pdlg.hDevNames); @@ -2548,13 +2622,79 @@ return TRUE; } +/****************************************************************************************** + * PRINTDLG_PS_ChangePaperPrev + * + * Changes paper preview size / position + * + * PARAMS: + * pda [i] Pointer for current PageSetupDataA structure + * + * RETURNS: + * always - TRUE + */ +static BOOL +PRINTDLG_PS_ChangePaperPrev(PageSetupDataA *pda) +{ + LONG width, height, x, y; + RECT rtTmp; + + if(pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y) { + width = pda->rtDrawRect.right - pda->rtDrawRect.left; + height = pda->curdlg.ptPaperSize.y * width / pda->curdlg.ptPaperSize.x; + } else { + height = pda->rtDrawRect.bottom - pda->rtDrawRect.top; + width = pda->curdlg.ptPaperSize.x * height / pda->curdlg.ptPaperSize.y; + } + x = (pda->rtDrawRect.right + pda->rtDrawRect.left - width) / 2; + y = (pda->rtDrawRect.bottom + pda->rtDrawRect.top - height) / 2; + TRACE("rtDrawRect(%ld, %ld, %ld, %ld) x=%ld, y=%ld, w=%ld, h=%ld", + pda->rtDrawRect.left, pda->rtDrawRect.top, pda->rtDrawRect.right, pda->rtDrawRect.bottom, + x, y, width, height); + +#define SHADOW 4 + MoveWindow(GetDlgItem(pda->hDlg, rct2), x+width, y+SHADOW, SHADOW, height, FALSE); + MoveWindow(GetDlgItem(pda->hDlg, rct3), x+SHADOW, y+height, width, SHADOW, FALSE); + MoveWindow(GetDlgItem(pda->hDlg, rct1), x, y, width, height, FALSE); + memcpy(&rtTmp, &pda->rtDrawRect, sizeof(RECT)); + rtTmp.right += SHADOW; + rtTmp.bottom += SHADOW; +#undef SHADOW + + InvalidateRect(pda->hDlg, &rtTmp, TRUE); + return TRUE; +} + +#define GETVAL(idc,val) \ +if(msg == EN_CHANGE){ \ + if (GetDlgItemTextA(hDlg,idc,buf,sizeof(buf)) > 0)\ + val = _c_str2sizeA(pda->dlga,buf); \ + else\ + FIXME("could not get dlgitemtexta for %x\n",id); \ +} + +/******************************************************************************** + * PRINTDLG_PS_WMCommandA + * process WM_COMMAND message for PageSetupDlgA + * + * PARAMS + * hDlg [in] Main dialog HANDLE + * wParam [in] WM_COMMAND wParam + * lParam [in] WM_COMMAND lParam + * pda [in/out] ptr to PageSetupDataA + */ + static BOOL PRINTDLG_PS_WMCommandA( HWND hDlg, WPARAM wParam, LPARAM lParam, PageSetupDataA *pda ) { + WORD msg = HIWORD(wParam); + WORD id = LOWORD(wParam); + char buf[200]; + TRACE("loword (lparam) %d, wparam 0x%x, lparam %08lx\n", LOWORD(lParam),wParam,lParam); - switch (LOWORD(wParam)) { + switch (id) { case IDOK: if (!PRINTDLG_PS_UpdateDlgStructA(hDlg, pda)) return(FALSE); @@ -2570,11 +2710,121 @@ pda->pdlg.hwndOwner = hDlg; if (PrintDlgA(&(pda->pdlg))) PRINTDLG_PS_ChangePrinterA(hDlg,pda); + } return TRUE; + case rad1: + if (pda->curdlg.ptPaperSize.x > pda->curdlg.ptPaperSize.y){ + DWORD tmp = pda->curdlg.ptPaperSize.x; + pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; + pda->curdlg.ptPaperSize.y = tmp; + } + PRINTDLG_PS_ChangePaperPrev(pda); + break; + case rad2: + if (pda->curdlg.ptPaperSize.y > pda->curdlg.ptPaperSize.x){ + DWORD tmp = pda->curdlg.ptPaperSize.x; + pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; + pda->curdlg.ptPaperSize.y = tmp; + } + PRINTDLG_PS_ChangePaperPrev(pda); + break; + case cmb1: /* Printer combo */ + if(msg == CBN_SELCHANGE){ + char crPrinterName[256]; + GetDlgItemTextA(hDlg, id, crPrinterName, 255); + PRINTDLG_PS_ChangeActivePrinterA(crPrinterName, pda); + PRINTDLG_PS_ChangePrinterA(hDlg, pda); + } + break; + case cmb2: /* Paper combo */ + if(msg == CBN_SELCHANGE){ + DWORD paperword = SendDlgItemMessageA(hDlg,cmb2,CB_GETITEMDATA, + SendDlgItemMessageA(hDlg, cmb2, CB_GETCURSEL, 0, 0), 0); + if (paperword != CB_ERR) { + PRINTDLG_PaperSizeA(&(pda->pdlg), paperword,&(pda->curdlg.ptPaperSize)); + pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga,pda->curdlg.ptPaperSize.x); + pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga,pda->curdlg.ptPaperSize.y); + + if (IsDlgButtonChecked(hDlg, rad2)) { + DWORD tmp = pda->curdlg.ptPaperSize.x; + pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; + pda->curdlg.ptPaperSize.y = tmp; + } + PRINTDLG_PS_ChangePaperPrev(pda); + } else + FIXME("could not get dialog text for papersize cmbbox?\n"); + } + break; + case cmb3: + if(msg == CBN_SELCHANGE){ + DEVMODEA *dm = GlobalLock(pda->pdlg.hDevMode); + dm->dmDefaultSource = SendDlgItemMessageA(hDlg, cmb3,CB_GETITEMDATA, + SendDlgItemMessageA(hDlg, cmb3, CB_GETCURSEL, 0, 0), 0); + GlobalUnlock(pda->pdlg.hDevMode); + } + break; + case psh2: /* Printer Properties button */ + { + HANDLE hPrinter; + char PrinterName[256]; + DEVMODEA *dm; + LRESULT count; + int i; + + GetDlgItemTextA(hDlg, cmb1, PrinterName, 255); + if (!OpenPrinterA(PrinterName, &hPrinter, NULL)) { + FIXME("Call to OpenPrinter did not succeed!\n"); + break; + } + dm = GlobalLock(pda->pdlg.hDevMode); + DocumentPropertiesA(hDlg, hPrinter, PrinterName, dm, dm, + DM_IN_BUFFER | DM_OUT_BUFFER | DM_IN_PROMPT); + ClosePrinter(hPrinter); + /* Changing paper */ + PRINTDLG_PaperSizeA(&(pda->pdlg), dm->u1.s1.dmPaperSize, &(pda->curdlg.ptPaperSize)); + pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.x); + pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.y); + if (dm->u1.s1.dmOrientation == DMORIENT_LANDSCAPE){ + DWORD tmp = pda->curdlg.ptPaperSize.x; + pda->curdlg.ptPaperSize.x = pda->curdlg.ptPaperSize.y; + pda->curdlg.ptPaperSize.y = tmp; + CheckRadioButton(hDlg, rad1, rad2, rad2); + } + else + CheckRadioButton(hDlg, rad1, rad2, rad1); + /* Changing paper preview */ + PRINTDLG_PS_ChangePaperPrev(pda); + /* Selecting paper in combo */ + count = SendDlgItemMessageA(hDlg, cmb2, CB_GETCOUNT, 0, 0); + if(count != CB_ERR){ + for(i=0; i<count; ++i){ + if(SendDlgItemMessageA(hDlg, cmb2, CB_GETITEMDATA, i, 0) == dm->u1.s1.dmPaperSize) { + SendDlgItemMessageA(hDlg, cmb2, CB_SETCURSEL, i, 0); + break; + } + } + } + + GlobalUnlock(pda->pdlg.hDevMode); + break; + } + case edt4: + GETVAL(id, pda->curdlg.rtMargin.left); + break; + case edt5: + GETVAL(id, pda->curdlg.rtMargin.right); + break; + case edt6: + GETVAL(id, pda->curdlg.rtMargin.top); + break; + case edt7: + GETVAL(id, pda->curdlg.rtMargin.bottom); + break; } - } + InvalidateRect(GetDlgItem(hDlg, rct1), NULL, TRUE); return FALSE; } +#undef GETVAL static BOOL PRINTDLG_PS_WMCommandW( @@ -2621,7 +2871,6 @@ HFONT hfont, holdfont; INT oldbkmode; TRACE("uMsg: WM_USER+%d\n",uMsg-WM_USER); - /* Call user paint hook if enable */ if (pda->dlga->Flags & PSD_ENABLEPAGEPAINTHOOK) if (pda->dlga->lpfnPagePaintHook(hwndDlg, uMsg, wParam, lParam)) @@ -2643,8 +2892,6 @@ Rectangle(hdc, lprc->left, lprc->top, lprc->right, lprc->bottom); DeleteObject(SelectObject(hdc, holdpen)); return TRUE; - - /* Draw the fake document */ case WM_PSD_GREEKTEXTRECT: /* select a nice scalable font, because we want the text really small */ @@ -2710,6 +2957,8 @@ * FALSE if all done correctly * */ + + static LRESULT CALLBACK PRINTDLG_PagePaintProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -2720,7 +2969,7 @@ HBRUSH hbrush, holdbrush; PageSetupDataA *pda; int papersize=0, orientation=0; /* FIXME: set this values */ - + double scalx, scaly; #define CALLPAINTHOOK(msg,lprc) PRINTDLG_DefaultPagePaintHook( hWnd, msg, (WPARAM)hdc, (LPARAM)lprc, pda) if (uMsg != WM_PAINT) @@ -2737,14 +2986,16 @@ hdc = BeginPaint(hWnd, &ps); GetClientRect(hWnd, &rcClient); - - /* FIXME: use real margin values */ + + scalx = rcClient.right / (double)pda->curdlg.ptPaperSize.x; + scaly = rcClient.bottom / (double)pda->curdlg.ptPaperSize.y; rcMargin = rcClient; - rcMargin.left += 5; - rcMargin.top += 5; - rcMargin.right -= 5; - rcMargin.bottom -= 5; - + + rcMargin.left += (LONG)pda->curdlg.rtMargin.left * scalx; + rcMargin.top += (LONG)pda->curdlg.rtMargin.top * scalx; + rcMargin.right -= (LONG)pda->curdlg.rtMargin.right * scaly; + rcMargin.bottom -= (LONG)pda->curdlg.rtMargin.bottom * scaly; + /* if the space is too small then we make sure to not draw anything */ rcMargin.left = min(rcMargin.left, rcMargin.right); rcMargin.top = min(rcMargin.top, rcMargin.bottom); @@ -2759,7 +3010,6 @@ hpen = CreatePen(PS_SOLID, 1, GetSysColor(COLOR_3DSHADOW)); holdpen = SelectObject(hdc, hpen); - /* paint left edge */ MoveToEx(hdc, rcClient.left, rcClient.top, NULL); @@ -2783,10 +3033,8 @@ DeleteObject(SelectObject(hdc, holdpen)); DeleteObject(SelectObject(hdc, holdbrush)); - CALLPAINTHOOK(WM_PSD_MARGINRECT, &rcMargin); - /* give text a bit of a space from the frame */ rcMargin.left += 2; rcMargin.top += 2; @@ -2807,23 +3055,34 @@ /*********************************************************************** * PRINTDLG_PageDlgProcA - * Message handler + * Message handler for PageSetupDlgA */ static INT_PTR CALLBACK PRINTDLG_PageDlgProcA(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { + DEVMODEA *dm; PageSetupDataA *pda; INT_PTR res = FALSE; + HWND hDrawWnd; - if (uMsg == WM_INITDIALOG) { + if (uMsg == WM_INITDIALOG) { /*Init dialog*/ pda = (PageSetupDataA*)lParam; + pda->hDlg = hDlg; /* saving handle to main window to PageSetupDataA structure */ + memcpy(&pda->curdlg, pda->dlga, sizeof(pda->curdlg)); + + hDrawWnd = GetDlgItem(hDlg, rct1); TRACE("set property to %p", pda); - SetPropA(hDlg, "__WINE_PAGESETUPDLGDATA", pda); - SetPropA(GetDlgItem(hDlg, rct1), "__WINE_PAGESETUPDLGDATA", pda); + SetPropA(hDlg, "__WINE_PAGESETUPDLGDATA", pda); + SetPropA(hDrawWnd, "__WINE_PAGESETUPDLGDATA", pda); + GetWindowRect(hDrawWnd, &pda->rtDrawRect); /* Calculating rect in client coordinates where paper draws */ + ScreenToClient(hDlg, (LPPOINT)&pda->rtDrawRect); + ScreenToClient(hDlg, (LPPOINT)(&pda->rtDrawRect.right)); lpfnStaticWndProc = (WNDPROC)SetWindowLongPtrW( - GetDlgItem(hDlg, rct1), + hDrawWnd, GWLP_WNDPROC, (ULONG_PTR)PRINTDLG_PagePaintProc); + + /* FIXME: Paint hook. Must it be at begin of initializtion or at end? */ res = TRUE; if (pda->dlga->Flags & PSD_ENABLEPAGESETUPHOOK) { res = pda->dlga->lpfnPageSetupHook(hDlg,uMsg,wParam,(LPARAM)pda->dlga); @@ -2833,8 +3092,10 @@ } } + /* if printer button disabled */ if (pda->dlga->Flags & PSD_DISABLEPRINTER) EnableWindow(GetDlgItem(hDlg, psh3), FALSE); + /* if margin edit boxes disabled */ if (pda->dlga->Flags & PSD_DISABLEMARGINS) { EnableWindow(GetDlgItem(hDlg, edt4), FALSE); EnableWindow(GetDlgItem(hDlg, edt5), FALSE); @@ -2846,6 +3107,7 @@ CheckRadioButton(hDlg, rad1, rad2, rad2); else /* this is default if papersize is not set */ CheckRadioButton(hDlg, rad1, rad2, rad1); + /* if orientation disabled */ if (pda->dlga->Flags & PSD_DISABLEORIENTATION) { EnableWindow(GetDlgItem(hDlg,rad1),FALSE); EnableWindow(GetDlgItem(hDlg,rad2),FALSE); @@ -2870,12 +3132,29 @@ SetDlgItemTextA(hDlg,edt5,str); SetDlgItemTextA(hDlg,edt6,str); SetDlgItemTextA(hDlg,edt7,str); + pda->curdlg.rtMargin.left = size; + pda->curdlg.rtMargin.top = size; + pda->curdlg.rtMargin.right = size; + pda->curdlg.rtMargin.bottom = size; } - PRINTDLG_PS_ChangePrinterA(hDlg,pda); + /* if paper disabled */ if (pda->dlga->Flags & PSD_DISABLEPAPER) { EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); } + /* filling combos: printer, paper, source. selecting current printer (from DEVMODEA) */ + PRINTDLG_PS_ChangePrinterA(hDlg, pda); + dm = GlobalLock(pda->pdlg.hDevMode); + if(dm){ + dm->dmDefaultSource = 15; /*FIXME: Automatic select. Does it always 15 at start? */ + PRINTDLG_PaperSizeA(&(pda->pdlg), dm->u1.s1.dmPaperSize, &pda->curdlg.ptPaperSize); + GlobalUnlock(pda->pdlg.hDevMode); + pda->curdlg.ptPaperSize.x = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.x); + pda->curdlg.ptPaperSize.y = _c_10mm2size(pda->dlga, pda->curdlg.ptPaperSize.y); + } else + WARN("GlobalLock(pda->pdlg.hDevMode) fail? hDevMode=%ld", (DWORD)pda->pdlg.hDevMode); + /* Drawing paper prev */ + PRINTDLG_PS_ChangePaperPrev(pda); return TRUE; } else { pda = (PageSetupDataA*)GetPropA(hDlg,"__WINE_PAGESETUPDLGDATA"); @@ -2915,6 +3194,7 @@ res = TRUE; } } + if (pda->dlga->Flags & PSD_ENABLEPAGEPAINTHOOK) { FIXME("PagePaintHook not yet implemented!\n"); } @@ -2961,6 +3241,7 @@ EnableWindow(GetDlgItem(hDlg,cmb2),FALSE); EnableWindow(GetDlgItem(hDlg,cmb3),FALSE); } + return TRUE; } else { pda = (PageSetupDataW*)GetPropW(hDlg, __WINE_PAGESETUPDLGDATA); @@ -2988,7 +3269,7 @@ * size, source, orientation and the width of the page margins. * * PARAMS - * setupdlg [in] PAGESETUPDLGA struct + * setupdlg [IO] PAGESETUPDLGA struct * * RETURNS * TRUE if the user pressed the OK button @@ -2997,12 +3278,7 @@ * NOTES * The values of hDevMode and hDevNames are filled on output and can be * changed in PAGESETUPDLG when they are passed in PageSetupDlg. - * BUGS - * PrintSetupDlg: - * * The Paper Orientation Icons are not implemented yet. - * * The Properties Button(s) should call DocumentPropertiesA(). - * * Settings are not yet taken from a provided DevMode or - * default printer settings. + * */ BOOL WINAPI PageSetupDlgA(LPPAGESETUPDLGA setupdlg) { @@ -3012,6 +3288,7 @@ PageSetupDataA *pda; PRINTDLGA pdlg; + /* TRACE */ if(TRACE_ON(commdlg)) { char flagstr[1000] = ""; struct pd_flags *pflag = psd_flags; @@ -3027,8 +3304,17 @@ setupdlg->hDevNames, setupdlg->hInstance, setupdlg->Flags, flagstr); } - if (setupdlg->Flags & PSD_ENABLEPAGEPAINTHOOK) - if (setupdlg->lpfnPagePaintHook == NULL) { + /* Checking setupdlg structure */ + if (setupdlg == NULL) { + COMDLG32_SetCommDlgExtendedError(CDERR_INITIALIZATION); + return FALSE; + } + if(setupdlg->lStructSize != sizeof(PAGESETUPDLGA)) { + COMDLG32_SetCommDlgExtendedError(CDERR_STRUCTSIZE); + return FALSE; + } + if ((setupdlg->Flags & PSD_ENABLEPAGEPAINTHOOK) && + (setupdlg->lpfnPagePaintHook == NULL)) { COMDLG32_SetCommDlgExtendedError(CDERR_NOHOOK); return FALSE; } @@ -3038,18 +3324,28 @@ pdlg.lStructSize = sizeof(pdlg); pdlg.Flags = PD_RETURNDEFAULT; bRet = PrintDlgA(&pdlg); - if (!bRet) return FALSE; - + if (!bRet){ + if(!(setupdlg->Flags & PSD_NOWARNING)){ + char errstr[256]; + LoadStringA(COMDLG32_hInstance, PD32_NO_DEFAULT_PRINTER, errstr, 255); + MessageBoxA(setupdlg->hwndOwner, errstr, 0, MB_OK | MB_ICONERROR); + } + return FALSE; + } + /* short cut exit, just return default values */ if (setupdlg->Flags & PSD_RETURNDEFAULT) { - setupdlg->hDevMode = pdlg.hDevMode; - setupdlg->hDevNames = pdlg.hDevNames; - /* FIXME: Just return "A4" for now. */ - PRINTDLG_PaperSizeA(&pdlg,"A4",&setupdlg->ptPaperSize); + DEVMODEA *dm; + + dm = GlobalLock(pdlg.hDevMode); + PRINTDLG_PaperSizeA(&pdlg, dm->u1.s1.dmPaperSize, &setupdlg->ptPaperSize); + GlobalUnlock(pdlg.hDevMode); setupdlg->ptPaperSize.x=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.x); setupdlg->ptPaperSize.y=_c_10mm2size(setupdlg,setupdlg->ptPaperSize.y); return TRUE; } + + /* get dialog template */ hDlgTmpl = PRINTDLG_GetPGSTemplateA(setupdlg); if (!hDlgTmpl) { COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); @@ -3060,6 +3356,7 @@ COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE); return FALSE; } + pda = HeapAlloc(GetProcessHeap(),0,sizeof(*pda)); pda->dlga = setupdlg; memcpy(&pda->pdlg,&pdlg,sizeof(pdlg)); @@ -3071,6 +3368,8 @@ PRINTDLG_PageDlgProcA, (LPARAM)pda) ); + + HeapFree(GetProcessHeap(),0,pda); return bRet; } /*********************************************************************** @@ -3082,6 +3381,7 @@ BOOL bRet; PageSetupDataW *pdw; PRINTDLGW pdlg; + FIXME("Unicode implementation is not done yet\n"); if(TRACE_ON(commdlg)) { char flagstr[1000] = "";