Muchas gracias por la información a Jorge_BH
Sobre el tema de transparencia de un formulario les envío algunas NOTAS que alclaran su utilización, donde también se incluye el uso API de windows para lograrlo.
How can I create a modeless VBA form in AutoCAD ?
Normally, you can do it as indicated below,
1. Start Acad and VBA.
2. Insert a user form, default name UserForm1.
3. Write a simple VBA sub routine to launch it as a modeless form
- Código: Seleccionar todo
You can run it and you can see that you have a modeless form floating there. However, you can't shift the focus to it. In another word, it can't keep focus on itself. The reason is that Acad has a custom message that is not handled by the VBA form.
There are two solutions, the first one works only in Acad 2002.
1. Within the VBA IDE, make sure the UserForm1 is visible and Toolbox toolbar is shown. Right mouse click on the Toolbox, click Additional Controls. In the Available Controls list, check AcFocusCtrl Class. Click OK. The AcFocusCtrl should show up in the Toolbox toolbar. Drag and insert it into anywhere inside the UserForm1. That's it. Now the Sub Test() routine above should work fine.
Note: You may have to manually register AcFocusCtrl.dll. To do that, run the following at the DOS prompt,
REGSVR32 "c:\program files\common files\autodesk shared\acfocusctrl.dll"
2. You can force the modeless form to keep the focus by specifying the WS_OVERLAPPED style. As this style isn't available to VBA, you have to use Win32 API function SetWindowLong(), and simply remove (XOR) the WS_POPUP style which is set by default (since WS_OVERLAPPED = 0). AutoCAD can't take the focus away from a dialog with this style, so the form and its controls keeps the focus properly. Also in VBA, you don't have access to the HWND of the dialog, but you can get it with EnumWindows().
- Código: Seleccionar todo
' Declare Win32 functions needed...
Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long) As Long
Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Declare Function EnumWindows Lib "user32" (ByVal lpEnumFunc As Long, ByVal lParam As Long) As Long
Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Dim ThisHwnd As Long
Public Const GWL_STYLE = -16
Public Const WS_POPUP = &H80000000
' When the form is activated, find the dialog's HWND, and subclass the styles...
Private Sub UserForm_Activate()
Call EnumWindows(AddressOf EnumWindowsProc, vbNull)
' Here is the callback for Enumwindows...
Function EnumWindowsProc(ByVal hWnd As Long, ByVal lParam As Long) As Integer
Dim title As String * 32
Call GetWindowText(hWnd, ByVal title, 32)
If InStr(title, "MyForm") Then
ThisHwnd = hWnd ' Found our window...
EnumWindowsProc = False' Cancel the search
EnumWindowsProc = True ' Continue the search
Public Function SubClass() As Long
Dim Flags As Long
Flags = GetWindowLong(ThisHwnd, GWL_STYLE)' Get the current styles...
Flags = Flags Xor WS_POPUP ' Get Rid of the POPUP style
SetWindowLong ThisHwnd, GWL_STYLE, Flags ' Reset the Style
This does require the ShowModal property to be set to false, and the Show method is still called to invoke it as normal. This may yet be simplified as well. A sample DVB file is attached.