Slt,

j'ai une question relative à la tabulation sur une appli,

j'utilise la classe suivante :

// transparentbitmapbutton.h
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
#pragma once
#include "afxext.h"
#include "DigiDialog.h"
#include <math.h>
 
//---------------------------------------------------------
// Ces boutons sont à utiliser sur les fiches DigiDialog	
// car ils utilisent les données membre m_fRatioWidth et 
// m_fRatioHeight pour se redimensionner
//---------------------------------------------------------
 
class CTransparentBitmapButton :
	public CBitmapButton
{
private:
	void DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap);
 
	// The colour inside this button's bitmap(s) that should be regarded as transparent
	// is selected by the one of the pixel locate by X, Y
	int m_iXPxlTranparent, m_iYPxlTranparent;
 
	float m_fRatioWidth, m_fRatioHeight;
	int GetWidthResized(int oldWidth);
	int GetHeightResized(int oldHeight);
 
	CBitmap m_BitmapBackground;
 
public:
	CTransparentBitmapButton(int XPxlT, int YPxlT);
	~CTransparentBitmapButton(void);
 
	//virtual void OnPaint();
	virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
	DECLARE_MESSAGE_MAP()
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
 
protected:
	virtual void PreSubclassWindow();
};
// transparentbitmapbutton.cpp
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
 
#include "StdAfx.h"
#include ".\transparentbitmapbutton.h"
 
BEGIN_MESSAGE_MAP(CTransparentBitmapButton, CBitmapButton)
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()
 
CTransparentBitmapButton::CTransparentBitmapButton(int XPxlT,int YPxlT)
{
	// Initialise the transparent pixel X,Y
	m_iXPxlTranparent = XPxlT;
	m_iYPxlTranparent = YPxlT;
 
	m_fRatioWidth = -1;
	m_fRatioHeight = -1;
}
 
CTransparentBitmapButton::~CTransparentBitmapButton(void)
{
}
 
// recupere l'image de fond avant le dessin du bouton
void CTransparentBitmapButton::PreSubclassWindow() 
{
	CBitmapButton::PreSubclassWindow();
 
	CWnd *pParent = GetParent();
	if (pParent)
	{	   
		CRect Rect;
		GetClientRect(&Rect);
		ClientToScreen(&Rect);
		pParent->ScreenToClient(&Rect);
		CDC *pDC = pParent->GetDC();
		m_BitmapBackground.CreateCompatibleBitmap(pDC,Rect.Width(),Rect.Height());	  
	}
}
 
int CTransparentBitmapButton::GetWidthResized(int oldWidth)
{
	return int ( ceil ( float(oldWidth) * m_fRatioWidth ) ) ;
}
 
int CTransparentBitmapButton::GetHeightResized(int oldHeight)
{
	return int ( ceil ( float(oldHeight) * m_fRatioHeight ) ) ;
}
 
BOOL CTransparentBitmapButton::OnEraseBkgnd(CDC* pDC)
{
	CDigiDialog *pParent = static_cast<CDigiDialog *> (GetParent());
 
	if ( pParent && ( (pParent->m_fRatioWidth != m_fRatioWidth) || (pParent->m_fRatioHeight != m_fRatioHeight) ) )
	{
		m_fRatioWidth  = pParent->m_fRatioWidth;
		m_fRatioHeight  = pParent->m_fRatioHeight;
 
		CRect Rect;
		GetClientRect(&Rect);
		ClientToScreen(&Rect);
		pParent->ScreenToClient(&Rect);
		CDC *pDC = pParent->GetDC();
		CDC memdc;
		memdc.CreateCompatibleDC(pDC);
		CBitmap *oldbmp = memdc.SelectObject(&m_BitmapBackground);
		memdc.BitBlt(0,0,Rect.Width(),Rect.Height(),pDC,Rect.left,Rect.top,SRCCOPY);
		memdc.SelectObject(oldbmp);
		pParent->ReleaseDC(pDC);
 
	}
 
 
	return TRUE;
}
 
/*
// From 'OnPaint()
void CTransparentBitmapButton::OnPaint() 
{
	if ((GetParent()) && (GetParent()->IsIconic()))
	{
		CBitmapButton::OnPaint();
	}
	else
	{
		CPaintDC dc(this); // device context for painting
 
		// At least onw bitmap must be loaded before calling 'Paint()'
		ASSERT(m_bitmap.m_hObject != NULL);
 
		// and we'll assume until we find otherwise, that
		// the button is being drawn in its normal state.
		CBitmap* pBitmap = &m_bitmap;
 
		if ((!(IsWindowEnabled())) && (NULL != m_bitmapDisabled.m_hObject))
			pBitmap = &m_bitmapDisabled;
 
		DrawTransparentBitmap(dc.m_hDC, *pBitmap);
	}
}
*/
void CTransparentBitmapButton::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
	ASSERT(lpDrawItemStruct != NULL);
 
	// At least onw bitmap must be loaded before calling 'DrawItem()'
	ASSERT(m_bitmap.m_hObject != NULL);
 
	CBitmap* pBitmap = &m_bitmap;
	UINT state = lpDrawItemStruct->itemState;
 
	if ((state & ODS_SELECTED) && (NULL != m_bitmapSel.m_hObject))
		pBitmap = &m_bitmapSel;
	else if ((state & ODS_FOCUS) && (NULL != m_bitmapFocus.m_hObject))
		pBitmap = &m_bitmapFocus;
	else if ((state & ODS_DISABLED) && (NULL != m_bitmapDisabled.m_hObject))
		pBitmap = &m_bitmapDisabled;
 
	DrawTransparentBitmap(lpDrawItemStruct->hDC, *pBitmap);
}
 
