ViewComposer problem with overlapping view (WM_PRINT problem)

Previous Topic Next Topic
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

ViewComposer problem with overlapping view (WM_PRINT problem)

Udo Schneider
Hi Andy, Blair,

If you add two overlapping sibling views using the ViewComposer their
drawing order is wrong. If you compare the preview in the ViewComposer
with the actual test window it's obvious.

It seems that the WM_PRINT route the ViewComposer is taking has some
additional limitations. After playing around a little bit it seems, that
WM_PRINT either uses a reversed drawing order for sibling views or (not
tested) doesn't care about clipping windows.

A few quick experiments lead me to PrintWindow() which seems to work
quite well but is just available on WXP.

Normally this "mis-"behaviour shouldn't be a problem ... however If you
are working with transparent/translucent overlayed views it's hard to
position them, if you don't see them.

I attached some TestCases for the problem. I hope this helps.



| package |
package := Package name: 'US WM_PRINT Testcase'.
package paxVersion: 1;
        basicComment: ''.

package classNames
        add: #WmPrintTest;

package methodNames
        add: #UserLibrary -> #printWindow:hdcBlt:nFlags:;
        add: #View -> #printWindow;

package binaryGlobalNames: (Set new

package globalAliases: (Set new

package setPrerequisites: (IdentitySet new
        add: '..\..\Object Arts\Dolphin\Base\Dolphin';
        add: '..\..\Object Arts\Dolphin\MVP\Presenters\Color\Dolphin Color
        add: '..\..\Object Arts\Dolphin\MVP\Base\Dolphin MVP Base';
        add: '..\..\Camp Smalltalk\SUnit\SUnit';


"Class Definitions"!

TestCase subclass: #WmPrintTest
        instanceVariableNames: 'wmPrintDib screenshotDib printWindowDib'
        classVariableNames: ''
        poolDictionaries: 'Win32Constants'
        classInstanceVariableNames: ''!

"Global Aliases"!

"Loose Methods"!

!UserLibrary methodsFor!

printWindow: hwnd hdcBlt: hdcBlt nFlags: nFlags
        "The PrintWindow function copies a visual window into the specified
device context (DC), typically a printer DC.
                BOOL PrintWindow(
                        HWND hwnd,               // Window to copy
                        HDC  hdcBlt,             // HDC to print into
                        UINT nFlags              // Optional flags

        <stdcall: bool PrintWindow handle handle dword>
        ^self invalidCall! !
!UserLibrary categoriesFor: #printWindow:hdcBlt:nFlags:!public! !

!View methodsFor!

        | bitmap |
        bitmap := Bitmap compatible: self canvas extent: self extent.
        UserLibrary default
                printWindow: self asParameter
                hdcBlt: bitmap canvas asParameter
                nFlags: 0.
        ^bitmap! !
!View categoriesFor: #printWindow!public! !

"End of package definition"!

"Source Globals"!


WmPrintTest guid: (GUID fromString:
WmPrintTest comment: ''!
!WmPrintTest categoriesForClass!SUnit! !
!WmPrintTest methodsFor!

captureUsingPrintWindow: view
        printWindowDib := DIBSection
                                width: view extent x
                                height: view extent y
                                depth: 32.
(view printWindow) drawOn:  printWindowDib canvas.!

captureUsingScreenshot: view
        screenshotDib := DIBSection
                                width: view extent x
                                height: view extent y
                                depth: 32.
        screenshotDib canvas
                bitBlt: View desktop canvas
                rectangle: ((view mapPoint: 0 @ 0 to: View desktop) extent: view extent)
                to: 0 @ 0
                rop: SRCCOPY!

captureUsingWmPrint: view
        wmPrintDib := DIBSection
                                width: view extent x
                                height: view extent y
                                depth: 32.
        (Bitmap fromView: view) drawOn: wmPrintDib canvas!

compareDib: dib1 with: dib2
        | dib1Base dib2Base bm |
self assert: (dib1 extent) = (dib2 extent) ; assert: (dib1 depth) =
(dib2 depth).
dib1Base := dib1 imageBits.
        dib2Base := dib2 imageBits.
        bm := dib1 getDIBSECTION dsBm.
        0 to: bm bmHeight - 1
                        [:y |
                        | lineOffset |
                        lineOffset := y * bm bmWidthBytes.
                        0 to: bm bmWidth - 1
                                        [:x |
                                        | offset |
                                        offset := lineOffset + (x * 4).
                                        self assert: (dib2Base dwordAtOffset: offset) = (dib1Base
dwordAtOffset: offset)]]!

        | view |
        view := ContainerView show.
        view topShell extent: 100 @ 120.
        (view addSubView: ColorView new)
                position: 0 @ 0;
                extent: 75 @ 75;
                value: Color blue.
        (view addSubView: ColorView new)
                position: 25 @ 25;
                extent: 75 @ 75;
                value: Color red.


        | view |
        view := self createView.
        SessionManager current inputState pumpMessages.
                captureUsingWmPrint: view;
                captureUsingPrintWindow: view;
                captureUsingScreenshot: view.
        view topShell close!

        self compareDib: printWindowDib with: wmPrintDib!

        self compareDib: screenshotDib with: printWindowDib!

        self compareDib: screenshotDib with: wmPrintDib! !
!WmPrintTest categoriesFor: #captureUsingPrintWindow:!private! !
!WmPrintTest categoriesFor: #captureUsingScreenshot:!private! !
!WmPrintTest categoriesFor: #captureUsingWmPrint:!private! !
!WmPrintTest categoriesFor: #compareDib:with:!private! !
!WmPrintTest categoriesFor: #createView!private! !
!WmPrintTest categoriesFor: #setUp!public! !
!WmPrintTest categoriesFor: #testPrintWindowEqualsWmPrint!public! !
!WmPrintTest categoriesFor: #testWmPaintEqualsPrintWindow!public! !
!WmPrintTest categoriesFor: #testWmPaintEqualsWmPrint!public! !

"Binary Globals"!