Menu Windows multilingue dynamique

Soyez le premier à donner votre avis sur cette source.

Vue 3 259 fois - Téléchargée 390 fois

Description

Bonjour,
Voici un "canevas" pour de simples programmes multilingues sous Windows.
Le changement de langue instantané repose sur le fait que la création d'un menu (même compliqué) ne prends qu'un temps minime.
Il n'est donc pas nécessaire d'initialiser un programme avec des menus "statiques".

Voici quelques propriétés du code présenté:
- Un seul fichier source WinMenu.cpp.
- Un seul include: <Windows.h>.
- Facilement adaptable à "beaucoup" de langues.
- Le changement de langue est instantané.
- Exemple de menus et sous-menus fréquemment utilisés.
- Facilement adaptables à vos propres menus.
- Le sous-menu Open permet de sélectionner un de vos fichiers.
- Utilisation de quelques "HotKeys".
- ...

#include <windows.h>

enum Lngs {ENGLISH,FRANCAIS,DEUTSCH,NL};
enum Cmds {LANG=1000 /* 1000-1099 used for languages */ ,OPEN=1100,
  EXIT=1101,ABOUT=1102,INDEX=1103,COPY=1104,PASTE=1105,OTHER=1106};
enum HKey {CTRLO=1201,CTRLC=1202,CTRLV=1203};

static char
     *Langues[NL]={"English","Français","Deutsch"},
    *MenuFile[NL]={"File","Fichier","File"},
    *MenuOpen[NL]=  {"Open...\tCtrl+O","Ouvrir...\tCtrl+O","Öffnen...\tCtrl+O"},
    *MenuExit[NL]=  {"Exit","Quitter","Exit"},
    *MenuEdit[NL]={"Edit","Edition","Edit"},
    *MenuCopy[NL]=  {"Copy\tCtrl+C","Copier\tCtrl+C","Kopieren\tCtrl+C"},
   *MenuPaste[NL]=  {"Paste\tCtrl+V","Coller\tCtrl+V","Einfügen\tCtrl+V"},
  *MenuOption[NL]={"Options","Options","Optionen"},
   *MenuOther[NL]=  {"Other...","Autres...","Andere..."},
    *MenuHelp[NL]={"Help","Aide","Hilfe"},
   *MenuIndex[NL]=  {"Index","Index","Index"},
   *MenuAbout[NL]=  {"About...","A propos de...","About..."};

char *Text[NL]={"Dynamic change of language",
  "Changement dynamique de langue","Dynamische Änderung der Sprache"};
int lang; // langue active
OPENFILENAME ofn; // must be global

void MakeMenu(HWND hWnd) {
  HMENU menu=CreateMenu(),m=CreateMenu();
  AppendMenu(menu,MF_POPUP,(unsigned int)m,MenuFile[lang]);
    AppendMenu(m,MF_STRING,OPEN,MenuOpen[lang]);
    AppendMenu(m,MF_STRING,EXIT,MenuExit[lang]);
  m=CreateMenu();
  AppendMenu(menu,MF_POPUP,(unsigned int)m,MenuEdit[lang]);
    AppendMenu(m,MF_STRING,COPY,MenuCopy[lang]);
    AppendMenu(m,MF_STRING,PASTE,MenuPaste[lang]);
  m=CreateMenu();
  AppendMenu(menu,MF_POPUP,(unsigned int)m,MenuOption[lang]);
    for (unsigned int i=0; i<NL; ++i)
      AppendMenu(m,MF_STRING|(i==lang)?MFS_CHECKED:0,LANG+i,Langues[i]);
    AppendMenu(m,MF_SEPARATOR,0,0);
    AppendMenu(m,MF_STRING,OTHER,MenuOther[lang]);
  m=CreateMenu();
  AppendMenu(menu,MF_POPUP,(unsigned int)m,MenuHelp[lang]);
    AppendMenu(m,MF_STRING,INDEX,MenuIndex[lang]);
    AppendMenu(m,MF_STRING,ABOUT,MenuAbout[lang]);
  SetMenu(hWnd,menu);
}

