2015-11-19 1 views
2

Nous utilisons un périphérique Windows CE 6.0 et la programmation avec .NET CF v2.0. Si je commence ma demande immédiatement la mise sous tension (avec un paramètre de registre approprié dans HKLM \ init), puis le code suivant fonctionne sur le contrôle des étiquettes, mais échoue sur les contrôles ListView:Impossible de modifier la police en "Arial" sous Windows CE

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

Le symptôme de l'échec est que Font.Name est toujours "Tahoma" même après avoir appelé ce code pour le ListView. Aucune idée pourquoi.

Maintenant, je modifie le registre pour arrêter l'application en démarrant immédiatement à la mise sous tension. Redémarrez l'appareil, attendez quelques secondes et démarrez manuellement mon application ... maintenant le code fonctionne pour tous les types de contrôle!

Sinon, j'ajoute un raccourci vers \ Windows \ Startup (ou le dossier de démarrage spécifié dans HKLM \ System \ Explorer \ Shell Folders \ Startup). Cela charge l'application automatiquement après quelques secondes de retard, et cela fonctionne aussi.

Au moment de la conception, les contrôles ont une police de caractères "Tahoma" et sont remplacés par "Arial" si la langue sélectionnée par l'utilisateur est le vietnamien. J'ai joint deux images de l'application pour montrer le problème.

App launched immediately on power up

App launched manually a few seconds after power up

Ce que vous remarquerez est que les contrôles d'étiquetage ne sont pas affectés, à des contrôles ListView. Nous avons un stock plus ancien de périphériques Windows CE 5.0 exécutant exactement le même code ... et il fonctionne correctement sur ces appareils. Cela suggère un problème de minutage subtile sur Windows CE 6.0.

Enfin, cela ne concerne que "Arial" et vietnamien. Le mandarin (utilisant la police "Droid Sans Fallback") et le thaïlandais (utilisant la police "Loma") fonctionnent correctement sur tous les appareils.

Des idées? Y at-il quelque chose que je peux faire pour forcer le chargement des polices, ou peut-être attendre que les polices soient chargées?

+0

Chose curieuse, si j'empêcher l'application de chargement via le registre et mettre à la place un raccourci d'application dans le dispositif dossier de démarrage, puis les polices vietnamiennes fonctionnent correctement dans le ListView! Il y a un délai sensiblement plus long entre la mise sous tension et le démarrage de ~ 2-3 en utilisant cette dernière méthode, mais le délai n'est pas trop important. Ceci suggère fortement qu'une partie du système d'exploitation CE 6.0 n'est pas correctement initialisée avant une seconde ou deux après la mise sous tension. – AlainD

+1

Certaines API sont chargées au démarrage. Ceux-ci ne sont pas disponibles directement et donc le système d'exploitation signalera, quand ces API sont prêts à utiliser: WaitForApiReady: https://msdn.microsoft.com/en-us/library/ee482994%28v=winembedded.60%29.aspx. Vous n'avez pas écrit quel 'démarrage' vous utilisez. Si HKLM \ init, il y a plus de dépendances à attendre que si vous utilisez \ Windows \ StartUp. – josef

+0

@josef: Le fournisseur de l'appareil a mis notre application dans HKLM \ init (je vais éditer la question avec cette info). – AlainD

Répondre

2

Si une application est démarrée à l'aide de HKLM \ Init, vous devez vous assurer que toutes les API et ressources nécessaires à votre application sont prêtes. Il y a plusieurs façons de contrôler que:

  • le numéro d'ordre de l'entrée init

  • la dépend valeur de votre application

  • la fonction WaitForAPIReady

Par exemple :

Le processus shell32.exe est r par exemple la clé [HKLM] \ Init \ "Launch50" = "shell32.exe" et l'entrée dépendante de ceci est "Depend50" = hex (3): 14,00,1e, 00. Cela signifie que le système d'exploitation lancera shell32.exe lorsque les processus derrière Launch20 (0x14) et Launch30 (0x1e) auront été signalés. Dans l'exemple Launch20 est device.exe (chargeur de pilote) et Launch30 est gwes.exe. Cela signifie que le système d'exploitation s'assurera que shell32.exe ne sera pas démarré avant que ces deux processus ne signalent que start et load sont terminés.

Si vous créez une entrée Launch51 avec Depend51 = 0x14,00,0x1e, 00 le processus pour Launch51 ne sera pas non plus démarré avant que les processus requis ne signalent leur disponibilité.En outre, si vous utilisez une fonction API shell ou GWES, vous devez vous assurer que la fonction est prête à être utilisée. Vous devez donc appeler WaitForAPIReady pour vérifier cela, sinon votre application risque de ne pas démarrer ou s'exécuter correctement. Le chargement de polices supplémentaire peut dépendre de GWES et de GDI. Vous devez donc attendre SH_GDI. Le chargement de GWES est déjà vérifié avec l'entrée Depend.

Même si vous avez démarré votre processus via un fichier lnk dans Windows \ StartUp, vous devrez peut-être utiliser WaitForApiReady. Certaines ressources peuvent ne pas être disponibles au début du processus de démarrage. C'est plus le cas le plus tôt un processus est lancé, comme par exemple via HKLM \ init.

+0

Je suis désolé, mais je ne sais pas sur quelle API les contrôles dans Compact Framework s'appuient. – josef

+0

Correction de ma faute de frappe WaitForAPIReady. DLLImport n'a pas été ajouté par moi-même. – josef

+0

Voir la réponse de josef pour l'arrière-plan au problème. Voir ma propre réponse pour les spécificités du code pour utiliser "WaitForAPIReady" (sur CE 6.0) ou "IsAPIReady" (sur CE 5.0) en utilisant C#. – AlainD

1

Élaborant sur la réponse de josef:

* 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);