IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MFC Discussion :

CMenu personnalisé en ActiveX vide


Sujet :

MFC

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 3
    Par défaut CMenu personnalisé en ActiveX vide
    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 ?

  2. #2
    Expert confirmé
    Avatar de Mat.M
    Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    8 526
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2006
    Messages : 8 526
    Par défaut
    Citation Envoyé par Misterweb34 Voir le message
    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 ?

    Des idées ?
    une appli Windows reçoit des messages envoyés par l'OS , le Program Manager de Windows dans la boucle de messages.
    Le PM envoit les messages selon le HINSTANCE et HWND de l'application
    Or un Active X possède un HWND (ou ne possède pas de HWND ) différent de l'application cliente.
    Donc vraisemblabement ton problème vient du fait que le CMenu passé en paramêtre aux méthodes de l'Active X ne pointe pas sur le bon CWnd/HWND de fenêtre.
    Il faudrait passer quelque part dans le code à l'Active X le CWnd de l'application cliente qui appelle les méthodes de l'Active X.
    Parce que le CMenu d'une application est rattaché au Handle de fenêtre...

Discussions similaires

  1. [OL-2007] Formulaire personnalisé vide
    Par Harry Covair dans le forum Outlook
    Réponses: 1
    Dernier message: 19/03/2010, 23h55
  2. Déclencher un evenement personnalisé d'un ActiveX
    Par Dung-Tri dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 03/09/2008, 10h36
  3. [MFC] Contrôle ActiveX vide
    Par tus01 dans le forum MFC
    Réponses: 3
    Dernier message: 15/12/2005, 20h44
  4. [] Datagrid vide après modification des propriétés
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 20/09/2002, 16h37
  5. [CR] Avoir seulement une page blanche qd la base est vide???
    Par littleChick dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 13/08/2002, 18h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo