登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: [delphi新思想]delphi7中直接编译 rc 为资源文件 res 及程序 manifest     [回主站]     [分站链接]
[delphi新思想]delphi7中直接编译 rc 为资源文件 res 及程序 manifest
clq
浏览(473) - 2020-05-14 15:21:45 发表 编辑

关键字: delphi

[2020-05-23 14:34:35 最后更新]
[delphi新思想]delphi7中直接编译 rc 为资源文件 res 及程序 manifest

delphi 编译资源文件的命令是
{$R *.DFM}
{$R t.res}
但这要求相关源码文件是编译过的二进制文件。命令类似于 brcc32 myfile.rc

但这样编译一个程序要多次调用程序,未免啰嗦,所以最好是有一个命令一次性处理就好了。
这个命令就是

//引入控制 dpi 的资源说明
{$R 'dpi.res' 'dpi.rc'}

那么如今最新的 vc 中项目属性中的  manifest 如何在 delphi7 中实现呢?

方法是在 rc 文件中加一行

1 24 "dpi.manifest"

1    是资源 id 不能改的
24   是指的是资源类型,为 RT_MANIFEST
另外控制程序管理权限也是要通过 manifest , 不过它们只能放在同一个文件中,因为资源 id 只能用 1 改成 2 这些是不行的

以控制程序的 dpi 为例,manifest 文件内容如下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application>
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
      <!-- legacy -->
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
      <!-- falls back to pm if pmv2 is not available -->
    </windowsSettings>
  </application>
</assembly>

--------------------------------------------------------
这个命令其实也可以通过 delphi 的菜单来加入。
只需通过“项目>添加到项目”菜单项将rc文件添加到项目中即会在项目文件中加入这些命令。
如果重新编译程序提示 .res 不存在的话,必须在要用这种方式再引入一次(delphi7)。

--------------------------------------------------------
既然资源 id 必须为 1 那么,同时有两个 manifest 文件显然是不允许的。不过 manifest 刀可以不放在资源文件中,只要名为 "xxx.exe.manifest" 就可以了,就是不知道外部的 manifest 和资源文件中的谁优先级高。


clq  2020-05-14 15:42:12 发表 编辑

 关于dpi awareness 的清单文件设置

要设置dpi 意识,一般是使用SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE)来设置

 

具体可参考:Setting the default DPI awareness for a process

 

不过官方更建议使用清单文件来设置dpi意识,我介绍一下方法:

新建一个后缀为.manifest的文件,然后在其中添加如下代码
复制代码

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application>
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
      <!-- legacy -->
      <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">permonitorv2,permonitor</dpiAwareness>
      <!-- falls back to pm if pmv2 is not available -->
    </windowsSettings>
  </application>
</assembly>

复制代码

保存后,在项目中添加这个文件,最后debug就可以了

请注意:也有其他方法可以设置dpi意识,看下图

直接改选项就可以了


clq  2020-05-14 15:50:25 发表 编辑

http://osask.cn/front/ask/view/687428


SetProcessDpiAwareness不起作用

我一直在尝试禁用ClickOnce应用程序的DPI意识。
我很快发现,无法在清单中指定它,因为ClickOnce不支持清单文件中的asm.v3。

我发现的下一个选项是调用新的Windows函数SetProcessDpiAwareness 。

根据本教程,

    在创建应用程序窗口之前调用SetProcessDpiAwareness。

而这个教程,

    您必须在任何Win32API调用之前调用SetProcessDpiAwareness

你必须很早就调用这个函数。 所以,为了测试,我创建了一个完全空白的WPF应用程序,并将其作为我的整个App类:

[DllImport("SHCore.dll", SetLastError = true)]
private static extern bool SetProcessDpiAwareness(PROCESS_DPI_AWARENESS awareness);

[DllImport("SHCore.dll", SetLastError = true)]
private static extern void GetProcessDpiAwareness(IntPtr hprocess, out PROCESS_DPI_AWARENESS awareness);

private enum PROCESS_DPI_AWARENESS
{
    Process_DPI_Unaware = 0,
    Process_System_DPI_Aware = 1,
    Process_Per_Monitor_DPI_Aware = 2
}

static App()
{
    var result = SetProcessDpiAwareness(PROCESS_DPI_AWARENESS.Process_DPI_Unaware);
    var setDpiError = Marshal.GetLastWin32Error();
    MessageBox.Show("Dpi set: " + result.ToString());

    PROCESS_DPI_AWARENESS awareness;
    GetProcessDpiAwareness(Process.GetCurrentProcess().Handle, out awareness);
    var getDpiError = Marshal.GetLastWin32Error();
    MessageBox.Show(awareness.ToString());

    MessageBox.Show("Set DPI error: " + new Win32Exception(setDpiError).ToString());
    MessageBox.Show("Get DPI error: " + new Win32Exception(getDpiError).ToString());
}

