2013-06-18 1 views
0

J'utilise SHBrowseForFolder API pour afficher la boîte de dialogue de sélection de dossier sous Windows. Mon application prend en charge la localisation de la langue de l'interface utilisateur en fonction de la sélection de l'utilisateur final. Ceci est réalisé en chargeant toutes les ressources en utilisant l'API FindResourceEx pour un LCID spécifique.SHBrowseForFolder avec localisation pour une langue spécifique

Alors j'étais curieux, est-il possible de faire en sorte que SHBrowseForFolder honore la sélection LCID du thread? Ou, de toute autre manière, faites-lui afficher du texte pour ma langue préférée en fonction du LCID?

+0

Il s'agit d'une boîte de dialogue Windows. Votre utilisateur n'aura aucun mal à le reconnaître, il parle sa langue. Si vous en avez besoin pour des captures d'écran localisées, procurez-vous une licence pour MSDN ou Windows Ultimate afin d'obtenir les packs de langues. –

+1

@HansPassant: Ils n'auront pas de mal à le reconnaître, ça a l'air mauvais. Dites, la langue de l'interface utilisateur de Windows est l'anglais. L'utilisateur final modifie l'interface utilisateur de mon application en allemand, mais cette boîte de dialogue affiche toujours le titre de la fenêtre, le bouton d'annulation, le nouveau bouton de dossier en anglais. J'ai besoin qu'il s'affiche en allemand dans ce cas. – c00000fd

+0

Cet utilisateur allemand aura une version en langue allemande de Windows. Et s'il ne le fait pas pour une raison étrange alors il sera bien familiarisé avec ce dialogue étant dans une autre langue, il l'utilise tous les jours. En fait, il pensera que le tien a l'air étrange. –

Répondre

2

Juste curieux, qui le downvote? Vous ne vous souciez pas de la localisation?

Néanmoins, je pense que je found a solution. Il m'a été suggéré sur un fil séparé et c'est un projet C# conçu pour MessageBox API, mais le concept est le même. Installez le crochet à l'échelle du fil avant d'appeler SHBrowseForFolder en utilisant SetWindowsHookEx(WH_CALLWNDPROCRET), puis interceptez la notification WM_INITDIALOG à partir de la procédure de raccordement. De là, il suffit de charger votre texte localisé en fonction de la langue de l'interface utilisateur et de le configurer en utilisant SetDlgItemText, où hDlg = handle de fenêtre vous obtenez dans la procédure de crochet et nIDDlgItem = ID des boutons et des champs de texte qui ont besoin de localisation. Voici ceux actuellement utilisés: IDOK = Bouton OK, IDCANCEL = Bouton Annuler, 0x3746 = Bouton "Créer un nouveau dossier". Vous pouvez également modifier le titre de la fenêtre de navigation en appelant le SetWindowText sur la poignée de la fenêtre. Puis, lorsque le SHBrowseForFolder renvoie, appelez le UnhookWindowsHookEx pour le décrocher.

Cette approche présente certains inconvénients. Le premier est qu'il repose sur MS pour conserver la disposition de la fenêtre de navigation. Jusqu'à présent, ça a été relativement pareil. Donc, vous voudrez peut-être suivre la version de Windows avec GetVersionEx et adapter en conséquence. Deuxièmement, vous devrez peut-être ajuster la taille des boutons et des étiquettes après l'ajout d'un nouveau texte. Mais heureusement, ce n'est pas un problème. Utilisez DrawText avec le drapeau DT_CALCRECT pour voir les grandes lignes d'une nouvelle étiquette, puis changez la taille de chaque contrôle avec MoveWindow. Notez qu'une approche plus sophistiquée impliquerait un redimensionnement complet de la fenêtre de navigation elle-même. Mais je vais vous laisser le soin de le faire. En terminant, je tiens à dire que c'est une honte que Microsoft soit si boiteux dans la preuve de moyens de localisation décents de leur interface utilisateur. Il y a des API qui ont été soi-disant conçues pour le faire, pour ne citer que quelques-uns:

  • SetThreadLocale - Honnêtement, je ne sais pas exactement ce qu'il fait et ce qui est son but. La documentation est proche d'être débile.

  • SetThreadUILanguage - malgré son introduction dans Windows XP, cette API ne fait que commencer par Windows Vista.Mais encore, il fixe seulement environ 80% de l'interface utilisateur à un LCID fourni. Par exemple, SHBrowseForFolder n'en est pas affecté, mais il peut y en avoir plus. Je n'ai pas vérifié les autres contrôles communs.

  • InitMUILanguage - Je ne sais pas ce que fait cette chose. Il n'a eu aucun effet sur mon application ...

  • setlocale - affecte seulement les choses C héritées comme printf et ainsi de suite. Cependant, rien de cela n'est utilisé pour l'interface utilisateur.

Alors c'est parti. Rien ne fonctionne techniquement. Donc un développeur forcé d'écrire pour Windows (et croyez-moi que je l'éviterai dès que possible) qui veut donner à l'utilisateur final la possibilité de changer la langue de l'interface utilisateur de son programme sans recourir à un lourd changement d'utilisateur Windows de la langue, est laissé à concevoir sa propre façon de le faire. Bon départ Microsoft!

Et enfin, à ce que @HansPassant a suggéré ci-dessus. Je ne peux pas faire payer 100 $ à mes utilisateurs pour pouvoir utiliser leur langue dans l'interface utilisateur de mon application. Je suis désolé, mais je ne peux pas tomber aussi bas ...

3

AFAIK, SHBrowseForFolder() n'est pas localisable par l'utilisateur. Quel texte dans la boîte de dialogue essayez-vous de localiser exactement? Vous devez lui fournir un titre, de sorte que vous pouvez fournir le texte pré-localisé que vous voulez pour cela.

Essayez-vous de localiser les légendes des boutons ou d'autres contrôles, peut-être? Vous devez utiliser la fonctionnalité de rappel pour accéder et manipuler les contrôles de dialogue manuellement pour cela. Jetez un coup d'œil à l'interface IFileOpenDialog. Il a SetFileNameLabel() et SetOkButtonLabel() au moins.

+0

Dans le meilleur des cas, je m'attends à ce que toute l'interface utilisateur soit localisée. Mais je vois votre point. Je vais probablement devoir le faire manuellement. Merci. – c00000fd

Questions connexes