![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | Alert Window on top of all other windows - like Task Manager Hi Group Is there an easy way (i guess there is) to make modal alert popping op on top af all windows. Cheers |
My System Specs![]() |
| | #2 (permalink) |
| | Re: Alert Window on top of all other windows - like Task Manager Leon wrote: Quote: > Is there an easy way (i guess there is) to make modal alert popping op > on top af all windows. > This is virtually impossible from script, and is virtually impossible even when you stretch things a bit. If by "modal alert" you mean a message box displayed by your own script, then it should initially show "on top", but as time goes on, other popups can intrude and cover over your own alert popup. About the best you can do FROM SCRIPT is to set a timer (one is available in the IE object model), to go off periodically. Your script will get control back -- even though a modal dialog is showing. You can then "AppActivate" the modal dialog window, which should give it focus and bring it back "on top", at least temporarily. If you are courageous enough, or foolhardy enough to use the system api from script, then you could use the "FindWindow" api to get the window handle of the dialog, and "SetWindowPos" api with the "HWND_TOPMOST" flag set. This may be more effective than the approach outlined above, and will last until some other app comes along and tries to make itself the topmost window. Microsoft has taken steps to make it difficult to place your own window on top, for a number of reasons, including the reason that microsoft's own programmers were among the worst offenders. It is considered rude behavior to insist that your own app is on top of all the others. Better to let the user choose which app he/she wants on top by using the taskbar. cheers, jw ____________________________________________________________ You got questions? WE GOT ANSWERS!!! ..(but, no guarantee the answers will be applicable to the questions) |
My System Specs![]() |
| | #3 (permalink) |
| | Re: Alert Window on top of all other windows - like Task Manager On Feb 5, 9:04*pm, mr_unreliable <kindlyReplyToNewsgr...@xxxxxx> wrote: Quote: > Leon wrote: Quote: > > Is there an easy way (i guess there is) to make modal alert popping op > > on top af all windows. > hi Leon, > > This is virtually impossible from script, and is virtually > impossible even when you stretch things a bit. > > If by "modal alert" you mean a message box displayed by > your own script, then it should initially show "on top", > but as time goes on, other popups can intrude and cover > over your own alert popup. > > About the best you can do FROM SCRIPT is to set a timer > (one is available in the IE object model), to go off > periodically. *Your script will get control back -- even > though a modal dialog is showing. *You can then "AppActivate" > the modal dialog window, which should give it focus and > bring it back "on top", at least temporarily. > > If you are courageous enough, or foolhardy enough to use > the system api from script, then you could use the > "FindWindow" api to get the window handle of the dialog, > and "SetWindowPos" api with the "HWND_TOPMOST" flag set. > This may be more effective than the approach outlined > above, and will last until some other app comes along > and tries to make itself the topmost window. > > Microsoft has taken steps to make it difficult to place > your own window on top, for a number of reasons, including > the reason that microsoft's own programmers were among the > worst offenders. *It is considered rude behavior to insist > that your own app is on top of all the others. *Better to > let the user choose which app he/she wants on top by using > the taskbar. > > cheers, jw > ____________________________________________________________ > > You got questions? *WE GOT ANSWERS!!! *..(but, no guarantee > * * the answers will be applicable to the questions) do you know an "easy" way to call API functions from script? I don't but I've always wondered if it's possible. As for the problem of placing windows on top, I a) agree, that it should be used with big caution for it may easily lead to unwanted behaviour. E.g.: I'm writing an e-mail. I'm typing these words: ... yours sincerellY Before I press the last key a window appears asking me: "Do you want to restart right now? [Yes] / [No]". To which I will inadvertently answer "Yes" though the reason why I pressed the "Y" was the last letter in the word "sincerellY". Well in fact, this is about stealing focus, not exactly about being on top, but I think it mostly tends to come together. BTW place your favourite question dialog above. E.g. "Do you really want to blast this atomic plant? [Yes] / [No]", "Do you want to open the airlock on this spaceship? [Yes] / [No]" b) disagree, that programmer shouldn't be barred in any way. Presumably he does it because the user wants/needs it. And if the user needs it, he/she should get it. It's the programmer's responsibility to use appropriate means, not "Microsoft's" or any other vendor's. regards Tomy |
My System Specs![]() |
| | #4 (permalink) |
| | Re: Alert Window on top of all other windows - like Task Manager Tomy wrote: Quote: > do you know an "easy" way to call API functions from script? > I don't but I've always wondered if it's possible. > Yes, there is an easy way, but then most professional scripters will scorn and dis-respect you if you do call api's from script. Their opinion is that if you were supposed to be able to call api's from script, then microsoft would have provided that capability. The "easy way" is to call a third-party control, which will then call the api for you. There is one such 3rd-party control called "DynaWrap" (see the "boilerplate" below. I have also included a demo script, which uses dynawrap to call api's and Steve McMahon's SSubTmr.dll actX object for it's built-in timer (NOT its subclassing capabilities). You may get SSubTmr here: http://www.vbaccelerator.com/home/VB...Tmr_Binary.asp The script (if it will run successfully on your system) will show periodic "progress message boxes" -- which start life as ordinary message boxes, but which are re-drawn using the system api. --- <DynaWrap Demo Code> --- ' script to demonstrate "buttonless" popup, jw 10Oct00 ' (a close cousin to the "three ugly hack" demo of 16Apr00) ' author: mr_unreliable ' ' Method: Call timer after showing popup to get control back. ' Then find the popup window, find the child window (button), ' and hide the button. (Final embellishment, resize the popup ' to eliminate the "void" where the button used to be)... ' ' Use Steve McMahon's SSubTmr control for the timer. ' Use DynaWrap to call the api's... ' ' This technique can be used for progress reporting, i.e., you could ' show a little popup periodically, to re-assure you users that you ' were still actively doing stuff for them... ' ' Note for this (and only this) script... ' Although in general my preference is to declare api's one-at-a-time, ' this script may be an exception. That's because timing is critical ' in the timer event handler. You want to run through a bunch of api ' calls faster than the screen can repaint, so as to avoid showing the ' popup in its original state, making it critical to run through as fast ' as possible. By (pre-) defining every api definition as a separate ' instance of DynaWrap, that cuts out about half of the code in the event ' handler. As it is, you can just make out (especially if you'refrom ' Klingon) the dialog changing. Perhaps if we had coded a separate ' instance for every api call, we could have made the popup changes ' more undetectable, or maybe not. (I didn't try this, and by making ' use of the "LockWindowUpdate" api, this is no longer a consideration)... ' ' --- revision histroy --------------------------- ' 16Apr00: begin life as "the three ugly hack" demo script... ' 10Oct00: revised to show popup and hide OK button... ' 16Jun01: added LockWindowUpdate code, to avoid the "flicker", ' also, recoded ALL the DynaWrap calls to use wrappers (makes code more svelte)... ' --- end of revisions --------------------------- Option Explicit ' --- module level variables --------------------- Public hWnd, hBtn ' as long Public nPctComp Public cTries ' as long (count of tries to find window) ' ' --- declarations and constants ----------------- Const nSecToWait = 2 ' limit of duration to show popup Const sPopupCaption = " < Demo Buttonless Popup >" ' ' note: you may have to adjust the "waitforpopup" interval, ' depending on the speed of your system. You have to allow time ' for the popup to be created, but also attempt to hide the button ' before the first screen repaint. For me 10ms works about right, ' i.e., you never see the button. 20-25ms is just a little too long... Const tWaitForPopup = 10 ' timer interval Const MAX_TRIES = 3 ' give up attempting to find popup win, after x tries... ' Const SW_HIDE = &H0 ' ShowWindow constants... Const SW_SHOW = &H5 Const SWP_NOMOVE = &H2 ' SetWindowPos constants... Const SWP_NOZORDER = &H4 ' ------------------------------------------------ ' instantiating ActX components here... Dim oTMR : Call Instantiate (oTMR, "SSubTimer.CTimer", "oTMR_") Dim oDW : Call Instantiate (oDW, "DynamicWrapper", "") ' (no events) Dim oSH : Set oSH = WScript.CreateObject("WScript.Shell") ' --- end of initialization ---------------------- ' a dummy loop, to report progress as we go along... For nPctComp = 10 to 100 step 10 WScript.Sleep 1500 ' pretend to work (don't tell the boss we're sleeping) Call ShowPopupMsg("Script work is: " & CStr(nPctComP) & " pct complete") Next ' nPctComp ' and for "good measure", one final (unadulterated) popup... oSH.Popup "YOUR SCRIPT WORK IS FINISHED!!!" & vbCr & vbCr _ & " (this dialog will close in 5 sec)", 5, _ " (this is a 'real' unadulterated popup)" ' finished showing popups, clean up and exit... oTMR.Interval = 0 ' make sure timer is OFF... Set oTMR = nothing Set oDW = nothing Set oSH = nothing WScript.Quit ' ================================================ ' === SUBROUTINES FOLLOW ========================= ' ================================================ ' --- SHOW POPUP MSG (i.e., a progress message) --- Sub ShowPopupMsg(sMsg) Const sAddReminder = " (note: no button below)" Dim hDskTop, nRtn ' as long oTMR.Interval = tWaitForPopup ' turn on timer (to get back control)... cTries = 0 ' init counter... ' LockWindowUpdate (so as to not show the mb popup until ready)... hDskTop = GetDesktopWindow() nRtn = LockWindowUpdate(hDskTop) oSH.Popup sMsg & vbCr & vbCr & sAddReminder, nSecToWait, sPopupCaption End Sub ' --- TIMER EVENT HANDLER ------------------------ Sub oTMR_ThatTime ' timer event... Dim nRtn ' as long cTries = cTries + 1 BugAssert (cTries <= MAX_TRIES), " ..couldn't find popup window" ' attempt to find popup window (giving: class, caption)... hWnd = FindWindow("#32770", sPopupCaption) if hWnd <> 0 then ' if you found the popup, then go find button... hBtn = FindWindowEx(hWnd, 0, "Button", 0) if hBtn <> 0 then ' if you find the button, then hide it... nRtn = ShowWindow(hBtn, SW_HIDE) ' then resize the popup, (a "belt-and-suspenders" touch, ' as the button is hidden, but resizing makes the popup look ' a little more svelte and eliminates that "void" where the ' button used to reside)... nRtn = SetWindowPos(hWnd, 0, 0, 0, 200, 85, SWP_NOMOVE Or SWP_NOZORDER) End If ' check hBtn End If ' check hWnd oTMR.Interval = 0 ' and turn off the timer... nRtn = LockWindowUpdate(False) ' UN-lock window update End Sub ' --- INSTANTIATE ACTX OBJECT (or class) AND CHECK ---- ' (using a sub to get this ugly instantiation code out of main line code)... Sub Instantiate (oObject, sProgramID, sEventPrefix) Const sME = "[sub Instantiate], " ' check variant sub-type parameters... BugAssert (VarType(sProgramID) = vbString), sME & "sProgramID must be a STRING!" BugAssert (VarType(sEventPrefix) = vbString), sME & "sEventPrefix must be a STRING!" On Error Resume Next ' turn on error checking Set oObject = WScript.CreateObject(sProgramID, sEventPrefix) BugAssert (err.number = 0), sME & "This script requires: " & sProgramID & vbCrlf _ & " kindly INSTALL and REGISTER this ActX component... " On Error goto 0 ' turn off error checking... End Sub ' --- BUGASSERT (yes, it's for debugging) -------- Sub BugAssert (bTest, sErrMsg) ' BugAssert is a Bruce McKinney creation. ' It is used to test for intermediate results... if bTest then Exit Sub oTMR.Interval = 0 ' make sure timer is OFF... Set oTMR = nothing MsgBox "Error Detected by BugAssert: " & vbCr & vbCr & sErrMsg, _ vbCritical, " << BugAssert FAILED >> " WScript.Quit End Sub ' ================================================ ' ================================================ ' === "WRAPPERS" FOR API CALLS (DynaWrap style) == ' ' the DynaWrap doc is rather inscrutable, but as best I can make out, ' DynaWrap can only accomodate ONE api declaration at a time. ' (If I'm wrong, maybe you experts can straighten me out on this). ' ' Assuming that my one-at-a-time hypothesis is correct, ' then one has two choices: ' - you need to set up a separate obj for EVERY api (ugh!), or ' - declare the api's to be used (one-at-a-time) as you go, ' which is what you see here (yes, it's "ugly")... ' ' ------------------------------------------------ ' the DynaWrap parameters are: ' i => the number and data type of the function's parameters ' (n.b., if no paramaters, LEAVE OUT this "i=" argument) ' f => type of call _stdcall or _cdecl. ' (Default to _stdcall. If that doesn't work use _cdecl). ' r => return data type. ' the data type declarations are: ' c => VT_I4: c signed char ' d => VT_R8: d 8 byte real ' f => VT_R4: f 4 byte real ' h => VT_I4: h HANDLE ' l => VT_I4: l long ' p => VT_PTR: p pointer ' s => VT_LPSTR: s string ' t => VT_I2: t short ' u => VT_UINT: u unsigned int ' w => VT_LPWSTR: w wide string ' r => VT_BYREF: (pass by reference) for strings only. ' ================================================ ' ================================================ Function GetDesktopWindow() Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... ' (note: no parameters, so LEAVE OUT "i=" argument)... oDW.Register "USER32.DLL", "GetDesktopWindow", "f=s", "r=h" GetDesktopWindow = oDW.GetDesktopWindow() End Function Function LockWindowUpdate(hWnd) Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... ' (note: string passed byref to allow for proper return address)... oDW.Register "USER32.DLL", "LockWindowUpdate", "i=l", "f=s", "r=l" LockWindowUpdate = oDW.LockWindowUpdate(CLng(hWnd)) End Function Function SetWindowPos(hWnd, hWndInsertAfter, x,y, cx,cy, wFlags) Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... oDW.Register "USER32.DLL", "SetWindowPos", "i=lllllll", "f=s", "r=l" SetWindowPos = oDW.SetWindowPos(CLng(hWnd), CLng(hWndInsertAfter), _ CLng(x), CLng(y), CLng(cx), CLng(cy), CLng(wFlags)) End Function Function ShowWindow(hWnd, nCommand) Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... oDW.Register "USER32.DLL", "ShowWindow", "i=ll", "f=s", "r=l" ShowWindow = oDW.ShowWindow(CLng(hWnd), CLng(nCommand)) End Function Function FindWindow(sClass, sCaption) Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... oDW.Register "USER32.DLL", "FindWindowA", "i=ss", "f=s", "r=h" FindWindow = oDW.FindWindowA(CStr(sClass), CStr(sCaption)) End Function Function FindWindowEx(hParent, hChildAfter, sChildClass, sChildCaption) Set oDW = nothing ' clear any previous instance Set oDW = CreateObject("DynamicWrapper") ' start over... ' register (declare) this flavor of api call... ' (fudged def a bit to allow for using "0" - for ignore - as ChildCaption) oDW.Register "USER32.DLL", "FindWindowExA", "i=hhsl", "f=s", "r=h" FindWindowEx = oDW.FindWindowExA(CLng(hParent), CLng(hChildAfter), CStr(sChildClass), 0) End Function ' === end of api call wrappers =================== ' ================================================ ' ================================================ --- </DynaWrap Demo Code> --- cheers, jw ____________________________________________________________ You got questions? WE GOT ANSWERS!!! ..(but, no guarantee the answers will be applicable to the questions) --- <DynaWrap Boilerplate> --- It is possible to declare-and-call an api from script, but you must use a third-party control to do so, or else write one yourself. It has already been correctly pointed out that there is no api-capability in "pure" script. If you are willing to use a third-party control, then one such control, called "DynaWrap", can be found on Guenter Born's website (note: Guenter refers to it as "DynaCall"). Here is the link to it: http://people.freenet.de/gborn/WSHBa...SHDynaCall.htm - or - http://ourworld.compuserve.com/homep...SHDynaCall.htm On that page you will find a download for the control, plus some code samples. Note: you may find additional sample code by searching the archives of the wsh and vbscript ng's. Note also: DynaWrap does have its limitations. There are certain things it can't do. For example, you can't call api's "by ordinal". (I had previously asserted that you can't use DynaWrap to call api's which take typedefs as parameters, but I have been proven wrong on that -- although it took me about two weeks to figure out how it was done). Regardless, Dynawrap will work for most of "the usual suspects". And finally, DynaWrap doesn't work entirely as advertised. For example, it is supposed to allow for the declaration of several api definitions in one instance of itself. I could never get that to work (in win9x -- but others have shown this to work as advertised under winNT). With win98, you will need a new instance of DynaWrap for every api, or else re-instantiate the object for every api. Someday I'm going to learn enough c++ to fix that... Another possibility (for calling api's from script is XNeat: http://www.xneat.com/doc/call_win32_api.html One other thing. While the above discussion is oriented to calling the system api's, contained in the user32, kernel32, gdi32 and other system dll's, you could use DynaWrap (and other similiar utilities) to call the exported interfaces to ANY dll. --- </DynaWrap Boilerplate> --- |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Windows Task Manager | Vista General | |||
| Task Manager will not come up in window | General Discussion | |||
my 'Task Manager' window changed.. | General Discussion | |||
| Windows task Manager | Vista General | |||
| Windows Task Manager | Vista installation & setup | |||