Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Visual C++/MFC/WTL > Очень непонятный глюк завершения программы в Vista


Автор: viktorrr 10.3.2010, 10:06
Доброго времени суток форумчанам. Просьба сильно не критиковать, но пишу на форум в первый раз.
Очень нужна помощь в устранении глюка.
Предистория: MFC CDialog программа для Visual Studio 2008 читает данные (х,у) из файла и выводит вначале на экран а затем на печать. Код по образцу как в официальных источниках.
При отладке использовалась Win XP и виртуальный принтер DoPDF. 
Все рисуется, печатается и отлаживается.
СУТЬ ГЛЮКА.
Проблема обнаружилась случайно при проверке программы на другом компьютере в Win Vista Basic.
Если программу запустить, открыть файл данных, сделать предварительный просмотр, НО НЕ ОТПРАВЛЯТЬ даные на печать, ТО программа закрывается и все ОК.
НО ЕСЛИ отправить задание на печать, то оно напечатается нормально, И нажав кнопку закрыть программу - программа закрывается. НО процесс программы из отладки не выходит (если запускать в режиме отладки в VisStudio), а в диспетчере задач системы наблюдается отлаживаемый (или просто запущенный) процесс (так будто его никто и не закрывал).
Если повисший процесс принудительно не завершить через диспетчер задач, то аналогичными манипуляциями можно получить еще один зависший процесс. В Windows XP все работает и завершается нормально.
Глюк наблюдался и после перекомпиляции программы в VS2008 на машине с Vista.
Также описанный глюк был и при печати из Vista на настоящий струйный принтер.
Кто знает хоть что то об этом???
- HELP - даже примерно не знаю че делать и где искать - HELP - HELP - HELP----?????


Автор: viktorrr 5.4.2010, 07:50
Всем доброго времени суток. 
К написанному выше можно добавить, что этот косяк разрешился весьма внезапно (точнее после манипуляций с флагами в поле xx.Flags структуры PRINTDLG).
Как еще один симптом могу добавить, что в рамках "Решения", в котором есть несколько проектов, был создан еще один проект. С аналогичным кодом вызова функции печати. И почему-то в этом проекте таких глюков не наблюдается.

Автор: viktorrr 5.4.2010, 08:05
Привожу код с решением проблемы:

Здесь ключевой строкой является вот эта
...
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC | PD_PRINTSETUP;
...
Если точнее, то без (..  | PD_PRINTSETUP .. ) была неполадка.

Код


int nCall_AbortProc;

BOOL CALLBACK SimpleAbortProc(HDC hDC, int iError)
{
    nCall_AbortProc ++;
    return TRUE;
}

void CPrintPrevDlg::OnLButtonDblClk(UINT nFlags, CPoint point)
{
    // TODO: добавьте свой код обработчика сообщений или вызов стандартного
    PRINTDLG pd;

    // Заполняем PRINTDLG
    ZeroMemory(&pd, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner   = this->m_hWnd ;
    pd.hDevMode    = NULL; // Не забудьте освободить или сохранить hDevMode
    pd.hDevNames   = NULL; // Не забудьте освободить или сохранить hDevNames
    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC | PD_PRINTSETUP;
    pd.nCopies     = 1;
    pd.nFromPage   = 0xFFFF;
    pd.nToPage     = 0xFFFF;
    pd.nMinPage    = 1;
    pd.nMaxPage    = 0xFFFF;

    if ( PrintDlg(&pd) )
    {
        if ( pd.hDC )
        {
            nCall_AbortProc = 0;
            SetAbortProc(pd.hDC, SimpleAbortProc);

            DOCINFO docinfo;
            docinfo.cbSize       = sizeof(docinfo);
            docinfo.lpszDocName  = _T("SimpleMultiPrint");
            docinfo.lpszOutput   = NULL; 
            docinfo.lpszDatatype = _T("EMF");
            docinfo.fwType         = 0; 

            if ( StartDoc(pd.hDC, & docinfo) > 0 )
            {
                for (int p=0; p<pd.nCopies; p++) // one page at a time
                    if ( StartPage(pd.hDC) <= 0 )
                        break;
                    else
                    {
                        int width  = GetDeviceCaps(pd.hDC, HORZRES);
                        int height = GetDeviceCaps(pd.hDC, VERTRES);
                        int dpix   = GetDeviceCaps(pd.hDC, LOGPIXELSX);
                        int dpiy   = GetDeviceCaps(pd.hDC, LOGPIXELSY);
                        int wx   = GetDeviceCaps(pd.hDC, PHYSICALWIDTH);
                        int hy   = GetDeviceCaps(pd.hDC, PHYSICALHEIGHT);
                        int noprintx   = GetDeviceCaps(pd.hDC, PHYSICALOFFSETX);
                        int noprinty   = GetDeviceCaps(pd.hDC, PHYSICALOFFSETY);
                

                                       // ЭТОТ ФРАГМЕНТ ВЫВОДИТ НА КОНТЕКСТ ПРИНТЕРА ГРАФИК
                        // печать самого графика
                        int SavedDCindex = SaveDC(pd.hDC);

                        CRect tmpRct(noprintx, noprinty, width, height);

                        double dpiKscale  = (double)GetDeviceCaps(pd.hDC, LOGPIXELSX) / 96.0;

                        tmpRct.DeflateRect(    (int)(dpiKscale*(dBorderLeft+10.0)), 
                                            (int)(dpiKscale*(dBorderTop+10.0)),
                                            (int)(dpiKscale*(dBorderRight+10.0)), 
                                            (int)(dpiKscale*(dBorderBottom+10.0))
                                            );

                        m_Grafik.Init(pd.hDC, tmpRct, pDataFile_ARR, pDataFile_ARR_Size);
                        m_Grafik.DrawGrafikToDC();
                                       // КОНЕЦ ФРАГМЕНТА




                        RestoreDC(pd.hDC, SavedDCindex);

                        if ( EndPage(pd.hDC)<0 )
                            break;
                    }
                EndDoc(pd.hDC);
            }

        }
    }

    if (pd.hDC != NULL)   DeleteDC(pd.hDC);
    if (pd.hDevMode != NULL)   GlobalFree(pd.hDevMode); 
    if (pd.hDevNames != NULL)  GlobalFree(pd.hDevNames); 



    CDialog::OnLButtonDblClk(nFlags, point);
}



Автор: viktorrr 5.4.2010, 08:33
ТАКЖЕ без опции ..  | PD_PRINTSETUP ..  диалоговое окно настройки печати выглядело вот так:

Автор: viktorrr 5.4.2010, 08:35
с опцией ..  | PD_PRINTSETUP ..  ----- вот так:
(не так красиво как прежде :(  но зато заработало)

Добавлено через 2 минуты и 44 секунды
таким образом (хоть и непонятно как именно, наверное с помощью  smile  танцев с бубном)
проблема была решена и вопрос для меня уже закрыт.

Автор: Earnest 5.4.2010, 10:47
viktorrr,  проблема не близка, но за то, что привел решение, спасибо. Возможно, кому-то поможет.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)