打印到TIFF, 图片打印机


源码: http://download.csdn.net/detail/kingmax54212008/9920964

如还有问题,请关注博主的其它打印驱动开发相关资料。或联系我的邮箱: kingmax5421@126.com







介绍

我个人不是PDF的粉丝。对我来说,它不是“开放”,它是大的,通常你不能编辑它后。我们经常在这些PDF文件中收到文件,如工资单和纸币。对于我的管理,我最近做了一些努力,从纸到电脑。我想使用“开放标准”,如TIFF和HTML。PDF不合适。所以我需要一种将PDF转换成TIFF的方法。这就是这个代码。

背景

我搜索了一些时间找到一些代码或工具将PDF转换为TIFF。不幸的是,我只能找到商业产品。而且我不知道如果我买一个,那就做我想要的。所以我寻找办法自己去做。

PDF和TIFF之间有很大的区别。PDF文档被“渲染”,而TIFF只是一堆像素。这意味着如果您在PDF查看器中放大页面,它将保持清晰。另一方面,TIFF 图像的分辨率有限。当然,您可以在PDF文档上按Alt Print Screen,但是您的设备(显示器)的大部分不会得到更好的分辨率(像素数)。我没有找到一种方法让PDF查看器在设备上下文中比物理屏幕的设备上下文更大。幸运的是,微软提供了一个Print er驱动程序示例,更幸运的是,由于有一段时间您可以下载包含示例的Windows驱动程序工具包。虽然代码在用户模式下运行,但它驱动程序。

使用打印机驱动程序,像素数量可能非常高。至少足以在正常页面上进行打印此外,通过更改应用程序中打印机属性,可以更改DPI,尺寸和颜色数量。更重要的是:只要应用程序可以打印,现在就可以将任何东西转换成TIFF 

入门

Microsoft示例是一个工作驱动程序。它将页面打印到一个位图(.BMP)。使用TIFF的一个原因是一个文件可以包含多个页面。因此,代码必须添加到样本中以分别写入每个页面,并将其写入TIFF而不是BMP。
要开始使用,您必须获得Windows驱动程序工具包。按照以下步骤:

  1. 下载Windows驱动程序工具包
  2. 它是一个ISO,所以你必须在CD刻录,或使用一些实用工具来安装图像
  3. 安装WDK。确保选择了完整开发环境。
  4. 我建议将样本复制到您的代码的其余部分所在的地方(并且您定期备份,对吗?)。<WinDDK-dir> \ src \ print \ oemdll \ bitmap复制<your-dir> \ Bitmap_Driver(确保路径和名称中没有空格)!
  5. 做一个目录Bitmap_Driver,例如“ Pack”。这将是将驱动程序分发到CD / DVD / USB / HD / FD / ...的目录
  6. 将一些WinDDK文件从[...] src \ print \ oemdll复制到新目录[...] \ Bitmap_Driver \ Pack
    • bitmap.gpd
    • bitmap.inf
    • bitmap.ini
  7. makefile.inc中,将第一行更改为“ INSTALLDIR =。\ Pack \ bitmap ”(不带引号)
  8. 现在您可以第一次构建示例。

构建驱动程序

正确的构建环境取决于计算机要使用它的位置。在开始菜单中,选择Windows驱动程序套件,WDK 7600。[...],Windows <您选择>,x <您选择>自由构建环境。这将打开一个具有正确设置的cmd框。在此框中,切换到您的Bitmap_Driver目录。然后键入“build”(不带引号)。您的驱动程序(bitmap.dll)将在Pack \ bitmap \ <架构>目录中。此路径在驱动程序文件中定义:bitmap.inf

使用代码

现在是添加代码以使其写入多页TIFF的时候了。需要更改以下文件:bitmap.hintrface.cppddihook.cppprecomp.h和源。

简而言之,这是打印时会发生什么

  1. COemUni2::EnablePDEV - 初始化所有的东西
  2. OEMStartPage - 当新页面启动时调用的钩子
  3. OEMSendPage - 通常不会被调用。我们不使用它
  4. COemUni2::ImageProcessing - 每个数据块之后
  5. COemUni2::FilterGraphics - 我们不使用
  6. OEMEndDoc - 最后一页后。这里我们将数据发送到打印子系统
  7. COemUni2::DisablePDEV

