Asignar impresora a CPageSetupDialog

11/10/2004 - 17:53 por Jordi | Informe spam
Hola!

Estoy intentando asignar una impresora, que no tiene porque ser la impresora
por defecto del sistema a CPageSetupDialog. El problema que tengo es que al
hacer el DoModal me da el Error:
"La instrucción en '0x79454c58' hace referencia a la memoria en
'0x0013fea7'. La memoria no se puede 'read'"
A continuación añado el código que utilizo a ver si podeis indicarme el
camino a seguir para corregir el fallo que tengo.

Gracias de antemano.
Jordi.

void CMiClase::OnPageCfg( )
{
CString sPrinterName,sPortName,sDriverName;
CPageSetupDialog dlg;
PAGESETUPDLG& psd = dlg.m_psd;
psd.Flags |= PSD_MARGINS | PSD_INHUNDREDTHSOFMILLIMETERS |
PSD_DISABLEORIENTATION | PSD_DISABLEPAPER ;

RECT rcMargins;
GetMargins( rcMargins, 1 );// Obtengo Margenes a asignar en mm
psd.rtMargin.left = rcMargins.left * 100;
psd.rtMargin.top = rcMargins.top * 100;
psd.rtMargin.right = rcMargins.right * 100;
psd.rtMargin.bottom = rcMargins.bottom * 100;
//
GetPrinterDoc( sPrinterName, sPortName, sDriverName );//Obtengo la
impresora que quiero asignar CPageSetupDialog

////////////////////////////////////
// Si ha una impresora seleccionada
if(!sPrinterName.IsEmpty())
{
LPDEVNAMES ptrdevnames_psd;
LPDEVMODE ptrdevmode_psd;
LPDEVMODE pDevMode = NULL;
LPDEVNAMES pDevNames = NULL;
LPSTR sgzPrinterName;
sgzPrinterName = sPrinterName.GetBuffer(0);
if(GetDevModeNamesPrinter(sgzPrinterName, pDevMode, pDevNames))
{
if (psd.hDevNames) GlobalFree(psd.hDevNames);
if (psd.hDevMode) GlobalFree(psd.hDevMode);

psd.hDevNames = GlobalAlloc(GPTR, GlobalSize (pDevNames));
psd.hDevMode = GlobalAlloc(GPTR, GlobalSize (pDevMode));
ptrdevnames_psd = (LPDEVNAMES) GlobalLock(psd.hDevNames);
ptrdevmode_psd = (LPDEVMODE) GlobalLock(psd.hDevMode);

memcpy(ptrdevnames_psd,pDevNames, (size_t) GlobalSize
(pDevNames));
memcpy(ptrdevmode_psd,pDevMode, (size_t) GlobalSize (pDevMode));

GlobalUnlock(pDevMode);
GlobalUnlock(pDevMode);
GlobalUnlock(ptrdevmode_psd);
GlobalUnlock(ptrdevnames_psd);
}
else
{
psd.hDevNames = NULL;
psd.hDevMode = NULL;
}
sPrinterName.ReleaseBuffer();
}
else
{
psd.hDevNames = NULL;
psd.hDevMode = NULL;
}

if (dlg.DoModal() == IDOK) // < Aqui se produce el error!!!
{
.
}
}

BOOL CMiClase::GetDevModeNamesPrinter(char* pszDeviceName, LPDEVMODE&
pDevMode, LPDEVNAMES& pDevNames)
{
BOOL bReturn = TRUE;
//Open printer and obtain PRINTER_INFO_2 structure.
HANDLE hPrinter;
if (::OpenPrinter(pszDeviceName, &hPrinter, NULL) == FALSE)
return FALSE;
DWORD dwBytesReturned, dwBytesNeeded;
::GetPrinter(hPrinter,2,NULL,0,&dwBytesNeeded);
PRINTER_INFO_2* p2 = (PRINTER_INFO_2*)GlobalAlloc(GPTR,dwBytesNeeded);
if(::GetPrinter(hPrinter,2,(LPBYTE)p2,dwBytesNeeded,&dwBytesReturned) == 0)
{
::GlobalFree(p2);
::ClosePrinter(hPrinter);
return FALSE;
}
::ClosePrinter(hPrinter);

/////////////////////////////////////////////////////////////
//Allocate a global handle for DEVMODE and copy DEVMODE data.
HGLOBAL hDevMode = GlobalAlloc(GHND, sizeof(*p2->pDevMode));
/*DEVMODE* */pDevMode = (DEVMODE*)GlobalLock(hDevMode);
memcpy(pDevMode, p2->pDevMode, sizeof(*p2->pDevMode));
::GlobalUnlock(hDevMode);

//////////////////////////////////////////////////////
//Allocate a global handle for the DEVNAMES structure.

// Start by figuring out how big it needs to be.
DWORD drvNameLen = strlen(p2->pDriverName);
DWORD ptrNameLen = strlen(p2->pPrinterName);
DWORD porNameLen = strlen(p2->pPortName);
DWORD devNameSize = sizeof(DEVNAMES) + ptrNameLen + drvNameLen + porNameLen
+ 3;

// Then allocate a properly sized handle.
HGLOBAL hDevNames = GlobalAlloc(GHND, devNameSize);
/*DEVNAMES**/ pDevNames = (DEVNAMES*) GlobalLock(hDevNames);

//////////////////////////////////////////////////////
//Copy DEVNAMES info into the DEVNAMES Structure

// Device driver info to DEVNAMES
pDevNames->wDeviceOffset = sizeof(DEVNAMES);
memcpy((char*)pDevNames +
pDevNames->wDriverOffset,p2->pDriverName,drvNameLen);

// Printer Name infor to DEVNAMES
pDevNames->wDeviceOffset = sizeof(DEVNAMES) + drvNameLen + 1;
memcpy((char*)pDevNames +
pDevNames->wDeviceOffset,p2->pPrinterName,ptrNameLen);

// Printer Name infor to DEVNAMES
pDevNames->wOutputOffset = sizeof(DEVNAMES) + drvNameLen + ptrNameLen + 2;
memcpy((char*)pDevNames +
pDevNames->wOutputOffset,p2->pPortName,porNameLen);

// Set the default flag to false.
pDevNames->wDefault = 0;
GlobalUnlock(hDevNames);

::GlobalFree(p2);

if(!pDevMode)
bReturn = FALSE;

return bReturn;
}
 

Leer las respuestas

#1 Rodrigo Corral [MVP]
11/10/2004 - 19:00 | Informe spam
Al ejecutar que linea de ese código se produce el error?


Un saludo
Rodrigo Corral González [MVP]

FAQ de microsoft.public.es.vc++
http://rcorral.mvps.org

Preguntas similares