PRB: ChangeDisplaySettingsEx() Fails When Called From a Service (249677)



The information in this article applies to:

  • Microsoft Platform Software Development Kit (SDK) 1.0, when used with:
    • the operating system: Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows NT 4.0 SP1
    • the operating system: Microsoft Windows NT 4.0 SP2
    • the operating system: Microsoft Windows NT 4.0 SP3
    • the operating system: Microsoft Windows NT 4.0 SP4
    • the operating system: Microsoft Windows NT 4.0 SP5
    • the operating system: Microsoft Windows NT 4.0 SP6
    • the operating system: Microsoft Windows NT 4.0 SP6a
    • the operating system: Microsoft Windows 2000 SP1
    • the operating system: Microsoft Windows 2000 SP2
    • the operating system: Microsoft Windows 2000 SP3
    • the operating system: Microsoft Windows XP SP1
  • the operating system: Microsoft Windows XP 64-Bit Edition

This article was previously published under Q249677

SYMPTOMS

The ChangeDisplaySettingsEx() function may fail when called from a service.

CAUSE

If ChangeDisplaySettingsEx() is being called from a thread that is not currently attached to the active Desktop, the thread cannot make changes to the display driver used by that Desktop.

RESOLUTION

To resolve this problem, attach the currently active Desktop to the thread that is running in the service.

The code demonstrates how to do the following:
  1. Switch to the active Desktop.
  2. Change the display mode.
  3. Switch back to the original desktop.
The following code demonstrates how to resolve this problem.
LONG ChangeDesktopDisplaySettings(LPDEVMODE lpdm)
{
    HDESK   hdeskInput;
    HDESK   hdeskCurrent;
    long    lRetVal;

    // Save the current desktop
    hdeskCurrent = GetThreadDesktop(GetCurrentThreadId());
    if (hdeskCurrent == NULL)
        return (-1);
 
    // Determine the current input desktop
    hdeskInput = OpenInputDesktop(0, FALSE, MAXIMUM_ALLOWED);
    if (hdeskInput == NULL)
        return (-1);

    // Set thread to the input desktop.
    if (!SetThreadDesktop(hdeskInput))
        return (-1);

    // Change the display settings. 
    lRetVal = ChangeDisplaySettingsEx (NULL, lpdm, NULL, CDS_GLOBAL|CDS_UPDATEREGISTRY|CDS_NORESET,NULL); 

    // Reset thread to the original desktop.
    SetThreadDesktop(hdeskCurrent);

    // Close handle to the input desktop.
    CloseDesktop(hdeskInput);

    return lRetVal;
}<BR/>
				

STATUS

This behavior is by design.

Modification Type:MinorLast Reviewed:5/3/2006
Keywords:kbDSWGDI2003Swept kbdisplay kbGDI kbprb kbService KB249677