• Welcome to Jose's Read Only Forum 2023.
 

How Does One Use A Manifest To Set DPI Awareness For Windows 10?

Started by Frederick J. Harris, November 30, 2016, 07:31:50 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Frederick J. Harris

Found this link where Jose, Pierre and Paul Yuan weighened in on the subject...

http://www.jose.it-berater.org/smfforum/index.php?topic=5068.0

... so I tried using this manifest which I put together from their various posts...

' Form4.xml

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

  <assemblyIdentity
     version="1.0.0.0"
     processorArchitecture="x86"
     name="Form4"
     type="win32"
  />
 
  <description>
     Trying To Get DPI Aware And XP Themes Working
  </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}"/>
        <!--This Id value indicates the application supports Windows 8 functionality-->
        <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
        <!--This Id value indicates the application supports Windows 8.1 functionality-->
        <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
        <!--This Id value indicates the application supports Windows 10 functionality-->
        <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
     </application>
  </compatibility>
 
  <!-- Trustinfo section -->
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
       <requestedPrivileges>
           <requestedExecutionLevel
              level="asInvoker"
              uiAccess="false"/>
       </requestedPrivileges>
    </security>
  </trustInfo>

  <!-- DPI Aware -->
  <asmv3:application>
     <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
       <dpiAware>true</dpiAware>
     </asmv3:windowsSettings>
  </asmv3:application>
 
  <!-- XP Theme -->
  <dependency>
     <dependentAssembly>
         <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="x86"
            publicKeyToken="6595b64144ccf1df"
            language="*" />
      </dependentAssembly>
  </dependency>

</assembly>


It works fine for Windows 7 but won't work for Windows 10 – at least for me.  Here is my test program which is a PowerBASIC Win 10 program...


' Form4.inc -- Tested With PowerBASIC Includes
%IDC_EXECUTE        = 2000

Type WndEventArgs
  wParam            As Long
  lParam            As Long
  hWnd              As Dword
  hInst             As Dword
End Type

Declare Function    FnPtr(wea As WndEventArgs) As Long

Type MessageHandler
  wMessage          As Long
  dwFnPtr           As Dword
End Type


' Form4.bas -- Tested With PowerBASIC Includes

#Compile            Exe
#Dim                All
%UNICODE            = 1

#If %Def(%UNICODE)
    Macro ZStr      = WStringz
    Macro BStr      = WString
#Else
    Macro ZStr      = Asciiz
    Macro BStr      = String
#EndIf
#Include            "Windows.inc"
#Include            "CommCtrl.inc"
#Include            "Form4.inc"
#Resource           Manifest, 1, "Form4.xml"


Function fnWndProc_OnCreate(Wea As WndEventArgs) As Long
  Local pCreateStruct As CREATESTRUCT Ptr
  Local uCC As INIT_COMMON_CONTROLSEX
  Local blnInitCommCtrls As Long
  Local blnDPIAware As Long
  Local hCtl As Dword
  Local fp As Long

  fp=Freefile : Open "Output.txt" For Output As #fp
  Print #fp, "Entering fnWndProc_OnCreate()"
  pCreateStruct    = Wea.lParam
  Wea.hInst        = @pCreateStruct.hInstance
  uCC.dwSize       = sizeof(uCC)
  uCC.dwICC        = %ICC_STANDARD_CLASSES
  blnInitCommCtrls = InitCommonControlsEx(uCC)
  blnDPIAware      = IsProcessDPIAware()
  hCtl             = CreateWindowEx(0,"Button","Execute",%WS_CHILD Or %WS_VISIBLE,100,225,100,25,Wea.hWnd,%IDC_EXECUTE,Wea.hInst,Byval %NULL)
  Print #fp, "  blnInitCommCtrls = " blnInitCommCtrls
  Print #fp, "  blnDPIAware      = " blnDPIAware
  Print #fp, "  hCtl             = " hCtl
  Print #fp, "Leaving fnWndProc_OnCreate()"
  Close #fp

  fnWndProc_OnCreate=0
End Function


Function fnWndProc_OnDestroy(Wea As WndEventArgs) As Long
  Call PostQuitMessage(0)
  fnWndProc_OnDestroy=0
End Function


Sub AttachMessageHandlers()
  Dim MsgHdlr(1) As Global MessageHandler 'Associate Windows Message With Message Handlers
  MsgHdlr(0).wMessage=%WM_CREATE          : MsgHdlr(0).dwFnPtr=CodePtr(fnWndProc_OnCreate)
  MsgHdlr(1).wMessage=%WM_DESTROY         : MsgHdlr(1).dwFnPtr=CodePtr(fnWndProc_OnDestroy)
End Sub


Function fnWndProc(ByVal hWnd As Long,ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long) As Long
  Local Wea As WndEventArgs
  Register iReturn As Long
  Register i As Long

  For i=0 To 1
    If wMsg=MsgHdlr(i).wMessage Then
       Wea.hWnd=hWnd: Wea.wParam=wParam: Wea.lParam=lParam
       Call Dword MsgHdlr(i).dwFnPtr Using FnPtr(Wea) To iReturn
       fnWndProc=iReturn
       Exit Function
    End If
  Next i

  fnWndProc=DefWindowProc(hWnd,wMsg,wParam,lParam)
End Function


