コード例 #1
0
ファイル: ownerdrw.cpp プロジェクト: gitrider/wxsj2
// draw the item
bool wxOwnerDrawn::OnDrawItem(
  wxDC&                             rDC
, const wxRect&                     rRect
, wxODAction                        eAction
, wxODStatus                        eStatus
)
{
    //
    // We do nothing on focus change
    //
    if (eAction == wxODFocusChanged )
        return TRUE;

    //
    // Select the font and draw the text
    // ---------------------------------
    //

    CHARBUNDLE                      vCbnd;
    HPS                             hPS= rDC.GetHPS();
    wxColour                        vColBack;
    wxColour                        vColText;
    COLORREF                        vRef;
    RECTL                           vRect = {rRect.x + 4, rRect.y + 1, rRect.x + (rRect.width - 2), rRect.y + rRect.height};

    memset(&vCbnd, 0, sizeof(CHARBUNDLE));

    //
    // Use default font if no font set
    //
    if (m_font.Ok())
    {
        m_font.RealizeResource();
    }
    else
    {
        ::GpiSetCharSet(hPS, LCID_DEFAULT);
    }

    //
    // Based on the status of the menu item, pick the right colors
    //
    if (eStatus & wxODSelected)
    {
        wxColour                        vCol2(wxT("WHITE"));
        vColBack.Set( (unsigned char)0
                     ,(unsigned char)0
                     ,(unsigned char)160
                    ); // no dark blue in color table
        vColText = vCol2;
    }
    else if (eStatus & wxODDisabled)
    {
        vRef = (ULONG)::WinQuerySysColor( HWND_DESKTOP
                                         ,SYSCLR_MENU // Light gray
                                         ,0L
                                        );
        vColBack.Set( GetRValue(vRef)
                     ,GetGValue(vRef)
                     ,GetBValue(vRef)
                    );
        vRef = (ULONG)::WinQuerySysColor( HWND_DESKTOP
                                         ,SYSCLR_MENUDISABLEDTEXT // dark gray
                                         ,0L
                                        );
        vColText.Set( GetRValue(vRef)
                     ,GetGValue(vRef)
                     ,GetBValue(vRef)
                    );
    }
    else
    {
        //
        // Fall back to default colors if none explicitly specified
        //
        vRef = ::WinQuerySysColor( HWND_DESKTOP
                                  ,SYSCLR_MENU  // we are using gray for all our window backgrounds in wxWidgets
                                  ,0L
                                 );
        vColBack.Set( GetRValue(vRef)
                     ,GetGValue(vRef)
                     ,GetBValue(vRef)
                    );
        vRef = ::WinQuerySysColor( HWND_DESKTOP
                                  ,SYSCLR_WINDOWTEXT // Black
                                  ,0L
                                 );
        vColText.Set( GetRValue(vRef)
                     ,GetGValue(vRef)
                     ,GetBValue(vRef)
                    );
    }

    rDC.SetTextBackground(vColBack);
    rDC.SetTextForeground(vColText);
    rDC.SetBackgroundMode(wxTRANSPARENT);
    vCbnd.lColor     = vColText.GetPixel();
    vCbnd.lBackColor = vColBack.GetPixel();
    ::GpiSetAttrs( hPS
                  ,PRIM_CHAR
                  ,CBB_BACK_COLOR | CBB_COLOR
                  ,0
                  ,&vCbnd
                 );
    ::GpiSetBackMix( hPS
                    ,BM_LEAVEALONE
                   );

    //
    // Paint the background
    //
    ::WinFillRect(hPS, &vRect, vColBack.GetPixel());

    //
    // Determine where to draw and leave space for a check-mark.
    //
    int                             nX = rRect.x + GetMarginWidth();

    //
    // Unfortunately, unlike Win32, PM has no owner drawn specific text
    // drawing methods like ::DrawState that can cleanly handle accel
    // mnemonics and deal, automatically, with various states, so we have
    // to handle them ourselves. Notice Win32 can't handle \t in ownerdrawn
    // strings either.  We cannot handle mnemonics either.  We display
    // them, though, in the hope we can figure them out some day.
    //

    //
    // Display main text and accel text separately to align better
    //
    wxString                        sTgt = wxT("\t");
    wxString                        sFullString = m_strName; // need to save the original text
    wxString                        sAccel;
    int                             nIndex;
    size_t                          nWidth;
    size_t                          nCharWidth;
    size_t                          nHeight;
    bool                            bFoundMnemonic = FALSE;
    bool                            bFoundAccel = FALSE;

    //
    // Deal with the tab, extracting the Accel text
    //
    nIndex = sFullString.Find(sTgt.c_str());
    if (nIndex != -1)
    {
        bFoundAccel = TRUE;
        sAccel = sFullString.Mid(nIndex + 1);
        sFullString.Remove(nIndex);
    }

    //
    // Deal with the mnemonic character
    //
    sTgt = wxT("~");
    nIndex = sFullString.Find(sTgt.c_str());
    if (nIndex != -1)
    {
        wxString                    sTmp = sFullString;

        bFoundMnemonic = TRUE;
        sTmp.Remove(nIndex);
        rDC.GetTextExtent( sTmp
                          ,(long *)&nWidth
                          ,(long *)&nHeight
                         );
        sTmp = sFullString[(size_t)(nIndex + 1)];
        rDC.GetTextExtent( sTmp
                          ,(long *)&nCharWidth
                          ,(long *)&nHeight
                         );
        sFullString.Replace(sTgt.c_str(), wxEmptyString, TRUE);
    }

    //
    // Draw the main item text sans the accel text
    //
    POINTL                      vPntStart = {nX, rRect.y + 4};
    ::GpiCharStringAt( rDC.GetHPS()
                      ,&vPntStart
                      ,sFullString.length()
                      ,(PCH)sFullString.c_str()
                     );
    if (bFoundMnemonic)
    {
        //
        // Underline the mnemonic -- still won't work, but at least it "looks" right
        //
        wxPen                       vPen;
        POINTL                      vPntEnd = {nX + nWidth + nCharWidth - 3, rRect.y + 2}; //CharWidth is bit wide

        vPntStart.x = nX + nWidth - 1;
        vPntStart.y = rRect.y + 2; // Make it look pretty!
        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
        //
        vPntStart.x = rRect.width - (nWidth + 7);
        vPntStart.y = rRect.y + 4;
        ::GpiCharStringAt( rDC.GetHPS()
                          ,&vPntStart
                          ,sAccel.length()
                          ,(PCH)sAccel.c_str()
                         );
    }

    //
    // 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 - 3;

            ::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                    vBmp(GetBitmap(IsCheckable() ? ((eStatus & wxODChecked) != 0) : TRUE));

        if (vBmp.Ok())
        {

            wxMemoryDC              vDCMem(&rDC);
            wxMemoryDC*             pOldDC = (wxMemoryDC*)vBmp.GetSelectedInto();

            if(pOldDC != NULL)
            {
                vBmp.SetSelectedInto(NULL);
            }
            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));

            int                     nHeightDiff = m_nHeight - nBmpHeight;

            rDC.Blit( rRect.x + (GetMarginWidth() - nBmpWidth) / 2
                     ,rRect.y + nHeightDiff / 2
                     ,nBmpWidth
                     ,nBmpHeight
                     ,&vDCMem
                     ,0
                     ,0
                     ,wxCOPY
                     ,TRUE
                    );

            if (eStatus & wxODSelected)
            {
                POINTL              vPnt1 = {rRect.x + 1, rRect.y + 3}; // Leave a little background border
                POINTL              vPnt2 = {rRect.x + GetMarginWidth(), rRect.y + m_nHeight - 3};

                LINEBUNDLE          vLine;

                vLine.lColor = vColBack.GetPixel();
                ::GpiSetAttrs( hPS
                              ,PRIM_LINE
                              ,LBB_COLOR
                              ,0
                              ,&vLine
                             );
                ::GpiMove(hPS, &vPnt1);
                ::GpiBox( hPS
                         ,DRO_OUTLINE
                         ,&vPnt2
                         ,0L
                         ,0L
                        );
            }
            vBmp.SetSelectedInto(NULL);
        }
    }
    return TRUE;
} // end of wxOwnerDrawn::OnDrawItem
コード例 #2
0
ファイル: checklst.cpp プロジェクト: gitrider/wxsj2
bool wxCheckListBoxItem::OnDrawItem (
  wxDC&                             rDc
, const wxRect&                     rRect
, wxODAction                        eAct
, wxODStatus                        eStat
)
{
    wxRect                          vRect = rRect;

    ::WinQueryWindowRect( m_pParent->GetHWND()
                         ,&rDc.m_vRclPaint
                        );
    if (IsChecked())
        eStat = (wxOwnerDrawn::wxODStatus)(eStat | wxOwnerDrawn::wxODChecked);

    //
    // Unfortunately PM doesn't quite get the text position exact.  We need to alter
    // it down and to the right, just a little bit.  The coords in rRect are OS/2
    // coords not wxWidgets coords.
    //
    vRect.x += 5;
    vRect.y -= 3;
    if (wxOwnerDrawn::OnDrawItem( rDc
                                 ,vRect
                                 ,eAct
                                 ,eStat))
    {
        size_t                      nCheckWidth  = GetDefaultMarginWidth();
        size_t                      nCheckHeight = m_pParent->GetItemHeight();
        int                         nParentHeight;
        int                         nX = rRect.GetX();
        int                         nY = rRect.GetY();
        int                         nOldY = nY;
        wxColour                    vColour(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
        wxPen                       vPenBack;
        wxPen                       vPenGray;
        wxPen                       vPenPrev;

        m_pParent->GetSize( NULL
                           ,&nParentHeight
                          );

        nY = nParentHeight - nY - nCheckHeight;
        vPenBack = wxPen(vColour, 1, wxSOLID);
        vPenGray = wxPen(wxColour(127, 127, 127), 1, wxSOLID);

        //
        // Erase the 1-pixel border
        //
        rDc.SetPen(vPenBack);
        rDc.DrawRectangle( nX
                          ,nY
                          ,nCheckWidth
                          ,nCheckHeight
                         );

        //
        // Now we draw the smaller rectangle
        //
        nY++;
        nCheckWidth  -= 2;
        nCheckHeight -= 2;

        //
        // Draw hollow gray rectangle
        //
        rDc.SetPen(vPenGray);
        rDc.DrawRectangle( nX
                          ,nY
                          ,nCheckWidth
                          ,nCheckHeight
                         );

        nX++;
        if (IsChecked())
        {
            //
            // Draw the check by loading the sys standard bitmap and drawing it
            //
            HBITMAP                 hChkBmp = ::WinGetSysBitmap( HWND_DESKTOP
                                                                ,SBMP_MENUCHECK
                                                               );
            POINTL                  vPoint = {nX, nOldY + 3};

            ::WinDrawBitmap( rDc.GetHPS()
                            ,hChkBmp
                            ,NULL
                            ,&vPoint
                            ,NULL
                            ,NULL
                            ,DBM_NORMAL
                           );
        }
        return TRUE;
    }
    return FALSE;
} // end of wxCheckListBoxItem::OnDrawItem