// DirectMailDlg.cpp : implementation file // #include "stdafx.h" #include "DirectMail.h" #include "DirectMailDlg.h" #include #include #include #include #include #ifdef _DEBUG #define new DEBUG_NEW #endif // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data enum { IDD = IDD_ABOUTBOX }; protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support // Implementation protected: DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP() // CDirectMailDlg dialog CDirectMailDlg::CDirectMailDlg(CWnd* pParent /*=NULL*/) : CDialog(CDirectMailDlg::IDD, pParent) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDirectMailDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); } BEGIN_MESSAGE_MAP(CDirectMailDlg, CDialog) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() //}}AFX_MSG_MAP ON_BN_CLICKED(IDOK, &CDirectMailDlg::OnBnClickedOk) END_MESSAGE_MAP() // CDirectMailDlg message handlers BOOL CDirectMailDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here m_tabAddresses.push_back(std::string(_T("Prenom NOM\r\nAdresse 1\r\nAdresse 2\r\nCP Ville"))); m_tabAddresses.push_back(std::string(_T("Prenom NOM\r\nAdresse 1\r\nAdresse 2\r\nCP Ville"))); m_tabAddresses.push_back(std::string(_T("Prenom NOM\r\nAdresse 1\r\nAdresse 2\r\nCP Ville"))); return TRUE; // return TRUE unless you set the focus to a control } void CDirectMailDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDirectMailDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this function to obtain the cursor to display while the user drags // the minimized window. HCURSOR CDirectMailDlg::OnQueryDragIcon() { return static_cast(m_hIcon); } /*----------------------------------------------------------------------------------* * PrepareImpression() * *----------------------------------------------------------------------------------* * Description : Prépare l'impression avec tous ses paramètres * * * * Algorithme : * * * *----------------------------------------------------------------------------------* * Entrées: Aucunes * *----------------------------------------------------------------------------------* * Sorties: TRUE : Impression prete a etre faite * * FALSE : Erreur lors de la préparation à l'impression * *----------------------------------------------------------------------------------*/ BOOL CDirectMailDlg::PrepareImpression() { //-------------------------------------------------------------------------- // Charge le driver de l'imprimante destination //-------------------------------------------------------------------------- HANDLE hDriver; if( (::OpenPrinter(_T("LZ_DIRECT_MAILING_2"),&hDriver,NULL) == 0) || (hDriver == NULL) ) { AfficheErreur(_T("::OpenPrinter")); return FALSE; } //-------------------------------------------------------------------------- // Récupère les informations sur l'imprimante utilisée //-------------------------------------------------------------------------- PRINTER_INFO_2 * pPrnInfo; DWORD ccBytes = 0; // Le premier appel permet de connaitre la taille requise pour les données ::GetPrinter(hDriver, 2, NULL, 0, reinterpret_cast(&ccBytes)); pPrnInfo = (PRINTER_INFO_2 *)malloc(ccBytes); if ( pPrnInfo != NULL ) { if ( ::GetPrinter(hDriver, 2, reinterpret_cast(pPrnInfo), ccBytes, reinterpret_cast(&ccBytes)) == 0 ) { AfficheErreur(_T("::GetPrinter")); return FALSE; } } else { AfficheErreur(_T("malloc")); return FALSE; } DWORD dwBufSize = 0; LPDEVMODE lpDM; //-------------------------------------------------------------------------- // Récupération du DEVMODE pour l'imprimante //-------------------------------------------------------------------------- // Le premier appel permet de connaître la taille nécessaire à allouer pour les informations dwBufSize =::DocumentProperties( NULL, (HANDLE)hDriver, (LPSTR)pPrnInfo->pDevMode->dmDeviceName, (LPDEVMODE)NULL, (LPDEVMODE)NULL, (DWORD) 0); // Allocation mémoire pour le DEVMODE HANDLE hDevMode = GlobalAlloc(GMEM_MOVEABLE, dwBufSize); lpDM = (LPDEVMODE)GlobalLock(hDevMode); // Récupération du DEVMODE dwBufSize = ::DocumentProperties(NULL, (HANDLE)hDriver, (LPSTR)pPrnInfo->pDevMode->dmDeviceName, (LPDEVMODE)lpDM, (LPDEVMODE)NULL, (DWORD)DM_COPY); lpDM->dmOrientation = DMORIENT_LANDSCAPE; lpDM->dmPaperSize = DMPAPER_ENV_C5; // Change le type de papier lpDM->dmDefaultSource = DMBIN_MIDDLE; // Change la source de papier // On indique quels sont les éléments qu'on a modifié lpDM->dmFields = DM_ORIENTATION | DM_PAPERSIZE | DM_DEFAULTSOURCE; // On renvoie le DEVMODE pour fixer les nouvelles options d'impression dwBufSize = ::DocumentProperties(NULL, (HANDLE)hDriver, (LPSTR)pPrnInfo->pDevMode->dmDeviceName, (LPDEVMODE)lpDM, (LPDEVMODE)lpDM, (DWORD)DM_IN_BUFFER | DM_OUT_BUFFER); // Fermeture du driver ClosePrinter(hDriver); //-------------------------------------------------------------------------- // Création d'un DC pour l'imprimante (nous permet de dessiner dessus) //-------------------------------------------------------------------------- m_pPrinterDC = new CDC; m_pPrinterDC->CreateDC(pPrnInfo->pDriverName, (LPCTSTR)pPrnInfo->pDevMode->dmDeviceName,NULL,lpDM); m_pPrinterDC->m_bPrinting = TRUE; //-------------------------------------------------------------------------- // Libération mémoire pour les informations de l'imprimante //-------------------------------------------------------------------------- free(pPrnInfo); //-------------------------------------------------------------------------- // Libère la mémoire pour le DEVMODE //-------------------------------------------------------------------------- ::GlobalUnlock(m_hDevMode); //-------------------------------------------------------------------------- // //-------------------------------------------------------------------------- CFont fontText; CSize sizeText; fontText.CreateFont(16 * 10, 0, 0, 0, 700, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, _T("Monotype Corsiva")); m_pOldFont = (CFont*) m_pPrinterDC->SelectObject(&fontText); m_pPrinterDC->GetTextMetrics(&m_tmPrint); return TRUE; } /*----------------------------------------------------------------------------------* * ImprimeEnveloppe() * *----------------------------------------------------------------------------------* * Description : Impression d'une enveloppe * * * * Algorithme : * * On commence l'impression en appelant StartDoc(). Puis la chaîne est découpée * * en utilisant les séparateurs \n\r pour en faire plusieurs lignes distinctes. * * Chaque ligne est ensuite imprimée (TextOut()) à une position donnée (PosX, PosY) * * et la position suivante est calculée en fonction de la hauteur des caractères. * *----------------------------------------------------------------------------------* * Entrées: lpszAdresse : Adresse à imprimer sur l'enveloppe * *----------------------------------------------------------------------------------* * Sorties: TRUE : Impression effectuée * * FALSE : Impression en erreur * *----------------------------------------------------------------------------------*/ BOOL CDirectMailDlg::ImprimeEnveloppe(const char * lpszAdresse) { DOCINFO di; ::ZeroMemory (&di, sizeof (DOCINFO)); di.cbSize = sizeof (DOCINFO); di.lpszDocName = "DirectMailing"; BOOL bRet=TRUE; // // start document printing process // if (m_pPrinterDC->StartDoc(&di)!= SP_ERROR) { m_pPrinterDC->StartPage (); int nPosX = 2700; int nPosY = 1800; // // Supprime les \n // std::string strAdresse = lpszAdresse; strAdresse.erase(std::remove_if(strAdresse.begin(), strAdresse.end(), std::bind2nd(std::equal_to(), '\n')), strAdresse.end()); // // Extrait chaque ligne // std::istringstream iss(strAdresse); std::string strMot; while ( std::getline(iss, strMot, '\r') ) { // Dessine le texte m_pPrinterDC->TextOut(nPosX, nPosY, strMot.c_str(), strMot.length()); // Calcule la position suivante pour le texte nPosY += m_tmPrint.tmHeight + m_tmPrint.tmExternalLeading; } // // Indique la fin de page et la fin de l'impression // m_pPrinterDC->EndPage(); // fin de page m_pPrinterDC->EndDoc(); } else { AfficheErreur(_T("StartDoc")); return FALSE; } return TRUE; } /*----------------------------------------------------------------------------------* * TermineImpression() * *----------------------------------------------------------------------------------* * Description : Libère les ressources utilisées pour l'impression * * * * Algorithme : Pour une utilisation par d'autres, on replace la fonte utilisée * * avant notre intervention. * * On libère le DC de l'imprimante. * * On libère la mémoire allouée pour le DEVMODE. * *----------------------------------------------------------------------------------* * Entrées: Aucunes * *----------------------------------------------------------------------------------* * Sorties: TRUE * *----------------------------------------------------------------------------------*/ BOOL CDirectMailDlg::TermineImpression() { // // On remet l'ancienne police d'écriture de l'imprimante // m_pPrinterDC->SelectObject(m_pOldFont); // // Libération du DC relatif a l'imprimante // delete m_pPrinterDC; // // Libération de la mémoire allouée pour les caractéristiques de l'imprimante // if( m_hDevMode != NULL ) { DEVMODE FAR* pDevMode =(DEVMODE FAR*)GlobalLock(m_hDevMode); ::GlobalFree(m_hDevMode); } return TRUE; } /*----------------------------------------------------------------------------------* * * *----------------------------------------------------------------------------------* * Description : * * * * Algorithme : * * * *----------------------------------------------------------------------------------* * Entrées: Aucunes * *----------------------------------------------------------------------------------* * Sorties: TRUE * *----------------------------------------------------------------------------------*/ void CDirectMailDlg::AfficheErreur(const char * lpszFunction) { LPVOID lpMsgBuf; DWORD dwError = GetLastError(); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); std::ostringstream ossMessage; ossMessage << (LPCTSTR)lpszFunction << _T(" failed with error ") << dwError << _T(" : ") << (LPCTSTR)lpMsgBuf; AfxMessageBox(ossMessage.str().c_str(), MB_ICONEXCLAMATION + MB_OK); LocalFree(lpMsgBuf); } void CDirectMailDlg::OnBnClickedOk() { BOOL bRet = TRUE; //-------------------------------------------------------------------------- // Préparation de l'impression, choix imprimante... bac... format papier... //-------------------------------------------------------------------------- bRet = PrepareImpression(); if ( bRet == FALSE ) { // Gestion d'erreur. // On doit continuer le traitement de validation de la commande } //-------------------------------------------------------------------------- // Impression de toutes les enveloppes //-------------------------------------------------------------------------- std::vector::const_iterator itAddresses; for ( itAddresses = m_tabAddresses.begin() ; itAddresses != m_tabAddresses.end() ; ++itAddresses ) { if ( (bRet == TRUE) && (ImprimeEnveloppe((*itAddresses).c_str()) == FALSE) ) { // Gestion d'erreur. } } //-------------------------------------------------------------------------- // Libération des ressources allouées pour l'impression //-------------------------------------------------------------------------- if ( bRet == TRUE ) { TermineImpression(); } }