jueves, abril 03, 2008

Mantenimiento con "LinQ to SQL"/"Entity Data Model (EDM)"

En Visual Studio 2008 aparece LinQ, y en el Framework 3.5, EDM (Entity Data Model).

A continuación explico brevemente cómo hacer un mantenimiento básico con esto (sólo el modelado de entidades, no la capa de presentación):

1) Abrir un proyecto de Visual Studio 2008 de WinForms (p.e.).
2) Añadir un nuevo item de tipo "LinQ to SQL Classes". Se abre un "designer" para modelar la entidad.
3) Arrastrar desde el Server Explorer las tablas que formen parte de la entidad (p.e. Orders y OrderDetails). Esto crea un "DataContext".

4) Desde el interface se utiliza el "DataContext" para obtener la lista completa o cada uno de los elementos de la entidad. Por ejemplo, con "Orders":

MiDataContext dc = new MiDataContext();

//Obtener una "order" (Acceso a la BDD)
Order order1 = dc.Orders.First();

//Modificar la "order"
order1.ShipCountry = "Spain";

//Insertar nueva "order"
Order order2 = new Order();
order2.ShipCity = "Barcelona";
order2.InsertOnSubmit();

//Eliminar una "order"
dc.Orders.DeleteOnSubmit(dc.Orders.Where(/*...*/));

//Persistir cambios (en la BDD)
dc.SubmitChanges();

miércoles, abril 02, 2008

Impresión matricial en C


// A continuación se explican 2 maneras de generar una impresión matricial.
// 1) En RawDataFileToPrinter() se utiliza la estructura AddJob/ScheduleJob.
// Utilizando GetJob() se puede obtener el nombre del fichero de impresión
// por si tengo que hacer cosas con él (p.e. en entorno ASP).
// 2) En RawDataFileToPrinter2() se utiliza la estructura
// StartDocPrinter/WritePrinter, porque con 1) no se puede acceder a
// impresoras de red desde S.O. basados en W2000.
//
// NOTA: Para impresión no matricial de un WMF se utiliza PlayMetafile(hPrinter,WMF...)


//Jaac 23/07/2002
// Copiada de MSDN!!!
// RawDataToPrinter - sends binary data directly to a printer
//
// szPrinterName: NULL-terminated string specifying printer name
// lpData: Pointer to raw data bytes
// dwCount Length of lpData in bytes
//
// Returns: TRUE for success, FALSE for failure.
//
BOOL RawDataToPrinter(LPSTR szPrinterName, LPBYTE lpData, DWORD dwCount)
{
HANDLE hPrinter;
DOC_INFO_1 DocInfo;
DWORD dwJob;
DWORD dwBytesWritten;

// Need a handle to the printer.
if( ! OpenPrinter( szPrinterName, &hPrinter, NULL ) )
return FALSE;

// Fill in the structure with info about this "document."
DocInfo.pDocName = "My Document";
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = "RAW";
// Inform the spooler the document is beginning.
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPSTR)&DocInfo )) == 0 )
{
ClosePrinter( hPrinter );
return FALSE;
}
// Start a page.
if( ! StartPagePrinter( hPrinter ) )
{
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}
// Send the data to the printer.
if( !WritePrinter( hPrinter, lpData, dwCount, &dwBytesWritten ) )
{
EndPagePrinter( hPrinter );
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}
// End the page.
if( ! EndPagePrinter( hPrinter ) )
{
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}
// Inform the spooler that the document is ending.
if( ! EndDocPrinter( hPrinter ) )
{
ClosePrinter( hPrinter );
return FALSE;
}
// Tidy up the printer handle.
ClosePrinter( hPrinter );
// Check to see if correct number of bytes were written.
if( dwBytesWritten != dwCount )
return FALSE;
return TRUE;
}

