#c #mfc #windows-ce
#c #mfc #windows-ce
Вопрос:
У меня проблема с CreateDC
функцией. После вызова hDC
дескриптора он возвращается NULL
.
Это фрагмент кода, в котором вызывается функция после нажатия кнопки. m_pPrint
является указателем на Print
класс, в котором определены функции, связанные с контекстом устройства. Он инициализируется как
m_pPrint = new Print
void MainMenuDlg::OnBnClickedMenuPrint()
{
int nPatientID = m_patientsDlg->m_pCurrSelData->nPatientId;
int nExamID = m_patientsDlg->m_pCurrSelData->nExamId;
m_outPrintingManager->PrintEcgSignal(nPatientID, nExamID);
short* sigPointer = m_outPrintingManager->GetSamplesPointer();
m_pPrint->PrinterInit();
m_pPrint->PageSetup();
m_pPrint->StartPrint();
m_pPrint->SignalAdjust(80,1000);
m_pPrint->DrawECG(sigPointer, 12, 9000);
m_pPrint->EndPrint();
}
Это заголовочный файл Print
класса
class Print
{
protected:
HWND hwnd;
CDC hDC;
int start_x;
int start_y;
//LPCWSTR captions[12] = { L" I ", L" II", L"III", L"aVR", L" aVL ", L"aVF", L"V1", L"V2", L"V3", L"V4", L"V5", L"V6" };
LPCWSTR captions[12];
int limit_x;
int limit_y;
int printmode;
int width;
int new_sign_len;
int channel_nr;
int startSample;
int channels[13];
int mode;
float sig_speed;
float amplitude;
int offset;
int channel_start;
int channel_stop;
int tmp_channel;
float frequency;
int space;
int page;
BOOL orientation;
public:
Print();
~Print();
int Print();
BOOL PrinterInit();
BOOL PageSetup();
BOOL StartPrint();
BOOL DrawGrid(int start_x, int start_y, int limit_x, int limit_y, int width);
BOOL EndPrint();
void DrawECG(short * pointer, int channel_nr, int channelLength);
void SignalAdjust(int start_x, int limit_x);
void rysujEKG_Vertical(short * pointer, int start_x = 20, int limit = 1100, int offset = 60);
void rysujEKG_Horizont(short * pointer, int start_x, int limit, int offset);
void setSpeed(float s);
void setAmplitude(float a);
void setPrintMode(int printmod);
void setChannelStart(int chan_start);
void setChannelOrder(int * pointer_channel);
void setChannelStop(int chan_stop);
void setChannelNr(int chan_nr);
void setSpace(int sp);
void setPage(int pg);
void setSignalLength(int sl);
void setOrientation(int orient);
void setStartSample(int startsample);
float getSpeed();
float getAmplitude();
float getFrequency();
int getChannelNr();
int getPrintMode();
int getChannelStart();
int getChannelStop();
int getSpace();
void DrawScaleVertic(int x, int y);
void DrawExaminationTextBox_Horizont(int start_x, int start_y, int stop_y);
}
;
И функция PageSetup
, которая CreateDC
вызывает. hDC
является CDC
типом. Инициализируется как CDC hDC
BOOL Print::PageSetup()
{
ZeroMemory(amp;psd, sizeof(psd));
psd.lStructSize = sizeof(psd); // psd is member of PAGESETUPDLG structure
psd.hwndOwner = NULL;
psd.hDevMode = hMode; // Don't forget to free or store hDevMode.
psd.hDevNames = hNames; // Don't forget to free or store hDevNames.
psd.Flags = PSD_INHUNDREDTHSOFMILLIMETERS | PSD_MARGINS | PSD_MINMARGINS;
psd.rtMargin.top = user_margins.top;
psd.rtMargin.left = user_margins.left;
psd.rtMargin.right = user_margins.right;
psd.rtMargin.bottom = user_margins.bottom;
psd.rtMinMargin.top = 100;
psd.rtMinMargin.left = 100;
psd.rtMinMargin.right = 100;
psd.rtMinMargin.bottom = 100;
psd.ptPaperSize.x = papersize.x;
psd.ptPaperSize.y = papersize.y;
psd.lpfnPagePaintHook = NULL;
lf_vertic.lfHeight = 30; // is member of LOGFONT structure
lf_vertic.lfWidth = 0;
//lf.lfOrientation = 2700;
lf_vertic.lfEscapement = 0;
lf_vertic.lfUnderline = FALSE;
lf_vertic.lfWeight = FW_BOLD;
lf_horizont.lfHeight = 30;
lf_horizont.lfWidth = 0;
//lf.lfOrientation = 2700;
lf_horizont.lfEscapement = 2700;
lf_horizont.lfUnderline = FALSE;
lf_horizont.lfWeight = FW_BOLD;
lf_exam_param.lfHeight = 30;
lf_exam_param.lfWidth = 0;
lf_exam_param.lfEscapement = 2700;
lf_exam_param.lfUnderline = FALSE;
lf_exam_param.lfWeight = FW_NORMAL;
hFontVertic = CreateFontIndirect(amp;lf_vertic);
hFontHorizont = CreateFontIndirect(amp;lf_horizont);
hFontExamParam = CreateFontIndirect(amp;lf_exam_param);
PRINTDLG pd;
pd.hwndOwner = NULL;
pd.rcMargin.top = 3000;
if (PageSetupDlg(amp;psd) == TRUE)
{
memcpy(amp;dm, (DEVMODE *)(psd.hDevMode), sizeof(DEVMODE));
lstrcpy(DriverName, ((TCHAR *)((BYTE *)psd.hDevNames ((DEVNAMES *)psd.hDevNames)->wDriverOffset)));
lstrcpy(DeviceName, ((TCHAR *)((BYTE *)psd.hDevNames ((DEVNAMES *)psd.hDevNames)->wDeviceOffset)));
lstrcpy(OutputName, ((TCHAR *)((BYTE *)psd.hDevNames ((DEVNAMES *)psd.hDevNames)->wOutputOffset)));
lstrcpy(OutputName, ((TCHAR *)((BYTE *)psd.hDevNames ((DEVNAMES *)psd.hDevNames)->wOutputOffset)));
user_margins.left = psd.rtMargin.left;
user_margins.right = psd.rtMargin.right;
user_margins.bottom = psd.rtMargin.bottom;
user_margins.top = psd.rtMargin.top;
papersize.x = psd.ptPaperSize.x;
papersize.y = psd.ptPaperSize.y;
dm.dmPrintQuality = 300;
dm.dmPaperSize = DMPAPER_A4;
hDC.CreateDC(DriverName, DeviceName, OutputName, amp;dm);
return TRUE;
}
Комментарии:
1. Если CreateDC возвращает значение null, вызовите GetLastError, чтобы получить представление о причине сбоя.
2. Элемент
hDevMode
PAGESETUPDLGA содержит дескриптор объекта DEVMODE. Вы уверены, что можете просто привести его к aDEVOMOD*
. Я бы проверил, что члены структуры DEVMODE правдоподобны. Обычно HGLOBAL требует GlobalLock для получения указателя на данные. — Поскольку вы запускаете ее в отладчике, должно быть достаточно распечатать структуру DEMOVE в журнале отладчика.3. @500 CreateDC (как и большинство GDI) предшествует введению отчетов об ошибках для каждого потока. При сбое не будет установлена последняя ошибка вызывающего потока.
4. @IInspectable: документация Windows CE SDK предполагает это.
5. Windows CE — это другая ОС. Он не использует ни свое ядро, ни оконный код с линейкой продуктов NT. Его API похож на Windows API, хотя часто с разными контрактами (как в этом случае). Вызов
GetLastError
в ответ на неудачный вызовCreateDC
в Windows не вернет значимого значения.
Ответ №1:
Когда я работаю со DEVMODE
структурой, я делаю это так:
void CCommunityTalksApp::GetPageSettings(CPrintInfo *pInfo, short amp;dmPaperSize, short amp;dmOrientation)
{
PRINTDLG pd;
DEVMODE FAR *pDevMode = nullptr;
pd.lStructSize = (DWORD)sizeof(PRINTDLG);
if(pInfo == nullptr)
{
if(GetPrinterDeviceDefaults(amp;pd))
{
// protect memory handle with ::GlobalLock and ::GlobalUnlock
pDevMode=(DEVMODE FAR *)::GlobalLock(m_hDevMode);
}
}
else
{
// protect memory handle with ::GlobalLock and ::GlobalUnlock
pDevMode=(DEVMODE FAR *)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode);
}
if(pDevMode != nullptr)
{
// is it set to landscape
dmPaperSize = pDevMode->dmPaperSize;
dmOrientation = pDevMode->dmOrientation;
}
if(pInfo == nullptr)
{
::GlobalUnlock(m_hDevMode);
}
else
{
::GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode);
}
}
Как вы можете видеть, я использую методы ::GlobalLock
и ::GlobalUnlock
:
pDevMode=(DEVMODE FAR *)::GlobalLock(m_hDevMode)
pDevMode=(DEVMODE FAR *)::GlobalLock(pInfo->m_pPD->m_pd.hDevMode)
::GlobalUnlock(m_hDevMode)
::GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode)