无法将字体更改为" Arial"在Windows CE上

时间:2015-11-19 14:29:50

标签: c# fonts compact-framework windows-ce

我们正在使用Windows CE 6.0设备并使用.NET CF v2.0进行编程。如果我在启动时立即启动我的应用程序(在HKLM \ init中使用合适的注册表设置),则以下代码适用于Label控件但在ListView控件上失败:

cntrl.Font = new Font("Arial", cntrl.Font.Size, cntrl.Font.Style);

故障症状是Font.Name仍然是" Tahoma"甚至在为ListView调用该代码之后。不知道为什么。

现在我编辑注册表以在启动时立即停止应用程序启动。重启设备,等待几秒钟,然后手动启动我的应用程序......现在代码适用于所有控件类型!

或者,我添加一个快捷方式到\ Windows \ Startup(或HKLM \ System \ Explorer \ Shell Folders \ Startup中指定的Startup文件夹)。这会在几秒钟的延迟后自动加载应用程序,这也可以。

在设计时,控件的字体为" Tahoma",并且正在替换为" Arial"如果用户选择的语言是越南语。我附上了应用程序的两个图像来显示问题。

App launched immediately on power up

App launched manually a few seconds after power up

您将注意到Label控件不受影响,只是ListView控件。我们有一个较旧的Windows CE 5.0设备库存完全相同的代码...它在这些设备上正常工作。这表明Windows CE 6.0上存在一些微妙的计时问题。

最后,这只会影响" Arial"和越南人。普通话(使用" Droid Sans Fallback"字体)和泰语(使用" Loma"字体)都可以在所有设备上正常工作。

有什么想法吗?我可以做些什么来强制加载字体,或者可能要等到字体被加载?

2 个答案:

答案 0 :(得分:2)

如果使用HKLM \ Init启动应用程序,则必须确保应用程序使用的所有所需API和资源已准备就绪。有几种方法可以控制它:

  • 初始条目的订单号

  • 您应用的依赖值

  • WaitForAPIReady函数

例如:

shell32.exe进程是reg键[HKLM] \ Init \“Launch50”=“shell32.exe”,其依赖条目是“Depend50”= hex(3):14,00,1e,00。这意味着当Launch20(0x14)和Launch30(0x1e)后面的进程发出启动信号时,操作系统将启动shell32.exe。在示例中,Launch20是device.exe(驱动程序加载程序),Launch30是gwes.exe。这意味着操作系统将确保在这些进程发出启动和加载完成之前不会启动shell32.exe。

如果使用Depend51 = 0x14,00,0x1e,00创建条目Launch51,则启动51的过程也不会在所需进程发出信号准备就绪之前启动。

此外,如果您使用的是shell或GWES API函数,则必须确保该函数已准备好使用。因此,您需要调用WaitForAPIReady来检查,否则您的应用可能无法启动或无法正常运行。额外的字体加载可能取决于GWES和GDI,因此您应该等待SH_GDI。已使用Depend条目检查GWES加载。

即使您通过Windows \ StartUp中的lnk文件启动进程,也可能需要使用WaitForApiReady。在启动过程的早期,某些资源可能仍然无法使用。这更像是一个过程开始的情况,例如通过HKLM \ init。

答案 1 :(得分:1)

阐述约瑟夫的答案:

* Use "WaitForAPIReady" (not "WinApiReady") on Windows CE 6.0 (or higher)

* Use "IsAPIReady" on CE 5.0 (or earlier)

* If using C# (which I was using) then you'll need to P/Invoke the functions:

    // If using Windows CE 6.0 (or higher)
    [DllImport("coredll.dll")]
    private static extern uint WaitForAPIReady(uint uAPISlotIndex, uint uTimeout);

    // If using Windows CE 5.0 (or earlier)
    [DllImport("coredll.dll")]
    private static extern bool IsAPIReady(uint hAPI);

* Define these constants:

    // If using Windows CE 6.0 (or higher)
    private const uint SH_GDI           = 80;
    private const uint SH_WMGR          = 81;
    private const uint SH_SHELL         = 85;

    // If using Windows CE 5.0 (or earlier)
    private const uint SH_GDI           = 16;
    private const uint SH_WMGR          = 17;
    private const uint SH_SHELL         = 21;

* If you need to be signalled that the OS is ready run this code:

    // If using Windows CE 6.0 (or higher)
    WaitForAPIReady(SH_GDI, 5000);
    WaitForAPIReady(SH_WMGR, 5000);
    WaitForAPIReady(SH_SHELL, 5000);

    // If using Windows CE 5.0 (or earlier) (IsAPIReady is a polling function)
    int nTimeout = 0;
    while ((!IsAPIReady(SH_GDI)) && (nTimeout++ < 50))
        System.Threading.Thread.Sleep(100);

    nTimeout = 0;
    while ((!IsAPIReady(SH_WMGR)) && (nTimeout++ < 50))
        System.Threading.Thread.Sleep(100);

    nTimeout = 0;
    while ((!IsAPIReady(SH_SHELL)) && (nTimeout++ < 50))
        System.Threading.Thread.Sleep(100);

* Finally, to be absolutely sure the OS is ready, I pause for 1s more

    System.Threading.Thread.Sleep(1000);