Il s'agit surtout de l'historique Windows : MessageBoxEx remplace MessageBox avec de nouvelles possibilités.
En C++, on aurait pu surcharger la fonction, en C, on se débrouille comme on peu. Ex = Extended = Etendu => c'est une version étendue de la fonction, qui accepte des parametres supp dont tu n'as pas souvent l'utilité (MessageBoxEx permettait de choisir la langue). On trouve aussi des fonction surchargées via un numéro (en COM généralement : Navigate, Navigate2...)
Les nouvelles API ...Ex acceptent désormais une structure et non plus une liste d'arguments. Cela permet d'éviter les erreurs.
Je crois que tu confonds avec Indirect (MessageBoxIndirect).
Les flags, comme MB_OK ou MB_ICONINFORMATION, sont donc des #define de puissances de 2 et on peut les combiner soit avec des | ou soit avec des + (mais avec des | je pense que c + rapide)
Attention, y'a une tres grosse différence entre utiliser | ou +.
Un + effectue une addition, et ça peut créer des surprise. Des fois, des flags sont une combinaison d'autres, genre :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| #define WS_OVERLAPPED 0x00000000L
#define WS_CAPTION 0x00C00000L /* WS_BORDER | WS_DLGFRAME */
#define WS_BORDER 0x00800000L
#define WS_DLGFRAME 0x00400000L
#define WS_SYSMENU 0x00080000L
#define WS_THICKFRAME 0x00040000L
#define WS_MINIMIZEBOX 0x00020000L
#define WS_MAXIMIZEBOX 0x00010000L
#define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED | \
WS_CAPTION | \
WS_SYSMENU | \
WS_THICKFRAME | \
WS_MINIMIZEBOX | \
WS_MAXIMIZEBOX) |
Si tu ne sait pas que WS_OVERLAPPEDWINDOW inclue déjà le style WS_DLGFRAME (inclu via WS_CAPTION), tu vas donc créer 2 fois le masque WS_DLGFRAME. Si tu utilises |, pas de conséquence car
01 OR 01 = 01
Mais avec un +, ça va faire n'importe quoi :
01 + 01 = 10
Ca ne revient pas du tout au même.
Donc, il ne faut pas utiliser +.
Le premier argument, que se passe-t-il si il vaut NULL ?
Pour le savoir, se référer à la doc :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/dialogboxes/dialogboxreference/dialogboxfunctions/messagebox.asp
Handle to the owner window of the message box to be created. If this parameter is NULL, the message box has no owner window.
Si tu mets le handle de ta fenêtre, c'est elle qui "détiendra" la messagebox (bloquée par elle).
TEXT permet de transformer les chaines en UNICODE.
Les chaines acceptées par Windows sont du type LPCTSTR, mais ce type n'existe en fait pas:
LP = pointeur
C = constant
T = ANSI ou UNICODE
STR = chaine de car
=> pointeur sur une chaine constante ansi ou unicode
La différence :
ANSI : CHAR * = char * = 1 octet
UNICODE : WCHAR * = wchar_t * = 2 octets
char * toto = "toto";
wchar_t * toto = L"toto";
Normalement, un prog Win9X doit être ANSI et WinNT unicode car Win9X est en interne ANSI et WinNT UNICODE en interne. Pour que n'importe quel prog (ansi ou unicode) fonctionne, les API existent (celles concernées) en 2 versions, Ex :
MessageBoxA : ANSI version
MessageBoxW : UNICODE version
MessageBox tout court n'existe pas!
Récapitulatif:
on a
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| WINUSERAPI
int
WINAPI
MessageBoxA(
IN HWND hWnd,
IN LPCSTR lpText,
IN LPCSTR lpCaption,
IN UINT uType);
WINUSERAPI
int
WINAPI
MessageBoxW(
IN HWND hWnd,
IN LPCWSTR lpText,
IN LPCWSTR lpCaption,
IN UINT uType); |
Si on veut être ansi, il faut faire :
MessageBoxA( 0, "msg", "tittre", 0 );
si on veut être unicode :
MessageBoxW( 0, L"msg", L"tittre", 0 );
Bref, faut écrire 2 différents programmes si on veut être l'un ou l'autre au choix.
Astuce utilisée : si rien n'est défini, on est ANSI. Si UNICODE est défini, on est UNICODE:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
// Generic types
#ifdef UNICODE
typedef wchar_t TCHAR;
#else
typedef unsigned char TCHAR;
#endif
typedef TCHAR * LPTSTR, *LPTCH;
// 8-bit character specific
typedef unsigned char CHAR;
typedef CHAR *LPSTR, *LPCH;
// Unicode specific (wide characters)
typedef unsigned wchar_t WCHAR;
typedef WCHAR *LPWSTR, *LPWCH;
#ifdef UNICODE
#define MessageBox MessageBoxW
#else
#define MessageBox MessageBoxA
#endif // !UNICODE |
voir winuser.h et
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_28c3.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/unicode_28c3.asp
reste plus qu'à convertir les string "toto" en L"toto pour unicode:
1 2 3 4 5 6
|
#ifdef UNICODE
#define TEXT(x) L##x
#else
#define TEXT(x) x
#endif |
Et maintenant le code suivant:
1 2 3
| LPCTSTR msg = TEXT( "message" );
LPCTSTR title = TEXT( "titre" );
MessageBox( 0, msg, title, 0 ); |
compile aussi bien en ANSI qu'en UNICODE
Pour la fonction WinMain, j'ai vu APIENTRY et WINMAIN pour déclarer la fonction... quelle(s) différence(s) ?
Tu veux dire WINAPI surement...
=> pas de différence, vis à vis du code.
C'est une histoire de convention. Je pense que WINAPI est plutot à utiliser pour déclarer des fonction de l'api win32, et APIENTRY pour déclarer des fonctions qui n'en font pas partie. WinMain faisant partie de win32, mieux vaut utiliser WINAPI.
Pour rajouter à la confusion :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows/windowreference/windowfunctions/winmain.asp
Partager