DIALOGBOXINDIRECT AVEC DES CONTROLES (WIN32)

BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019 - 4 juin 2006 à 23:11
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 - 10 juin 2006 à 14:28
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.

https://codes-sources.commentcamarche.net/source/37949-dialogboxindirect-avec-des-controles-win32

deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
10 juin 2006 à 14:28
Merci bien pour l'explication :D
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
10 juin 2006 à 10:54
Dans MSDN c'est écrit que les DLGITEMTEMPLATES doivent être alignées sur des DWORD (Each DLGITEMTEMPLATE structure in the template must be aligned on a DWORD boundary).
Or le premier param est aligné sur un WORD, mais pas forcément un DWORD
Si tu me demandes ce que signifie aligné sur un DWORD, ca veut juste dire que l'adresse est un mutliple de la taille d'un DWORD, soit 4
Donc, si (lpw & 3) est différent de 0, ca veut dire que c'est pas un multiple de 4 (les multiples de 4 on leur deux bits de poids faible à 0). Dans ce cas je l'incrémente (ce qui ajoute en fait deux au pointeur, qui est maintenant aligné sur un DWORD).
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
10 juin 2006 à 09:31
Yop vecchio, j'ai regardé ton utilisation de DLGITEMTEMPLATE ca ressemble fort a DLGTEMPLATE mais je ne comprend pas cece :
if((LPARAM)lpw & 3) lpw++; // Aligner sur un DWORD

A quoi cella sert-il (et ne me dit pas a aligner sur un DWORD mdr :) ).
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
7 juin 2006 à 16:29
Dommage que les fenêtres ne supportent pas cette méthode. On est obligés de passer par CreateWindow().
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
7 juin 2006 à 16:20
Merci por ces précisions.
Pour modifier la police de tous les controles enfants, une simple petite boucle do while() suffit. J'ai utilisé cette astuce dans mes dernières sources déposées sur le site. Mais ta solution doit être meilleure car plus rapide.
C'est vrai que CreateWindow() travaille en pixels. Je contourne le problème dans une DialogBox en récupérant le clientrect(qui est en pixels) de la boite de dialogue et positionner les controles dans ce rectangle.
A propos de GetDlgItem(), si on utilise beaucoup les HWNDs, on peut les récupérer une seule fois pendant WM_INITDALOG. La boite s'affiche un peu moins vite mais c'est mieux que CreateWindow().
10/10
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
7 juin 2006 à 15:44
Le projet est en mode console pour la version debug, c'est une habitude que j'ai prise car j'utilise souvent la console en debug.
CreateControl ne peut pas retourner un HWND, car cette fonction est appelée avant la création du DialogBox, et donc quand CreateControl retourne, aucune fenêtre n'est encore créée.
Il faut donc en effet utilsier GetDlgItem, ou d'autres fonctions comme SendDlgItemMessage
Cela dit, a mon avis ma solution reste meilleure. Comme tu le dis le chargement est plus rapide, car au moment de l'appel de DialogBoxParam, tout est prêt en mémoire, ce qui est faux quand on fait des appels successifs à CreateWindow
Par ailleurs, l'utilisation de CreateWindow n'est pas logique, car les coordonnées fournies sont en pixels, alors que dans une DialogBox on doit raisonner en dialog unit.
Ainsi, si tu choisis de modifier ta police, ma solution sera meilleure, car tous les contrôles seront automatiquement redimentionnés. Ce n'est évidemment pas le cas avec des appels à CreateWindow.
Si pour toi le seul inconvénient est qu'il faut appeler GetDlgItem, je trouve qu'il s'agit d'un inconvénient mineur
racpp Messages postés 1909 Date d'inscription vendredi 18 juin 2004 Statut Modérateur Dernière intervention 14 novembre 2014 17
7 juin 2006 à 15:03
Salut,
vecchio56 a raison, l'intérêt de ce code réside dans l'utilisation de la structure DLGITEMTEMPLATE. Il l'utilise dans la fonction CreateControl() pour justement créer des controles. Pour créer la boite de dialogue il est normal qu'il utilise DLGTEMPLATE. Ca, ce n'est pas nouveau. Cela fait presque deux ans que j'ai déposé une source utilisant cette structure pour créer des boites de dialogue sans ressources. Je connaissais la structure DLGITEMTEMPLATE mais je trouvais son utilisation moins pratique que CreateWindow(). Il est vrai qu'on n'aura plus besoin de WM_SETFONT. Par contre il faudra utiliser GetDlgItem() pour récupérer le HWND des controles. Tout le monde sait que beaucoup de fonctions API utilisent un HWND comme paramètre. Si on pourrait améliorer la fonction CreateControl() pour qu'elle retourne un HWND ce serait parfait.
En lançant l'exécutable, deux choses m'ont frappé. La taille de l'exe (2 Ko), c'est un record, et la rapidité. Même en ajoutant beaucoup de controles, tout s'affiche instantanément. J'aimerais juste préciser que pour mettre beaucoup de controles, il faut allouer suffisamment de mémoire avec GlobalAlloc().
Je pense que ja vais explorer davantage ta méthode car elle semble intéressante.
Une question: Ce projet est console? car une fenêtre console s'affiche en mode Debug.
Merci pour le code.
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
6 juin 2006 à 20:46
par contre "C'est l'utilisation de la structure DLGITEMTEMPLATE qui est expliquée ici (et pas DLGTEMPLATE)" vraiment? alors qu'est ce que :

