More about CWindow

Started by José Roca, February 26, 2012, 07:13:25 PM

Previous topic - Next topic

José Roca

Quote
Jose's cWindow class has a SetWindowPos method built into it so you can use that to make things easier.

And the good thing is that if we need more handy methods we can add them when I wish, and without bloating the code that does not use them.

Quote
Likewise (and obvious), if you are manually creating child windows/controls then you need to manually scale them as well. If you are using Jose's cWindow then the scaling of windows and child controls happens automatically.

Did you know that you even can change the aspect ratios and imitate digital TVs?


   ' // Set process DPI aware
   SetProcessDPIAware   ' ---> Better to use  manifest, but this is quick for testing purposes

   ' // Create an instance of the class
   LOCAL pWindow AS IWindow
   pWindow = CLASS "CWindow"
   IF ISNOTHING(pWindow) THEN EXIT FUNCTION

   pWindow.rxRatio = pWindow.rxRatio * (16 / 9)
   pWindow.ryRatio = pWindow.ryRatio / (16 / 9)


In the attached picture, the window with the listbox on the left side displays the normal appearance. The other, in HiDef 16/9 aspect.

Paul Squires

It is amazing just how different programs look when virtualization is enabled versus programs that are native DPI aware. DPI aware programs are so much more crisper and sharp looking.

I never realized how much is involved in making your app high DPI aware. I guess until you are forced to go through it, it does not really make full sense. I am happy that I am making the changes to FireFly. Still not 100% finished but it is looking pretty good.
Paul Squires
PlanetSquires Software

José Roca

#2
Now I'm beginning to do research about new graphics technologies, such Direct2D and DirectWrite, that replaces the deprecated GDI and GDI+ and are DPI aware. They use what they call DIPs (Device independent pixels), that use exactly the same way of calculation that CWindow.

In the attached picture, the first image is a capture of an example that draws a circle using Direct2D, running virtualized.

The 2nd one is the same example but having made it High DPI aware.

The 3rd one is the same DPI aware example with a change: in the properties structure used to create the RenderTarget I have passed the DPI value instead of the default value of 0. Now the circle will be rendered correctly in any computer no matter of his DPI setting, and the scaling work is done by Direct2D.

Say goodbye to GDI. It will live for as long as XP, because Direct2D requires Windows 7. When XP will disappear, the problem will be that the programs that use GDI without scaling will go directly to the trash binder, and those that will be modified to do scaling will be slow because they will have to draw more pixels. Direct2D and DirectWrite also have to draw more pixels with high resolution monitors, but these technologies are faster because they are hardware accelerated and use DirectX under the hood.

All of these new technologies use low-level COM, and you don't master low-level COM in two days, so begin to pay attention to my posts that use it. There are not books such "Low-level COM for dummies" or "Learn low-level COM in 12 hours".


José Roca

Quote
It is amazing just how different programs look when virtualization is enabled versus programs that are native DPI aware. DPI aware programs are so much more crisper and sharp looking.

This is because virtualization draws the contents in a bitmap and then stretches it, and also uses old fonts. It is a workaround to allow non DPI aware applications to work more or less well to give time to programmers to switch to DPI awareness.

Quote
I never realized how much is involved in making your app high DPI aware. I guess until you are forced to go through it, it does not really make full sense.

Yeah. I have spent a year and a half preaching in the desert about DPI, and several years about low-level COM, but knowing that one day would come the hour of my revenge :)


Elias Montoya


Quote from: Jose Roca on February 26, 2012, 11:22:21 PMThere are not books such "Low-level COM for dummies" or "Learn low-level COM in 12 hours".

The keywords being... "There are not". :)

I can i say i know a little bit of com programming, just enough to complete simple automation tasks like executing javascript from my firefly applications and get a result and the like... but there are still things that puzzle me. I would like a book that teaches high level COM programming (powerbasic) and optionally a few chapters about low level com programming.

Have you, Jose, given a though to write such book? maybe you could sell it good. :)

Win7, iMac x64 Retina display 5K, i7-5820K 4.4 ghz, 32GB RAM, All updates applied. - Firefly 3.70.

José Roca

Zapatero a tus zapatos (Stick to your shoes). I have some talent for writing code, but not for writing books.

Elias Montoya

I get what you mean. I also have a hard time writing help files. :P
Win7, iMac x64 Retina display 5K, i7-5820K 4.4 ghz, 32GB RAM, All updates applied. - Firefly 3.70.

Paul Squires

Quote from: Jose Roca on February 27, 2012, 01:22:56 AM
...but knowing that one day would come the hour of my revenge :)

:D

Yup, it's comin'.
Paul Squires
PlanetSquires Software

Jim Dunn

I know how to write a native DPI program (that is very small on my large 1920x1080 monitor).

But, would it be too much to ask for a (very) small sample of a "virtual-ized program" source, and a "DPI Aware program" source???

Thx!
3.14159265358979323846264338327950
"Ok, yes... I like pie... um, I meant, pi."

José Roca

