Ownerdrawn stuff. Text display done, image display next.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9572 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Webster 2001-03-22 23:23:19 +00:00
parent 9c0b55475a
commit 5afb945835
6 changed files with 392 additions and 69 deletions

View File

@ -16,16 +16,18 @@
class WXDLLEXPORT wxMemoryDC: public wxDC
{
DECLARE_DYNAMIC_CLASS(wxMemoryDC)
DECLARE_DYNAMIC_CLASS(wxMemoryDC)
public:
public:
wxMemoryDC(void);
wxMemoryDC( wxDC *dc ); // Create compatible DC
wxMemoryDC(wxDC* pDC); // Create compatible DC
~wxMemoryDC(void);
virtual void SelectObject( const wxBitmap& bitmap );
virtual void DoGetSize( int *width, int *height ) const;
};
virtual void SelectObject(const wxBitmap& rBitmap);
virtual void DoGetSize( int* pWidth
,int* pHeight
) const;
}; // end of CLASS wxMemoryDC
#endif
// _WX_DCMEMORY_H_

View File

@ -1326,19 +1326,178 @@ wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
// bit blit
// ---------------------------------------------------------------------------
bool wxDC::DoBlit( wxCoord xdest
,wxCoord ydest
,wxCoord width
,wxCoord height
,wxDC *source
,wxCoord xsrc
,wxCoord ysrc
,int rop
,bool useMask
)
bool wxDC::DoBlit(
wxCoord vXdest
, wxCoord vYdest
, wxCoord vWidth
, wxCoord vHeight
, wxDC* pSource
, wxCoord vXsrc
, wxCoord vYsrc
, int nRop
, bool bUseMask
)
{
// TODO
return(TRUE);
wxMask* pMask = NULL;
CHARBUNDLE vCbnd;
COLORREF vOldTextColor;
COLORREF vOldBackground = ::GpiQueryBackColor(m_hPS);
POINTL aPoint[4] = { vXdest, vYdest
,vXdest + vWidth, vYdest + vHeight
,vXsrc, vYsrc
,vXsrc + vWidth, vYsrc + vHeight
};
if (bUseMask)
{
const wxBitmap& rBmp = pSource->m_vSelectedBitmap;
pMask = rBmp.GetMask();
if (!(rBmp.Ok() && pMask && pMask->GetMaskBitmap()))
{
bUseMask = FALSE;
}
}
::GpiQueryAttrs( m_hPS
,PRIM_CHAR
,CBB_COLOR
,&vCbnd
);
vOldTextColor = (COLORREF)vCbnd.lColor;
if (m_textForegroundColour.Ok())
{
vCbnd.lColor = (LONG)m_textForegroundColour.GetPixel();
::GpiSetAttrs( m_hPS // presentation-space handle
,PRIM_CHAR // Char primitive.
,CBB_COLOR // sets color.
,0
,&vCbnd // buffer for attributes.
);
}
if (m_textBackgroundColour.Ok())
{
::GpiSetBackColor(m_hPS, (LONG)m_textBackgroundColour.GetPixel());
}
LONG lRop = ROP_SRCCOPY;
switch (nRop)
{
case wxXOR: lRop = ROP_SRCINVERT; break;
case wxINVERT: lRop = ROP_DSTINVERT; break;
case wxOR_REVERSE: lRop = 0x00DD0228; break;
case wxAND_REVERSE: lRop = ROP_SRCERASE; break;
case wxCLEAR: lRop = ROP_ZERO; break;
case wxSET: lRop = ROP_ONE; break;
case wxOR_INVERT: lRop = ROP_MERGEPAINT; break;
case wxAND: lRop = ROP_SRCAND; break;
case wxOR: lRop = ROP_SRCPAINT; break;
case wxEQUIV: lRop = 0x00990066; break;
case wxNAND: lRop = 0x007700E6; break;
case wxAND_INVERT: lRop = 0x00220326; break;
case wxCOPY: lRop = ROP_SRCCOPY; break;
case wxNO_OP: lRop = ROP_NOTSRCERASE; break;
case wxSRC_INVERT: lRop = ROP_SRCINVERT; break;
case wxNOR: lRop = ROP_NOTSRCCOPY; break;
default:
wxFAIL_MSG( wxT("unsupported logical function") );
return FALSE;
}
bool bSuccess;
#if 0
if (bUseMask)
{
//
// Blit bitmap with mask
//
//
// Create a temp buffer bitmap and DCs to access it and the mask
//
HDC dc_mask = ::CreateCompatibleDC(GetHdcOf(*source));
HDC dc_buffer = ::CreateCompatibleDC(GetHdc());
HBITMAP buffer_bmap = ::CreateCompatibleBitmap(GetHdc(), width, height);
::SelectObject(dc_mask, (HBITMAP) mask->GetMaskBitmap());
::SelectObject(dc_buffer, buffer_bmap);
// copy dest to buffer
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
GetHdc(), xdest, ydest, SRCCOPY) )
{
wxLogLastError(wxT("BitBlt"));
}
// copy src to buffer using selected raster op
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
GetHdcOf(*source), xsrc, ysrc, dwRop) )
{
wxLogLastError(wxT("BitBlt"));
}
// set masked area in buffer to BLACK (pixel value 0)
COLORREF prevBkCol = ::SetBkColor(GetHdc(), RGB(255, 255, 255));
COLORREF prevCol = ::SetTextColor(GetHdc(), RGB(0, 0, 0));
if ( !::BitBlt(dc_buffer, 0, 0, (int)width, (int)height,
dc_mask, xsrc, ysrc, SRCAND) )
{
wxLogLastError(wxT("BitBlt"));
}
// set unmasked area in dest to BLACK
::SetBkColor(GetHdc(), RGB(0, 0, 0));
::SetTextColor(GetHdc(), RGB(255, 255, 255));
if ( !::BitBlt(GetHdc(), xdest, ydest, (int)width, (int)height,
dc_mask, xsrc, ysrc, SRCAND) )
{
wxLogLastError(wxT("BitBlt"));
}
::SetBkColor(GetHdc(), prevBkCol); // restore colours to original values
::SetTextColor(GetHdc(), prevCol);
// OR buffer to dest
success = ::BitBlt(GetHdc(), xdest, ydest,
(int)width, (int)height,
dc_buffer, 0, 0, SRCPAINT) != 0;
if ( !success )
{
wxLogLastError(wxT("BitBlt"));
}
// tidy up temporary DCs and bitmap
::SelectObject(dc_mask, 0);
::DeleteDC(dc_mask);
::SelectObject(dc_buffer, 0);
::DeleteDC(dc_buffer);
::DeleteObject(buffer_bmap);
}
}
#endif
// else // no mask, just BitBlt() it
// {
bSuccess = (::GpiBitBlt( m_hPS
,pSource->GetHPS()
,4L
,aPoint
,lRop
,BBO_IGNORE
) != GPI_ERROR);
if (!bSuccess )
{
wxLogLastError(wxT("BitBlt"));
}
// }
vCbnd.lColor = (LONG)vOldTextColor;
::GpiSetAttrs( m_hPS // presentation-space handle
,PRIM_CHAR // Char primitive.
,CBB_COLOR // sets color.
,0
,&vCbnd // buffer for attributes.
);
::GpiSetBackColor(m_hPS, (LONG)vOldBackground);
return bSuccess;
}
void wxDC::DoGetSize( int* width, int* height ) const

