Ce code montre comment créer une DialogBox contenant des controles sans utilsier des ressources. Il y a déja des codes utilisant DialogBoxIndirect, mais aucun je crois ne montre la création de controles, grâce à la structure DLGITEMTEMPLATE.
Source / Exemple :
#include <windows.h>
#include <commctrl.h>
#pragma comment(lib, "comctl32.lib")
INT_PTR CALLBACK DialogProc(HWND hDlg, UINT uMsg, WPARAM, LPARAM)
{
if(uMsg == WM_CLOSE) EndDialog(hDlg, 0);
return 0;
}
LPWORD CreateControl(LPWORD lpw, DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,
int x, int y, int cx, int cy, int ctlID)
{
if((LPARAM)lpw & 3) lpw++; // Aligner sur un DWORD
LPDLGITEMTEMPLATE lpit = (LPDLGITEMTEMPLATE)lpw;
lpit->x = x;
lpit->y = y;
lpit->cx = cx;
lpit->cy = cy;
lpit->style = dwStyle;
lpit->dwExtendedStyle = dwExStyle;
lpit->id = ctlID;
lpw = (LPWORD) (lpit + 1);
lpw += MultiByteToWideChar(CP_ACP, 0, lpClassName, -1, (LPWSTR)lpw, 128);
if(lpWindowName) lpw += MultiByteToWideChar(CP_ACP, 0, lpWindowName, -1, (LPWSTR)lpw, 128);
else *lpw++ = 0;
- lpw++ = 0; // Pas de data
return lpw;
}
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;
return lpw + MultiByteToWideChar(CP_ACP, 0, lpFontName, -1, (LPWSTR)lpw, 128);
}
#ifdef _DEBUG
int main()
#else
#pragma comment(linker, "/entry:myWinMain")
int __stdcall myWinMain()
#endif
{
InitCommonControls();
HGLOBAL mem = GlobalAlloc(GPTR, 1024);
LPWORD lpw = (LPWORD)mem;
lpw = CreateDlg(lpw, "Test", DS_SETFONT | DS_CENTER | WS_POPUP | WS_BORDER | WS_MINIMIZEBOX | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION,
0, 0, 249, 89, 0, 0, 3);
// Création de quelques controles
lpw = CreateControl(lpw, 0, "Button", "Cancel", WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 192, 68, 50, 14, 1000);
lpw = CreateControl(lpw, 0, "msctls_progress32", 0, WS_VISIBLE | WS_CHILD | PBS_SMOOTH, 7, 40, 235, 9, 1001);
lpw = CreateControl(lpw, WS_EX_CLIENTEDGE, "edit", 0, WS_VISIBLE | WS_CHILD, 7, 7, 100, 13, 1002);
DialogBoxIndirect(0, (LPDLGTEMPLATE)mem, NULL, DialogProc);
GlobalFree(mem);
#ifdef _DEBUG
return 0;
#else
ExitProcess(0);
#endif
}
10 juin 2006 à 14:28
10 juin 2006 à 10:54
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).
10 juin 2006 à 09:31
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 :) ).
7 juin 2006 à 16:29
7 juin 2006 à 16:20
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
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.