void Open()  {
  char filePath[MAX_PATH];
  ofn={sizeof(OPENFILENAME),0,0,"*.txt",0,0,1,filePath,MAX_PATH,0,0,0,
    "Select the file",OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST};
  GetOpenFileName(&ofn);
  MessageBox(0,ofn.lpstrFile,"File name",0); // à développer
}

void Paint(PAINTSTRUCT *ps) {
  static HFONT fnt=CreateFont(36,15,70,50,400,0,0,0,0,0,0,0,16,"Arial");
  HGDIOBJ ff=SelectObject(ps->hdc,fnt);
  TextOut(ps->hdc,4,90,Text[lang],strlen(Text[lang]));
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT mes,WPARAM wParam,LPARAM lParam) {
  PAINTSTRUCT ps;
  switch(mes) {
    case WM_CREATE:
      RegisterHotKey(hWnd,CTRLO,MOD_CONTROL,'O');
      RegisterHotKey(hWnd,CTRLC,MOD_CONTROL,'C');
      RegisterHotKey(hWnd,CTRLV,MOD_CONTROL,'V');
      lang=ENGLISH; MakeMenu(hWnd);
      return 0;
    case WM_COMMAND: {int i=LOWORD(wParam)-LANG;
      if ((i>=0)&&(i<NL)) {
        DestroyMenu(GetMenu(hWnd)); lang=i; MakeMenu(hWnd);
        RedrawWindow(hWnd,0,0,RDW_INVALIDATE|RDW_UPDATENOW|RDW_ERASE); return 0;
      } else switch(LOWORD(wParam)) {
        case OPEN: Open(); return 0;
        case ABOUT: MessageBox(0,"About","Menu",0); return 0; // à développer
        case COPY:  MessageBox(0,"Copy" ,"Menu",0); return 0; // à développer
        case INDEX: MessageBox(0,"Index","Menu",0); return 0; // à développer
        case OTHER: MessageBox(0,"Index","Menu",0); return 0; // à développer
        case PASTE: MessageBox(0,"Paste","Menu",0); return 0; // à développer
        case EXIT: PostQuitMessage(0); return 0;
      }} return 0;
    case WM_HOTKEY:
      switch(wParam) {
        case CTRLO: Open(); return 0;
        case CTRLC: MessageBox(0,"Copy" ,"Menu",0); return 0; // à développer
        case CTRLV: MessageBox(0,"Paste","Menu",0); return 0; // à développer
      }
    case WM_PAINT:
      BeginPaint(hWnd,&ps); Paint(&ps); EndPaint(hWnd,&ps); return 0;
    case WM_DESTROY: PostQuitMessage(0); return 0;
  } return DefWindowProc(hWnd,mes,wParam,lParam);
}

int WINAPI WinMain(HINSTANCE hI,HINSTANCE,PSTR,int iCmdShow) {
  WNDCLASS wc={CS_HREDRAW|CS_VREDRAW,WndProc,0,0,hI,LoadIcon(0,IDI_APPLICATION)
    ,LoadCursor(0,IDC_ARROW),CreateSolidBrush(0XFFFFFF),0,"GDImenu"};
  RegisterClass(&wc);
  HWND hWnd=CreateWindow("GDImenu","Window avec menu dynamique",
    WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,800,600,0,0,hI,0);
  ShowWindow(hWnd,iCmdShow); UpdateWindow(hWnd);
  MSG m;
  while(GetMessage(&m,0,0,0)) {TranslateMessage(&m); DispatchMessage(&m);}
  return (int)m.wParam;
}

Pour ajouter une langue, il suffit d'adapter la line 3: enum Lngs ... et les textes sous8: static char ....
Veillez à ce que NL figure toujours à la fin de l'enum Lngs.
On peut également utiliser un "système de messages multilingues" plus évolué.

Il est bien entendu que d'autres affichages peuvent être modifiés en fonction de la langue choisie.
L'appel à RedrawWindow(...); n'est pas nécessaire pour mettre instantanément à jour le menu, mais seulement pour redessiner une visualisation qui dépend de la langue choisie.

Bonne lecture

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.