The source is the same. To make it DPI aware you can either call the SetProcessDPIAware function or add a resource file that includes a manifest such this one:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" >

      <assemblyIdentity version="1.0.0.0"
         processorArchitecture="X86"
         name="MyProgram"
         type="win32"/>
      <description>MyProgram</description>

      <!-- Compatibility section -->
      <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
         <application>
            <!--The ID below indicates application support for Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
            <!--The ID below indicates application support for Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
         </application>
       </compatibility>

      <!-- Trustinfo section -->
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
         <security>
            <requestedPrivileges>
               <requestedExecutionLevel
                  level="asInvoker"
                  uiAccess="false"/>
               </requestedPrivileges>
         </security>
      </trustInfo>

      <dependency>
         <dependentAssembly>
            <assemblyIdentity
               type="win32"
               name="Microsoft.Windows.Common-Controls"
               version="6.0.0.0"
               processorArchitecture="X86"
               publicKeyToken="6595b64144ccf1df"
               language="*" />
         </dependentAssembly>
      </dependency>

      <asmv3:application>
         <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
         </asmv3:windowsSettings>
      </asmv3:application>

   </assembly>


If you're using a DPI of 96, the sizes of the GUI elements, fonts and graphics will be the same, but if you're using a higher DPI value the one that is DPI aware will be rendered smaller that the one running virtualized. If you want render it the same size, you have to calculate a scaling ratio and multiply the values in pixels by that ratio.

José Roca

#10
Until now, SDK programmers have been working with physical pixels. DPI introduces a new concept: DIPs.

What is a DIP?

Quote
A device independent pixel (DIP) is a logical pixel that maps to the pixels of the physical device through a scalar, the DPI. DPI stands for dots per inch, where a dot represents a physical device pixel. (The nomenclature comes from printing, where dots are the smallest ink dot that a printing process can produce). Because a standard monitor used to have 96 dots per inch, a DPI of 96 meant that a device independent pixel (or DIP) mapped 1:1 with a physical pixel. For example, if the DPI were 96*2 = 192, then a single DIP would encompass two physical pixels.

There are many reasons why applications don't necessarily handle this scaling correctly; one of the simplest reasons is that it requires extra work to discover and use this scalar value when rendering. In Direct2D, the scaling is applied by default. Because of this mapping, physical device pixels might end up at fractional DIP coordinates, which is one of the reasons why Direct2D uses a floating-point coordinate space.

    physical pixel = (dip × DPI) / 96

To convert a physical pixel to a DIP, use this formula:

    dip = (physical pixel × 96) / DPI

The above quote is from the M$ documentation for Direct2D, but applies to CWindow because it uses exactly the same methodology.

So, from now, when writing a DPI aware application that uses CWindow and its methods, be aware that you're using DIPs, not physical pixels.

As GDI is not DPI aware, if you call one of its functions directly, the values passed and returned will be in physical pixels, not DIPs, and therefore you will have to scale them.

Other methods, such twips and dialog units have been used in the past, but these were focused in resolution independence, not DPI, for the simple reason that DPI did not exist at that time.

Microsoft has listed as legacy graphics:

GDI
GDI+
Monitor Configuration
OpenGL
Picture Acquisition
Windows Color System
WPF Bitmap Effects

The current new graphics technologies are:

Direct2D/DirectWrite (that use DirectX under the hood)
Windows Image Adquisition (WIA)
Windows Image Component (WIC)

Windows 8 will introduce a new technology called DirectComposition.

All of them are low-level COM, not standard functions (there are a few standard functions, but are simple helpers).

My headers allow to use all of them except DirectComposition, because I don’t have yet the SDK headers for Windows 8.

José Roca

#11
Another example of problems caused by virtualization. In the attached image you can see a capture seeing the results of a program that captures the desktop window and displays it in a graphic control. As you can see, the one being run virtualized has produced an image that is bigger than the one of the editor at the background; the other has been produced by the same program making it DPI aware by calling SetProcessDPIAware, and the image produced matches the one of the editor at the background. This demonstrates that programs being running virtualized don't interact well with programs that are DPI aware (the editor is DPI aware).



Patrice Terrier

#12
DirectCompositing has been there since VISTA, through the use of DWM.

Hence it is very important to be able to adjust the child control's z-order, and to use full ARGB colors (DirectX compatible) to render correctly the variable opacity onto the DirectDraw surface.

For example when using GDI RGB(0,0,0) = black, then it becomes totaly transparent in composited mode, while when using the appropriate ARGB color, black is still opaque black.

That would be, by far, the most challenging part for DDT users, and also to move from bmp to 32-bit png (for the purpose of using variable opacity).

If you don't know what working in composited mode means, then give a try at my WinLIFT/GDImage HUDplus or Crystal demo projects.
http://www.zapsolution.com/DW/US/gcorner.html


...



José Roca

Now is a Windows component that enables high-performance bitmap composition with transforms, effects, and animations.

http://msdn.microsoft.com/en-us/library/windows/desktop/hh437371%28v=vs.85%29.aspx

Patrice Terrier

The problem with the (new) Microsoft DirectComposition is that it would work only with Windows 8, while both WinLIFT and GDImage are able to do it on VISTA and SEVEN (and of course Windows8).
All the tedious work being done transparently by the graphic engine, at full speed, because everything is GPU based.

About effects and animations, when working in composited mode, the only limit becomes: imagination and artistic talent ;)

Like you, i have i have been also preaching in the desert for several years  ;D

...