请注意:要求只显示选定的打印机的Setup对话框,而不是用CPrintDialog来显示一个Setup对话框(在其中用户还可以选择其他打印机)以下是我的代码,但是对有些打印机设置不成功,请高手指点,该如何做?void CMainFrame::OnCopierBtSetting() 
{
// SHInvokePrinterCommand(NULL,PRINTACTION_PROPERTIES,g_CurPrinterName.GetBuffer(0),NULL,0);
HANDLE hPrinter = NULL;
DWORD dwNeeded = 0;
PRINTER_INFO_2 *pi2 = NULL;
DEVMODE *pDevMode = NULL;
PRINTER_DEFAULTS pd;
BOOL bFlag;
LONG lFlag;
BOOL bNetPrn = FALSE;
ZeroMemory(&pd, sizeof(pd));
pd.DesiredAccess = PRINTER_ALL_ACCESS;
bFlag = OpenPrinter(g_CurPrinterName.GetBuffer(0), &hPrinter, &pd);
if (!bFlag || (hPrinter == NULL))
{
bFlag = OpenPrinter(g_CurPrinterName.GetBuffer(0), &hPrinter, NULL);
bNetPrn = TRUE;
}
// 判断缓冲区是否足够;
SetLastError(0);
bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
if ((!bFlag) && (GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
{
ClosePrinter(hPrinter); }
pi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
if (pi2 == NULL)
{
ClosePrinter(hPrinter); }
bFlag = GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter); }
dwNeeded = DocumentProperties(NULL, hPrinter,g_CurPrinterName.GetBuffer(0),NULL, NULL, 0);
if (dwNeeded <= 0)
{
GlobalFree(pi2);
ClosePrinter(hPrinter); }
pDevMode = (DEVMODE *)GlobalAlloc(GPTR, dwNeeded);
if (pDevMode == NULL)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
}
  lFlag = DocumentProperties(NULL, hPrinter,g_CurPrinterName.GetBuffer(0),pDevMode, NULL,DM_OUT_BUFFER|DM_IN_PROMPT);
if (lFlag != IDOK || pDevMode == NULL)
{
GlobalFree(pDevMode);
GlobalFree(pi2);
ClosePrinter(hPrinter);
return;
}
else
{
if(!bNetPrn)
lFlag = DocumentProperties(NULL, hPrinter,g_CurPrinterName.GetBuffer(0),pDevMode, NULL,DM_OUT_BUFFER);
pi2->pDevMode = pDevMode;
}

bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);
if (!bFlag)
{
GlobalFree(pi2);
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
return;
}
if (pi2)
GlobalFree(pi2);
if (hPrinter)
ClosePrinter(hPrinter);
if (pDevMode)
GlobalFree(pDevMode);
}

解决方案 »

  1.   

    HANDLE hPrint;
     char dev[255],*dp;
    GetProfileString("windows","device","",dev,255);
      if(strcmp(dev,"")==0) return;
      dp=strchr(dev,',');
      *dp='\0';
        if(OpenPrinter(dev,&hPrint,NULL))
        { PrinterProperties(NULL,hPrint);
          ClosePrinter(hPrint) ;
        }
      

  2.   

    TO ZHENG017(风中王子) :用你的这种方法是不行的,我要的是打印机驱动带的Setup Dialog。
      

  3.   

    TO  damezc():你可以自己做个例子,把这段代码考过去,试一下看看。也说不出来哪些行哪些不行。反正在我这是网络打印机有点问题。你可以调试一下看看。
      

  4.   

    PRINTDLG pd ;
    pd.lStructSize = sizeof(PRINTDLG) ;
    pd.Flags = PD_RETURNDC ;
    pd.hDC = NULL ;
    pd.hwndOwner = NULL ;
    pd.hInstance = NULL ;
    pd.nMaxPage = 1 ;
    pd.nMinPage = 1 ;
    pd.nFromPage = 1 ;
    pd.nToPage  = 1 ;
    pd.nCopies = 1 ;
    pd.hDevMode = NULL ; 
    pd.hDevNames = NULL ; if ( !PrintDlg( &pd ) ) return FALSE ; 
      

  5.   

    TO chen_jun_fen(bitwise):用这个方法会出现一个打印对话框,但是用户还是可以选择其他的打印机。而我要的是在这个对话框中点“属性”BUTTON 后出来的那对话框。
      

  6.   

    问个问题
    g_CurPrinterName.GetBuffer(0)
    是怎么得到的?或者说是如何定义并得到初始值?
    呵呵,是个新手,所以问问
      

  7.   


    bFlag = SetPrinter(hPrinter, 2, (LPBYTE)pi2, 0);我觉得这句话有害无益,因为对打印机的设置已经在对话框中做了。假设你调DocumentProperty()驱动没有返回正确的pDevmode值,(这是驱动做得不标准),你再调用SetPrinter()反而把不正确的值设给打印机了。试试看吧。另外,
    代码最好去掉错误处理,看得清楚;
    把你Debug的一些情况列出来,省得别人做测试程序
      

  8.   

    TO silent1(怪怪):恩,你说的很对,不过关键问题不在这而。当我对网络打印机进行设置的时候,
    bFlag = OpenPrinter(g_CurPrinterName.GetBuffer(0), &hPrinter, &pd);
    调式结果显示打印机没打开成功。

    if (!bFlag || (hPrinter == NULL))
    {
    bFlag = OpenPrinter(g_CurPrinterName.GetBuffer(0), &hPrinter, NULL);
    bNetPrn = TRUE;
    }
    可以打开。但是bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);显示GetPrinter没有成功。关键是有些打印机打开不成功,我不知道原因在什么地方。不知道跟访问权限有没有关系?该怎么做?我这个程序需要在98、2000、XP下运行。
    TO  damezc():可以用EnumPrinters来列举机器上的打印机,然后看你自己选择的是哪一个,就把它传给g_CurPrinterName就好了。
      

  9.   

    权限的问题,如果你没有权限,OpenPrinter()不会成功,所以应该不是权限的问题。
    以前的经验,在调用GetPrinter()之前,调一下DocumentProperty()可以提高成功率。 
    可以一试
      

  10.   

    TO silent1(怪怪):你的方法不行呀!
      

  11.   

    我是黔驴几穷了。
    能说一下是什么打印机?
    本机的?网络的?别人共享的?另外,既然已经不用SetPrinter()了,还取ppi2干吗?只要DocumentProperty()成功不就得了吗?