1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: msw/ownerdrw.cpp
3 // Purpose: implementation of wxOwnerDrawn class
4 // Author: David Webster
8 // Copyright: (c) David Webster
9 // Licence: wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
13 #pragma implementation
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
20 #include "wx/window.h"
21 #include "wx/msw/private.h"
23 #include "wx/bitmap.h"
24 #include "wx/dcmemory.h"
31 #include "wx/ownerdrw.h"
32 #include "wx/menuitem.h"
35 // ============================================================================
36 // implementation of wxOwnerDrawn class
37 // ============================================================================
43 wxOwnerDrawn
::wxOwnerDrawn(
50 m_bCheckable
= bCheckable
;
51 m_bOwnerDrawn
= FALSE
;
53 m_nMarginWidth
= ms_nLastMarginWidth
;
55 m_font
= *wxNORMAL_FONT
;
56 } // end of wxOwnerDrawn::wxOwnerDrawn
58 size_t wxOwnerDrawn
::ms_nDefaultMarginWidth
= 15;
60 size_t wxOwnerDrawn
::ms_nLastMarginWidth
= ms_nDefaultMarginWidth
;
67 bool wxOwnerDrawn
::OnMeasureItem(
74 vDC
.SetFont(GetFont());
76 wxString sStr
= wxStripMenuCodes(m_strName
);
82 nIndex
= sStr
.Find(sTgt
.c_str());
86 nIndex
= sStr
.Find(sTgt
.c_str());
88 sStr
.Replace(sTgt
.c_str(), "", TRUE
);
90 vDC
.GetTextExtent( sStr
95 (*pHeight
) = (*pHeight
) + 2;
96 m_nHeight
= *pHeight
; // remember height for use in OnDrawItem
98 } // end of wxOwnerDrawn::OnMeasureItem
101 bool wxOwnerDrawn
::OnDrawItem(
103 , const wxRect
& rRect
109 // We do nothing on focus change
111 if (eAction
== wxODFocusChanged
)
115 // Select the font and draw the text
116 // ---------------------------------
120 HPS hPS
= rDC
.GetHPS();
124 RECTL vRect
= {rRect
.x
+ 4, rRect
.y
+ 1, rRect
.x
+ (rRect
.width
- 2), rRect
.y
+ rRect
.height
};
128 // Use default font if no font set
132 m_font
.RealizeResource();
136 ::GpiSetCharSet(hPS
, LCID_DEFAULT
);
140 // Base on the status of the menu item pick the right colors
142 if (eStatus
& wxODSelected
)
144 wxColour
vCol2("WHITE");
145 vColBack
.Set( (unsigned char)0
148 ); // no dark blue in color table
151 else if (eStatus
& wxODDisabled
)
153 vRef
= (ULONG
)::WinQuerySysColor( HWND_DESKTOP
154 ,SYSCLR_MENU
// Light gray
157 vColBack
.Set( GetRValue(vRef
)
161 vRef
= (ULONG
)::WinQuerySysColor( HWND_DESKTOP
162 ,SYSCLR_MENUDISABLEDTEXT
// dark gray
165 vColText
.Set( GetRValue(vRef
)
173 // Fall back to default colors if none explicitly specified
175 vRef
= ::WinQuerySysColor( HWND_DESKTOP
176 ,SYSCLR_MENU
// we are using gray for all our window backgrounds in wxWindows
179 vColBack
.Set( GetRValue(vRef
)
183 vRef
= ::WinQuerySysColor( HWND_DESKTOP
184 ,SYSCLR_WINDOWTEXT
// Black
187 vColText
.Set( GetRValue(vRef
)
192 rDC
.SetTextBackground(vColBack
);
193 rDC
.SetTextForeground(vColText
);
194 rDC
.SetBackgroundMode(wxTRANSPARENT
);
197 // Paint the background
199 ::WinFillRect(hPS
, &vRect
, vColBack
.GetPixel());
202 // Determine where to draw and leave space for a check-mark.
204 int nX
= rRect
.x
+ GetMarginWidth();
207 // Unfortunately, unlike Win32, PM has no owner drawn specific text
208 // drawing methods like ::DrawState that can cleanly handle accel
209 // pneumonics and deal, automatically, with various states, so we have
210 // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
211 // strings either. We cannot handle mneumonics either. We display
212 // it, though, in hopes we can figure it out some day.
216 // Display main text and accel text separately to allign better
218 wxString sTgt
= "\t";
219 wxString sFullString
= m_strName
; // need to save the original text
225 bool bFoundMneumonic
= FALSE
;
226 bool bFoundAccel
= FALSE
;
229 // Deal with the tab, extracting the Accel text
231 nIndex
= sFullString
.Find(sTgt
.c_str());
235 sAccel
= sFullString
.Mid(nIndex
+ 1);
236 sFullString
.Remove(nIndex
);
240 // Deal with the mneumonic character
243 nIndex
= sFullString
.Find(sTgt
.c_str());
246 wxString sTmp
= sFullString
;
248 bFoundMneumonic
= TRUE
;
250 rDC
.GetTextExtent( sTmp
254 sTmp
= sFullString
[nIndex
+ 1];
255 rDC
.GetTextExtent( sTmp
259 sFullString
.Replace(sTgt
.c_str(), "", TRUE
);
263 // Draw the main item text sans the accel text
264 rDC
.DrawText( sFullString
271 // Underline the mneumonic -- still won't work, but at least it "looks" right
274 POINTL vPntStart
= {nX
+ nWidth
- 1, rRect
.y
+ 2}; // Make it look pretty!
275 POINTL vPntEnd
= {nX
+ nWidth
+ nCharWidth
- 3, rRect
.y
+ 2}; //CharWidth is bit wide
277 vPen
= wxPen(vColText
, 1, wxSOLID
); // Assuming we are always black
279 ::GpiMove(hPS
, &vPntStart
);
280 ::GpiLine(hPS
, &vPntEnd
);
284 // Now draw the accel text
291 rDC
.GetTextExtent( sAccel
296 // Back off the starting position from the right edge
299 ,rRect
.width
- (nWidth
+ 7) // this seems to mimic the default OS/2 positioning
308 if (IsCheckable() && !m_bmpChecked
.Ok())
310 if (eStatus
& wxODChecked
)
313 HBITMAP hBmpCheck
= ::WinGetSysBitmap(HWND_DESKTOP
, SBMP_MENUCHECK
);
315 vRect
.xLeft
= rRect
.x
;
316 vRect
.xRight
= rRect
.x
+ GetMarginWidth();
317 vRect
.yBottom
= rRect
.y
;
318 vRect
.yTop
= rRect
.y
+ m_nHeight
;
320 ::WinDrawBitmap( hPS
// PS for this menuitem
321 ,hBmpCheck
// system checkmark
322 ,NULL
// draw the whole bitmap
323 ,(PPOINTL
)&vRect
// destination -- bottom left corner of the menuitem area
326 ,DBM_NORMAL
// draw normal size
333 // For uncheckable item we use only the 'checked' bitmap
335 wxBitmap
vBmp(GetBitmap(IsCheckable() ?
((eStatus
& wxODChecked
) != 0) : TRUE
));
339 wxMemoryDC
vDCMem(&rDC
);
341 vDCMem
.SelectObject(vBmp
);
346 int nBmpWidth
= vBmp
.GetWidth();
347 int nBmpHeight
= vBmp
.GetHeight();
350 // There should be enough space!
352 wxASSERT((nBmpWidth
<= rRect
.width
) && (nBmpHeight
<= rRect
.height
));
355 //MT: blit with mask enabled.
357 rDC
.Blit( rRect
.x
+ (GetMarginWidth() - nBmpWidth
) / 2
358 ,rRect
.y
+ (m_nHeight
- nBmpHeight
) /2
368 if (eStatus
& wxODSelected
)
370 RECT vRectBmp
= { rRect
.x
372 ,rRect
.x
+ GetMarginWidth()
377 vLine
.lColor
= vColBack
.GetPixel();
394 } // end of wxOwnerDrawn::OnDrawItem
396 #endif //wxUSE_OWNER_DRAWN