View File

@ -123,7 +123,17 @@ wxWindowDC::wxWindowDC(
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
::GpiCreateLogColorTable( m_hPS
,0L
,LCOLF_RGB
,0L
,0L
,NULL
);
SetBackground(wxBrush(m_pCanvas->GetBackgroundColour(), wxSOLID));
::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
,&m_vRclPaint
);
}
wxWindowDC::~wxWindowDC()
@ -190,6 +200,13 @@ wxClientDC::wxClientDC(
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
::GpiCreateLogColorTable( m_hPS
,0L
,LCOLF_RGB
,0L
,0L
,NULL
);
//
// Default mode is BM_LEAVEALONE so we make no call Set the mix
//
@ -197,6 +214,12 @@ wxClientDC::wxClientDC(
,wxSOLID
)
);
//
// Set the DC/PS rectangle
//
::WinQueryWindowRect( GetWinHwnd(m_pCanvas)
,&m_vRclPaint
);
} // end of wxClientDC::wxClientDC
wxClientDC::~wxClientDC()

View File

@ -28,6 +28,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
wxMemoryDC::wxMemoryDC(void)
{
ERRORID vError;
wxString sError;
HDC hDC;
HPS hPS;
DEVOPENSTRUC vDOP = {0L, "DISPLAY", NULL, 0L, 0L, 0L, 0L, 0L, 0L};
@ -48,6 +50,33 @@ wxMemoryDC::wxMemoryDC(void)
m_bOwnsDC = TRUE;
SetBrush(*wxWHITE_BRUSH);
SetPen(*wxBLACK_PEN);
if (!::GpiCreateLogColorTable( m_hPS
,0L
,LCOLF_CONSECRGB
,0L
,(LONG)wxTheColourDatabase->m_nSize
,(PLONG)wxTheColourDatabase->m_palTable
))
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
//
// Set the color table to RGB mode
//
if (!::GpiCreateLogColorTable( m_hPS
,0L
,LCOLF_RGB
,0L
,0L
,NULL
))
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
}
else
{
@ -155,7 +184,7 @@ void wxMemoryDC::SelectObject(
m_vSelectedBitmap.SetSelectedInto(this);
hBmp = (WXHBITMAP)::GpiSetBitmap(m_hPS, (HBITMAP)hBmp);
if (hBmp != HBM_ERROR)
if (hBmp == HBM_ERROR)
{
wxLogLastError(wxT("SelectObject(memDC, bitmap)"));
wxFAIL_MSG(wxT("Couldn't select a bitmap into wxMemoryDC"));

View File

@ -75,6 +75,7 @@ bool wxOwnerDrawn::OnMeasureItem(
wxString sStr = wxStripMenuCodes(m_strName);
#if 0
wxString sTgt = "\t";
size_t nIndex;
@ -85,7 +86,7 @@ bool wxOwnerDrawn::OnMeasureItem(
nIndex = sStr.Find(sTgt.c_str());
if (nIndex != -1)
sStr.Replace(sTgt.c_str(), "", TRUE);
#endif
vDC.GetTextExtent( sStr
,(long *)pWidth
,(long *)pHeight
@ -120,6 +121,7 @@ bool wxOwnerDrawn::OnDrawItem(
wxColour vColBack;
wxColour vColText;
COLORREF vRef;
RECTL vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height};
char zMsg[128];
//
@ -133,17 +135,18 @@ bool wxOwnerDrawn::OnDrawItem(
{
::GpiSetCharSet(hPS, LCID_DEFAULT);
}
//
// Base on the status of the menu item pick the right colors
//
if (eStatus & wxODSelected)
{
vRef = (ULONG)::WinQuerySysColor( HWND_DESKTOP
,SYSCLR_MENUHILITEBGND // Light gray
,0L
);
vColBack.Set( GetRValue(vRef)
,GetGValue(vRef)
,GetBValue(vRef)
);
vColText = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_MENUTEXT);
wxColour vCol2("WHITE");
vColBack.Set( (unsigned char)0
,(unsigned char)0
,(unsigned char)160
); // no dark blue in color table
vColText = vCol2;
}
else if (eStatus & wxODDisabled)
{
@ -186,24 +189,14 @@ bool wxOwnerDrawn::OnDrawItem(
,GetBValue(vRef)
);
}
vRef = vColBack.GetPixel();
vCbnd.lBackColor = (LONG)vRef;
rDC.SetTextBackground(vColBack);
rDC.SetTextForeground(vColText);
rDC.SetBackgroundMode(wxTRANSPARENT);
vRef = vColText.GetPixel();
vCbnd.lColor = (LONG)vRef;
sprintf(zMsg, "Color: %ld", vRef);
wxMessageBox( "wxWindows Menu Sample"
,zMsg
,wxICON_INFORMATION
);
::GpiSetAttrs( hPS
,PRIM_CHAR
,CBB_COLOR | CBB_BACK_COLOR
,0
,&vCbnd
);
//
// Paint the background
//
::WinFillRect(hPS, &vRect, vColBack.GetPixel());
//
// Determine where to draw and leave space for a check-mark.
@ -215,34 +208,99 @@ bool wxOwnerDrawn::OnDrawItem(
// 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.
// strings either. We cannot handle mneumonics either. We display
// it, though, in hopes we can figure it out some day.
//
//
// Manually replace the tab with spaces
// Display main text and accel text separately to allign better
//
wxString sTgt = "\t";
wxString sReplace = " ";
wxString sFullString = m_strName; // need to save the original text
wxString sAccel;
size_t nIndex;
size_t nWidth;
size_t nCharWidth;
size_t nHeight;
bool bFoundMneumonic = FALSE;
bool bFoundAccel = FALSE;
nIndex = m_strName.Find(sTgt.c_str());
//
// Deal with the tab, extracting the Accel text
//
nIndex = sFullString.Find(sTgt.c_str());
if (nIndex != -1)
m_strName.Replace(sTgt.c_str(), sReplace.c_str(), TRUE);
{
bFoundAccel = TRUE;
sAccel = sFullString.Mid(nIndex + 1);
sFullString.Remove(nIndex);
}
//
// Deal with the mneumonic character
//
sTgt = "~";
nIndex = m_strName.Find(sTgt.c_str());
nIndex = sFullString.Find(sTgt.c_str());
if (nIndex != -1)
m_strName.Replace(sTgt.c_str(), "", TRUE);
{
wxString sTmp = sFullString;
POINTL vPoint;
bFoundMneumonic = TRUE;
sTmp.Remove(nIndex);
rDC.GetTextExtent( sTmp
,(long *)&nWidth
,(long *)&nHeight
);
sTmp = sFullString[nIndex + 1];
rDC.GetTextExtent( sTmp
,(long *)&nCharWidth
,(long *)&nHeight
);
sFullString.Replace(sTgt.c_str(), "", TRUE);
}
vPoint.x = nX;
vPoint.y = rRect.y + 4;
::GpiCharStringAt( hPS
,&vPoint
,m_strName.length()
,(PCH)m_strName.c_str()
);
//
// Draw the main item text sans the accel text
rDC.DrawText( sFullString
,nX
,rRect.y + 4
);
if (bFoundMneumonic)
{
//
// Underline the mneumonic -- still won't work, but at least it "looks" right
//
wxPen vPen;
POINTL vPntStart = {nX + nWidth - 1, rRect.y + 2}; // Make it look pretty!
POINTL vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide
vPen = wxPen(vColText, 1, wxSOLID); // Assuming we are always black
rDC.SetPen(vPen);
::GpiMove(hPS, &vPntStart);
::GpiLine(hPS, &vPntEnd);
}
//
// Now draw the accel text
//
if (bFoundAccel)
{
size_t nWidth;
size_t nHeight;
rDC.GetTextExtent( sAccel
,(long *)&nWidth
,(long *)&nHeight
);
//
// Back off the starting position from the right edge
//
rDC.DrawText( sAccel
,rRect.width - (nWidth + 7) // this seems to mimic the default OS/2 positioning
,rRect.y + 4
);
}
#if 0
//
// Draw the bitmap
// ---------------
@ -316,7 +374,7 @@ bool wxOwnerDrawn::OnDrawItem(
};
LINEBUNDLE vLine;
vLine.lColor = lColBack;
vLine.lColor = vColBack.GetPixel();
::GpiSetAttrs( hPS
,PRIM_LINE
,LBB_COLOR
@ -332,7 +390,6 @@ bool wxOwnerDrawn::OnDrawItem(
}
}
}
#endif
return TRUE;
} // end of wxOwnerDrawn::OnDrawItem

View File

@ -2663,6 +2663,8 @@ bool wxWindow::OS2OnDrawItem(
//
if (vId == 0)
{
ERRORID vError;
wxString sError;
POWNERITEM pMeasureStruct = (POWNERITEM)pItemStruct;
wxFrame* pFrame = (wxFrame*)this;
wxMenuItem* pMenuItem = pFrame->GetMenuBar()->FindItem(pMeasureStruct->idItem, pMeasureStruct->hItem);
@ -2676,6 +2678,36 @@ bool wxWindow::OS2OnDrawItem(
,FALSE
);
vDc.SetHPS(pMeasureStruct->hps);
//
// Load the wxWindows Pallete and set to RGB mode
//
if (!::GpiCreateLogColorTable( pMeasureStruct->hps
,0L
,LCOLF_CONSECRGB
,0L
,(LONG)wxTheColourDatabase->m_nSize
,(PLONG)wxTheColourDatabase->m_palTable
))
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
//
// Set the color table to RGB mode
//
if (!::GpiCreateLogColorTable( pMeasureStruct->hps
,0L
,LCOLF_RGB
,0L
,0L
,NULL
))
{
vError = ::WinGetLastError(vHabmain);
sError = wxPMErrorToStr(vError);
wxLogError("Unable to set current color table. Error: %s\n", sError);
}
wxCHECK( pMenuItem->IsKindOf(CLASSINFO(wxMenuItem)), FALSE );
@ -2719,11 +2751,32 @@ bool wxWindow::OS2OnDrawItem(
}
else
{
//
// For now we don't care about doing our own highlighting so we'll
// just ignore the entie message!
//
return TRUE;
if (pMeasureStruct->fsAttribute & MIA_HILITED)
{
eAction = wxOwnerDrawn::wxODDrawAll;
eStatus |= wxOwnerDrawn::wxODSelected;
//
// Keep the system from trying to highlight with its bogus colors
//
pMeasureStruct->fsAttributeOld = pMeasureStruct->fsAttribute &= ~MIA_HILITED;
}
else if (!(pMeasureStruct->fsAttribute & MIA_HILITED))
{
eAction = wxOwnerDrawn::wxODDrawAll;
eStatus = 0;
//
// Keep the system from trying to highlight with its bogus colors
//
pMeasureStruct->fsAttribute = pMeasureStruct->fsAttributeOld &= ~MIA_HILITED;
}
else
{
//
// For now we don't care about anything else
// just ignore the entire message!
//
return TRUE;
}
}
//
// Now redraw the item