Patrice Terrier
Extended DDW
June 26, 2009 02:35PM
Extended DDW

You probably like the WinDev exclusive DDW feature, however it has some limitations:
1 - It works only with native WinDev controls.
2 - It relies on the graphic card configuration and on the processor speed.
3 - It doesn't work with DirectX nor with OpenGL.

The CreateDDW below has no limitation, however it must be used only on true 32-bit or 64-bit OS (W2K, XP, VISTA, Windows 7).
It is based on direct call to the low level API, and uses the layerd window extended style.
It could be used with any third party addons as well as with 3D graphics using DirectX or OpenGL.


CONSTANT
   CS_VREDRAW        = 1
   CS_HREDRAW        = 2
   WM_SETCURSOR      = 32
   IDC_WAIT          = 32514
   WS_EX_TOOLWINDOW  = 128
   WS_POPUP          = -2147483648
   WS_DISABLED       = 134217728
   WS_EX_LAYERED     = 524288
   GWL_EXSTYLE       = -20
   LWA_ALPHA         = 2
END

WNDCLASSEX is structure
   cbSize        is unsigned int //Type C : UINT
   style         is unsigned int //Type C : UINT
   lpfnWndProc   is int      //Type C : WNDPROC
   cbClsExtra    is int      //Type C : int
   cbWndExtra    is int      //Type C : int
   hInstance     is int      //Type C : HINSTANCE
   hIcon         is int      //Type C : HICON
   hCursor       is int      //Type C : HCURSOR
   hbrBackground is int      //Type C : HBRUSH
   lpszMenuName  is int      //Type C : LPCSTR
   lpszClassName is int      //Type C : LPCSTR
   hIconSm       is int      //Type C : HICON
END

FUNCTION GetWindowRgn(LOCAL nX is int, LOCAL nY is int, LOCAL nhWnd is int)
nRet, nRgn, n1, n2, n3, n4 are int = 0
nRgn = API("GDI32", "CreateRectRgn", n1, n2, n3, n4)
IF API("USER32", "GetWindowRgn", nhWnd, nRgn) THEN
   IF API("GDI32", "OffsetRgn", nRgn, nX, nY) THEN nRet = nRgn
END
RESULT nRet

FUNCTION DDWproc(LOCAL nhWnd is int, LOCAL nMsg is int, LOCAL nwParam is int, LOCAL nlParam is int)
nRet is int
IF nMsg = WM_SETCURSOR THEN
   API("USER32", "SetCursor", API("USER32", "LoadCursorA", Null, IDC_WAIT))
   nRet = 1
ELSE
   nRet = API("USER32", "DefWindowProcA", nhWnd, nMsg, nwParam, nlParam)
END
RESULT nRet

FUNCTION RegisterDDWclass()
wc is WNDCLASSEX
zClass is string ASCIIZ on 16 = "DDWINDOWEX"
wcStyle is int = CS_HREDRAW + CS_VREDRAW
IsInitialized is int = API("USER32.DLL", "GetClassInfoExA", Instance, &zClass, &wc)
IF IsInitialized    = 0 THEN
   wc:cbSize        = Dimension(wc)
   wc:style         = wcStyle
   wc:lpfnWndProc   = &DDWproc
   wc:cbClsExtra    = 0
   wc:cbWndExtra    = 0 // Extend_cbWndExtra * 4
   wc:hInstance     = Instance
   wc:hIcon         = Null
   wc:hCursor       = API("USER32", "LoadCursorA", Null, IDC_WAIT)
   wc:hbrBackground = API("GDI32", "GetStockObject", 4) // BlackBrush
   wc:lpszMenuName  = Null
   wc:lpszClassName = &zClass
   wc:hIconSm       = Null
   IF API("USER32.DLL", "RegisterClassExA", &wc) THEN IsInitialized = True
END
RESULT IsInitialized

FUNCTION IsOsNT()
nRet is int
sVersion is string = SysWindowsVersion()
IF sVersion = "NT 5" THEN sVersion = "0"
// Check the OS before to apply the shadow effect
IF StringCount("0XV2", Left(sVersion, 1)) THEN nRet = -1 // 2000, XP, 2003, VISTA
RESULT nRet

FUNCTION GetWindowLong(LOCAL nHandle is int, LOCAL nIndex is int)
nRet is int = API("USER32", "GetWindowLongA", nHandle, nIndex)
RESULT nRet

FUNCTION SetWindowLong(LOCAL nHandle is int, LOCAL nIndex is int, LOCAL nNewValue is int)
nRet is int = API("USER32", "SetWindowLongA", nHandle, nIndex, nNewValue)
RESULT nRet

FUNCTION SetLayeredWindowAttributes(LOCAL nHandle is int, LOCAL nAlpha is 1-byte unsigned int)
nRet, nBlackColor, nUseStyle are int
IF IsOsNT THEN
  nBlackColor = 0
  nUseStyle = BinaryOR(GetWindowLong(nHandle, GWL_EXSTYLE), WS_EX_LAYERED)
  SetWindowLong(nHandle, GWL_EXSTYLE, nUseStyle)
  nRet = API("USER32", "SetLayeredWindowAttributes", nHandle, nBlackColor, nAlpha, LWA_ALPHA)
END
RESULT nRet

FUNCTION CreateDDW(LOCAL nParent is int)
nDDW, nUseStyle are is int
stRW is RECT
IF RegisterDDWclass() THEN
   IF nParent <> 0 THEN
      nUseStyle = BinaryOR(WS_POPUP, WS_DISABLED)
      nDDW = API("USER32","CreateWindowExA", ...
      WS_EX_TOOLWINDOW, ... // SDK extended style
      "DDWINDOWEX",...      // The unique class name
      "", ...               // Caption
      nUseStyle, ...        // SDK style
      0, ...                // X location
      0, ...                // Y location
      0, ...                // Control width
      0, ...                // Control height
      nParent, ...          // Parent handle
      0, ...                // Control ID
      Instance, ...         // Instance
      0)
      IF nDDW THEN
         SetLayeredWindowAttributes(nDDW, 132)
         // Get the region of the parent window.
         nRgn is int = GetWindowRgn(0, 0, nParent)
         // Assign same region shape to our DDW window.
         nRet is int = API("USER32", "SetWindowRgn", nDDW, nRgn, 0)
         API("USER32", "GetWindowRect", nParent, &stRW)
         // Setup the good size for our DDW window.
         API("USER32", "SetWindowPos", nDDW, nParent, stRW:nLeft, stRW:nTop, stRW:nRight, stRW:nBottom, SWP_NOACTIVATE)
         API("USER32", "ShowWindow", nDDW, SW_SHOW)
      END
   END
END
RESULT nDDW

PROCEDURE DestroyDDW(nDDW is int)
IF nDDW THEN API("USER32", "DestroyWindow", nDDW); nDDW = 0

To use it, call CreateDDW before to open the child popup, then call DestroyDDW once done.
MyWindow..Handle is the handle of the parent window that should be grayed.

Syntax example:
nDDW is int = CreateDDW(MyWindow..Handle)
   Open("MyChildPopupWindow")
DestroyDDW(nDDW)
Author:

Your Email:


Subject:


Spam prevention:
Please, enter the code that you see below in the input field. This is for blocking bots that try to post this form automatically. If the code is hard to read, then just try to guess it right. If you enter the wrong code, a new image is created and you get another chance to enter it right.
Message: