Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to freeze a top-level form

Status
Not open for further replies.

vernpace

Programmer
Feb 22, 2015
209
US
Hi All,

OK, this is a strange requirement. I need to "freeze" a top-level form during long decryption processes which cannot be interrupted. What I mean by "freeze": The form cannot be moved, closed, minimized, maximized, and a user cannot have the ability to click on any objects. The user needs to retain the ability to click on any desktop icon and load any application on top of the "frozen" form.

I know this can be done (maybe not in VFP) because I am now watching ScanDisk SecureAccess doing that exact thing. Any ideas?
 
Something like that makes a form pretty unusable:

Code:
form.minbutton=.f.
form.maxbutton=.f.
form.closable=.f.
form.titlebar=0
form.setall("enabled",.F.)

Anyway, you can't stop users killing your process via task manager.

Bye, Olaf.



 
I would add the following to Olaf's suggestion:

[tt]thisform.MousePointer = 11[/tt]

This displays the mouse pointer as an hourglass. Set it to 0 afterwards to return it to normal.

In general, users can't click on any controls while a long process is running. You don't have to take any special action to achieve that. However, by setting the mouse pointer to an hourglass, you make that more obvious to the users.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Olaf,

I tried all of that but having problems with my PageFrame toolbar. I have a lightbox method in my form baseclass that works, but sometimes the form will shift a few pixels from the bitmap during the process which is very annoying.

Mike, the mouse pointer displays the hourglass without my having to do anything. We are decrypting large documents which is CPU intensive. Actually, the hourglass is a problem because we would like users to access other applicaions during the process if they need to.
 
Accessing other applications shouldn't be a problem. The hourglass will only be active while the mouse is over your form. The user should still be able to use the Windows taskbar, Start menu, etc., as well as other applications.

Regarding your problem re the form shifting a few pixels, can you explain what you mean. Waht is a "pageframe toolbar"? And what is a "lightbox method"?

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Pageframe toolbar is indeed unclear. There are the tabs of a pageframe and you may have a toolbar also controlling a form.

The titlebar=0 would oviously remove the titlebar and therefore shift the form. But nothing else will make the form immovable by gripping it at the titlebar and moving it around.

If you only need that part of your prerequisites to have the right rectangle darkened, then don't set titlebar=0

@Mike: Lightbox is the term for darkening the whole screen but a single form needing attention, as Windows does, if you start a setup, for example.
A Lightbox effect is not what you should aim for, as you want the whole windows system to stay usable, you only want to disable the current form and just keep it running.

Bye, Olaf.
 
I have a pageframe (with pages) in my toolbar. That is my menu system. There are button images on the pages. Works great.

The lightbox method I have creates image bitmaps (exact pictures with optional shading) of form objects, then sets the objects visible = .F.. This is necessary for ActiveX controls:

Code:
LPARAMETERS toObject AS Object, tlEnable AS Logical, tiColor AS Integer, tnFactor AS Number
LOCAL loContainer, lcImage, llImage, loImage, liWidth, liHeight, liColor, lnFactor, lnRed, lnGreen, ;
      lnBlue, loClrMatrix, loBmp, loGfx, lcFile

loContainer = toObject

DO WHILE NOT INLIST(loContainer.BaseClass, "Form", "Page")
   loContainer = loContainer.Parent
ENDDO

lcImage = "oImgLightBox_" + toObject.Name
llImage = PEMSTATUS(loContainer, lcImage, 5)

