Bonjour à tous !
Alors là, je suis un problème assez tordu qui demande pas mal de connaissance...

Je bosse sur une application où je souhaite à un moment avoir une PopupMenu (Menu du clic droit) personnalisée. Selon la doc, je fais en sorte d'avoir le flag MF_OWNERDRAW quand j'appelle les AppendMenu et que je surcharge les méthodes DrawItem et MesureItem de CMenu pour y préciser comment le menu doit être. Une fois que je TrackPopupMenu, je m'aperçois que mon menu est vide graphiquement (mais on peut tout de même cliquer sur différentes lignes)... (Je précise que je suis en ActiveX)

Après quelques recherches, c'est la méthode DrawItem que j'ai surchargée de CMenu qui n'est jamais appelée (alors qu'elle est censée l'être vu que j'ai mit le flag MF_OWNERDRAW). Pourtant la méthode MesureItem est bien appelée (qui est aussi une surcharge de CMenu)...

Je suis allé plus loin, le menu s'affiche quand je suis dans une application MFC complète...

Je suis perdu, j'ai l'impression que le message DRAWITEM n'est jamais émit, mais je ne comprend pas pourquoi. L'environnement ActiveX est différent ?

Bref, les codes de la création du menu (j'ai coupé le code inutile) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
	DStr         csTxt;
    CPoint       PtCursorPos;
    CMenuSupedit Menu;
    CMenuSupedit SousMenuSpecial;
    CMenuSupedit SousMenuBlanc;
 
[...]
 
	// Display the contextual menu
    GetCursorPos(&PtCursorPos);
    Menu.CreatePopupMenu();
 
	// Mode selection
	if(m_pTContainer->IsSelectionMode())
		Menu.AppendMenu(MF_OWNERDRAW, NOTIFY_CLIP_MODE);
	else
		Menu.AppendMenu(MF_OWNERDRAW, NOTIFY_SELECTION_MODE);
	//  Mode Insertion
	if(m_pTContainer->IsInsertionMode())
		Menu.AppendMenu(MF_OWNERDRAW, NOTIFY_REPLACE_MODE);
	else
		Menu.AppendMenu(MF_OWNERDRAW, NOTIFY_INSERTION_MODE);
	Menu.AppendMenu(MF_DISABLED|MF_OWNERDRAW,NOTIFY_SEPARATOR);
 
[...]
 
 
	Menu.TrackPopupMenu(TPM_LEFTALIGN,PtCursorPos.x,PtCursorPos.y,this);
 
[...]
Ici la classe CMenusupedit (pour la surcharge de CMenu) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
void 
CMenuSupedit::MeasureItem( LPMEASUREITEMSTRUCT lpMeasureItemStruct )
{
	CMenu::MeasureItem(lpMeasureItemStruct);
	lpMeasureItemStruct->itemWidth = 170;
 
	if (lpMeasureItemStruct->itemID==NOTIFY_SEPARATOR)
	{
		lpMeasureItemStruct->itemHeight = 10;
	}
}
 
 
 
void 
CMenuSupedit::DrawItem( LPDRAWITEMSTRUCT lpDrawItemStruct )
{
	BOOL bSeparator = FALSE;
	if (lpDrawItemStruct->CtlType!=ODT_MENU || lpDrawItemStruct->itemID==0) return;
 
	if (lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT))
	{
		LPTSTR   szTemp;
		HDC      hDC = lpDrawItemStruct->hDC;
		CRect    Rect(lpDrawItemStruct->rcItem);
		DStr     csTxt;
		COLORREF oldTextColor = SetTextColor(hDC,RGB(0,0,0));
		int      IdIcon=0;
 
		if ( !(lpDrawItemStruct->itemState & ODS_SELECTED) || (lpDrawItemStruct->itemState & ODS_DISABLED)) 
			SetBkColor(hDC, STD_BK_COLOR);	
		else
			SetBkColor(hDC,GEN_HILIGHT_COLOR);
 
		switch (lpDrawItemStruct->itemID)
		{
			case NOTIFY_SELECTION_MODE :
				GetCurLangMessage(2200,csTxt, _T("Selection Mode")); 
				IdIcon = IDI_SELECTION_ZONE;
			break;
[...]
 
			case NOTIFY_END_EXTENSION : 
			{
				GetCurLangMessage(2258,csTxt,_T("End extension"));
				IdIcon = IDI_ENDEXTENT; 	
			}
			break;
 
 
			case NOTIFY_SEPARATOR :
				bSeparator = TRUE;
				break;
 
			default :
				szTemp = (LPTSTR) lpDrawItemStruct->itemData;
				if (szTemp != NULL && lstrlen(szTemp) > 0 && lstrlen(szTemp) < 32)
				{
					DStr csSpecial;
 
					GetCurLangMessage(2110,csSpecial,_T("Special"));
 
					csTxt = szTemp;
					if (csTxt == csSpecial) IdIcon = IDI_NETIA;
					else                    IdIcon = IDI_BLANK;
				}
			break;
		}
 
 
		ExtTextOut(hDC,0, 0, ETO_OPAQUE,(const RECT*)  &Rect, NULL, NULL, NULL );
 
		if (bSeparator)
		{
			HPEN pOldPen = (HPEN) SelectObject(hDC,GetStockObject(WHITE_PEN));
			MoveToEx(hDC,Rect.left,Rect.top + (Rect.Height()/2),NULL);
			LineTo(hDC,Rect.right,Rect.top + (Rect.Height()/2));
			if (pOldPen!=NULL) SelectObject(hDC,pOldPen);
		}
 
		Rect.left  += 25;
		//Rect.right = Rect.left + 135;
 
		if (IdIcon!=0)
		{
			HANDLE hIcon = LoadImage(g_hCurrentModuleInstance,MAKEINTRESOURCE(IdIcon),IMAGE_ICON,16,16,LR_DEFAULTCOLOR|LR_SHARED);
			if (!DrawIconEx(hDC,2,Rect.top,(HICON) hIcon,16,16,0,NULL,DI_NORMAL))
			{
				//DWORD dwErr = GetLastError();
			}
		}
 
		if (csTxt.Length()!=0) 
		{
			DrawText(hDC,csTxt,csTxt.Length(),&Rect,DT_LEFT|DT_VCENTER|DT_SINGLELINE);
		}
 
		SetTextColor(hDC,oldTextColor);
	}
}
DrawItem n'est jamais appelée en ActiveX...
Des idées ?