วิธีการดึงข้อมูล และการตั้งค่าเครื่องพิมพ์เริ่มต้นใน Windows

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 246772 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
หมายเหตุ
บทความนี้ใช้ได้กับ Windows 2000 นั้น สนับสนุนสำหรับ Windows 2000 สิ้นสุดในวันที่ 13 กรกฎาคม 2010 ที่ ศูนย์แก้ไขปัญหาของจุดสิ้นสุดของสนับสนุน Windows 2000 มีจุดเริ่มต้นสำหรับการวางแผนกลยุทธ์ของคุณสำหรับการย้ายข้อมูลจาก Windows 2000 สำหรับข้อมูลเพิ่มเติมให้ดู นโยบาย Lifecycle ของฝ่ายสนับสนุนของ Microsoft.
ขยายทั้งหมด | ยุบทั้งหมด

สรุป

คุณสามารถดึงข้อมูล หรือการตั้งค่าเครื่องพิมพ์เริ่มต้น โดยการใช้วิธีที่แตกต่างกัน ขึ้นอยู่กับรุ่นของ Windows ที่คุณใช้

ข้อมูลเพิ่มเติม

Windows NT 4.0 (และรุ่นก่อนหน้านี้), คุณไม่สามารถใช้กับ:
  • เป็นSetPrinterหรือSetDefaultPrinterเพื่อตั้งค่าเครื่องพิมพ์เริ่มต้น
  • เป็นEnumPrintersหรือGetDefaultPrinterเพื่อเรียกดูเครื่องพิมพ์เริ่มต้น
ด้วย Windows NT 4.0 คุณสามารถใช้:
  • GetProfileStringเพื่อเรียกดูเครื่องพิมพ์เริ่มต้น
  • WriteProfileString เพื่อตั้งค่าเครื่องพิมพ์เริ่มต้น
ค่าอุปกรณ์ที่คุณได้รับ หรือตั้งค่าประกอบด้วยองค์ประกอบที่สามที่ถูกคั่น ด้วยจุลภาค เป็นดังนี้:
      printer name,driver name,port
				
ตัวอย่าง:
      My Printer,HPPCL5MS,lpt1:
				
หมายเหตุต่อไปนี้:
  • เมื่อคุณใช้วิธีนี้ คุณต้องระบุชื่อเครื่องพิมพ์ที่ถูกต้อง ไดรเวอร์ และพอร์ต ถ้าคุณยังไม่มี Api ที่จะไม่ล้มเหลว และอาจทำให้โปรแกรมอื่น ๆ เพื่อตั้งค่าเครื่องพิมพ์กลับไปยังเครื่องพิมพ์ที่ถูกต้องก่อนหน้า หรือกลายเป็นสับสน

    เมื่อต้องเรียกชื่อเครื่องพิมพ์ ชื่อไดรเวอร์ และชื่อพอร์ตเครื่องพิมพ์ที่พร้อมใช้งานทั้งหมด ใช้EnumPrinters API
  • Windows NT แมปอ้างอิงแฟ้ม.ini ส่วนใหญ่กับรีจิสทรี ผลGetProfileStringและWriteProfileStringยังคงทำเสมือนว่าพวกเขาได้ถูกเรียกใช้ภายใต้ Windows 16 บิต (Microsoft Windows และ Windows สำหรับเวิร์กกรุ๊ป)
  • หลังจากที่คุณตั้งค่าเครื่องพิมพ์เริ่มต้น ด้วยGetPrinter, GetDefaultPrinterหรือWriteProfileStringแจ้งให้ทราบทั้งหมดเปิดโปรแกรมอื่น ๆ ของการเปลี่ยนแปลง โดยการออกอากาศข้อความ WM_SETTINGCHANGE โปรแกรมที่จัดการกับข้อความนี้จดจำการเปลี่ยนแปลง

    WM_SETTINGCHANGE และ WM_WININICHANGE จะเหมือนกัน ใช้ WM_SETTINGCHANGE สำหรับโปรแกรม Win32

โค้ดตัวอย่าง

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการเรียกใช้เครื่องพิมพ์เริ่มต้น (DPGetDefaultPrinter) และการตั้งค่าเครื่องพิมพ์เริ่มต้น (DPSetDefaultPrinter)
// You are explicitly linking to GetDefaultPrinter because linking 
// implicitly on Windows 95/98 or NT4 results in a runtime error.
// This block specifies which text version you explicitly link to.
#ifdef UNICODE
  #define GETDEFAULTPRINTER "GetDefaultPrinterW"
#else
  #define GETDEFAULTPRINTER "GetDefaultPrinterA"
#endif

// Size of internal buffer used to hold "printername,drivername,portname"
// string. You may have to increase this for huge strings.
#define MAXBUFFERSIZE 250

