Hide Autocad activity while VBA program is in progress

Hide Autocad activity while VBA program is in progress

Anonymous
Not applicable
6,273 Views
25 Replies
Message 1 of 26

Hide Autocad activity while VBA program is in progress

Anonymous
Not applicable
I have created a program with some quick plotting macros for our various layouts and printers. So far it seems to work fine. Although, while running, it shows autocad switching to paperspace, creating the viewport before switching back to modelspace again. Can this activity be hidden from the user? It would make the program more professional looking if it could be hidden.
0 Likes
6,274 Views
25 Replies
Replies (25)
Message 2 of 26

arcticad
Advisor
Advisor
Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

LockWindowUpdate (ThisDrawing.hwnd)
' do stuff here
LockWindowUpdate (0)
---------------------------



(defun botsbuildbots() (botsbuildbots))
0 Likes
Message 3 of 26

jeremye86
Advocate
Advocate

your code is not working for me.  I gave up and just decided to use

 

acadApp.WindowState = acMin

 

Do you have any pointers when using your code?

0 Likes
Message 4 of 26

Ed__Jobe
Mentor
Mentor

Try

 

Declare PtrSafe Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 5 of 26

jeremye86
Advocate
Advocate

Ed,

 

I am already using this and it works fine.

 

#If VBA7 And Win64 Then
Public Declare PtrSafe Function LockWindowUpdate Lib "user32" (ByVal hwndLock As LongPtr) As Long
#Else
Public Declare Function LockWindowUpdate Lib "user32" (ByVal hwndLock As Long) As Long
#End If

 

The only problem is im not sure what to put inside the function

 

LockWindowUpdate (???????.Hwnd)

 

 

right now i am doing this

Set acadApp = GetObject(, "AutoCAD.Application")

LockWindowUpdate (acadApp.Hwnd)

 

it seems to be working but the only thing it is hiding in the screen update is this

acadApp.Application.Documents.Add 

where i don't see the additional document windows pop up

 

But i still see the actual drawing window doing screen updates (which i need turned off)

 

 

 

 

0 Likes
Message 6 of 26

Ed__Jobe
Mentor
Mentor

Use the handle of the document, ThisDrawing.HWND.

 

Edit, I see you might be running this from another app. Set a variable to the active document.

 

Dim oDoc as AcadDocument

Set oDoc = acadApp.ActiveDocument

LockWindowUpdate(oDoc.HWND)

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 7 of 26

jeremye86
Advocate
Advocate

Ed,

You are correct, i am running the code from excel.

Unfortunately, what you just suggested is causing excel to crash and shut down.

 

It is interesting, when i change Dim oDoc as AcadDocument to Dim oDoc as object it does not crash, but i don't see the LockWindowUpdate function working correctly.

 

 

 

 

 

 

 

0 Likes
Message 8 of 26

Ed__Jobe
Mentor
Mentor

It would seem that you don't have the correct AutoCAD tlb referenced in Excel. Set a breakpoint in Excel and see which line causes the crash. It also sounds like you don't have any error checking in your sub. You should be getting an error to the effect "Can't create object" or something similar.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 9 of 26

jeremye86
Advocate
Advocate

it crashes right when i step into the procedure.

What do you mean 'you don't have the correct AutoCAD tlb referenced'?

0 Likes
Message 10 of 26

Ed__Jobe
Mentor
Mentor

it crashes right when i step into the procedure.

 Do you have your breakpoint at the beginning of the sub?

 

 

What do you mean 'you don't have the correct AutoCAD tlb referenced'?

If you are going to to use AutoCAD objects you have to reference its type library (*.tlb). Go to Tools>References and check the appropriate tlb for your version of AutoCAD. I thought you might be using an older reference.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 11 of 26

jeremye86
Advocate
Advocate

yes i have it break at the beginning of the sub. 

 

i have the error trapping to break on all errors as well.  I also have the correct reference for autocad.  still no solution

 

this crashes excel

Dim oDoc as AcadDocument

Set oDoc = acadApp.ActiveDocument

LockWindowUpdate(oDoc.HWND)

 

this does not crash excel

Dim oDoc as object

Set oDoc = acadApp.ActiveDocument

LockWindowUpdate(oDoc.HWND)

 

0 Likes
Message 12 of 26

Ed__Jobe
Mentor
Mentor

i have the error trapping to break on all errors as well.

That's not error handling. Its the responsibility of your sub to determine what should happen when an error occurs. Below is a template of my standard error handling. What error number you should put in your Case..Select is a matter of trial and error. 🙂

Sub Main()
    On Error GoTo Err_Control

    'Do your work here.
    
    
Cleanup:
    Set oDwg = Nothing
    Set oDbx = Nothing
    
