Forums before death by AOL, social media and spammers... "We can't have nice things"
|    comp.databases.paradox    |    To crash or not to crash, asks Borland    |    9,834 messages    |
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
|    Message 9,297 of 9,834    |
|    Robert Wiltshire to All    |
|    Preventing a form from opening a second     |
|    26 Jul 08 00:51:40    |
   
   From: nomail@nospam.com   
      
   I have a form that assists me with programming tasks,   
   and I would like to make sure it does not open a second time.   
      
   Using a script,   
   I am familiar with doing something like the following   
   ( I am typing this off the top of head, so it is not syntax checked )   
      
   stFormname=":ztools:\\coding\\pickfields.fsl"   
   stTitle = "Pick Field Utility"   
   if not f.attach(stTitleOfForm) then   
    f.open(stFormname)   
   endif   
      
   And that would be fine,   
   except, as part of my issue,   
   I would like the code to be *inside* the form itself,   
   not in an external script.   
      
   I ended up figuring out 2 ways to do this,   
   and I wanted to share this experience,   
   but I welcome any input from others on how to do this.   
   This post gets a little long, so proceed with caution. =)   
      
   Remember, I want the prevention code to be inside the form,   
   not in an external script, form, or library.   
      
      
   Solution 1 :   
      
   I decided to start in the init section of the form,   
   and I am using either pdox 10 sp3 or pdox X3.   
      
   Inside the form, I found the following useful :   
      
   f.attach()   
   stTitleThisForm = f.getTitle()   
      
   This allows me to fetch the title on the fly, as the form that is opening,   
   and eliminates the need to hard code the form title.   
   ( which I think is a huge plus )   
      
   I then used enumFormnames(arForms) to list all open forms to an array,   
   and I can step through that array to see that the form is in there twice.   
   If I find that arForms contains stTitleThisForm more than once,   
   I simply exited the form that was loading as follows :   
      
    eventInfo.setErrorCode(canNotArrive)   
    close()   
    return   
      
   This closes the form, and only leaves one instance of the form open on the   
   desktop.   
   But, that form is not guaranteed to be on top,   
   and even though I did not want this form open 2 times,   
   I did want the open copy of this form to come to the top of the pile.   
      
   So as many programming tasks happen,   
   the main idea was fairly easy, but the last touch was a pita.   
      
      
   If I had a form handle, I could use f.bringToTop(),   
   but.........I dont see any way to get a handle to the first instance of the   
   form,   
   from the code in that form as it is opening the second time.   
      
   The problem is, the title of the 1st instance is the same title as the 2nd   
   instance,   
   and we are now talking about the code that is running in the 2nd instance of   
   the form.   
      
   If you call enumFormnames(arForms)   
   and then call ( or somethign similar, depending on what forms open)   
   if arForms[1] = arForms[2] then   
    msgInfo("Note","2 titles are the same")   
   endif   
   So, this proves that pdox thinks both instances of the form have the same   
   name.   
   Obviously the above indexes to the array need to be correct,   
   to reflect where they are ni the array.   
   I simply used arForms.view() to look at array and determine necessary index.   
      
   Trying   
   f.attach(arForms[1]) and f.attach(arForms[2])   
   always returned a form handle to the 2nd instance of the form,   
   which makes sense , since it was the same exact title.   
      
   Without the form handle,   
   I was unable to call the pdox form method bringToTop.   
      
      
   I did find that there was a windows api call,   
   and the uses statement looks like   
      
   "USER32"   
   BringWindowToTop(hWnd CLONG) CLONG   
      
   This requires a windows handle for the form,   
   not a paradox form handle.   
   This ended up being fairly easy to get,   
   using the paradox procedure : enumDesktopWindowHandles,   
   which returns all paradox form handles in a dynarray,   
   with the index of the dynarray being the handle,   
   and the value being the window name.   
      
   enumDesktopWindowHandles(dyHandles)   
      
   We get the handle for the currently executing 2nd instance of the form   
   rather easily as follows :   
   This gets handle of the current instance of the form   
   liHandleThisForm = f.windowHandle()   
      
   init handle of the 1st instance we are looking for   
   liHandleOtherForm = 0   
      
   Now step thru dynarray, and find title   
   but remember title is in the dynarray 2 times   
   and we want the handle for the one that is different from the current form   
      
   foreach stHandle in dyHandles   
    stTitle = dyHandles[stHandle]   
      
    if stTitle = stTitleThisForm then   
    liHandle = longint(stHandle)   
    if liHandle <> liHandleThisForm then   
    liHandleOtherForm = liHandle   
    quitloop   
    endif   
    endif   
      
   endforeach   
      
   If for some reason, we didnt find it, do not call windows api function   
   if liHandleOtherForm = 0 then   
    return(false)   
    endif   
      
   call api function, to bring 1st instance to the top of the pile   
   liRet = BringWindowToTop(liHandleOtherForm)   
      
   and then exit and close self as mentioned before   
      
      
      
   Second Solution   
      
   I had mentioned before,   
   the issue to get pdox form handle is difficult   
   because both instances have the same exact title.   
      
   I went and manually entered the form title to be   
   stTitle = "Pick Field Utilityx"   
      
   My idea was to modify the title of the open form,   
   so that it had a slightly differnt value than the form in the init stage.   
   This worked rather well.   
      
   So the init method looks like   
      
   method init(var eventInfo Event)   
      
   var   
    fThis,fOrig form   
    stTitleThisForm,stNewTitle string   
   endvar   
      
   attach to current form, and get its title   
   fThis.attach()   
   stTitleThisForm = fThis.getTitle()   
      
   for new title, removes last char from orig title   
   stNewTitle = stTitleThisForm.substr(1,stTitleThisForm.sizeEx()-1)   
      
   if possible, attach to corrected title, bring to top, and close down   
   if fOrig.attach(stNewTitle) then   
    fOrig.bringtotop()   
    eventInfo.setErrorCode(canNotArrive)   
    close()   
    return   
    endif   
      
   form was not open, so change this form title   
   fThis.setTitle(stNewTitle)   
      
   endMethod   
      
   Thats it.   
   It seems to work ok.   
      
      
   I added this to the close method of this form,   
      
   fix up title to original   
   f.attach()   
   f.setTitle(f.getTitle() + "x")   
      
   I was thinking of putting a box object on the form,   
   and putting all relevant code inside it,   
   so that I could simply plop it on any form that needed this code,   
   but I did not get around to that yet.   
      
   Perhaps there are easier ways to do this.   
   Comments, suggestions, and discussion always welcome.   
      
      
   Robert Wiltshire   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   
|
[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]
(c) 1994, bbs@darkrealms.ca