DO CASE
   CASE tlEnable and llImage
        loImage = EVALUATE("loContainer." + lcImage)
        loImage.ZOrder(1)
        loImage.Visible = .F.
        loImage.PictureVal = ""
        toObject.Visible = .T.

   CASE NOT tlEnable
        IF NOT llImage
           loContainer.AddObject(lcImage, "Image")
        ENDIF

        liWidth  = toObject.Width
        liHeight = toObject.Height
        loImage  = EVALUATE("loContainer." + lcImage)

        WITH loImage
            .Stretch = 2
            .Top     = toObject.Top
            .Left    = toObject.Left
            .Width   = liWidth
            .Height  = liHeight
            .Anchor  = 240
        ENDWITH

        IF PCOUNT() > 2
           IF VARTYPE(tiColor) = "N"
              liColor = tiColor
           ELSE
              liColor = RGB(240, 240, 240)
           ENDIF

           IF VARTYPE(tnFactor) = "N" AND tnFactor <= 1
              lnFactor = tnFactor
           ELSE
              lnFactor = 0.90 && 0 = Dark   1 = Bright
           ENDIF

           lnRed   = BITAND(liColor, 0x000000FF) / 255 * lnFactor
           lnGreen = BITRSHIFT(BITAND(liColor, 0x0000FF00), 8) / 255 * lnFactor
           lnBlue  = BITRSHIFT(BITAND(liColor, 0x00FF0000), 16) / 255 * lnFactor

           WITH _Screen.System.Drawing
                loClrMatrix = .Imaging.ColorMatrix.New(lnRed,       0,      0, 0, 0, ;
                                                           0, lnGreen,      0, 0, 0, ;
                                                           0,       0, lnBlue, 0, 0, ;
                                                           0,       0,      0, 1, 0, ;
                                                           0,       0,      0, 0, 1)
                loBmp = .Bitmap.FromScreen(loImage)
                loBmp.ApplyColorMatrix(loClrMatrix)
                loGfx = .Graphics.FromImage(loBmp)
                loGfx.FillRectangle(.SolidBrush.New(.Color.FromARGB(10, 0, 0, 0)), 0, 0, liWidth, liHeight)
           ENDWITH
        ELSE
           loBmp = _Screen.System.Drawing.Bitmap.FromScreen(loImage)
        ENDIF

        WITH loImage
            .PictureVal = loBmp.GetPictureValFromHBitmap()
            .ZOrder(0)
            .Visible = .T.
        ENDWITH

        toObject.Visible = .F.

ENDCASE

To use this, you have to have GDIPlusX v1.20 installed and running. This is very usefull for many things. For example, my slider class uses it for ActiveX controls. ActiveX controls are problematic since they show through everything laid over them.

The problem with the method is that I cannot figure out how to use it with an entire form without errors. I'll tinker around and get it to work...
 
>The problem with the method is that I cannot figure out how to use it with an entire form without errors.

Passing in a form?

The routine takes an object:
LPARAMETERS toObject AS Object
...and...
toObject.Visible = .F.
in the end sets it invisible.

>DO WHILE NOT INLIST(loContainer.BaseClass, "Form", "Page")
If you want this to work for a toolbar, you have to add the root parent class Toolbar here, of course.

Besides it creates an image control and sizes it to the size of the form, sets it to be on top of everything (except ActiveX, as you know) and shows a screenshot of the form. If that is moved some pixels, your _screen may be shifted, you get a slightly wrong rectangle. And it doesn't and can't cover the titlebar, as the added image control can only span the inner form canvas.

Anyway, if the form is moved, it still shows the inner image control of it's own screenshot.

For me, it's often not working, the line "loBmp = _Screen.System.Drawing.Bitmap.FromScreen(loImage)" is not creating a BMP object, though I updated system.app to the latest gdiplusx version.

Even if this works, it simply freezes the look of your form, users could still tab behind the image and use the form blindfolded, unless it really is set Visible =.f., when passing in the form itself. But that also hides the image with the screenshot of the form itself.

Bye, Olaf.
 
>For me, it's often not working, the line "loBmp = _Screen.System.Drawing.Bitmap.FromScreen(loImage)" is not creating a BMP object

Yes, it does not work for forms, pageframes, and pages for some reason. I think it is documented in Ceasar's code somewhere. I'll take a look.

DO WHILE NOT INLIST(loContainer.BaseClass, "Form", "Page") should be DO WHILE NOT INLIST(loContainer.BaseClass, "Form", "Page", "Pageframe").

But, you are right. I don't think this will work for a form or a form with a toolbar. Back to the drawing board. Maybe there is a win api that does the trick.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top