3个消息框显示了这个内容:

    Dpi集合:是的
    Process_System_DPI_Aware
    设置DPI错误:System.ComponentModel.Win32Exception(0x80004005):访问被拒绝
    System.ComponentModel.Win32Exception(0x80004005):操作成功完成

为什么应用程序仍然设置为DPI_Aware? 这个电话不够早?
该应用程序确实经历了DPI缩放。

当我使用清单定义时:

<application xmlns="urn:schemas-microsoft-com:asm.v3">
  <windowsSettings>
    <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">false</dpiAware>
  </windowsSettings>
</application>

它确实返回Process_DPI_Unaware。

编辑1:
现在直接在pInvoke方法之后抓取Marshal.GetLastWin32Error(),现在实际上返回一个错误。
c# wpf pinvoke clickonce dpi
author:
采纳答案:

注意SetLastError和GetLastWin32Error ,诸如MessageBox.Show之间的任何调用都会影响其结果。 确保在调用你的本地方法后总是得到最后一个错误。

因此,您可能会得到预期的行为,但会被错误代码误导。

请参阅此博客文章以获取完整说明: http : //blogs.msdn.com/b/oldnewthing/archive/2015/08/19/10636096.aspx

编辑

不太清楚导致访问被拒绝的原因......但是有一个简单而有效的技巧会禁用DPI认知:

编辑您的AssemblyInfo.cs并添加以下内容:

[assembly: DisableDpiAwareness]

来源: https ://code.msdn.microsoft.com/windowsdesktop/Per-Monitor-Aware-WPF-e43cde33(PerMonitorAwareWPFWindow.xaml.cs中的评论)



clq  2020-05-14 15:54:42 发表 编辑

https://www.jianshu.com/p/d504a1b1fb06

win32界面库duilib DPI的使用,及兼容win10
李里里Riss
2017.03.19 04:12:49
字数 1,212阅读 4,864

    duilib是win32一个不错的界面库,有人维护的版本也支持DPI

DPI是什么

先了解什么是DPI,DPI全名是Dots Per Inch 就是每英寸中像素点的个数。Windows中默认为96。
在以前,电脑的屏幕一般分辨率都不高(1366x768),随着屏幕技术进步,逐渐高分屏也多了起来,到目前新出产品最低都是1080p,也就是1920x1080的分辨率,将来可能最低配还得上升,参见iMac的分辨率。分辨率提高了,但是屏幕的尺寸却没变,所以看起来颗粒感减少,画面细腻,是个好事啊。

可是,1080p的普及,对于很多还停留在老分辨率的软件,如果放到1080p或者更高的显示器上,如果还使用原来的96DPI,界面会看起来很小,眼睛很累,所以win8以上都有调整DPI缩放的设置,推荐一档是125%,也就是缩放1.25倍,原来的程序界面就被系统放大到1.25倍。
Windows采用DWM(Desktop Window Manager)来负责窗口显示,当DPI较高时,而软件又没有自己处理,这时系统帮你适配,如前面设置的125%的缩放。类似放大图片,所以你的程序会看起来模糊,这就你的界面库要支持DPI的重要性。

所谓界面库支持DPI,就是根据当前的缩放比例,使用相对应的分辨率的资源(图片和文字等)。

科普太多。直接进入主题吧。
DPI在Duilib中使用

有两种方法,一种是函数实现,一种是清单文件设置
1、函数实现

直接在你的InitWindows()里调用,

m_pm.GetDPIObj()->SetDPIAwareness(PROCESS_PER_MONITOR_DPI_AWARE);

内部是调用WindowsAPI

 HRESULT WINAPI SetProcessDpiAwareness(_In_ PROCESS_DPI_AWARENESSvalue);

typedef enum _PROCESS_DPI_AWARENESS {
  PROCESS_DPI_UNAWARE            = 0,
  PROCESS_SYSTEM_DPI_AWARE       = 1,
  PROCESS_PER_MONITOR_DPI_AWARE  = 2
} PROCESS_DPI_AWARENESS;

