Vista Aero Support

With the introduction of Windows Vista, Microsoft offered a new visual theme called Aero. This produced incompatibility with mixing GDI draw calls with a hardware accelerated window, such as DirectX. In previous versions of 3ds Max, many viewport operations gave visual feedback implemented with XOR lines in GDI. This typical scenario would produce viewport artifacts where an XOR line is being drawn with Aero active, as illustrated by the white artifacts in the image below:

In 3ds Max 2009 SDK, the XOR drawing method has been extended to support Aero. A developer wanting to draw XOR lines in the viewport should use these methods as they work for any Windows version.

Defined in Winutil.h and exported through Core.dll, the following functions were updated:

The methods listed above have 2 new parameters added:

bool bErase, and bool bDelayUpdate, both defaulting to false.

CoreExport void XORDottedRect(HWNDhwnd, IPoint2 p0, IPoint2 p1,
int solidToRight = 0,
bool bErase = false, bool bDelayUpdate = false);

bErase, is used to clear the foreground and use the background color to fill the pixels.

bDelayUpdate, is used to store draw calls. (The draw calls are performed, but only the presenting is delayed. The draw result is stored on the back buffer). If you need immediate results, set bDelayUpdate to false. Typical usage for GDI drawing would be calling draw twice: once to clear and a second time to draw. For the first call, you could set this flag to true.

The following code example shows a simple Mouse call-back to draw an XORDottedRect in the viewport:

int AeroDrawXORLineMouseProc::proc(HWND hwnd, int msg, int point, int flags, IPoint2 m)
{
    switch(msg)
    {
        case MOUSE_POINT:
             if(point ==0)
            {
                 m_startPoint = m_oldPoint = m;
                 m_bClicked = true;
            }
             else
            {
                 m_bClicked = false;
                 //! Erase the old line
                 //! Force an immediate update.
                XORDottedRect(hwnd,m_oldPoint,m_startPoint,0,true,false);
            }
             break;
        case MOUSE_MOVE:
             if(m_bClicked)
            {
                 //! Erase the old line
                 //! Delay the update as we draw straight away.
                XORDottedRect(hwnd,m_oldPoint,m_startPoint,0,true,true);
    
                 //! Draw new line
                 //! Update the foreground with the new rect.
                XORDottedRect(hwnd,m,m_startPoint,0,false,false);
                 m_oldPoint = m;
            }
             break;
        case MOUSE_FREEMOVE:
             break;
        case MOUSE_PROPCLICK:
        case MOUSE_ABORT:
             m_bClicked = false;
            GetCOREInterface()->PopCommandMode();
             break;
    }
    return TRUE;
  }
 

Although the callback above is using the new Aero supported methods, this callback could be used for non-Aero installations. To check if Aero is running, use the function IsVistaAeroEnabled() function in Core.dll.