Discussions related to Visual Prolog
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

I am trying to copy an image of a form's client window to the Windows clipboard. What is the difference in how these two event handlers receive the window handle? (Of course, I wouldn't normally try to get a snapshot of the client window -- that is just there for debugging.) In both predicates Source appears to have the same window handle. The onKeyUp/3 predicate has the same problem.

Code: Select all

predicates     onPaint : window::paintResponder. clauses     onPaint(Source, _Rectangle, GDI) :-         XYn = xynPainter::new(Source, GDI),         XYn:paint(data),         gfxImageIO::clientWin_putClipboardBMP(Source), % <== this works OK         nothing("").   predicates     onMouseUp : window::mouseUpListener. clauses     onMouseUp(Source, _Point, _ShiftControlAlt, _Button) :-         gfxImageIO::clientWin_putClipboardBMP(Source), % <== this causes exception         /* ----------------------------------------             VPI cannot open a picture.                   ExtraInfo = pict_GetFromWin: Cannot create compatible DC                 error code = 6103               vpi_UnableOpenPicture (vpi)             vpi::vpiExceptionRaiser             pfc\vpi\vpi.pro(243,9)             ---------------------------------------- */         succeed.
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

Hmmm ... there are many things happening in GUI event processing that I don't fully understand yet. :o

If I call vpi::processEvents() at the end of the onPaint/3 call and put it after the clientWin_putClipboardBMP(Source) call in onMouseUp/4 like below, the code works OK.

Code: Select all

... gfxImageIO::clientWin_putClipboardBMP(Source), _ = vpi::processEvents().
I stumbled on this when testing and found that window image capture would sometimes work inconsistently when invoked with mouse-click or key-press or button-press. When I inserted stdio::write("\n",Source) for debugging and found it magically cured the problem I then recalled that writing "\nl" to the Messages window would invoke processEvents().
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Thomas Linder Puls »

The paint event is special because it has access to a windowGDI with which to do painting. This is a "thing" that has top be released again, and therefore you should never use processEvents inside a paint listener.

The windowGDI is probably the difference in the two situations, but we don't know what gfxImageIo::clientWin_putClipboardBMP does, so how should we be able to say anything about it?
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

I didn't understand that about onPaint. For testing purposes, the only predicate call in onPaint was processEvents(). My thought was that it would be the last predicate call in onPaint if I were to use in practice.

When initially testing using the debugger (VP8, Win32) I noticed that the Source window ID was different in onPaint, onMouseUp, and onKeyUP -- and that was raising the exception. Very strange!

After I put in stdio::write statements or processEvents then the Source ID was the same.

I have attached the relevant files for clientwin_putClipboardBMP/1.
Attachments
screenCaptureFiles.zip
Screen capture source files
(5.47 KiB) Downloaded 304 times
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Thomas Linder Puls »

OK, so clientWin_putClipboardBMP does this:

Code: Select all

clauses     clientWin_putClipboardBMP(W) :-         WinVPI = W:getVpiWindow(),         Pic = vpi::pictGetFromWin(WinVPI, vpi::winGetClientRect(WinVPI)),         cbPutPicture(Pic).
And it is vpi::pictGetFromWin that raises the exception.

So the question is what Source is in your code?
Why do use Source why not just supply the window that you want to capture directly from its fact?

Anyways, what source is depends very much on which window you have attached the event handlers to. But that code is unknown.
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

I wonder if there is an inconsistency in building the application because the code below will either always work on one build or always raise an exception in another build. I force recompilation by just inserting a few spaces to the source .PRO file.

It seems to occur randomly in 32 & 64 bit compilations and with or without running the debugger.

Code: Select all

predicates     onPushButtonClick : button::clickResponder. clauses     onPushButtonClick(Button) = button::defaultAction :-         Source = Button:getParent(),         WinVPI = Source:getVpiWindow(),         Pic = vpi::pictGetFromWin(WinVPI, vpi::winGetClientRect(WinVPI)),         vpi::cbPutPicture(Pic).   predicates     onMouseUp : window::mouseUpListener. clauses     onMouseUp(Source, _Point, _ShiftControlAlt, _Button) :-         WinVPI = Source:getVpiWindow(),         Pic = vpi::pictGetFromWin(WinVPI, vpi::winGetClientRect(WinVPI)),         vpi::cbPutPicture(Pic).
I have attached a tiny test project. Press F8 to open the dialog, search for TODO to get to the code above.
Attachments
TestScreenCapt.zip
(25.75 KiB) Downloaded 308 times
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

Here is a scenario that will raise the above exception with seeming healthy code:

Build a 32 bit application with 64 bit IDE: the application executes OK.
When I try to run with debugger I get a message asking to switch to 32 bit IDE.
I accept the switch to 32 bit IDE.

Run application without debugger and get exception in test dialog (onMouseUp or onButtonPress)

Application EXE sizes are different for the 2 IDEs:
32 bit IDE: 30908 bytes
64 bit IDE: 30909 bytes

Comparing the EXEs with BeyondCompare I see that the Code/Data sizes are different in the 2 EXEs
32 bit IDE: 4,001,280 bytes
64 bit IDE: 4,002,816 bytes

----------

Next, I did a Rebuild All (32 bit application in 32 bit IDE)
The application behaves OK in the test dialog.

Next, do a Debug Run in the IDE
Exception is raised on the test dialog.
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Thomas Linder Puls »

Sorry for the late answer. I have not really been able to figure out what the problem is. My main problem is that everything works when I debug the program, but it fails when I don't debug it.

In any case it has to do with getting a device context for the window and creating a corresponding in memory device context from this context.

The underlying Windows calls does not give any error codes.

One of the relevant functions are GetDC. If you see the documentation it says it returns a handle if it succeeds and NULL if it fails. But there is nothing saying why it should fail.

The other function is CreateCompatibleDC. And it has exactly the same problem, it can fail but you don't know why?

And in my case one or both of them return NULL when I run the program normally, but they return fine handles when I debug the program.
Regards Thomas Linder Puls
PDC
Harrison Pratt
VIP Member
Posts: 439
Joined: 5 Nov 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Harrison Pratt »

Thomas, thank you very much for looking into this.

I guess at this point it is sufficient to label this behavior "unfathomable" so that I can stop doubting my sanity. :D

Does this misbehavior also occur with VIP-9 ?
User avatar
Thomas Linder Puls
VIP Member
Posts: 1398
Joined: 28 Feb 2000 0:01

Re: onPaint/3 vs onMouseUp/4 event handling

Unread post by Thomas Linder Puls »

Yes, it is the same in Vip 9.
Regards Thomas Linder Puls
PDC
Post Reply