//Jaac 23/07/2002
// Adaptación de RawDataToPrinter de MSDN
// RawDataFileToPrinter - sends binary data directly to a printer
//
// szPrinterName: NULL-terminated string specifying printer name
// szFileName: Pointer to file containing raw data bytes
//
// Returns: TRUE for success, FALSE for failure.
//
BOOL RawDataFileToPrinter(LPSTR szPrinterName, LPSTR szDataFileName, LPSTR szDocTitle)
{
HANDLE hPrinter;
HANDLE hDataFile;
DOC_INFO_1 DocInfo;
DWORD dwJob;
DWORD dwBytesWritten;
DWORD dwBytesRead;
char lpData[0x1000];

// Need a handle to the printer.
if( !OpenPrinter( szPrinterName, &hPrinter, NULL ) )
return FALSE;

// Fill in the structure with info about this "document."
DocInfo.pDocName = szDocTitle;
DocInfo.pOutputFile = NULL;
DocInfo.pDatatype = "RAW";

// Inform the spooler the document is beginning.
if( (dwJob = StartDocPrinter( hPrinter, 1, (LPSTR)&DocInfo )) == 0 )
{
ClosePrinter( hPrinter );
return FALSE;
}

/*// Start a page.
if( !StartPagePrinter( hPrinter ) )
{
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}*/

// Open raw data file
if( (hDataFile = CreateFile( szDataFileName,
GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL )) == INVALID_HANDLE_VALUE )
{
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}

// Read-Write data
for(;;)
{
dwBytesRead = 0;

// Read data from file
if( !ReadFile( hDataFile, lpData, sizeof(lpData), &dwBytesRead, NULL ) )
{
//EndPagePrinter( hPrinter );
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
CloseHandle( hDataFile );
return FALSE;
}

// Comprobar si se ha alcanzado el final del DataFile.
if(dwBytesRead == 0)
break;

// Send the data to the printer.
if( !WritePrinter( hPrinter, lpData, dwBytesRead, &dwBytesWritten ) )
{
//EndPagePrinter( hPrinter );
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
CloseHandle( hDataFile );
return FALSE;
}
}

// Close DataFile handle
if( !CloseHandle( hDataFile ) )
{
//EndPagePrinter( hPrinter );
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}

/*// End the page.
if( !EndPagePrinter( hPrinter ) )
{
EndDocPrinter( hPrinter );
ClosePrinter( hPrinter );
return FALSE;
}*/

// Inform the spooler that the document is ending.
if( !EndDocPrinter( hPrinter ) )
{
ClosePrinter( hPrinter );
return FALSE;
}

// Tidy up the printer handle.
if( !ClosePrinter( hPrinter ) )
{
return FALSE;
}

// ok
return TRUE;
}