该函数告诉系统,要不要你帮我适配,就是前面讲的给我强行拉伸。

    ** PROCESS_DPI_UNAWARE** 告诉系统改程序自己无法处理不同DPI,获取的数据都是被处理过的。
    PROCESS_SYSTEM_DPI_AWARE 告诉系统该程序会在启动的显示器上自己支持不同的DPI,但是如果程序被拖动到了其他DPI不一样的显示器上时,需要DWM的帮助。
    PROCESS_PER_MONITOR_DPI_AWARE 告诉系统任何时候该程序都能适应不同的DPI,不需要任何帮助。
    如果你的程序支持 PROCESS_PER_MONITOR_DPI_AWARE,当你的窗口移动到DPI不同的显示器上时,会收到 WM_DPICHANGED 消息。
    主要相关API:
    SetProcessDpiAwareness :设置当前进程的DPI感知等级。
    GetDpiForMonitor :查询显示的DPI。
    MonitorFromPoint :获取指定点的显示器的句柄。
    MonitorFromRect :获取与指定矩形相交面积最大的显示器句柄。

二、清单文件配置

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

设置dpi感知为ture,即自己处理适配。
配置完成后,你的程序不会随着系统设置的缩放而被拉伸。
PS:刚发现清单文件配置的duilib不能动态设置DPI,why?暂时先使用第一种方法吧!-_-
动态设置DPI显示:

//m_pm为窗口管理类,有的维护库为m_pManager
m_pm.SetDPI(120);  //当前窗口
m_pm.SetAllDPI(120);//所有窗口

注意120是DPI,96x125%=120,duilib默认是96,就是不缩放。
一般跟随系统的缩放比例可以写成:

int sysDPI =  GetDeviceCaps(m_pm.GetPaintDC(), LOGPIXELSX);   //获取系统DPI
m_pm.SetAllDPI(sysDPI);               

LOGPIXELSX: Logical pixels/inch in X
LOGPIXELSY: Logical pixels/inch in Y
兼容win10

发现,duilib并不支持win10的DPI。方法一里的设置一直不成功,看了会源码发现,是SetDPIAwareness里调用IsWindows8Point1OrGreater()一直失败,该函数顾名思义就是判断系统版是否8.1及以上版本。
注意 win8.1及以上才支持DPI Aware,所以这里要判断。
发现函数是拷贝了win10SDK的VersionHelpers.h里的源码。
内部调用

VerifyVersionInfo(...)

MSDN关于这个解释了一波
Targeting your application for Windows
GetVersion, GetVersionEx, VerifyVersionInfo这些函数最高只能识别出Win8,IsWindowsVersionOrGreater系列函数只是VerifyVersionInfo的一个封装,所以也存在同样的问题。
MSDN里说需要在配置清单里说明程序兼容win10

<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <!-- OSVersion -->  
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
        <application>
            <!-- Windows 10 -->
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
            <!-- Windows 8.1 -->
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
            <!-- Windows Vista -->
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
            <!-- Windows 7 -->
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
            <!-- Windows 8 -->
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
        </application>
    </compatibility>
</assembly>

程序清单加入上述。
visual studio里配置清单文件。

上述代码拷贝进xml文件,建议软件名.xml

    项目属性-清单工具-输入输出-附加清单文件,加入$(TargetName).xml。

可以选择是否嵌入清单选项,否的话,程序exe目录下还会生成响应的xxxx.manifest,软件运行需要带上它,是的话就不用。

附常用清单文件:
支持Windows 6.0界面库、支持管理员权限、兼容WIN8/WIN10下取系统版本、兼容DPI Aware

<?xml version="1.0" encoding="UTF-8"?>  
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <!-- Windows 6.0 Style --> 
    <dependency>
        <dependentAssembly>
            <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*"></assemblyIdentity>
        </dependentAssembly>
    </dependency>
    <!-- Administrator --> 
    <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
            <requestedPrivileges>
                <requestedExecutionLevel level="requireAdministrator"></requestedExecutionLevel>
            </requestedPrivileges>
        </security>
    </trustInfo>
    <!-- DPI Aware -->
    <asmv3:application xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
        <asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
            <dpiAware>true</dpiAware>
        </asmv3:windowsSettings>
    </asmv3:application>
    <!-- OSVersion -->
    <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">  
        <application>  
            <!-- Windows 10 -->  
            <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/> 
            <!-- Windows 8.1/Windows Blue/Server 2012 R2 --> 
            <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/> 
            <!-- Windows Vista/Server 2008 --> 
            <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>  
            <!-- Windows 7/Server 2008 R2 --> 
            <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> 
            <!-- Windows 8/Server 2012 --> 
            <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/> 
        </application>  
    </compatibility> 
</assembly>












总数:3 页次:1/1 首页 尾页  
总数:3 页次:1/1 首页 尾页  


所在合集/目录
delphi_lost 更多



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1