Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование CPrintDialog, Ошибки при печати 
:(
    Опции темы
Tiffany
  Дата 4.4.2011, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 23.12.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



В программе рисуется график во View'шке.. Требуется реализовать печать этого графика.
Кое-как вроде получилось, осталось доработать пересчет координат, печатает в целом нормально, НО есть две проблемы:
1) если производилась печать, то позже прога вылетает (при нормальном выходе из приложения)
2) если один раз распечатали, и пытаемся это повторить - тоже эррор =(

Места ошибок обозначила в коде:


Код

void IPChartDlg::OnFilePrintSetup()
{
    CPrintDialog a_Dlg(false, PD_RETURNDC | PD_ALLPAGES | PD_USEDEVMODECOPIES | PD_NOPAGENUMS | PD_HIDEPRINTTOFILE | PD_NOSELECTION);

    PRINTDLG a_PD;
    a_PD.hDevMode = NULL;
    AfxGetApp()->GetPrinterDeviceDefaults(&a_PD);

    DEVMODE *a_dm = (DEVMODE *)LocalLock(a_PD.hDevMode);
/*ВОТ ТУТ ВЫЛЕТАЕТ ПРИ ПОВТОРНОЙ ПЕЧАТИ----->*/    a_dm->dmFields = DM_ORIENTATION;
    a_dm->dmOrientation = DMORIENT_LANDSCAPE; 

    a_Dlg.m_pd.hDevMode = a_PD.hDevMode;
    LocalUnlock(a_PD.hDevMode);

    if(a_Dlg.DoModal() == IDCANCEL)
        return;

    CDC a_dcPrinter;
    a_dcPrinter.Attach(a_Dlg.GetPrinterDC());
    
    DOCINFO a_DocInfo;
    memset(&a_DocInfo, 0, sizeof(a_DocInfo));
    a_DocInfo.cbSize = sizeof(a_DocInfo);
    a_DocInfo.lpszDocName = _T("IPChart document");

    if(a_dcPrinter.StartDoc(&a_DocInfo) < 0) 
    {
        AfxMessageBox(L"Error starting document!", MB_ICONSTOP);
        a_dcPrinter.AbortDoc(); 
        a_dcPrinter.Detach();
        a_dcPrinter.DeleteDC();
        return;
    }

    CPrintInfo a_Info;

    int a_HorRes = a_dcPrinter.GetDeviceCaps(HORZRES);
    int a_VertRes = a_dcPrinter.GetDeviceCaps(VERTRES);
    a_Info.m_rectDraw.SetRect(0, 0, a_HorRes, a_VertRes);

    if (a_dcPrinter.StartPage() < 0) 
    { 
        AfxMessageBox(_T("Error starting page"), MB_ICONSTOP); 
        a_dcPrinter.AbortDoc(); 
        a_dcPrinter.Detach();
        a_dcPrinter.DeleteDC();
        return;
    }
    
    a_dcPrinter.m_bPrinting = true;
    
    m_MainView.printPlot(&a_dcPrinter, &a_Info);

    if(a_dcPrinter.EndPage() < 0)
    {
        AfxMessageBox(L"Error ending page!", MB_ICONSTOP);
        a_dcPrinter.AbortDoc();
        a_dcPrinter.Detach();
        a_dcPrinter.DeleteDC();
        return;
    }
    if(a_dcPrinter.EndDoc() < 0)
    {
        AfxMessageBox(L"Error ending document!", MB_ICONSTOP);
        a_dcPrinter.AbortDoc();
    }
    a_dcPrinter.Detach();
    a_dcPrinter.DeleteDC();
}



в winutil.cpp


Код

void AFXAPI AfxGlobalFree(HGLOBAL hGlobal)
{
    if (hGlobal == NULL)
        return;

    // avoid bogus warning error messages from various debugging tools
/*ВОТ ТУТ ВЫЛЕТАЕТ ПРИ ВЫХОДЕ ИЗ ПРИЛОЖЕНИЯ----->*/    ASSERT(GlobalFlags(hGlobal) != GMEM_INVALID_HANDLE);
    UINT nCount = GlobalFlags(hGlobal) & GMEM_LOCKCOUNT;
    while (nCount--)
        GlobalUnlock(hGlobal);

    // finally, really free the handle
    GlobalFree(hGlobal);
}



Помогите, кто чем может....  smile 
PM MAIL   Вверх
Earnest
Дата 5.4.2011, 06:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 87
Всего: 183



Что показывает отладчик в первом и втором случаях?
В первом коде, похоже, что-то не так с dm...
Кроме того, в структуре PRINTDLG  нужно обязательно заполнить первое поле, перед тем как куда-то передавать:
a_PD.dwSize = sizeof (a_PD);
Второй вылет - скорее всего результат первого; видимо, срабатывает ASSERT.


--------------------
...
PM   Вверх
Tiffany
Дата 6.4.2011, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 23.12.2006
Где: Санкт-Петербург

Репутация: нет
Всего: нет



Earnest, про отладчик не поняла..
Поправлю: вместо a_PD.dwSize следует писать a_PD.lpStructSize

Ну да, дело в dm и в Ассерте - это понятно..
При повторной печати у dm оказывается "bad ptr", то есть вроде как он теряется, хотя, по идее, там все заново должно создаваться.
Интересный момент, что если вместо 
Код

 DEVMODE *a_dm = (DEVMODE *)LocalLock(a_PD.hDevMode);
 a_dm->dmFields = DM_ORIENTATION;
 a_dm->dmOrientation = DMORIENT_LANDSCAPE; 
 a_Dlg.m_pd.hDevMode = a_PD.hDevMode;
 LocalUnlock(a_PD.hDevMode);

написать
Код

 DEVMODE a_dm;
 a_dm->dmFields = DM_ORIENTATION;
 a_dm->dmOrientation = DMORIENT_LANDSCAPE; 
 a_Dlg.m_pd.hDevMode = a_PD.hDevMode;
 

, то печатает сколько угодно раз, но с параметрами "по умолчанию"(у меня было вертикальное расположение листа вместо желаемого горизонтального).. Ошибка при выходе из программы сохраняется.
В MSDN что-то написано про то, как работать с DEVMODE и с блоками памяти, только все никак не могу понять, что там куда установить правильно, может кто сталкивался?...

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0425 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.