每一页都在一个或多个部分。渲染的一部分之后,该方法intrface.cpp被调用。该方法增加一个缓冲区并添加新的图形数据。该示例将挂起事件在这个挂钩功能中,缓冲区被给予“ 打印子系统”,实际上它将写入您点击打印时指定的文件COemUni2::ImageProcessingOEMEndDoc

因为我们要写一个Multipage TIFF,所以我们需要收到一个新页面开始的通知。因此,我们要勾画OEMStartPage你可能会期望这样OEMSendPage 会更有意义,但事实证明它通常不会被调用。

static const> DRVFN s_aOemHookFuncs[] = {
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
{INDEX_DrvStartPage, (PFN) OEMStartPage},
{INDEX_DrvSendPage, (PFN) OEMSendPage}
};

OEMStartPage 被调用时,我们正在开始一个新的页面。在这一刻,我们必须写上一页

// --- Write the previous page - if exists ---
if (pOemPDEV->pBufStart) {
    if (SaveFrame( pOemPDEV, pDevObj, false))
        pOemPDEV->m_iframe+=1;
    }

然后启动一个新的:

// --- New page ---
// Initializing private oempdev stuff
pOemPDEV->bHeadersFilled = FALSE;
pOemPDEV->bColorTable = FALSE;
pOemPDEV->cbHeaderOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pOemPDEV->bmInfoHeader.biHeight = 0;
pOemPDEV->bmInfoHeader.biSizeImage = 0;
pOemPDEV->pBufStart = NULL;
pOemPDEV->dwBufSize = 0;

SaveFrame 是将一个页面写入缓冲区的新功能。这里我们要把一些代码写入一个TIFF文件中的缓冲区。这个文件实际上是一个内存流,因为在最后(OEMEndDoc)我们必须将数据直接传递给假脱机程序。

/*******************************************************\
*
* Save Frame
*
\*******************************************************/
BOOL SaveFrame(POEMPDEV pOemPDEV, PDEVOBJ pdevobj, BOOL fClose) {

	INT cScans;
	Gdiplus::Bitmap* pbmp = NULL; //second+ frames: local bitmap

	log( L"SaveFrame");
	
	// --- Number of scanlines ---
	cScans = pOemPDEV->bmInfoHeader.biHeight;
	// --- Flip the biHeight member so that it denotes top-down bitmap ---
	pOemPDEV->bmInfoHeader.biHeight = cScans * -1;

	BITMAPINFO* pbmpinf = (BITMAPINFO*) LocalAlloc( LPTR, 
		sizeof(BITMAPINFOHEADER) + (pOemPDEV->cPalColors * sizeof(ULONG)));
	CopyMemory( &pbmpinf->bmiHeader, &pOemPDEV->bmInfoHeader, 
				sizeof(BITMAPINFOHEADER));
	if (pOemPDEV->bColorTable)	{
		CopyMemory( &pbmpinf->bmiColors, pOemPDEV->prgbq, 
				pOemPDEV->cPalColors*sizeof(RGBQUAD));
		LocalFree(pOemPDEV->prgbq);
		}

	Gdiplus::Status sstat;
	log(L"init Gdiplus::Bitmap");
	if (!pOemPDEV->m_pbmp) //Make Bitmap for the first time
		pOemPDEV->m_pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);
	else //Second time: local bitmap
		pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);

	if ((pOemPDEV->m_pbmp) || (pbmp)) {
		// --- Encoder Parameters ---
		Gdiplus::EncoderParameters* pEncoderParameters = 
			(Gdiplus::EncoderParameters*)
			LocalAlloc( LPTR, sizeof(Gdiplus::EncoderParameters) + 
			2*sizeof(Gdiplus::EncoderParameter));
		ULONG parameterValue0;
		ULONG parameterValue1;

		// An EncoderParameters object has an 
		// array of EncoderParameter objects. 
		pEncoderParameters->Count = 2;
		pEncoderParameters->Parameter[0].Guid = Gdiplus::EncoderCompression;
		pEncoderParameters->Parameter[0].Type = 
			Gdiplus::EncoderParameterValueTypeLong;
		pEncoderParameters->Parameter[0].NumberOfValues = 1;
		pEncoderParameters->Parameter[0].Value = ¶meterValue0;

		pEncoderParameters->Parameter[1].Guid = Gdiplus::EncoderSaveFlag;
		pEncoderParameters->Parameter[1].Type = 
			Gdiplus::EncoderParameterValueTypeLong;
		pEncoderParameters->Parameter[1].NumberOfValues = 1;
		pEncoderParameters->Parameter[1].Value = ¶meterValue1;

		//Black n White: CCITT4, else LZW
		if (pOemPDEV->bmInfoHeader.biBitCount == 1)
			parameterValue0 = Gdiplus::EncoderValueCompressionCCITT4;
		else
			parameterValue0 = Gdiplus::EncoderValueCompressionLZW;

		CLSID clsid;
		GetEncoderClsid(L"image/tiff", &clsid);
		
		log(L"Save (frame: %u)", pOemPDEV->m_iframe);

		if (pOemPDEV->m_iframe == 0) { //First frame
		   parameterValue1 = Gdiplus::EncoderValueMultiFrame;
			pOemPDEV->m_pbmp->SetResolution( 
				pdevobj->pPublicDM->dmPrintQuality, 
				pdevobj->pPublicDM->dmYResolution);
			sstat = pOemPDEV->m_pbmp->Save( pOemPDEV->m_pstm, 
				&clsid, pEncoderParameters);
			}
		
		else { //Second+ frame
		   parameterValue1 = Gdiplus::EncoderValueFrameDimensionPage;
			//TODO: Necessary?
			pbmp->SetResolution( 
				pdevobj->pPublicDM->dmPrintQuality, 
				pdevobj->pPublicDM->dmYResolution);
			sstat = pOemPDEV->m_pbmp->SaveAdd( pbmp, pEncoderParameters);
			if (pbmp)
				delete [] pbmp;
			}

		if (sstat != Gdiplus::Ok) log(L"Bitmap->
			Save failed (frame: %u)", pOemPDEV->m_iframe);

		if (fClose) {
			// Finishing:
			parameterValue1 = Gdiplus::EncoderValueFlush;
			sstat = pOemPDEV->m_pbmp->SaveAdd(pEncoderParameters);
			}

		LocalFree( pEncoderParameters);
		}

	else
		log(L"Couldn\'t make Gdiplus::Bitmap");

	LocalFree( pbmpinf);

	return true;
	}