//Jaac 23/07/2002
// Adaptación de RawDataToPrinter de MSDN
// RawDataFileToPrinter - sends binary data directly to a printer
//
// szPrinterName: NULL-terminated string specifying printer name
// szFileName: Pointer to file containing raw data bytes
//
// Returns: TRUE for success, FALSE for failure.
//
BOOL RawDataFileToPrinter2(LPSTR szPrinterName, LPSTR szDataFileName, LPSTR szDocTitle)
{
HANDLE hPrinter;
ADDJOB_INFO_1 info;
char path[1000];
DWORD Nece;
HANDLE hFileJob;
HANDLE hFileSpool;
DWORD leidos;
DWORD grabados;
PRINTER_DEFAULTS PrinterDefs;

info.Path = (LPTSTR) &path[0];

PrinterDefs.DesiredAccess = PRINTER_ALL_ACCESS; // | PRINTER_ACCESS_ADMINISTER;
PrinterDefs.pDatatype = NULL;
PrinterDefs.pDevMode = NULL;
if (!OpenPrinter(PrinterName, &hPrinter, &PrinterDefs/*NULL*/))
return FALSE;

if(AddJob(hPrinter,(DWORD)1,(LPBYTE)&path[0],(DWORD)sizeof(path),(LPDWORD)&Nece))
{
info = *((ADDJOB_INFO_1 *)&path[0]);

{//Jaac 11/07/2002: Para ASP...
DWORD dwNeeded, dwReturned;
int i;
JOB_INFO_2 *pJobInfo;
//char sAutor[] = "Jaac";
char sMascara[_MAX_FNAME];
char sMascaraExt[_MAX_EXT];
char sPageCount[5];
//char sCopies[2];

GetJob(hPrinter, info.JobId, 2, NULL, 0, &dwNeeded);
pJobInfo = malloc( dwNeeded );
GetJob(hPrinter, info.JobId, 2, pJobInfo, dwNeeded, &dwReturned);

if (strlen(g_sTitleByProgram) > 0)
{
pJobInfo->pDocument=malloc(strlen(g_sTitleByProgram)+1);
strcpy(pJobInfo->pDocument, g_sTitleByProgram);
}
else
{
pJobInfo->pDocument = malloc(strlen(FormHdr.name)+1);
strcpy(pJobInfo->pDocument, FormHdr.name);
}

_splitpath( FrFileName, NULL, NULL, sMascara, sMascaraExt );
strcat(sMascara, sMascaraExt);
sprintf(sPageCount, "%d", PageCount);
//sprintf(sCopies, "%d", (OpcionInforme.NroCopias>1) ? OpcionInforme.NroCopias : 1);

pJobInfo->pDocument = realloc(pJobInfo->pDocument,
strlen(FormHdr.name)+1+
strlen(info.Path)+1+
strlen(sMascara)+1+
strlen(sPageCount)+1);
//strlen(sCopies)+1);

strcat(pJobInfo->pDocument, "|");
strcat(pJobInfo->pDocument, info.Path);
strcat(pJobInfo->pDocument, "|");
strcat(pJobInfo->pDocument, sMascara);
strcat(pJobInfo->pDocument, "|");
strcat(pJobInfo->pDocument, sPageCount);
//strcat(pJobInfo->pDocument, "|");
//strcat(pJobInfo->pDocument, sCopies);

//pJobInfo->pNotifyName = &sAutor[0];
SetJob(hPrinter, info.JobId, 2, pJobInfo, (DWORD)(0));

free(pJobInfo);
}

hFileSpool = CreateFile(info.Path,
GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL);
if(hFileSpool != INVALID_HANDLE_VALUE)
{

hFileJob = CreateFile(FileJob,
GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);
if(hFileJob != INVALID_HANDLE_VALUE)
{
// bucle leer grabar
for(;;)
{
leidos = grabados = 0;

ReadFile(hFileJob,buffer,sizeof(buffer),&leidos,NULL);
if(leidos == 0) break;
WriteFile(hFileSpool,buffer,leidos,&grabados,NULL);
}

CloseHandle(hFileJob);
}
CloseHandle(hFileSpool);
}
ScheduleJob(hPrinter,info.JobId);
}
else
{
// el AddJob ha fallado ( debe ser un NT compartiendo impresora)
PRINTER_INFO_2 APrinter[100];
DWORD Needed;
DWORD copiados;

char remoto[512];
remoto[0] = '\0';
if(!EnumPrinters(
PRINTER_ENUM_CONNECTIONS,
PrinterName, // name of printer object
2, // specifies type of printer info structure
(LPBYTE)&APrinter, // pointer to buffer to receive printer info structures
sizeof(APrinter), // size, in bytes, of array
&Needed, // pointer to variable with no. of bytes copied (or required)
&copiados // pointer to variable with no. of printer info. structures copied
))
{
return FALSE;
}
else
{
strcpy(remoto,APrinter[0].pServerName);
strcat(remoto,"\\");
strcat(remoto,APrinter[0].pShareName);
}
hFileSpool = CreateFile(remoto,
GENERIC_WRITE,0,NULL,OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL);
if(hFileSpool != INVALID_HANDLE_VALUE)
{
hFileJob = CreateFile(FileJob,
GENERIC_READ,0,NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL);

if(hFileJob != INVALID_HANDLE_VALUE)
{
// bucle leer grabar
for(;;)
{
leidos = grabados = 0;

ReadFile(hFileJob,buffer,sizeof(buffer),&leidos,NULL);
if(leidos == 0) break;
WriteFile(hFileSpool,buffer,leidos,&grabados,NULL);
}

CloseHandle(hFileJob);
}
CloseHandle(hFileSpool);
}
}
ClosePrinter(hPrinter);
}