/*----------------------------------------------------------------*/ 
/* DPGetDefaultPrinter                                            */ 
/*                                                                */ 
/* Parameters:                                                    */ 
/*   pPrinterName: Buffer alloc'd by caller to hold printer name. */ 
/*   pdwBufferSize: On input, ptr to size of pPrinterName.        */ 
/*          On output, min required size of pPrinterName.         */ 
/*                                                                */ 
/* NOTE: You must include enough space for the NULL terminator!   */ 
/*                                                                */ 
/* Returns: TRUE for success, FALSE for failure.                  */ 
/*----------------------------------------------------------------*/ 
BOOL DPGetDefaultPrinter(LPTSTR pPrinterName, LPDWORD pdwBufferSize)
{
  BOOL bFlag;
  OSVERSIONINFO osv;
  TCHAR cBuffer[MAXBUFFERSIZE];
  PRINTER_INFO_2 *ppi2 = NULL;
  DWORD dwNeeded = 0;
  DWORD dwReturned = 0;
  HMODULE hWinSpool = NULL;
  PROC fnGetDefaultPrinter = NULL;
  
  // What version of Windows are you running?
  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx(&osv);
  
  // If Windows 95 or 98, use EnumPrinters.
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  {
    // The first EnumPrinters() tells you how big our buffer must
    // be to hold ALL of PRINTER_INFO_2. Note that this will
    // typically return FALSE. This only means that the buffer (the 4th
    // parameter) was not filled in. You do not want it filled in here.
    SetLastError(0);
    bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, NULL, 0, &dwNeeded, &dwReturned);
    {
      if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
        return FALSE;
    }
    
    // Allocate enough space for PRINTER_INFO_2.
    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
    if (!ppi2)
      return FALSE;
    
    // The second EnumPrinters() will fill in all the current information.
    bFlag = EnumPrinters(PRINTER_ENUM_DEFAULT, NULL, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded, &dwReturned);
    if (!bFlag)
    {
      GlobalFree(ppi2);
      return FALSE;
    }
    
    // If specified buffer is too small, set required size and fail.
    if ((DWORD)lstrlen(ppi2->pPrinterName) >= *pdwBufferSize)
    {
      *pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;
      GlobalFree(ppi2);
      return FALSE;
    }
    
    // Copy printer name into passed-in buffer.
    lstrcpy(pPrinterName, ppi2->pPrinterName);
    
    // Set buffer size parameter to minimum required buffer size.
    *pdwBufferSize = (DWORD)lstrlen(ppi2->pPrinterName) + 1;
  }
  
  // If Windows NT, use the GetDefaultPrinter API for Windows 2000,
  // or GetProfileString for version 4.0 and earlier.
  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
  {
    if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)
    {
      hWinSpool = LoadLibrary("winspool.drv");
      if (!hWinSpool)
        return FALSE;
      fnGetDefaultPrinter = GetProcAddress(hWinSpool, GETDEFAULTPRINTER);
      if (!fnGetDefaultPrinter)
      {
        FreeLibrary(hWinSpool);
        return FALSE;
      }

      bFlag = fnGetDefaultPrinter(pPrinterName, pdwBufferSize);
        FreeLibrary(hWinSpool);
      if (!bFlag)
        return FALSE;
    }
    
    else // NT4.0 or earlier
    {
      // Retrieve the default string from Win.ini (the registry).
      // String will be in form "printername,drivername,portname".
      if (GetProfileString("windows", "device", ",,,", cBuffer, MAXBUFFERSIZE) <= 0)
        return FALSE;
      
      // Printer name precedes first "," character.
      strtok(cBuffer, ",");
      
      // If specified buffer is too small, set required size and fail.
      if ((DWORD)lstrlen(cBuffer) >= *pdwBufferSize)
      {
        *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
        return FALSE;
      }
      
      // Copy printer name into passed-in buffer.
      lstrcpy(pPrinterName, cBuffer);
      
      // Set buffer size parameter to minimum required buffer size.
      *pdwBufferSize = (DWORD)lstrlen(cBuffer) + 1;
    }
  }
  
  // Clean up.
  if (ppi2)
    GlobalFree(ppi2);
  
  return TRUE;
}
#undef MAXBUFFERSIZE
#undef GETDEFAULTPRINTER


// You are explicitly linking to SetDefaultPrinter because implicitly
// linking on Windows 95/98 or NT4 results in a runtime error.
// This block specifies which text version you explicitly link to.
#ifdef UNICODE
  #define SETDEFAULTPRINTER "SetDefaultPrinterW"
#else
  #define SETDEFAULTPRINTER "SetDefaultPrinterA"
