Author Topic: Activate new window  (Read 20270 times)

0 Members and 1 Guest are viewing this topic.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« on: November 25, 2003, 03:06:04 PM »
Ok, anyone out there familiar with API please help....
I am in need of making the AutoCAD current drawing the current window AFTER I specify a new application window as HWND_TOPMOST.

Here is the scenario....
I am developing an external app that runs in windows alongside of AutoCAD. I need this app to stay on top so that the user can change the settings on the fly AND be visible so the user can select the commands associated with the program.

I have been able to set the HWND_TOPMOST setting of the external dialog, but whenever I send the commands to AutoCAD, I have to click 2 or 3 times in the drawing window to make it current so I can use the program. This is really a frustrating proposition.

I would like to have the external app remain on top, but be inactive and the AutoCAD current drawing to become active so I don't have to click 2 or 3 times in the drawing, then inadvertently clicking in the wrong place and having to start again.

Am I making myself clear?
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« Reply #1 on: November 26, 2003, 02:37:21 PM »
Ok just to let you guys know... you are off the hook... I received an email from someone I didn't know (maybe they didn't want to offend me by making me feel inferior) Anyway the answer is:
Code: [Select]

Public Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Public Declare Function SetForegroundWindow Lib "user32" (ByVal hWnd As Long) As Boolean

SetForegroundWindow FindWindow(vbNullString, AcadApplication.Caption)


He just pointed me in the right direction and the rest was mine...

This API stuff is awesome!!
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
Activate new window
« Reply #2 on: November 26, 2003, 02:48:23 PM »
Well, if you didn't find out, I was thinking of sending you to vbdesign.net. I have some questions. What are the uses of programming the API and how do you go about understanding how?

SMadsen

  • Guest
Activate new window
« Reply #3 on: November 26, 2003, 03:01:33 PM »
KEB, just curious, don't you have to take specific action to keep the inactivated window on top?
I thought SetForegroundWindow would put the whdl in front, while e.g. PutFocus would simply allow it to be handled without put in front.

SMadsen

  • Guest
Activate new window
« Reply #4 on: November 26, 2003, 03:03:25 PM »
Daron, check out http://www.allapi.net. They have some great (and free) resources.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« Reply #5 on: November 26, 2003, 03:08:21 PM »
SMadsen, the inactive window is behind the controlling application. The controlling application has the HWND_TOPMOST bit set and as such will always remain on top (similar to WinZip when you select the "Always on Top" checkbox).
The topmost window can be inactive, and regardless of which window is the active one, it will remain on top but greyed out.
What I needed was for the topmost application to automatically make the AutoCAD window the active window, since it was done outside of AutoCAD, the process was handled through API functions.
I have already implemented the function calls in my program and it works wonderfully.

Daron, API programming allows you to use ANY function defined as portable within ANY dll,exe,odl,arx,tlb, and any other format of executable binary file you can imagine.

Think of the C and C++ functions that you are aware of. All you do is declare that function with the appropriate arguments and types within VBA and then you can simply call that C or C++ function.

For example, you want to change the title of AutoCAD to reflect your addon package defined in VBA. In plain VBA the AcadApplication.Caption is 'read only', so you can't apply a new caption with AcadApplication.Caption = "New Caption" BUT you can call the SetWindowText C++ command by declaring it and set the caption there. This is powerful stuff that can get you into trouble if you are not sure what you are doing.

Check out this post to see what I mean.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

SMadsen

  • Guest
Activate new window
« Reply #6 on: November 26, 2003, 03:29:17 PM »
Quote from: KEB
I have already implemented the function calls in my program and it works wonderfully.
Sounds great. Gotta check it out sometime soon.
On the Mac one could specify a always-on-top window by its window proc. I got confused by the Z ordering in Windows where it seems you can force windows on top of such a window.

Quote from: KEB
This is powerful stuff that can get you into trouble if you are not sure what you are doing.
Yeah .. and in trouble with your colleagues by making AutoCAD play music to each command :)

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« Reply #7 on: November 26, 2003, 03:35:28 PM »
I hadn't though of that.... Maybe make a little program that ran in the background that waited every 5 or 10 minutes and then played their "you got mail" wave. They would wonder what the heck was going on.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

SMadsen

  • Guest
Activate new window
« Reply #8 on: November 26, 2003, 03:40:07 PM »
Here's one for simple wav's  :)

Code: [Select]
Private Const SND_ASYNC = &H1         '  play asynchronously
Private Const SND_FILENAME = &H20000  '  file name
Private Declare Function PlaySound Lib "winmm.dll" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long

Private Sub PlayItSam()
    PlaySound "C:\WINDOWS\MEDIA\TADA.WAV", ByVal 0&, SND_FILENAME Or SND_ASYNC
End Sub

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« Reply #9 on: November 26, 2003, 04:03:15 PM »
Now all we need is a timer.....

I was thinking about....

Code: [Select]

Declare Function SetTimer Lib "user32" (ByVal Hwnd As Long, ByVal IdEvent As Long, ByVal seconds As Long, ByVal Func As Variant) As Long
Sub NewTimer()
Dim RVal As Long
 RVal = SetTimer(NULL, 1, 30, NULL)
End Sub

But I am getting an invalid use of NULL error.
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

daron

  • Guest
Activate new window
« Reply #10 on: November 26, 2003, 04:24:27 PM »
That is funny.

SMadsen

  • Guest
Activate new window
« Reply #11 on: November 26, 2003, 05:14:20 PM »
Hmm, can't get it to work either - the SetTimer thing that is

SomeCallMeDave

  • Guest
Activate new window
« Reply #12 on: November 26, 2003, 07:53:37 PM »
I think SetTimer needs a callback function.  Something like
 
in a module
Code: [Select]

Option Explicit
Public Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerFunc As Long) As Long
Public Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Public Function TimerProc() As Long
  MsgBox "Timer Fired"
End Function

Public Function TimerSetup(pInterval As Long) As Long
  Dim lngRet As Long
  lngRet = SetTimer(0&, 0&, pInterval, AddressOf TimerProc)
  TimerSetup = lngRet
End Function

Public Function StopTimer(pTimer As Long)
  KillTimer 0&, pTimer
End Function


In a form, I put
Code: [Select]

Option Explicit
Dim hwndTimer As Long
Private Sub Command1_Click()
 hwndTimer = Module1.TimerSetup(2000)
End Sub

Private Sub Command2_Click()
  Module1.StopTimer hwndTimer
End Sub

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Activate new window
« Reply #13 on: November 27, 2003, 06:54:52 AM »
Beautiful!!!
Now all I need to do is make it transparent to the user....
 :twisted:  :twisted:  :twisted:  :twisted:
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

SMadsen

  • Guest
Activate new window
« Reply #14 on: November 27, 2003, 07:10:44 AM »
SCD, thanks. I tried handing SetTimer a proc in the same manner but couldn't figure out why AddressOf returned an error: expression expected.
Isn't there something about pointers not being a valid datatype in VBA?