Exit_Here:
    Exit Sub
Err_Control:
    Select Case Err.Number
    'Add your Case selections here
    'Case Is = 1000
        'Handle error
        'Err.Clear
        'Resume Exit_Here
    Case Else
        MsgBox Err.Number & ", " & Err.Description, , "Main Title"
        Err.Clear
        Resume Exit_Here
    End Select
End Sub

 

After some research, I found this in an MSDN article.


 

Instead of LockWindowUpdate(hwnd)
Use SendMessage(hwnd, WM_SETREDRAW, FALSE, 0) or
SetWindowRedraw(hwnd, FALSE)
Instead of LockWindowUpdate(NULL)
Use SendMessage(hwnd, WM_SETREDRAW, TRUE, 0) or
SetWindowRedraw(hwnd, TRUE)

As we noted earlier, only one window in the system can be locked for update at a time. If your intention for calling LockWindowUpdate is merely to prevent a window from redrawing, say, because you're updating it and don't want the window continuously refreshing until your update is complete, then just disable redraw on that window. If you use LockWindowUpdate, you create a whole slew of subtle problems.



So...

Public Const WM_SETREDRAW = &HB

Declare PtrSafe Function SendMessage Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Any) As Long

'Lock window redraw
SendMessage(oDoc.HWND, WM_SETREDRAW, FALSE, 0)

'Do work here

'Reset window redraw
SendMessage(oDoc.HWND, WM_SETREDRAW, TRUE, 0)

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

Message 13 of 26

jeremye86
Advocate
Advocate

thanks Ed for your insights

 

this line is giving an error 

SendMessage(oDoc.HWND, WM_SETREDRAW, FALSE, 0)
0 Likes
Message 14 of 26

Ed__Jobe
Mentor
Mentor

Did you implement the error handling I gave you and did you get an error number/description?

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 15 of 26

jeremye86
Advocate
Advocate

its a syntax error

0 Likes
Message 16 of 26

Ed__Jobe
Mentor
Mentor

Try changing true/false to vbTrue/vbFalse.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 17 of 26

jeremye86
Advocate
Advocate

hey Ed, i still get a syntax error.

 

I guess i need to study up on windows API before i start using it.  thanks for all your help

0 Likes
Message 18 of 26

Ed__Jobe
Mentor
Mentor

You might have misspelled something or left out an argument. Post your code so we can have a look at it.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature

0 Likes
Message 19 of 26

jeremye86
Advocate
Advocate

i took out a lot for simplicity but here is the general idea of what i am doing

Option Explicit

Public Const WM_SETREDRAW = &HB
#If VBA7 And Win64 Then
Declare PtrSafe Function SendMessage Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As Any) As Long
#Else
Declare Function SendMessage Lib "user32" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, _
ByVal lParam As Any) As Long
#End If


Sub open_autocad()

    Dim acadApp As Object
    Dim oDoc As AcadDocument

    'Check if AutoCAD application is open. If it is not opened create a new instance and make it visible.
    On Error Resume Next
    Set acadApp = GetObject(, "AutoCAD.Application")
    acadApp.Visible = True
    If acadApp Is Nothing Then
        Set acadApp = CreateObject("AutoCAD.Application")
        acadApp.Visible = True
    End If
    
    'Check (again) if there is an AutoCAD object.
    If acadApp Is Nothing Then
        MsgBox "Sorry, it was impossible to start AutoCAD!", vbCritical, "AutoCAD Error"
        Exit Sub
    End If

    On Error GoTo 0
  
    acadApp.WindowState = acMax
    

    acadApp.Application.Documents.Add
    Set oDoc = acadApp.ActiveDocument

    
    SendMessage(oDoc.HWND, WM_SETREDRAW, vbfalse, 0)
    
    
    'do work here
    
    acadApp.Application.Documents.Add
    acadApp.Application.Documents.Add
    acadApp.Application.Documents.Add
    acadApp.Application.Documents.Add
 
    SendMessage(oDoc.HWND, WM_SETREDRAW, vbtrue, 0)
 
 
End Sub

 

0 Likes
Message 20 of 26

Ed__Jobe
Mentor
Mentor

Try

 

SendMessage oDoc.HWND, WM_SETREDRAW, 0&, 0

 

SendMessage oDoc.HWND, WM_SETREDRAW, 1&, 0

 

You only use the parenthesis when the function is on the right side of an equals sign, like when you are setting a variable to the value returned by the function.

 

Also, I changed the TRUE/FALSE to 1& and 0& because those constants are defined in .NET, but not VBA. vbTrue is a tristate and not quite the same.

Ed


Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
How to post your code.

EESignature