正如你所看到的,我们使用Gdiplus做这个工作。为什么我们在第一帧中使用成员变量作为位图,然后为以下帧使用局部变量?当我们要添加一个页面到第一个,我们使用一个方法在初始位图,所以我们必须重用那个。

要完整地关闭文件,在end(OEMEndDoc)中,EncoderValueFlush 通过设置参数来指示函数的写入fClose

安装打印

现在让我们安装打印机,然后尝试一下。

  1. 添加本地打印
  2. 使用现有端口:FILE:(打印到文件)
  3. 有磁盘...
  4. 浏览到<your-dir> \ Bitmap_Driver \ Pack,然后选择bitmap.inf
  5. 如果这不是第一次:更换当前驱动程序
  6. 接下来,下一步,完成

现在打印一些新的打印呃。

如果你不能使它工作

记录

正如你可能已经注意到的,在某些点上,一行显示如下:

log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);	

因为它是一个驱动程序,你不能直接写入屏幕。另外,调试并不那么容易。这就是为什么我添加了一个函数来写消息使用OutputDebugStringW您可能知道,您必须做一些额外的工作才能使用Windows 7查看邮件:

  1. 使用RegEdit:导航到HKLM \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Debug 打印过滤器
  2. 将DEFAULT的值更改为0xf(REG_DWORD
  3. 重启
  4. 您可以使用DbgView (以前的Sysinternals)查看消息,并选择“Capture Global Win32”

现在可以在代码中添加日志记录。

重新安装新版本后无更改

Windows从驱动程序缓存中选出相同的旧驱动程序。要安装新的,请更改bitmap.inf中的驱动程序版本,然后重新安装。现在新的驱动程序将被安装。

错误0x000003eb

如果您尝试安装驱动程序,将显示此错误。在这种情况下,文件bitmap.gpd可能会有错误如果您更改了它,请尝试将其替换为原件。

兴趣点

由于Gdiplus用于保存文件,因此很容易将驱动程序保存为JPEG,GIF或其他类型的文件。事实上,它与更改行一样简单但是:其他格式不支持一个文件中的多个页面。所以,如果您需要另一种文件格式,最好从原始样本开始,然后添加代码以使用Gdiplus(in 保存文件另外,检查的依赖关系:“ gdiplus.lib ”和precomp.h:“gdiplus.h”GetEncoderClsid(L"image/tiff", &clsid); OEMEndDoc(...)



介绍

我个人不是PDF的粉丝。对我来说,它不是“开放”,它是大的,通常你不能编辑它后。我们经常在这些PDF文件中收到文件,如工资单和纸币。对于我的管理,我最近做了一些努力,从纸到电脑。我想使用“开放标准”,如TIFF和HTML。PDF不合适。所以我需要一种将PDF转换成TIFF的方法。这就是这个代码。

背景

我搜索了一些时间找到一些代码或工具将PDF转换为TIFF。不幸的是,我只能找到商业产品。而且我不知道如果我买一个,那就做我想要的。所以我寻找办法自己去做。

PDF和TIFF之间有很大的区别。PDF文档被“渲染”,而TIFF只是一堆像素。这意味着如果您在PDF查看器中放大页面,它将保持清晰。另一方面,TIFF 图像的分辨率有限。当然,您可以在PDF文档上按Alt Print Screen,但是您的设备(显示器)的大部分不会得到更好的分辨率(像素数)。我没有找到一种方法让PDF查看器在设备上下文中比物理屏幕的设备上下文更大。幸运的是,微软提供了一个Print er驱动程序示例,更幸运的是,由于有一段时间您可以下载包含示例的Windows驱动程序工具包。虽然代码在用户模式下运行,但它驱动程序。

使用打印机驱动程序,像素数量可能非常高。至少足以在正常页面上进行打印此外,通过更改应用程序中打印机属性,可以更改DPI,尺寸和颜色数量。更重要的是:只要应用程序可以打印,现在就可以将任何东西转换成TIFF 

入门

Microsoft示例是一个工作驱动程序。它将页面打印到一个位图(.BMP)。使用TIFF的一个原因是一个文件可以包含多个页面。因此,代码必须添加到样本中以分别写入每个页面,并将其写入TIFF而不是BMP。
要开始使用,您必须获得Windows驱动程序工具包。按照以下步骤:

  1. 下载Windows驱动程序工具包
  2. 它是一个ISO,所以你必须在CD刻录,或使用一些实用工具来安装图像
  3. 安装WDK。确保选择了完整开发环境。
  4. 我建议将样本复制到您的代码的其余部分所在的地方(并且您定期备份,对吗?)。<WinDDK-dir> \ src \ print \ oemdll \ bitmap复制<your-dir> \ Bitmap_Driver(确保路径和名称中没有空格)!
  5. 做一个目录Bitmap_Driver,例如“ Pack”。这将是将驱动程序分发到CD / DVD / USB / HD / FD / ...的目录
  6. 将一些WinDDK文件从[...] src \ print \ oemdll复制到新目录[...] \ Bitmap_Driver \ Pack
    • bitmap.gpd
    • bitmap.inf
    • bitmap.ini
  7. makefile.inc中,将第一行更改为“ INSTALLDIR =。\ Pack \ bitmap ”(不带引号)
  8. 现在您可以第一次构建示例。

构建驱动程序

正确的构建环境取决于计算机要使用它的位置。在开始菜单中,选择Windows驱动程序套件,WDK 7600。[...],Windows <您选择>,x <您选择>自由构建环境。这将打开一个具有正确设置的cmd框。在此框中,切换到您的Bitmap_Driver目录。然后键入“build”(不带引号)。您的驱动程序(bitmap.dll)将在Pack \ bitmap \ <架构>目录中。此路径在驱动程序文件中定义:bitmap.inf

使用代码

现在是添加代码以使其写入多页TIFF的时候了。需要更改以下文件:bitmap.hintrface.cppddihook.cppprecomp.h和源。

简而言之,这是打印时会发生什么

  1. COemUni2::EnablePDEV - 初始化所有的东西
  2. OEMStartPage - 当新页面启动时调用的钩子
  3. OEMSendPage - 通常不会被调用。我们不使用它
  4. COemUni2::ImageProcessing - 每个数据块之后
  5. COemUni2::FilterGraphics - 我们不使用
  6. OEMEndDoc - 最后一页后。这里我们将数据发送到打印子系统
  7. COemUni2::DisablePDEV

每一页都在一个或多个部分。渲染的一部分之后,该方法intrface.cpp被调用。该方法增加一个缓冲区并添加新的图形数据。该示例将挂起事件在这个挂钩功能中,缓冲区被给予“ 打印子系统”,实际上它将写入您点击打印时指定的文件COemUni2::ImageProcessingOEMEndDoc

因为我们要写一个Multipage TIFF,所以我们需要收到一个新页面开始的通知。因此,我们要勾画OEMStartPage你可能会期望这样OEMSendPage 会更有意义,但事实证明它通常不会被调用。

static const> DRVFN s_aOemHookFuncs[] = {
{INDEX_DrvEndDoc, (PFN)OEMEndDoc},
{INDEX_DrvStartPage, (PFN) OEMStartPage},
{INDEX_DrvSendPage, (PFN) OEMSendPage}
};

OEMStartPage 被调用时,我们正在开始一个新的页面。在这一刻,我们必须写上一页

// --- Write the previous page - if exists ---
if (pOemPDEV->pBufStart) {
    if (SaveFrame( pOemPDEV, pDevObj, false))
        pOemPDEV->m_iframe+=1;
    }

然后启动一个新的:

// --- New page ---
// Initializing private oempdev stuff
pOemPDEV->bHeadersFilled = FALSE;
pOemPDEV->bColorTable = FALSE;
pOemPDEV->cbHeaderOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
pOemPDEV->bmInfoHeader.biHeight = 0;
pOemPDEV->bmInfoHeader.biSizeImage = 0;
pOemPDEV->pBufStart = NULL;
pOemPDEV->dwBufSize = 0;

SaveFrame 是将一个页面写入缓冲区的新功能。这里我们要把一些代码写入一个TIFF文件中的缓冲区。这个文件实际上是一个内存流,因为在最后(OEMEndDoc)我们必须将数据直接传递给假脱机程序。

/*******************************************************\
*
* Save Frame
*
\*******************************************************/
BOOL SaveFrame(POEMPDEV pOemPDEV, PDEVOBJ pdevobj, BOOL fClose) {

	INT cScans;
	Gdiplus::Bitmap* pbmp = NULL; //second+ frames: local bitmap

	log( L"SaveFrame");
	
	// --- Number of scanlines ---
	cScans = pOemPDEV->bmInfoHeader.biHeight;
	// --- Flip the biHeight member so that it denotes top-down bitmap ---
	pOemPDEV->bmInfoHeader.biHeight = cScans * -1;

	BITMAPINFO* pbmpinf = (BITMAPINFO*) LocalAlloc( LPTR, 
		sizeof(BITMAPINFOHEADER) + (pOemPDEV->cPalColors * sizeof(ULONG)));
	CopyMemory( &pbmpinf->bmiHeader, &pOemPDEV->bmInfoHeader, 
				sizeof(BITMAPINFOHEADER));
	if (pOemPDEV->bColorTable)	{
		CopyMemory( &pbmpinf->bmiColors, pOemPDEV->prgbq, 
				pOemPDEV->cPalColors*sizeof(RGBQUAD));
		LocalFree(pOemPDEV->prgbq);
		}

	Gdiplus::Status sstat;
	log(L"init Gdiplus::Bitmap");
	if (!pOemPDEV->m_pbmp) //Make Bitmap for the first time
		pOemPDEV->m_pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);
	else //Second time: local bitmap
		pbmp = new Gdiplus::Bitmap( pbmpinf, pOemPDEV->pBufStart);

	if ((pOemPDEV->m_pbmp) || (pbmp)) {
		// --- Encoder Parameters ---
		Gdiplus::EncoderParameters* pEncoderParameters = 
			(Gdiplus::EncoderParameters*)
			LocalAlloc( LPTR, sizeof(Gdiplus::EncoderParameters) + 
			2*sizeof(Gdiplus::EncoderParameter));
		ULONG parameterValue0;
		ULONG parameterValue1;

		// An EncoderParameters object has an 
		// array of EncoderParameter objects. 
		pEncoderParameters->Count = 2;
		pEncoderParameters->Parameter[0].Guid = Gdiplus::EncoderCompression;
		pEncoderParameters->Parameter[0].Type = 
			Gdiplus::EncoderParameterValueTypeLong;
		pEncoderParameters->Parameter[0].NumberOfValues = 1;
		pEncoderParameters->Parameter[0].Value = ¶meterValue0;

		pEncoderParameters->Parameter[1].Guid = Gdiplus::EncoderSaveFlag;
		pEncoderParameters->Parameter[1].Type = 
			Gdiplus::EncoderParameterValueTypeLong;
		pEncoderParameters->Parameter[1].NumberOfValues = 1;
		pEncoderParameters->Parameter[1].Value = ¶meterValue1;

		//Black n White: CCITT4, else LZW
		if (pOemPDEV->bmInfoHeader.biBitCount == 1)
			parameterValue0 = Gdiplus::EncoderValueCompressionCCITT4;
		else
			parameterValue0 = Gdiplus::EncoderValueCompressionLZW;

		CLSID clsid;
		GetEncoderClsid(L"image/tiff", &clsid);
		
		log(L"Save (frame: %u)", pOemPDEV->m_iframe);

		if (pOemPDEV->m_iframe == 0) { //First frame
		   parameterValue1 = Gdiplus::EncoderValueMultiFrame;
			pOemPDEV->m_pbmp->SetResolution( 
				pdevobj->pPublicDM->dmPrintQuality, 
				pdevobj->pPublicDM->dmYResolution);
			sstat = pOemPDEV->m_pbmp->Save( pOemPDEV->m_pstm, 
				&clsid, pEncoderParameters);
			}
		
		else { //Second+ frame
		   parameterValue1 = Gdiplus::EncoderValueFrameDimensionPage;
			//TODO: Necessary?
			pbmp->SetResolution( 
				pdevobj->pPublicDM->dmPrintQuality, 
				pdevobj->pPublicDM->dmYResolution);
			sstat = pOemPDEV->m_pbmp->SaveAdd( pbmp, pEncoderParameters);
			if (pbmp)
				delete [] pbmp;
			}

		if (sstat != Gdiplus::Ok) log(L"Bitmap->
			Save failed (frame: %u)", pOemPDEV->m_iframe);

		if (fClose) {
			// Finishing:
			parameterValue1 = Gdiplus::EncoderValueFlush;
			sstat = pOemPDEV->m_pbmp->SaveAdd(pEncoderParameters);
			}

		LocalFree( pEncoderParameters);
		}

	else
		log(L"Couldn\'t make Gdiplus::Bitmap");

	LocalFree( pbmpinf);

	return true;
	}

正如你所看到的,我们使用Gdiplus做这个工作。为什么我们在第一帧中使用成员变量作为位图,然后为以下帧使用局部变量?当我们要添加一个页面到第一个,我们使用一个方法在初始位图,所以我们必须重用那个。

要完整地关闭文件,在end(OEMEndDoc)中,EncoderValueFlush 通过设置参数来指示函数的写入fClose

安装打印

现在让我们安装打印机,然后尝试一下。

  1. 添加本地打印
  2. 使用现有端口:FILE:(打印到文件)
  3. 有磁盘...
  4. 浏览到<your-dir> \ Bitmap_Driver \ Pack,然后选择bitmap.inf
  5. 如果这不是第一次:更换当前驱动程序
  6. 接下来,下一步,完成

现在打印一些新的打印呃。

如果你不能使它工作

记录

正如你可能已经注意到的,在某些点上,一行显示如下:

log(L"Bitmap->Save failed (frame: %u)", pOemPDEV->m_iframe);	

因为它是一个驱动程序,你不能直接写入屏幕。另外,调试并不那么容易。这就是为什么我添加了一个函数来写消息使用OutputDebugStringW您可能知道,您必须做一些额外的工作才能使用Windows 7查看邮件:

  1. 使用RegEdit:导航到HKLM \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ Debug 打印过滤器
  2. 将DEFAULT的值更改为0xf(REG_DWORD
  3. 重启
  4. 您可以使用DbgView (以前的Sysinternals)查看消息,并选择“Capture Global Win32”

现在可以在代码中添加日志记录。

重新安装新版本后无更改

Windows从驱动程序缓存中选出相同的旧驱动程序。要安装新的,请更改bitmap.inf中的驱动程序版本,然后重新安装。现在新的驱动程序将被安装。

错误0x000003eb

如果您尝试安装驱动程序,将显示此错误。在这种情况下,文件bitmap.gpd可能会有错误如果您更改了它,请尝试将其替换为原件。

兴趣点

由于Gdiplus用于保存文件,因此很容易将驱动程序保存为JPEG,GIF或其他类型的文件。事实上,它与更改行一样简单但是:其他格式不支持一个文件中的多个页面。所以,如果您需要另一种文件格式,最好从原始样本开始,然后添加代码以使用Gdiplus(in 保存文件另外,检查的依赖关系:“ gdiplus.lib ”和precomp.h:“gdiplus.h”GetEncoderClsid(L"image/tiff", &clsid); OEMEndDoc(...)

相关文章
相关标签/搜索