# LPWORD CreateDlg(LPWORD lpw, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int cx, int cy,
# int fontSize, LPCTSTR lpFontName, int ctrlNum)
# {
# LPDLGTEMPLATE lpdt = (LPDLGTEMPLATE)lpw;
#
# if(!lpFontName)
# {
# lpFontName = "Ms Shell Dlg 2";
# fontSize = 8;
# }
#
# lpdt->style = dwStyle;
# lpdt->x = x;
# lpdt->y = y;
# lpdt->cx = cx;
# lpdt->cy = cy;
# lpdt->cdit = ctrlNum; // Nombre de contrôles
#
# lpw = (LPWORD)(lpdt + 1);
# *lpw++ = 0; // Pas de menu
# *lpw++ = 0; // Classe par défaut
# if(lpWindowName) lpw += MultiByteToWideChar(CP_ACP, 0, lpWindowName, -1, (LPWSTR)lpw, 128);
# else *lpw++ = 0;
#
# *lpw++ = fontSize;
# return lpw + MultiByteToWideChar(CP_ACP, 0, lpFontName, -1, (LPWSTR)lpw, 128);
# }

héhé bon bon cava j'arrête MDR :D
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
6 juin 2006 à 20:45
Trop tard, encore une blague de ce genre et t'es viré :)
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
6 juin 2006 à 20:38
oui oui je m'en susi rendu compte après, toutes mes excuse :p
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
6 juin 2006 à 20:37
Oui, mais c'est toi qui a des problèmes de vue :)
DLGTEMPLATE -> Pour la dialogBox
DLGITEMTEMPLATE -> pour les contrôles
C'est l'utilisation de la structure DLGITEMTEMPLATE qui est expliquée ici (et pas DLGTEMPLATE)
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
6 juin 2006 à 20:36
ha dans une dialogbox non, sorry mais je crée bien une dialogbox sans ressource ;) .
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
6 juin 2006 à 20:34
? vecchio tu a des problèmes de vue regarde :D :

HGLOBAL hgMemory;
LPDLGTEMPLATE stDlgBox;
LPWORD lpwWord;
LPWSTR lpwsUnicode;

hgMemory = GlobalAlloc(GPTR,512);
if(!hgMemory){
MessageBox(hwnd,"Function : GlobalAlloc()","Erreur",MB_OK |MB_ICONERROR);
break;
}
stDlgBox = (LPDLGTEMPLATE) hgMemory;

stDlgBox->style = WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_POPUP | DS_MODALFRAME;
stDlgBox->cx = 110;
stDlgBox->cy = 50;
stDlgBox->x = GetSystemMetrics(SM_CXSCREEN)/6;
stDlgBox->y = GetSystemMetrics(SM_CYSCREEN)/6;

lpwWord = (LPWORD) (stDlgBox + 1);
lpwsUnicode = (LPWSTR) (lpwWord + 2);

MultiByteToWideChar(CP_ACP,0,"Execute",-1,lpwsUnicode,128);
DialogBoxIndirect(GlobalHInstance,stDlgBox,0,(DLGPROC)ExeProc);

J'utilise bien LPDLGTEMPLATE mdr
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
6 juin 2006 à 18:45
Un avantage de ma méthode aussi, c'est que tu n'a pas à te soucier des problèmes de police (pas de WM_SETFONT a envoyer, c'est géré automatiquement: les contrôles héritent de la police de la boite de dialogue)
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
6 juin 2006 à 18:38
Je ne vois pas de DLGITEMTEMPLATE pour créer des controles dans ta source.
Tu utilises des CreateWindow, ce qui n'est pas logique dans une DialogBox
deck_bsd Messages postés 1243 Date d'inscription jeudi 31 mars 2005 Statut Membre Dernière intervention 3 août 2016 2
6 juin 2006 à 17:56
"mais aucun je crois ne montre la création de controles".Si moi je crée mes boites de dialogue comme cela :D avec LPDLGTEMPLATE.D'ailleur cela ce voi dans ma dernière source mdr.

Mais c'est une bonne source :D
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
5 juin 2006 à 10:26
Moi je ne pense pas
gagah1 Messages postés 509 Date d'inscription samedi 28 juin 2003 Statut Membre Dernière intervention 3 août 2010
5 juin 2006 à 07:47
Je pense que tu as utilisé ce code pour l'aperçu dans ton éditeur de ressources.
vecchio56 Messages postés 6535 Date d'inscription lundi 16 décembre 2002 Statut Membre Dernière intervention 22 août 2010 14
4 juin 2006 à 23:14
Ce code la je l'utilise pas dedans t'inquiète pas
Je renomme l'exe...
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
4 juin 2006 à 23:11
Renomme ton exe.
En bonne voie pour fournir ton éditeur de ressources par petits morceaux.
Rejoignez-nous