Function WinMain(ByVal hInstance As Long, ByVal hPrevIns As Long, ByVal lpCmdLn As ZStr Ptr, ByVal iShowWnd As Long) As Long
  Local szAppName As ZStr*16
  Local wc As WNDCLASSEX
  Local hWnd As Dword
  Local Msg As tagMsg

  szAppName        = "Form4"              : Call AttachMessageHandlers()
  wc.lpszClassName = VarPtr(szAppName)    : wc.lpfnWndProc = CodePtr(fnWndProc)
  wc.hInstance     = hInstance            : wc.hCursor     = LoadCursor(%NULL, ByVal %IDC_ARROW)
  wc.hbrBackground = %COLOR_BTNFACE+1     : wc.cbSize      = sizeof(WNDCLASSEX)
  Call RegisterClassEx(wc)
  hWnd=CreateWindow(szAppName,"Form1",%WS_OVERLAPPEDWINDOW,300,300,320,305,0,0,hInstance,ByVal 0)
  Call ShowWindow(hWnd,iShowWnd)
  While GetMessage(Msg,%NULL,0,0)
    TranslateMessage Msg
    DispatchMessage Msg
  Wend

  Function=msg.wParam
End Function


The program works fine in Windows 7 (I think I said that), but not in Windows 10.  I added the stuff in the xml file that I believe Pierre added for Windows 10.  The program opens a text output file in WM_CREATE handler code to output the success/failure of calls to test for DPI Awareness and InitCommonControlsEx() to set XP Themes.  Here is the output text file when run on Windows 10...


Entering fnWndProc_OnCreate()
  blnInitCommCtrls =  1
  blnDPIAware      =  0
  hCtl             =  3474620
Leaving fnWndProc_OnCreate()


As can be seen above, my call to IsProcessDPIAware() is returning FALSE.  On Windows 7 it returns TRUE.  I might add that using the function Microsoft recommends against using to set DPI Awareness, that is, SetProcessDPIAware() works just peachy.  Using that function one doesn't need to use a mamifest.  Would appreciate some guidance here.

Frederick J. Harris

What got me started on this was working on some of the code James posted.  I actually found the issue while doing C++ coding and in x64.  The processor Architecture setting in the manifest needs to be changed to "amd64" from "x86" to get it to work in 64 bit.  But I put the PowerBASIC program together to see what would happen using PowerBASIC in x86 instead of C in x64.  Doesn't seem to matter.  Both work just fine for Windows 7 and both fail for Windows 10. 

Frederick J. Harris

Middle of the night and I ought to just go to bed but found this...

https://msdn.microsoft.com/en-us/library/windows/desktop/mt748620(v=vs.85).aspx

...which recommends this in xml file...

<dpiAwareness>System</dpiAwareness>

This just keeps getting weirder and weirder.

James C. Fuller

Fred,
  This is what I use on Win10. It is in the file xpmanifest.xml
James


<?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="amd64"
         name="ApplicationName"
         type="win32"/>
      <description>Optional description of your application</description>

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

      <!-- 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}"/>
            <!--This Id value indicates the application supports Windows 8 functionality-->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
            <!--This Id value indicates the application supports Windows 8.1 functionality-->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
            <!-- This Id value indicates the application supports Windows 10 functionality-->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>           
         </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="amd64"
               publicKeyToken="6595b64144ccf1df"
               language="*" />
         </dependentAssembly>
      </dependency>

   </assembly>


Here is my resource file:

#define MANIFEST 24
#define IDR_XPMANIFEST1 1

IDR_XPMANIFEST1 MANIFEST "xpmanifest.xml"


James C. Fuller

Fred

Not sure if this is related but I noticed I needed to make sure WINVER and _WIN32_WINNT were defined to at least _WIN32_WINNT_VISTA.

There were items I needed from headers  not included because the default must be XP ??

I needed to go through and update all my batch files.

James

José Roca

Instead of using processorArchitecture="amd64", I will try using processorArchitecture="*" to see if it also works.

Frederick J. Harris

Thanks a bunch James!  I finally tracked it down.  My fault mostly I guess.  The culpret was this line...

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

That was the 2nd line in my manifest.  In yours you had...

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">

It worked when I changed that line.  I looked back at that link I referred to, and Jose had added that in support for Windows 8 and 8.1.  I simply missed it.

First I tried messing with those equates, i.e., WINVER and _WIN32_WINNT but it didn't help.  Whatever black magic is contained within that asmv3 - asm.v3 stuff is the magic that worked.

Frederick J. Harris

#7
Don't know if "*" will work for processor Architecture Jose.  When doing C and working with rc.exe and cvtres.exe the latter program has an x86 0r x64 value that must be set to get it to produce the correct *.obj file for inclusion in the binary.  If one use the wrong one and they don't match the executable, when you start the executable it crashes and you get an evil error message.

Doesn't seem to matter with rc, but cvtres has that switch.

Frederick J. Harris

I'm not at all happy with the way computer programming is going.  At one time it seemed one could do well by learning the documentation on a programming language, understanding it,  then writing good code. 

As things stand now, what seems to matter in terms of 'doing well', is being adept at searching the internet for obscure and nearly incomprehensible stuff that needs to be associated in some way with one's code - manifest files being a prime example of that sort of thing.   That's one of the main reasons I abandoned .NET.  That sort of thing seems to proliferate there.

Theo Gottwald

I agree with you Fred.
It all comes out of the babylonic bitch that is currently behind all cultural and technical stuff.
Especially DOTNET and this.