// implementation of wxOwnerDrawn class
// ============================================================================
+//
// ctor
// ----
-wxOwnerDrawn::wxOwnerDrawn(const wxString& str,
- bool bCheckable, bool bMenuItem)
- : m_strName(str)
+//
+wxOwnerDrawn::wxOwnerDrawn(
+ const wxString& rsStr
+, bool bCheckable
+, bool bMenuItem
+)
+: m_strName(rsStr)
{
- m_bCheckable = bCheckable;
- m_bOwnerDrawn = FALSE;
- m_nHeight = 0;
- m_nMarginWidth = ms_nLastMarginWidth;
-}
+ m_bCheckable = bCheckable;
+ m_bOwnerDrawn = FALSE;
+ m_nHeight = 0;
+ m_nMarginWidth = ms_nLastMarginWidth;
+ if (wxNORMAL_FONT)
+ m_font = *wxNORMAL_FONT;
+} // end of wxOwnerDrawn::wxOwnerDrawn
- size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 15;
+size_t wxOwnerDrawn::ms_nDefaultMarginWidth = 15;
size_t wxOwnerDrawn::ms_nLastMarginWidth = ms_nDefaultMarginWidth;
-// drawing
+//
+// Drawing
// -------
+//
-// get size of the item
-bool wxOwnerDrawn::OnMeasureItem(size_t *pwidth, size_t *pheight)
+bool wxOwnerDrawn::OnMeasureItem(
+ size_t* pWidth
+, size_t* pHeight
+)
{
- wxMemoryDC dc;
- dc.SetFont(GetFont());
-
- // ## ugly...
- wxChar *szStripped = new wxChar[m_strName.Len()];
- wxStripMenuCodes((wxChar *)m_strName.c_str(), szStripped);
- wxString str = szStripped;
- delete [] szStripped;
-
- // # without this menu items look too tightly packed (at least under Windows)
- str += wxT('W'); // 'W' is typically the widest letter
-
- dc.GetTextExtent(str, (long *)pwidth, (long *)pheight);
-
- // JACS: items still look too tightly packed, so adding 2 pixels.
- (*pheight) = (*pheight) + 2;
-
- m_nHeight = *pheight; // remember height for use in OnDrawItem
-
- return TRUE;
-}
+ wxMemoryDC vDC;
+
+ vDC.SetFont(GetFont());
+
+ wxString sStr = wxStripMenuCodes(m_strName);
+
+ //
+ // # without this menu items look too tightly packed (at least under Windows)
+ //
+ sStr += wxT('W'); // 'W' is typically the widest letter
+ vDC.GetTextExtent( sStr
+ ,(long *)pWidth
+ ,(long *)pHeight
+ );
+
+ //
+ // JACS: items still look too tightly packed, so adding 2 pixels.
+ //
+ (*pHeight) = (*pHeight) + 2;
+ m_nHeight = *pHeight; // remember height for use in OnDrawItem
+ return TRUE;
+} // end of wxOwnerDrawn::OnMeasureItem
// searching for this macro you'll find all the code where I'm using the native
// Win32 GDI functions and not wxWindows ones. Might help to whoever decides to
// embossing?
// draw the item
-bool wxOwnerDrawn::OnDrawItem(wxDC& dc, const wxRect& rc, wxODAction act, wxODStatus st)
+bool wxOwnerDrawn::OnDrawItem(
+ wxDC& rDC
+, const wxRect& rRect
+, wxODAction eAction
+, wxODStatus eStatus
+)
{
-///////////////////////////////////////////////////////////////////////////////////////////////////
-// Might want to check the native drawing apis for here and doo something like MSW does for WIN95
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
- // we do nothing on focus change
- if ( act == wxODFocusChanged )
- return TRUE;
+ //
+ // For now we let PM deal with highlighting and framing and such in a
+ // default manner. So we leave fsAttribute and fsOldAttribute ( or
+ // fsState and fsOldState ) the same and pass it on. We may want to add
+ // code later to draw theseattributes in a more custom manner.
+ //
+
+ //
+ // WxWinGdi_CColour <-> RGB
+ //
+ #define ToRGB(col) OS2RGB(col.Red(), col.Green(), col.Blue())
+ #define UnRGB(col) GetRValue(col), GetGValue(col), GetBValue(col)
+
+ CHARBUNDLE vCbndText;
+ CHARBUNDLE vCbndBack;
+ HPS hPS= rDC.GetHPS();
+ ULONG lColBack;
+ ULONG lColText;
+
+ if (eStatus & wxODSelected)
+ {
+ lColBack = (DWORD)::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_MENUHILITEBGND // Light gray
+ ,0L
+ );
+ lColText = (DWORD)::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_MENUTEXT // Black
+ ,0L
+ );
+ }
+ else if (eStatus & wxODDisabled)
+ {
+ lColBack = (DWORD)::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_MENU // Light gray
+ ,0L
+ );
+ lColText = (DWORD)::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_MENUDISABLEDTEXT // dark gray
+ ,0L
+ );
+ }
+ else
+ {
+ //
+ // Fall back to default colors if none explicitly specified
+ //
+ lColBack = m_colBack.Ok() ? ToRGB(m_colBack) : ::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_MENU // we are using gray for all our window backgrounds in wxWindows
+ ,0L
+ );
+ lColText = m_colText.Ok() ? ToRGB(m_colText) : ::WinQuerySysColor( HWND_DESKTOP
+ ,SYSCLR_WINDOWTEXT // Black
+ ,0L
+ );
+ }
+ vCbndText.lColor = (LONG)lColText;
+ vCbndBack.lColor = (LONG)lColBack;
+
+ ::GpiSetAttrs( hPS
+ ,PRIM_CHAR
+ ,CBB_BACK_COLOR
+ ,0
+ ,&vCbndBack
+ );
+ ::GpiSetAttrs( hPS
+ ,PRIM_CHAR
+ ,CBB_COLOR
+ ,0
+ ,&vCbndText
+ );
+
+
+ //
+ // Determine where to draw and leave space for a check-mark.
+ //
+ int nX = rRect.x + GetMarginWidth();
+
+ //
+ // Select the font and draw the text
+ // ---------------------------------
+ //
+
+ //
+ // Use default font if no font set
+ //
+ if (m_font.Ok())
+ {
+ m_font.RealizeResource();
+ }
+ else
+ {
+ ::GpiSetCharSet(hPS, LCID_DEFAULT);
+ }
- // wxColor <-> RGB
- #define ToRGB(col) RGB(col.Red(), col.Green(), col.Blue())
- #define UnRGB(col) GetRValue(col), GetGValue(col), GetBValue(col)
-
- // set the colors
- // --------------
- DWORD colBack, colText;
-// TODO:
-/*
- if ( st & wxODSelected ) {
- colBack = GetSysColor(COLOR_HIGHLIGHT);
- colText = GetSysColor(COLOR_HIGHLIGHTTEXT);
- }
- else {
- // fall back to default colors if none explicitly specified
- colBack = m_colBack.Ok() ? ToRGB(m_colBack) : GetSysColor(COLOR_WINDOW);
- colText = m_colText.Ok() ? ToRGB(m_colText) : GetSysColor(COLOR_WINDOWTEXT);
- }
-*/
-// dc.SetTextForeground(wxColor(UnRGB(colText)));
-// dc.SetTextBackground(wxColor(UnRGB(colBack)));
-
- // select the font and draw the text
- // ---------------------------------
-
- // determine where to draw and leave space for a check-mark.
- int x = rc.x + GetMarginWidth();
-
- dc.SetFont(GetFont());
- dc.DrawText(m_strName, x, rc.y);
-
- // draw the bitmap
- // ---------------
- if ( IsCheckable() && !m_bmpChecked.Ok() ) {
- if ( st & wxODChecked ) {
- // using native APIs for performance and simplicity
-// TODO:
-/*
- HDC hdcMem = CreateCompatibleDC(hdc);
- HBITMAP hbmpCheck = CreateBitmap(GetMarginWidth(), m_nHeight, 1, 1, 0);
- SelectObject(hdcMem, hbmpCheck);
- // then draw a check mark into it
- RECT rect = { 0, 0, GetMarginWidth(), m_nHeight };
-
- // finally copy it to screen DC and clean up
- BitBlt(hdc, rc.x, rc.y, GetMarginWidth(), m_nHeight,
- hdcMem, 0, 0, SRCCOPY);
- DeleteDC(hdcMem);
-*/
+ //
+ // Unfortunately, unlike Win32, PM has no owner drawn specific text
+ // drawing methods like ::DrawState that can cleanly handle accel
+ // pneumonics and deal, automatically, with various states, so we have
+ // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
+ // strings either.
+
+ rDC.DrawText( m_strName
+ ,nX
+ ,rRect.y
+ );
+
+ //
+ // Draw the bitmap
+ // ---------------
+ //
+ if (IsCheckable() && !m_bmpChecked.Ok())
+ {
+ if (eStatus & wxODChecked)
+ {
+ RECTL vRect;
+ HBITMAP hBmpCheck = ::WinGetSysBitmap(HWND_DESKTOP, SBMP_MENUCHECK);
+
+ vRect.xLeft = rRect.x;
+ vRect.xRight = rRect.x + GetMarginWidth();
+ vRect.yBottom = rRect.y;
+ vRect.yTop = rRect.y + m_nHeight;
+
+ ::WinDrawBitmap( hPS // PS for this menuitem
+ ,hBmpCheck // system checkmark
+ ,NULL // draw the whole bitmap
+ ,(PPOINTL)&vRect // destination -- bottom left corner of the menuitem area
+ ,0L // ignored
+ ,0L // draw a bitmap
+ ,DBM_NORMAL // draw normal size
+ );
+ }
}
- }
- else {
- // for uncheckable item we use only the 'checked' bitmap
- wxBitmap bmp(GetBitmap(IsCheckable() ? ((st & wxODChecked) != 0) : TRUE));
- if ( bmp.Ok() ) {
- wxMemoryDC dcMem(&dc);
- dcMem.SelectObject(bmp);
-
- // center bitmap
- int nBmpWidth = bmp.GetWidth(),
- nBmpHeight = bmp.GetHeight();
-
- // there should be enough place!
- wxASSERT((nBmpWidth <= rc.GetWidth()) && (nBmpHeight <= rc.GetHeight()));
-
- //MT: blit with mask enabled.
-// TODO:
-/*
- dc.Blit(rc.x + (GetMarginWidth() - nBmpWidth) / 2,
- rc.y + (m_nHeight - nBmpHeight) /2,
- nBmpWidth, nBmpHeight,
- &dcMem, 0, 0, wxCOPY,true);
-
- if ( st & wxODSelected ) {
- #ifdef O_DRAW_NATIVE_API
- RECT rectBmp = { rc.GetLeft(), rc.GetTop(),
- rc.GetLeft() + GetMarginWidth(),
- rc.GetTop() + m_nHeight };
- SetBkColor(hdc, colBack);
- DrawEdge(hdc, &rectBmp, EDGE_RAISED, BF_SOFT | BF_RECT);
- }
-*/
+ else
+ {
+ //
+ // For uncheckable item we use only the 'checked' bitmap
+ //
+ wxBitmap vBmp(GetBitmap(IsCheckable() ? ((eStatus & wxODChecked) != 0) : TRUE));
+
+ if (vBmp.Ok())
+ {
+ wxMemoryDC vDCMem(&rDC);
+
+ vDCMem.SelectObject(vBmp);
+
+ //
+ // Center bitmap
+ //
+ int nBmpWidth = vBmp.GetWidth();
+ int nBmpHeight = vBmp.GetHeight();
+
+ //
+ // There should be enough space!
+ //
+ wxASSERT((nBmpWidth <= rRect.width) && (nBmpHeight <= rRect.height));
+
+ //
+ //MT: blit with mask enabled.
+ //
+ rDC.Blit( rRect.x + (GetMarginWidth() - nBmpWidth) / 2
+ ,rRect.y + (m_nHeight - nBmpHeight) /2
+ ,nBmpWidth
+ ,nBmpHeight
+ ,&vDCMem
+ ,0
+ ,0
+ ,wxCOPY
+ ,TRUE
+ );
+
+ if (eStatus & wxODSelected)
+ {
+ RECT vRectBmp = { rRect.x
+ ,rRect.y
+ ,rRect.x + GetMarginWidth()
+ ,rRect.y + m_nHeight
+ };
+ LINEBUNDLE vLine;
+
+ vLine.lColor = lColBack;
+ ::GpiSetAttrs( hPS
+ ,PRIM_LINE
+ ,LBB_COLOR
+ ,0
+ ,&vLine
+ );
+ ::GpiBox( hPS
+ ,DRO_OUTLINE
+ ,(PPOINTL)&vRectBmp
+ ,0L
+ ,0L
+ );
+ }
+ }
}
- }
-/*
- #ifdef O_DRAW_NATIVE_API
- ::SetTextColor(hdc, colOldText);
- ::SetBkColor(hdc, colOldBack);
-
- #undef hdc
- #endif //O_DRAW_NATIVE_API
-*/
+
return TRUE;
}
, WXDRAWITEMSTRUCT* pItemStruct
)
{
- //
- // I'll get to owner drawn stuff later
- //
+ wxDC vDc;
//
- // is it a menu item or control?
+ // Is it a menu item?
//
- wxWindow* pItem = FindItem(vId);
+ if (vId == 0)
+ {
#if wxUSE_OWNER_DRAWN
- if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
- {
- return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
- }
- else if (pItem && pItem->IsKindOf(CLASSINFO(wxMenu)))
- {
- /*
- // TODO: draw a menu item
+ POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
+ wxMenuItem vMenuItem;
+ HDC hDC = ::GpiQueryDevice(pMeasureStruct->hps);
+
+ vDc.SetHDC( hDC
+ ,FALSE
+ );
+ vDc.SetHPS(pMeasureStruct->hps);
+
+ //
+ // We stored the CMenuItem itself into the menuitem text field so now
+ // we need to extract it.
//
- POWNERITEM pDrawStruct = (OWNERITEM *)pItemStruct;
- wxMenuItem* pMenuItem = (wxMenuItem *)(pDrawStruct->pItemData);
+ ::WinSendMsg( pMeasureStruct->hItem
+ ,MM_QUERYITEMTEXT
+ ,MPFROM2SHORT( (USHORT)pMeasureStruct->idItem
+ ,(SHORT)(sizeof(wxMenuItem))
+ )
+ ,(PSZ)&vMenuItem
+ );
+
+ wxRect vRect( pMeasureStruct->rclItem.xLeft
+ ,pMeasureStruct->rclItem.yTop
+ ,pMeasureStruct->rclItem.xRight
+ ,pMeasureStruct->rclItem.yBottom
+ );
- wxCHECK(pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE);
+ wxOwnerDrawn::wxODAction eAction;
//
- // Prepare to call OnDrawItem()
+ // Attribute applies to menuitems, fsState to listbox and other controls
+ //
+ if (pMeasureStruct->fsAttribute == pMeasureStruct->fsAttributeOld)
+ eAction = wxOwnerDrawn::wxODDrawAll;
+ else
+ eAction = wxOwnerDrawn::wxODSelectChanged;
+
+ return(vMenuItem.OnDrawItem( vDc
+ ,vRect
+ ,eAction
+ ,(wxOwnerDrawn::wxODStatus)pMeasureStruct->fsAttribute
+ ));
+ //
+ // leave the fsAttribute and fsOldAttribute unchanged. If different,
+ // the system will do the highlight or fraeming or disabling for us,
+ // otherwise, we'd have to do it ourselves.
//
- HPSdc;
- dc.SetHDC((WXHDC)pDrawStruct->hDC, FALSE);
- wxRect rect(pDrawStruct->rcItem.left, pDrawStruct->rcItem.top,
- pDrawStruct->rcItem.right - pDrawStruct->rcItem.left,
- pDrawStruct->rcItem.bottom - pDrawStruct->rcItem.top);
-
- return pMenuItem->OnDrawItem
- (
- dc, rect,
- (wxOwnerDrawn::wxODAction)pDrawStruct->itemAction,
- (wxOwnerDrawn::wxODStatus)pDrawStruct->itemState
- );
- */
}
- else
- return FALSE;
+ wxWindow* pItem = FindItem(vId);
+
+ if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
+ {
+ return ((wxControl *)pItem)->OS2OnDraw(pItemStruct);
+ }
#endif
- return TRUE;
+ return FALSE;
} // end of wxWindow::OS2OnDrawItem
-bool wxWindow::OS2OnMeasureItem(int id, WXMEASUREITEMSTRUCT *itemStruct)
+bool wxWindow::OS2OnMeasureItem(
+ int lId
+, WXMEASUREITEMSTRUCT* pItemStruct
+)
{
- // TODO: more owner drawn menu related stuff, get to it later
-/*
-#if wxUSE_OWNER_DRAWN
- // is it a menu item?
- if ( id == 0 )
+ //
+ // Is it a menu item?
+ //
+ if (lId == 0)
{
- MEASUREITEMSTRUCT *pMeasureStruct = (MEASUREITEMSTRUCT *)itemStruct;
- wxMenuItem *pMenuItem = (wxMenuItem *)(pMeasureStruct->itemData);
+ POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
+ wxMenuItem vMenuItem;
+
+ //
+ // We stored the CMenuItem itself into the menuitem text field so now
+ // we need to extract it.
+ //
+ ::WinSendMsg( pMeasureStruct->hItem
+ ,MM_QUERYITEMTEXT
+ ,MPFROM2SHORT( (USHORT)pMeasureStruct->idItem
+ ,(SHORT)(sizeof(wxMenuItem))
+ )
+ ,(PSZ)&vMenuItem
+ );
+ wxCHECK(vMenuItem.IsKindOf(CLASSINFO(wxMenuItem)), FALSE);
- wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
+ size_t lWidth = (size_t)(pMeasureStruct->rclItem.xRight - pMeasureStruct->rclItem.xLeft);
+ size_t lHeight = (size_t)(pMeasureStruct->rclItem.yTop - pMeasureStruct->rclItem.yBottom);
- return pMenuItem->OnMeasureItem(&pMeasureStruct->itemWidth,
- &pMeasureStruct->itemHeight);
+ return(vMenuItem.OnMeasureItem( &lWidth
+ ,&lHeight
+ ));
}
+ wxWindow* pItem = FindItem(id);
- wxWindow *item = FindItem(id);
- if ( item && item->IsKindOf(CLASSINFO(wxControl)) )
+ if (pItem && pItem->IsKindOf(CLASSINFO(wxControl)))
{
- return ((wxControl *)item)->MSWOnMeasure(itemStruct);
+ return ((wxControl *)pItem)->OS2OnMeasure(pItemStruct);
}
-#endif // owner-drawn menus
-*/
return FALSE;
}