#endif

/*-----------------------------------------------------------------*/ 
/* DPSetDefaultPrinter                                             */ 
/*                                                                 */ 
/* Parameters:                                                     */ 
/*   pPrinterName: Valid name of existing printer to make default. */ 
/*                                                                 */ 
/* Returns: TRUE for success, FALSE for failure.                   */ 
/*-----------------------------------------------------------------*/ 
BOOL DPSetDefaultPrinter(LPTSTR pPrinterName)

{
  BOOL bFlag;
  OSVERSIONINFO osv;
  DWORD dwNeeded = 0;
  HANDLE hPrinter = NULL;
  PRINTER_INFO_2 *ppi2 = NULL;
  LPTSTR pBuffer = NULL;
  LONG lResult;
  HMODULE hWinSpool = NULL;
  PROC fnSetDefaultPrinter = NULL;
  
  // What version of Windows are you running?
  osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  GetVersionEx(&osv);
  
  if (!pPrinterName)
    return FALSE;
  
  // If Windows 95 or 98, use SetPrinter.
  if (osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
  {
    // Open this printer so you can get information about it.
    bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);
    if (!bFlag || !hPrinter)
      return FALSE;
    
    // The first GetPrinter() tells you how big our buffer must
    // be to hold ALL of PRINTER_INFO_2. Note that this will
    // typically return FALSE. This only means that the buffer (the 3rd
    // parameter) was not filled in. You do not want it filled in here.
    SetLastError(0);
    bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
    if (!bFlag)
    {
      if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
      {
        ClosePrinter(hPrinter);
        return FALSE;
      }
    }
    
    // Allocate enough space for PRINTER_INFO_2.
    ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
    if (!ppi2)
    {
      ClosePrinter(hPrinter);
      return FALSE;
    }
    
    // The second GetPrinter() will fill in all the current information
    // so that all you have to do is modify what you are interested in.
    bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
    if (!bFlag)
    {
      ClosePrinter(hPrinter);
      GlobalFree(ppi2);
      return FALSE;
    }
    
    // Set default printer attribute for this printer.
    ppi2->Attributes |= PRINTER_ATTRIBUTE_DEFAULT;
    bFlag = SetPrinter(hPrinter, 2, (LPBYTE)ppi2, 0);
    if (!bFlag)
    {
      ClosePrinter(hPrinter);
      GlobalFree(ppi2);
      return FALSE;
    }
    
    // Tell all open programs that this change occurred. 
    // Allow each program 1 second to handle this message.
    lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L,
      (LPARAM)(LPCTSTR)"windows", SMTO_NORMAL, 1000, NULL);
  }
  
  // If Windows NT, use the SetDefaultPrinter API for Windows 2000,
  // or WriteProfileString for version 4.0 and earlier.
  else if (osv.dwPlatformId == VER_PLATFORM_WIN32_NT)
  {
    if (osv.dwMajorVersion >= 5) // Windows 2000 or later (use explicit call)
    {
      hWinSpool = LoadLibrary("winspool.drv");
      if (!hWinSpool)
        return FALSE;
      fnSetDefaultPrinter = GetProcAddress(hWinSpool, SETDEFAULTPRINTER);
      if (!fnSetDefaultPrinter)
      {
        FreeLibrary(hWinSpool);
        return FALSE;
      }

      bFlag = fnSetDefaultPrinter(pPrinterName);
      FreeLibrary(hWinSpool);
      if (!bFlag)
        return FALSE;
    }

    else // NT4.0 or earlier
    {
      // Open this printer so you can get information about it.
      bFlag = OpenPrinter(pPrinterName, &hPrinter, NULL);
      if (!bFlag || !hPrinter)
        return FALSE;
      
      // The first GetPrinter() tells you how big our buffer must
      // be to hold ALL of PRINTER_INFO_2. Note that this will
      // typically return FALSE. This only means that the buffer (the 3rd
      // parameter) was not filled in. You do not want it filled in here.
      SetLastError(0);
      bFlag = GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
      if (!bFlag)
      {
        if ((GetLastError() != ERROR_INSUFFICIENT_BUFFER) || (dwNeeded == 0))
        {
          ClosePrinter(hPrinter);
          return FALSE;
        }
      }
      
      // Allocate enough space for PRINTER_INFO_2.
      ppi2 = (PRINTER_INFO_2 *)GlobalAlloc(GPTR, dwNeeded);
      if (!ppi2)
      {
        ClosePrinter(hPrinter);
        return FALSE;
      }
      
      // The second GetPrinter() fills in all the current<BR/>
      // information.
      bFlag = GetPrinter(hPrinter, 2, (LPBYTE)ppi2, dwNeeded, &dwNeeded);
      if ((!bFlag) || (!ppi2->pDriverName) || (!ppi2->pPortName))
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
        return FALSE;
      }
      
      // Allocate buffer big enough for concatenated string.
      // String will be in form "printername,drivername,portname".
      pBuffer = (LPTSTR)GlobalAlloc(GPTR,
        lstrlen(pPrinterName) +
        lstrlen(ppi2->pDriverName) +
        lstrlen(ppi2->pPortName) + 3);
      if (!pBuffer)
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
        return FALSE;
      }
      
      // Build string in form "printername,drivername,portname".
      lstrcpy(pBuffer, pPrinterName);  lstrcat(pBuffer, ",");
      lstrcat(pBuffer, ppi2->pDriverName);  lstrcat(pBuffer, ",");
      lstrcat(pBuffer, ppi2->pPortName);
      
      // Set the default printer in Win.ini and registry.
      bFlag = WriteProfileString("windows", "device", pBuffer);
      if (!bFlag)
      {
        ClosePrinter(hPrinter);
        GlobalFree(ppi2);
        GlobalFree(pBuffer);
        return FALSE;
      }
    }
    
    // Tell all open programs that this change occurred. 
    // Allow each app 1 second to handle this message.
    lResult = SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0L, 0L,
      SMTO_NORMAL, 1000, NULL);
  }
  
  // Clean up.
  if (hPrinter)
    ClosePrinter(hPrinter);
  if (ppi2)
    GlobalFree(ppi2);
  if (pBuffer)
    GlobalFree(pBuffer);
  
  return TRUE;
}
#undef SETDEFAULTPRINTER
				