void CTransparentBitmapButton::DrawTransparentBitmap(HDC hdc, HBITMAP hBitmap)
{
BITMAP	bm;
COLORREF cColour;
HBITMAP	bmAndBack, bmAndObject, bmAndMem, bmSave;
HBITMAP	bmBackOld, bmObjectOld, bmMemOld, bmSaveOld;
HDC		hdcMem, hdcBack, hdcObject, hdcTemp, hdcSave;
POINT		ptSize;
 
 
	hdcTemp = CreateCompatibleDC(hdc);
	if (HGDIOBJ hOldObj = SelectObject(hdcTemp, hBitmap)) // Select the bitmap
		DeleteObject(hOldObj);
 
	GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
	ptSize.x = bm.bmWidth;
	ptSize.y = bm.bmHeight;
 
	DPtoLP(hdcTemp, &ptSize, 1); // Convert from device  to logical points
 
	// Create some DCs to hold temporary data.
	hdcBack	 = CreateCompatibleDC(hdc);
	hdcObject = CreateCompatibleDC(hdc);
	hdcMem	 = CreateCompatibleDC(hdc);
	hdcSave	 = CreateCompatibleDC(hdc);
 
	// Create a bitmap for each DC. DCs are required for a number of GDI functions.
 
	// Monochrome DC
	bmAndBack = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
 
	// Monochrome DC
 
	bmAndObject = CreateBitmap(ptSize.x, ptSize.y, 1, 1, NULL);
 
	bmAndMem = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
	bmSave = CreateCompatibleBitmap(hdc, ptSize.x, ptSize.y);
 
 
	// Each DC must select a bitmap object to store pixel data.
	bmBackOld	= (HBITMAP)SelectObject(hdcBack, bmAndBack);
	bmObjectOld = (HBITMAP)SelectObject(hdcObject, bmAndObject);
	bmMemOld	= (HBITMAP)SelectObject(hdcMem, bmAndMem);
	bmSaveOld	= (HBITMAP)SelectObject(hdcSave, bmSave);
 
	// Set proper mapping mode.
	SetMapMode(hdcTemp, GetMapMode(hdc));
 
	// Save the bitmap sent here, because it will be overwritten.
	BitBlt(hdcSave, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
 
	COLORREF transparentColour = GetPixel(hdcTemp, m_iXPxlTranparent, m_iYPxlTranparent);
 
	if (transparentColour) cColour = SetBkColor(hdcTemp, transparentColour);
 
	// Create the object mask for the bitmap by performing a BitBlt
	// from the source bitmap to a monochrome bitmap.
	BitBlt(hdcObject, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCCOPY);
 
	SetBkColor(hdcTemp, cColour);
 
	// Create the inverse of the object mask.
	BitBlt(hdcBack, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, NOTSRCCOPY);
 
	// Copy the background of the main DC to the destination.
	CDC MemDC;
	CDC* pDC = CDC::FromHandle(hdc) ;	
	BITMAP InfosBmp;
	m_BitmapBackground.GetBitmap(&InfosBmp);
	MemDC.CreateCompatibleDC(pDC);
	MemDC.SelectObject(&m_BitmapBackground);
	BitBlt(hdcMem, 0, 0, InfosBmp.bmWidth, InfosBmp.bmHeight, MemDC, 0, 0, SRCCOPY);
	DeleteDC(MemDC);
 
	// Mask out the places where the bitmap will be placed.
	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcObject, 0, 0, SRCAND);
 
	// Mask out the transparent coloured pixels on the bitmap.
	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcBack, 0, 0, SRCAND);
 
 
	// XOR the bitmap with the background on the destination DC.
	BitBlt(hdcMem, 0, 0, ptSize.x, ptSize.y, hdcTemp, 0, 0, SRCPAINT);
 
	// Copy the destination to the screen.
	StretchBlt(hdc, 0, 0, GetWidthResized(ptSize.x), GetHeightResized(ptSize.y), hdcMem, 0, 0,ptSize.x, ptSize.y, SRCCOPY);
	//BitBlt(hdc, 0, 0, ptSize.x, ptSize.y, hdcMem, 0, 0, SRCCOPY);
 
	// Place the original bitmap back into the bitmap sent here.
	BitBlt(hdcTemp, 0, 0, ptSize.x, ptSize.y, hdcSave, 0, 0, SRCCOPY);
 
	// Delete the memory bitmaps.
	DeleteObject(SelectObject(hdcBack, bmBackOld));
	DeleteObject(SelectObject(hdcObject, bmObjectOld));
	DeleteObject(SelectObject(hdcMem, bmMemOld));
	DeleteObject(SelectObject(hdcSave, bmSaveOld));
 
	// Delete the memory DCs.
	DeleteDC(hdcMem);
	DeleteDC(hdcBack);
	DeleteDC(hdcObject);
	DeleteDC(hdcSave);
	DeleteDC(hdcTemp);
}
Elle me permet de créer des boutons utilisant des images que j'ai en ressource ainsi :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
m_boutonImprimer.LoadBitmaps(IDB_BITMAP_IMPRIMER, IDB_BITMAP_IMPRIMER_CLICK, 0, IDB_BITMAP_IMPRIMER_DISABLED);
Cela fonctionne tres bien, mon seul probleme vient du fait que du coup, quand je fais tabulation, apparemment, le bouton prend bien le focus dans la sequence de tabulation, mais quand il l'a, taper ENTRE ne sert a rien, il ne lance pas le code du onclick,

comment faire pour corriger cela ?