รหัสปรากฏขึ้นเพื่อที่ ไม่ทำงานในบางสถานการณ์:
  • ถ้าคุณปล่อยให้หมดโทรSendMessageTimeoutไม่มีโปรแกรมจดจำการเปลี่ยนแปลงจนกว่าคุณเริ่มการทำงานของโปรแกรม
  • ถ้าโปรแกรม 32 บิตอื่นไม่ได้จัดการกับข้อความ WM_SETTINGCHANGE โปรแกรมอื่น ๆ ไม่รู้จักว่า มีการเปลี่ยนเครื่องพิมพ์เริ่มต้น คุณต้องออก และเริ่มการทำงานของโปรแกรมเมื่อต้องบังคับให้รับรู้การเปลี่ยนแปลง
  • นี่เกินกว่าจะเล็กเกินไปเพื่อจัดเก็บข้อความต่อไปนี้:
    printername,portname,drivername
    					
  • เมื่อคุณใช้การWriteProfileString API จากโค้ดตัวอย่างนี้ (ซึ่งคุณต้องใช้สำหรับ Windows NT 4.0 และรุ่นก่อนหน้านี้เท่านั้น), โปรดจำไว้ว่า คุณดึงข้อมูลชื่อพอร์ตที่ถูกส่งไปที่WriteProfileStringโดยใช้ API แบบ 32 บิตGetPrinter

    ถึงแม้ว่าชื่อของพอร์ตนี้มีผลบังคับใช้ โปรแกรม 16 บิตไม่สามารถอ่าน และอาจมีปัญหา ถ้าคุณใช้วิธีนี้กับ Windows NT (รุ่น 4.0 และรุ่นก่อนหน้า) และโปรแกรม 16 บิตจำเป็นต้องทำความเข้าใจชื่อพอร์ตใหม่ คุณต้องใช้นามแฝง 16 บิตสำหรับชื่อพอร์ (NE0xโดยที่ x คือ ตัวเลข) คุณสามารถค้นหาการแม็ประหว่างชื่อพอร์ต 32 บิตและนามแฝงของพวกเขา 16 บิตในรีจิสทรี

ข้อมูลอ้างอิง

สำหรับข้อมูลเพิ่มเติม คลิกหมายเลขบทความต่อไปนี้เพื่อดูบทความในฐานความรู้ของ Microsoft:
266767 HOWTO: ชุดที่พิมพ์เป็นเครื่องพิมพ์ Start ระบบ
140560 HOWTO: กำหนดเครื่องพิมพ์เริ่มต้นโดยการเขียนโปรแกรม ใน Windows 95, Windows 98, Windows Me

คุณสมบัติ

หมายเลขบทความ (Article ID): 246772 - รีวิวครั้งสุดท้าย: 30 ตุลาคม 2555 - Revision: 4.0
ใช้กับ
  • Microsoft Windows XP Professional Edition
  • Microsoft Windows 2000 Server
Keywords: 
kbdswgdi2003swept kbgdi kbhowto kbprint kbmt KB246772 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:246772

ให้ข้อเสนอแนะ

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com